Is the following test bench correct?
I tried to use a text file with the content
00
01
10
11
to test an architecture of an and port.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use std.textio.all;
entity my_and_tb is
end entity my_and_tb;
architecture tb_arch of my_and_tb is
component my_and is
port ( x, y : in std_ulogic;
z : out std_ulogic);
end component;
signal x_tb, y_tb, z_tb : std_ulogic;
begin
my_and_inst : my_and port map( x => x_tb, y => y_tb, z => z_tb);
tb_process : process
file my_input : TEXT open READ_MODE is "my_input.txt";
file my_output : TEXT open WRITE_MODE is "my_output.txt";
variable my_line : LINE;
variable my_input_line : LINE;
variable my_output_line : LINE;
variable x_bit : bit;
variable y_bit : bit;
variable z_bit : bit;
begin
while not endfile(my_input) loop
readline(my_input,my_line);
read(my_line,x_bit);
read(my_line,y_bit);
x_tb <= to_stdulogic(x_bit) after 5 ns;
y_tb <= to_stdulogic(y_bit) after 5 ns;
z_bit := to_bit(z_tb);
write(my_output_line,z_bit);
writeline(my_output,my_output_line);
wait for 10 ns;
end loop;
end process;
end architecture tb_arch;
Basically the simulation with ncsim is blocked…
Update…
Same problem for this example (is a flip flop d, and basically the clock make me confuse, i thought it was ok but it isn't… could you help me?)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_misc.all;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
use std.textio.all;
entity ff_d_tb is
end entity ff_d_tb;
architecture ff_d_tb_arch of ff_d_tb is
component ff_d is
port(clk, d : in std_logic;
q : out std_logic);
end component;
signal clk_tb, d_tb, q_tb : std_logic;
begin
ff_d_comp : ff_d
port map(clk => clk_tb, d => d_tb, q => q_tb);
clk_process : process
begin
clk_tb <= '0','1' after 5 ns;
wait for 10 ns;
end process;
ff_process : process
file in_file : text open READ_MODE is "input.txt";
file out_file : text open WRITE_MODE is "output.txt";
variable l_in : line;
variable l_out : line;
variable q_loc, d_loc : std_logic;
begin
while not endfile(in_file) loop
readline(in_file,l_in);
read(l_in,d_loc);
d_tb <= d_loc after 5 ns;
wait until falling_edge(clk_tb);
q_loc := q_tb;
write(l_out,q_loc);
writeline(out_file,l_out);
end loop;
wait;
end process;
end architecture ff_d_tb_arch;
Best Answer
No. Your testbench isn't correct.
You have two superfluous use clauses:
Your process
tb_process
should havewait;
end loop;
allowing the simulation to complete when you've finished processing input stimulus frommy_input.txt
.About then you'll notice all your results in
my_output.txt
are all0
, which is caused by delta cycle delay in assignment to signalz_tb
in entitymy_and
. Your process also has delayed assignments tox_tb
andy_tb
which need to be taken into account.No signal update occurs during the execution of any process (and all signal updates occur within processes, concurrent statements are elaborated into process statements or process statements and block statements). Essentially you need to suspend the process before any of these assignments take effect.
The cure is one or more wait statements which will suspend execution. The following shows two, a
wait for 5 ns;
and await for 0 ns;
. They can be collapsed in to one wait statement. The purpose is to show that you need at least a delta cycle delay following assignments tox_tb
andy_tb
taking effect forz_tb
to be updated. If there were a delayed signal assignment forz
(z_tb
) in entitymy_and
that delay would also be added to the first wait statement.Note the
wait for 10 ns;
is commented out, it's not needed when your process has a linear model of time allowing signal assignments to take affect (has (an) other wait statement(s)).The above modification to your process statement with a zero delay model for
my_and
gives:Which is the expected output.
Notice the commented report statements which can be used to debug the process statement. If you don't have enough delay the first report for
z_tb
will show a'U'
.