Reputation: 131
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;
What is the problem with the testbench? Thank a lot for any help!
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');
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;
Upvotes: 0
Views: 533
Reputation: 131
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