如何使用 32 个寄存器在 VHDL 中制作 32x32 RAM?

问题描述 投票:0回答:1

我写的第一个文件是为 D Flip-FLop 写的。触发器必须有一个异步 RST 输入和一个取反的 QN 输出。它的目的是作为一个记忆细胞。

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

ENTITY DFF IS
    PORT (
        CLK: IN  STD_LOGIC;
        RST: IN  STD_LOGIC; -- Active-high Reset
        D:   IN  STD_LOGIC;
        Q:   OUT STD_LOGIC;
        QN:  OUT STD_LOGIC
    );
END DFF;

ARCHITECTURE Behavioral OF DFF IS

    SIGNAL Q_tmp: STD_LOGIC;
    
BEGIN

    PROCESS (CLK, RST, Q_tmp)
    BEGIN
        IF (RST = '1') THEN
            Q_tmp <= '0';
        ELSIF (RISING_EDGE(CLK)) THEN
            Q_tmp <= D;
        END IF;
        Q <= Q_tmp;
        QN <= NOT Q_tmp;
    END PROCESS;
    
END Behavioral;

我写的第二个文件是一个32位的REGISTER:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

ENTITY REGISTER_32 IS
    GENERIC (N: INTEGER := 32);
    PORT (
        CLK: IN  STD_LOGIC;
        EN:  IN  STD_LOGIC;
        RST: IN  STD_LOGIC;
        D:   IN  STD_LOGIC_VECTOR(N-1 DOWNTO 0);
        Q:   OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0);
        QN:  OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0)
    );
END REGISTER_32;

ARCHITECTURE Behavioral OF REGISTER_32 IS

    SIGNAL Q_tmp:  STD_LOGIC_VECTOR(N-1 DOWNTO 0);
    SIGNAL QN_tmp: STD_LOGIC_VECTOR(N-1 DOWNTO 0);
    
BEGIN
    
    CELLS : FOR i IN 0 TO (N-1) GENERATE
        CELL_i : ENTITY work.DFF
            PORT MAP (
                CLK => CLK,
                RST => RST,
                D   => D(i),
                Q   => Q_tmp(i),
                QN  => QN_tmp(i)
            );
    END GENERATE CELLS;

    PROCESS (CLK, RST)
    BEGIN
        IF (RST = '1') THEN
            Q  <= (OTHERS => '0');
            QN <= (OTHERS => '1');
        ELSIF (RISING_EDGE(CLK)) THEN
            IF (EN = '1') THEN
                Q  <= Q_tmp;
                QN <= QN_tmp;
            END IF;
        END IF;
        
    END PROCESS;

END Behavioral;

第三个文件给我带来了问题,我不知道如何修复“multi-driven net on pin RAM[0][31]...”错误。

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;

ENTITY RAM_32x32 IS
    GENERIC (N: INTEGER := 32);
    PORT (
        CLK:  IN  STD_LOGIC;
        WE:   IN  STD_LOGIC;                        -- Active-high Write Enable
        RST:  IN  STD_LOGIC;                        -- Active-high Reset
        ADDR: IN  STD_LOGIC_VECTOR(4 DOWNTO 0);
        DIN:  IN  STD_LOGIC_VECTOR(N-1 DOWNTO 0);
        DOUT: OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0)
    );
END RAM_32x32;

ARCHITECTURE Behavioral OF RAM_32x32 IS

    TYPE RAM_ARRAY IS ARRAY (0 TO N-1) OF STD_LOGIC_VECTOR(N-1 DOWNTO 0);
    SIGNAL RAM : RAM_ARRAY;
    
BEGIN

    P1: PROCESS (RST)
    BEGIN
        IF (RST = '1') THEN
            RAM <= (OTHERS => (OTHERS => '0'));
        END IF;
    END PROCESS P1;

    P2: PROCESS (CLK)
    BEGIN
        IF (RISING_EDGE(CLK)) THEN
            IF (WE = '1') THEN
                RAM(TO_INTEGER(UNSIGNED(ADDR))) <= DIN;
            END IF;
        END IF;
    END PROCESS P2;
    
    DOUT <= RAM(TO_INTEGER(UNSIGNED(ADDR)));
    
    REGISTERS : FOR i IN 0 TO (N-1) GENERATE
        REGISTER_i : ENTITY work.REGISTER_32
            PORT MAP (
                CLK => CLK,
                EN  => WE,
                RST => RST,
                D   => RAM(i),
                Q   => RAM(i),
                QN  => OPEN
            );
    END GENERATE REGISTERS;

END Behavioral;

你能告诉我我做错了什么以及如何解决吗?

vhdl ram flip-flop
1个回答
0
投票

这似乎是家庭作业,所以我会提供一般指导。

当前的问题

在 VHDL 中,信号只能在一个进程内分配。 RAM_32x32 实体在 3 个地方分配 RAM 信号。

首先在P1重置过程中。然后在P2计时过程中。最后作为每个 REGISTER_32

的输出端口

建议的后续步骤

首先删除这两个进程并找到另一种方法来控制 generate 语句中的 enable 行以容纳地址。

然后一旦为 SIM 编译,重新评估您如何使用 REGISTER_32 实体内的启用信号,因为它似乎并没有完全按照您的想法进行操作。

© www.soinside.com 2019 - 2024. All rights reserved.