High impedance signal does not enter the test bench [VHDL]

First of all, I am new to VHDL and I was trying to create a RAM model (or something similar). The model works fine and I started building my test bench, but it does not reproduce the behavior of the signal file generated from the original model. The main problem is that the high impedance signal “** Z ” turned into “ U ” (undefined), and after the reset signal, the value ( X “0000” *) became “ * X ". ** "(unknown). I have 3 main tests, marked by tags Test_N, in the testbench, but first one, and the last one fails due to aforesaid errors. Therefore the lines with Test_1 and Test_3 are commented. Here is the code for RAM.vhd and RAM_TB.vhd with two screenshots of testing them.

RAM.vhd

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity RAM is
    port (CLK : in std_logic; -- Clock
          R   : in std_logic; -- Reset
          WR  : in std_logic; -- Write
          AE  : in std_logic; -- Address saving in temp.    
          OE  : in std_logic; -- Signal about output word
          AD  : inout std_logic_vector(15 downto 0)); -- out address(11 bits address)/ in data(16 bits data) 
end RAM;

architecture BEH of RAM is
type MEM2KX16 is array(0 to 2047) of std_logic_vector(AD'range);
constant RAM_init : MEM2KX16 := (X"0000", others=>X"0000"); -- initial memory state
signal do : std_logic_vector(AD'range); -- signal for data output
signal addr : std_logic_vector(10 downto 0); -- 2047 = 0111 1111 1111, 11 bits needed
signal addri : natural;
signal RAM_out : MEM2KX16; -- For debug purposes
begin
    RG_ADDR : process (CLK, R)
    begin
        if (R = '1') then
            addr <= "00000000000"; -- Reset address
        elsif rising_edge(CLK) and AE = '1' then
            addr <= AD(10 downto 0); -- Receive address
        end if;
    end process;
    
    RAM2K : process (CLK, addr, addri)
    variable RAM : MEM2KX16 := RAM_init;
    begin
        addri <= to_integer(unsigned(addr(10 downto 0)));
        if rising_edge(CLK) then
            if (WR = '1') then -- Write to memory
                RAM(addri) := AD(15 downto 0);
            end if;
            if (R = '1') then -- Reset memory 
                do <= X"0000";
            else
                do <= RAM(addri); -- Return data from memory
            end if;
        end if;
    RAM_out <= RAM; -- For debug purposes
    end process;
    
    TRI : AD <= do when (OE = '1') -- Three-state buffer
    else "ZZZZZZZZZZZZZZZZ";
end architecture;

RAM_TB.vhd

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity RAM_TB is
end entity;

architecture RAM_TB_arch of RAM_TB is
    component RAM 
    port (CLK : in std_logic; -- Clock
          R   : in std_logic; -- Reset
          WR  : in std_logic; -- Write
          AE  : in std_logic; -- Address saving in temp.    
          OE  : in std_logic; -- Signal about output word
          AD  : inout std_logic_vector(15 downto 0)); -- out address(11 bits address)/ in data(16 bits data) 
    end component;
    constant T : time := 20 ns;
    
    signal CLK_TB, R_TB, WR_TB, AE_TB, OE_TB : std_logic;
    signal AD_TB : std_logic_vector(15 downto 0);
    
    begin
        
        DUT : RAM port map (CLK_TB, R_TB, WR_TB, AE_TB, OE_TB, AD_TB);
        
        process
        begin
            CLK_TB <= '0';
            wait for T/2;
            CLK_TB <= '1';
            wait for T/2;
        end process;
        
        STIMULUS : process
        variable value : std_logic_vector(AD_TB'range) := X"FFFF";
        variable addr  : std_logic_vector(AD_TB'range) := X"0004"; 
        begin
            -- Test ZZZZ output of AD
            R_TB  <= '0'; -- No reset
            WR_TB <= '0'; -- No write
            AE_TB <= '0'; -- No address 
            OE_TB <= '0'; -- No output
            wait for 2*T;
            --Test_1 : assert AD_TB = "ZZZZZZZZZZZZZZZZ" report "[INFO] AD initial state is not ..Z..!" severity FAILURE;
            
            -- Test input of AD
            R_TB  <= '0'; -- No reset
            WR_TB <= '0'; -- No write
            AE_TB <= '1'; -- Read address 
            OE_TB <= '0'; -- No output
            AD_TB <= addr; -- Address RAM(4)
            wait for T;
            WR_TB <= '1'; -- Write
            AE_TB <= '0'; -- Do not read address
            AD_TB <= value; -- Data to write
            wait for T;
            -- Test output of AD
            WR_TB <= '0'; -- No write
            OE_TB <= '1'; -- Output data from RAM
            wait for T;
            Test_2 : assert AD_TB = value report "[INFO] AD output not equals value in RAM(addr)!" severity FAILURE;
            
            -- Test Reset
            R_TB <= '1'; -- Reset
            wait for T;
            --Test_3 : assert AD_TB = X"0000" report "[INFO] AD output not equals zero after Reset!" severity FAILURE;
            
            wait;      
        end process;
end architecture;

RAM waveform RAM wafeform file

RAM testbench waveform RAM testbench waveform

What is the problem with the testbench? Thank a lot for any help!

UPDATE 1

I followed Brian's suggestion in the comment and that partially solved the problem. Now, the uninitialized state in the first test became the high impedance state as intended. But the state "X" in place of zeros still remains.

Updated code in RAM_TB.vhd

signal AD_TB : std_logic_vector(15 downto 0) := (others => 'Z');

RAM_TB waveform (update 1) RAM_TB waveform after update

UPDATE 2

Thanks @Tricky for the solution in comment section.

Updated code in RAM_TB.vhd for Test_3

    R_TB <= '1'; -- Reset
    AD_TB <= "ZZZZZZZZZZZZZZZZ";
    wait for T;

RAM_TB waveform (update 2) RAM_TB waveform (update 2)

Upvotes: 0

Views: 533

Answers (1)

Guided by the comments of @BrianDrummond and @Tricky, I can post an answer to my problem. The causes of the problems and their solutions can be found in the comments under the question.

RAM_TB.vhd

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity RAM_TB is
end entity;

architecture RAM_TB_arch of RAM_TB is
    component RAM 
    port (CLK : in std_logic; -- Clock
          R   : in std_logic; -- Reset
          WR  : in std_logic; -- Write
          AE  : in std_logic; -- Address saving in temp.    
          OE  : in std_logic; -- Signal about output word
          AD  : inout std_logic_vector(15 downto 0)); -- out address(11 bits address)/ in data(16 bits data) 
    end component;
    constant T : time := 20 ns;
    
    signal CLK_TB, R_TB, WR_TB, AE_TB, OE_TB : std_logic;
    signal AD_TB : std_logic_vector(15 downto 0) := (others => 'Z');
    
    begin
        
        DUT : RAM port map (CLK_TB, R_TB, WR_TB, AE_TB, OE_TB, AD_TB);
        
        process
        begin
            CLK_TB <= '0';
            wait for T/2;
            CLK_TB <= '1';
            wait for T/2;
        end process;
        
        STIMULUS : process
        variable value : std_logic_vector(AD_TB'range) := X"FFFF";
        variable addr  : std_logic_vector(AD_TB'range) := X"0004"; 
        begin
            -- Test ZZZZ output of AD
            R_TB  <= '0'; -- No reset
            WR_TB <= '0'; -- No write
            AE_TB <= '0'; -- No address 
            OE_TB <= '0'; -- No output
            wait for 2*T;
            Test_1 : assert AD_TB = "ZZZZZZZZZZZZZZZZ" report "[INFO] AD initial state is not ..Z..!" severity FAILURE;
            
            -- Test input of AD
            R_TB  <= '0'; -- No reset
            WR_TB <= '0'; -- No write
            AE_TB <= '1'; -- Read address 
            OE_TB <= '0'; -- No output
            AD_TB <= addr; -- Address RAM(4)
            wait for T;
            WR_TB <= '1'; -- Write
            AE_TB <= '0'; -- Do not read address
            AD_TB <= value; -- Data to write
            wait for T;
            -- Test output of AD
            AD_TB <= "ZZZZZZZZZZZZZZZZ";
            WR_TB <= '0'; -- No write
            OE_TB <= '1'; -- Output data from RAM
            wait for T;
            Test_2 : assert AD_TB = value report "[INFO] AD output not equals value in RAM(addr)!" severity FAILURE;
            
            -- Test Reset
            wait for T;
            R_TB <= '1'; -- Reset
            AD_TB <= "ZZZZZZZZZZZZZZZZ";
            wait for T;
            Test_3 : assert AD_TB = X"0000" report "[INFO] AD output not equals zero after Reset!" severity FAILURE;
            
            wait;      
        end process;
end architecture;

Upvotes: 0

Related Questions