在测试中输出“强制未知”值

时间:2014-10-09 08:42:17

标签: vhdl

我正在尝试用VHDL编写寄存器文件。首先,我为N位定义存储元素。其次实现寄存器文件,具有WA(写地址),RA(读地址),WDR / RDP(写/读数据端口)等功能。之后为regfile生成testbench,但在测试中获取“X”时,通过RA地址获取任何数据。我怎么解决这个问题?执行我的regfile可能有问题吗?

waveform

a)存储数据元素

library ieee;
use ieee.std_logic_1164.all;

entity REGn is 
    generic(INITREG: std_logic_vector:="1001");
    port(Din : in std_logic_vector(INITREG'range);
         EN  : in std_logic;    
         INIT: in std_logic;
         CLK : in std_logic;
         OE  : in std_logic;
         Dout: out std_logic_vector(INITREG'range));
end REGn;

architecture beh_regn of REGn is
    signal reg: std_logic_vector(INITREG'range);    
    constant ALLZ: std_logic_vector(INITREG'range):=(others => 'Z');
begin
    Main: process(Din, EN, INIT, CLK)
    begin                              
        if INIT = '1' then
            reg <= INITREG;
        elsif EN = '1' then
            if rising_edge(CLK) then
                reg <= Din;
            end if;
        end if;
    end process;
    Dout <= reg when OE='0' else ALLZ;
end beh_regn;

b)注册文件

library ieee;
use ieee.std_logic_1164.all; 
use ieee.std_logic_unsigned.all;

entity REGFile is
    generic(INITREG: std_logic_vector:="0000";
            a      : integer:=2);
    port(INIT:  in std_logic;
         WDP :  in std_logic_vector(INITREG'range);
         WA  :  in std_logic_vector(a-1 downto 0);
         RA  :  in std_logic_vector(a-1 downto 0);
         WE  :  in std_logic;
         RDP : out std_logic_vector(INITREG'range));
end REGFile;

architecture beh_regfile of REGFile is
    component REGn is
        generic(INITREG: std_logic_vector:="1001");
        port(Din:  in std_logic_vector(INITREG'range);
            EN  :  in std_logic;                   
            INIT:  in std_logic;
            CLK :  in std_logic;
            OE  :  in std_logic;
            Dout: out std_logic_vector(INITREG'range));
    end component;    
    signal wen: std_logic_vector(2**a-1 downto 0);
    signal ren: std_logic_vector(2**a-1 downto 0);
    signal readd: std_logic_vector(INITREG'range);
begin                    
    -- Write decoder
    WAD: process(WA)
    begin
        for i in 0 to 2**a-1 loop   
            if i = CONV_INTEGER(WA) then
                wen(i) <= '1';
            else
                wen(i) <= '0';
            end if;
        end loop;
    end process;               

    -- Read decoder
    RAD: process(RA)
    begin       
        for i in 0 to 2**a-1 loop
            if i = CONV_INTEGER(RA) then
                ren(i) <= '1';
            else
                ren(i) <= '0';
            end if;
        end loop;
    end process;

REGi: for i in 2**a-1 downto 0 generate
    REGi: REGn generic map (INITREG)
               port map (WDP, wen(i), INIT, WE, ren(i), readd);
end generate;

RDP <= readd;
end beh_regfile;

c)注册文件的测试平台

library ieee;       
library std;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use std.textio.all;

    -- Add your library and packages declaration here ...

entity regfile_tb is
    -- Generic declarations of the tested unit
        generic(
        INITREG : STD_LOGIC_VECTOR := "0000";
        a : INTEGER := 2 );
end regfile_tb;

architecture TB_ARCHITECTURE of regfile_tb is
    -- Component declaration of the tested unit
    component regfile
        generic(
        INITREG : STD_LOGIC_VECTOR := "0000";
              a : INTEGER := 2 );
    port(
        INIT : in STD_LOGIC;
        WDP : in STD_LOGIC_VECTOR(INITREG'range);
        WA : in STD_LOGIC_VECTOR(a-1 downto 0);
        RA : in STD_LOGIC_VECTOR(a-1 downto 0);
        WE : in STD_LOGIC;
        RDP : out STD_LOGIC_VECTOR(INITREG'range) );
    end component;

    -- Stimulus signals - signals mapped to the input and inout ports of tested entity
    signal INIT : STD_LOGIC;
    signal WDP  : STD_LOGIC_VECTOR(INITREG'range);
    signal WA   : STD_LOGIC_VECTOR(a-1 downto 0);
    signal RA   : STD_LOGIC_VECTOR(a-1 downto 0);
    signal WE   : STD_LOGIC;
    -- Observed signals - signals mapped to the output ports of tested entity
    signal RDP : STD_LOGIC_VECTOR(INITREG'range);

    -- Add your code here ...               
    type TEST_REC is record          
           INIT : STD_LOGIC;
            WDP : STD_LOGIC_VECTOR(INITREG'range);
            WA  : STD_LOGIC_VECTOR(a-1 downto 0);
            RA  : STD_LOGIC_VECTOR(a-1 downto 0);    
            WE  : STD_LOGIC;
    end record;

    type TEST_ARRAY is array(positive range <>) of TEST_REC;
    constant PATTERN : test_array:= (        
        -- initialize
        (INIT=>'1', WDP=>"0000", WA=>"00", RA=>"00", WE=>'0'),
        (INIT=>'1', WDP=>"0000", WA=>"01", RA=>"01", WE=>'0'),
        (INIT=>'1', WDP=>"0000", WA=>"10", RA=>"10", WE=>'0'),
        (INIT=>'1', WDP=>"0000", WA=>"11", RA=>"11", WE=>'0'),
        --- test vectors      
        (INIT=>'0', WDP=>"1000", WA=>"00", RA=>"00", WE=>'1'),
        (INIT=>'0', WDP=>"1000", WA=>"00", RA=>"00", WE=>'0')
    );

begin

    -- Unit Under Test port map
    UUT : regfile
        generic map (
            INITREG => INITREG,
            a => a
        )

        port map (
            INIT => INIT,
            WDP  => WDP,
            WA   => WA,
            RA   => RA,
            WE   => WE,
            RDP  => RDP
        );

    -- Add your stimulus here ...     
    process
        variable VECTOR: TEST_REC;
    begin
        for i in PATTERN'range loop
            VECTOR:= PATTERN(i);     
            INIT  <= VECTOR.INIT;
            WDP   <= VECTOR.WDP;
            WA    <= VECTOR.WA;
            RA    <= VECTOR.RA;    
            WE    <= VECTOR.WE;
            wait for 100 ns;
        end loop;
    end process;          

    process
        variable my_line: line;
    begin                         
        wait for 5ns;
        write(my_line,"WDP=");
        write(my_line,WDP);  
        write(my_line," INIT=");
        write(my_line,INIT);
        write(my_line," WA=");
        write(my_line,WA);
        write(my_line," RA=");
        write(my_line,RA);       
        write(my_line," RDP=");
        write(my_line,RDP);
        writeline(output,my_line);   
        wait for 96ns;
    end process;


end TB_ARCHITECTURE;

configuration TESTBENCH_FOR_regfile of regfile_tb is
    for TB_ARCHITECTURE
        for UUT : regfile
            use entity work.regfile(beh_regfile);
        end for;
    end for;
end TESTBENCH_FOR_regfile;

1 个答案:

答案 0 :(得分:1)

您的输出无法正确显示:

regfile_tb_ghw.png (图片链接到完整尺寸的图片)

对于所有四个Regn实例,注意三个同时为低,并且它们导致与Readd的位不同的冲突。

Regn的架构beh_regn:

Dout <= reg when OE='0' else ALLZ;

有三个输出启用&#39; 0&#39;,&#39; 1&#39;和&#39; 0&#39;解析为&#39; X&#39; (参见包std_logic_1164,正文,resolution_table)。

你有ren(i)反转的赋值,应该是:

-- Read decoder
RAD: process(RA)
begin       
    for i in 0 to 2**a-1 loop
        if i = CONV_INTEGER(RA) then
            ren(i) <= '0';  -- was '1'
        else
            ren(i) <= '1';  -- was '0'
        end if;
    end loop;
end process;

不能保证这一切都是错误的,但是在通过RA地址获取任何数据时,在测试获取&#34; X&#34;中回答 &#34; ...我怎么解决这个问题?在我的regfile实现中可能有问题吗?&#34;

(将赋值转换为ren(i),是的,REGFile中有错误。)

另请注意,尽管您的VHDL工具允许,但您需要在数字文字和后续标识符之间留出空格(例如,您的测试平台中为96ns)。这在标准的下一版本中不会发生变化。