一般来说,在写入地址之前读取地址不会产生任何有用的结果。
您的框图显示了一个 32 位宽、8 字深的寄存器文件,具有两个读取端口和一个写入端口,其中 RegWrite 用作由写入地址的解码门控的时钟。稳定的 WriteRegNum 值和 RegWrite 的上升沿会影响对 WriteRegNum 指定的地址的写入。
两个读取端口看起来完全独立。在相应的 ReadRegNumA 或 ReadRegNumB 上指定地址应将该寄存器的内容输出到相应的输出端口。
为了得到有用的东西,你必须首先写入该位置,否则它将是默认值((其他=>'U'),),就像你的波形一样。
在期望从某个位置读取有效数据之前尝试写入该位置。使用可通过寄存器位置区分的值。理论上,您应该保留 WriteRegNum 相对于 RegWrite 上升沿的建立和保持时间。
刺激产生输出的示例:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity registerfile_32x8 is
port (
RegWrite: in std_logic;
WriteRegNum: in std_logic_vector (2 downto 0);
WriteData: in std_logic_vector (31 downto 0);
ReadRegNumA: in std_logic_vector (2 downto 0);
ReadRegNumB: in std_logic_vector (2 downto 0);
PortA: out std_logic_vector (31 downto 0);
PortB: out std_logic_vector (31 downto 0)
);
end entity;
architecture fum of registerfile_32x8 is
type reg_array is array (0 to 7) of std_logic_vector(31 downto 0);
signal reg_file: reg_array;
begin
process(RegWrite)
begin
if rising_edge(RegWrite) then
reg_file(to_integer(unsigned(WriteRegNum))) <= WriteData;
end if;
end process;
PortA <= reg_file(to_integer(unsigned(ReadRegNumA)));
PortB <= reg_file(to_integer(unsigned(ReadRegNumB)));
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity reg_tb is
end entity;
architecture fum of reg_tb is
component registerfile_32x8
port (
RegWrite: in std_logic;
WriteRegNum: in std_logic_vector (2 downto 0);
WriteData: in std_logic_vector (31 downto 0);
ReadRegNumA: in std_logic_vector (2 downto 0);
ReadRegNumB: in std_logic_vector (2 downto 0);
PortA: out std_logic_vector (31 downto 0);
PortB: out std_logic_vector (31 downto 0)
);
end component;
signal RegWrite: std_logic := '1';
signal WriteRegNum: std_logic_vector (2 downto 0) := "000";
signal WriteData: std_logic_vector (31 downto 0) := (others => '0');
signal ReadRegNumA: std_logic_vector (2 downto 0) := "000";
signal ReadRegNumB: std_logic_vector (2 downto 0) := "000";
signal PortA: std_logic_vector (31 downto 0);
signal PortB: std_logic_vector (31 downto 0);
begin
DUT:
registerfile_32x8
port map (
RegWrite => RegWrite,
WriteRegNum => WriteRegNum,
WriteData => WriteData,
ReadRegNumA => ReadRegNumA,
ReadRegNumB => ReadRegNumB,
PortA => PortA,
PortB => PortB
);
STIMULUS:
process
begin
wait for 20 ns;
RegWrite <= '0';
wait for 20 ns;
RegWrite <= '1';
wait for 20 ns;
WriteData <= x"feedface";
WriteRegnum <= "001";
RegWrite <= '0';
wait for 20 ns;
RegWrite <= '1';
ReadRegNumA <= "001";
wait for 20 ns;
WriteData <= x"deadbeef";
WriteRegNum <= "010";
ReadRegNumB <= "010";
RegWrite <= '0';
wait for 20 ns;
RegWrite <= '1';
wait for 20 ns;
wait for 20 ns;
wait;
end process;
end architecture;
david_koontz@Macbook: ghdl -a regfile_32x8.vhdl
david_koontz@Macbook: ghdl -e reg_tb
david_koontz@Macbook: ghdl -r reg_tb --wave=reg_tb.ghw
大卫·孔茨@Macbook:打开 reg_tb.gtkw
本质上,重点是在正在读取的寄存器文件中包含非“U”值。如果您注意到对 WriteRegNum =“010”的最后一次写入,则 PortB 显示未定义的输出,直到写入发生。