14733

test bench of a 32x8 register file VHDL

I wrote the assembly code for this circuit in vhdl already. I want to simulate it with a test bench.

<img src="https://i.stack.imgur.com/BifOR.png" alt="enter image description here">

    <li>RegWrite: 1 bit input (clock)</li> <li>Write Register Number: 3-bit input(write addresses) </li> <li>Write Data: 32-bit input (data in) Read</li> <li>Register Number A: 3-bit input (read addresses)</li> <li>Read Register Number B: 3-bit input (read adddresses) </li> <li>Port A: 32-bit output (data out) </li> <li>Port B: 32-bit output (data out)</li> </ul>

    I think my problem is that I don't understand what this circuit does. I chose random values to assign to the inputs, but it didn't output anything. What are good inputs to choose for this circuit?

    here is my test bench file for reference:

    library ieee; use ieee.std_logic_1164.all; entity Reg_TB is -- entity declaration end Reg_TB; architecture TB 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 T_RegWrite : std_logic; signal T_WriteRegNum: std_logic_vector(2 downto 0); signal T_WriteData: std_logic_vector(31 downto 0); signal T_ReadRegNumA: std_logic_vector(2 downto 0); signal T_ReadRegNumB: std_logic_vector(2 downto 0); signal T_PortA : std_logic_vector(31 downto 0); signal T_PortB : std_logic_vector(31 downto 0); begin T_WriteRegNum <= "011"; T_WriteData <= "00000000000000000000000000000001"; T_ReadRegNumA <= "001"; T_ReadRegNumB <= "100"; U_RegFile: RegisterFile_32x8 port map (T_RegWrite, T_WriteRegNum, T_WriteData,T_ReadRegNumA, T_ReadRegNumB, T_PortA, T_PortB); -- concurrent process to offer clock signal process begin T_RegWrite <= '0'; wait for 5 ns; T_RegWrite <= '1'; wait for 5 ns; end process; process begin wait for 12 ns; -- case 2 wait for 28 ns; -- case 3 wait for 2 ns; -- case 4 wait for 10 ns; -- case 5 wait for 20 ns; wait; end process; end TB;

    as you can see I chose

      <li>WriteRegNum = "011"</li> <li>WriteData = "00000000000000000000000000000001"</li> <li>ReadRegNumA = "001"</li> <li>ReadRegNumB = "100" </li> </ul>

      I think that I chose bad inputs. The simulation does this:

      <img src="https://i.stack.imgur.com/1yeDg.png" alt="enter image description here">

      Answer1:

      In general reading an address before it is written doesn't produce any useful results.

      Your block diagram shows a 32 bit wide 8 word deep register file with two read ports and one write port with RegWrite used as a clock gated by the decode of the write address. A stable WriteRegNum value and a rising edge on RegWrite effects a write to the address specified by WriteRegNum.

      The two read ports appear completely independent. Specifying an address on the respective ReadRegNumA or ReadRegNumB should output the contents of that register to the respective output port.

      To get something useful out, you have to write to that location first, otherwise it will be the default value ((others => 'U'),) suspiciously like your waveform.

      Trying writing to a location before expecting valid read data from it. Use values that are distinguishable by register location. Theoretically you should be preserving set up and hold time on WriteRegNum with respect to the rising edge of RegWrite.

      Example stimulus producing output:

      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 david_koontz@Macbook: open reg_tb.gtkw

      <img src="https://i.stack.imgur.com/9nRUl.png" alt="reg_tb showing register contents">

      Essentially, the point is to have non 'U' values in a register file that's being read. If you notice the last write to WriteRegNum = "010", PortB shows undefined output until the write occurs.

Recommend