32x8 寄存器文件 VHDL 的测试台 [英] test bench of a 32x8 register file VHDL

查看:33
本文介绍了32x8 寄存器文件 VHDL 的测试台的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在 vhdl 中为这个电路编写了汇编代码.我想用测试台模拟它.

  • RegWrite:1 位输入(时钟)
  • 写寄存器编号:3位输入(写地址)
  • 写入数据:32 位输入(数据输入)读取
  • 寄存器编号 A:3 位输入(读取地址)
  • 读取寄存器编号 B:3 位输入(读取地址)
  • 端口 A:32 位输出(数据输出)
  • 端口 B:32 位输出(数据输出)

我想我的问题是我不明白这个电路是做什么的.我选择了随机值分配给输入,但它没有输出任何内容.为该电路选择哪些好的输入?

这是我的测试平台文件以供参考:

library ieee;使用 ieee.std_logic_1164.all;实体 Reg_TB 是——实体声明结束 Reg_TB;Reg_TB 的架构 TB 是组件 RegisterFile_32x8端口(RegWrite:在 std_logic 中;WriteRegNum: 在 std_logic_vector(2 downto 0) 中;写入数据:在 std_logic_vector(31 downto 0) 中;ReadRegNumA:在 std_logic_vector(2 downto 0) 中;ReadRegNumB:在 std_logic_vector(2 downto 0) 中;PortA: out std_logic_vector(31 downto 0);PortB: out std_logic_vector(31 downto 0));终端组件;信号 T_RegWrite : std_logic;信号 T_WriteRegNum: std_logic_vector(2 downto 0);信号 T_WriteData: std_logic_vector(31 downto 0);信号 T_ReadRegNumA: std_logic_vector(2 downto 0);信号 T_ReadRegNumB: std_logic_vector(2 downto 0);信号 T_PortA : std_logic_vector(31 downto 0);信号 T_PortB : std_logic_vector(31 downto 0);开始T_WriteRegNum <= "011";T_WriteData <= "00000000000000000000000000000001";T_ReadRegNumA <= "001";T_ReadRegNumB <= "100";U_RegFile:RegisterFile_32x8 端口映射(T_RegWrite, T_WriteRegNum, T_WriteData,T_ReadRegNumA, T_ReadRegNumB, T_PortA, T_PortB);-- 提供时钟信号的并发进程过程开始T_RegWrite <= '0';等待 5 ns;T_RegWrite <= '1';等待 5 ns;结束过程;过程开始等待 12 ns;-- 案例2等待 28 ns;-- 案例 3等待 2 ns;-- 案例 4等待 10 ns;-- 案例5等待 20 ns;等待;结束过程;结束结核病;

如你所见,我选择了

  • WriteRegNum = "011"
  • WriteData = "00000000000000000000000000000001"
  • ReadRegNumA = "001"
  • ReadRegNumB = "100"

我认为我选择了错误的输入.模拟是这样的:

解决方案

通常在写入地址之前读取地址不会产生任何有用的结果.

您的框图显示了一个 32 位宽 8 字深的寄存器文件,带有两个读端口和一个写端口,其中 RegWrite 用作时钟,由写地址的解码控制.稳定的 WriteRegNum 值和 RegWrite 的上升沿会影响写入 WriteRegNum 指定的地址.

两个读取端口看起来完全独立.在相应的 ReadRegNumA 或 ReadRegNumB 上指定地址应将该寄存器的内容输出到相应的输出端口.

为了得到有用的东西,你必须先写到那个位置,否则它会是默认值((others => 'U'),)就像你的波形一样.

在期望从中读取有效数据之前尝试写入该位置.使用可通过寄存器位置区分的值.从理论上讲,相对于 RegWrite 的上升沿,您应该保留 WriteRegNum 上的建立和保持时间.

产生输出的刺激示例:

library ieee;使用 ieee.std_logic_1164.all;使用 ieee.numeric_std.all;实体 registerfile_32x8 是港口 (RegWrite:在 std_logic 中;WriteRegNum: 在 std_logic_vector (2 downto 0);WriteData: 在 std_logic_vector (31 downto 0) 中;ReadRegNumA:在 std_logic_vector (2 downto 0) 中;ReadRegNumB:在 std_logic_vector (2 downto 0) 中;PortA: out std_logic_vector (31 downto 0);PortB: out std_logic_vector (31 downto 0));最终实体;registerfile_32x8 的架构乐趣是类型 reg_array 是 std_logic_vector(31 downto 0) 的数组(0 到 7);信号 reg_file: reg_array;开始进程(正则写)开始如果rising_edge(RegWrite) 那么reg_file(to_integer(unsigned(WriteRegNum))) <= WriteData;万一;结束过程;PortA <= reg_file(to_integer(unsigned(ReadRegNumA)));PortB <= reg_file(to_integer(unsigned(ReadRegNumB)));终端架构;图书馆 IEEE;使用 ieee.std_logic_1164.all;实体 reg_tb 是最终实体;reg_tb 的架构乐趣是组件 registerfile_32x8港口 (RegWrite:在 std_logic 中;WriteRegNum: 在 std_logic_vector (2 downto 0);WriteData: 在 std_logic_vector (31 downto 0) 中;ReadRegNumA:在 std_logic_vector (2 downto 0) 中;ReadRegNumB:在 std_logic_vector (2 downto 0) 中;PortA: out std_logic_vector (31 downto 0);PortB: out std_logic_vector (31 downto 0));终端组件;信号 RegWrite: std_logic := '1';信号 WriteRegNum: std_logic_vector (2 downto 0) := "000";信号写入数据:std_logic_vector (31 downto 0) := (others => '0');信号 ReadRegNumA: std_logic_vector (2 downto 0) := "000";信号 ReadRegNumB: std_logic_vector (2 downto 0) := "000";信号端口A:std_logic_vector(31降到0);信号端口B: std_logic_vector (31 downto 0);开始被测件:registerfile_32x8港口地图(RegWrite =>正则写,WriteRegNum =>写入RegNum,写入数据 =>写数据,ReadRegNumA =>读取RegNumA,ReadRegNumB =>读取RegNumB,端口A =>端口A,端口B =>端口B);刺激:过程开始等待 20 ns;正则写入 <= '0';等待 20 ns;正则写入 <= '1';等待 20 ns;WriteData <= x"feedface";WriteRegnum <= "001";正则写入 <= '0';等待 20 ns;正则写入 <= '1';ReadRegNumA <= "001";等待 20 ns;WriteData <= x"deadbeef";WriteRegNum <= "010";ReadRegNumB <= "010";正则写入 <= '0';等待 20 ns;正则写入 <= '1';等待 20 ns;等待 20 ns;等待;结束过程;终端架构;

<块引用>

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:打开 reg_tb.gtkw

本质上,重点是在正在读取的寄存器文件中具有非U"值.如果您注意到对 WriteRegNum = "010" 的最后一次写入,则 PortB 会显示未定义的输出,直到写入发生.

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

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

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

  • WriteRegNum = "011"
  • WriteData = "00000000000000000000000000000001"
  • ReadRegNumA = "001"
  • ReadRegNumB = "100"

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

解决方案

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

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.

这篇关于32x8 寄存器文件 VHDL 的测试台的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆