I have a vector A that's 64bits long and I want the output B to equal 3 while A is 30-35 and zero elsewhere. I can't figure out the testbench to loop through the vector A as a bit. I've tried several different ways but only got 1/5 of the array to give any output at all. This is as far as I could get without syntax/compile errors.
Main code
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.ALL;
entity ent is
port(A:in std_logic_vector(5 downto 0);
B:out std_logic_vector(3 downto 0));
end ent;
architecture arch_ent of ent is
begin
with A select
B <= "0011" when "011110",
"0011" when "011111",
"0011" when "100000",
"0011" when "100001",
"0011" when "100010",
"0011" when "100011",
"0000" when others;
end arch_ent;
Testbench
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity tb is
end tb;
architecture arch_tb of tb is
component ent
port(A:in std_logic_vector(5 downto 0);
B:out std_logic_vector(3 downto 0));
end component;
signal A_tb: std_logic_vector(5 downto 0);
signal B_tb: std_logic_vector(3 downto 0);
begin
uut: entity ent port map(A=>A_tb, B=>B_tb);
tb: process
constant period: time := 20ns;
begin
for i in A_tb'range loop
A_tb <= std_logic_vector(to_unsigned(i,6));
wait for period;
assert (B_tb = "0011")
report "test failed" severity error;
end loop;
wait;
end process;
end arch_tb;
In the end I'm trying to plot out the waveform like this: http://i10.photobucket.com/albums/a142/blargonblop/wave.png
where A will go to 63 and each output is its correct value from 30-35 and 0 elsewhere
The loop parameter you use to specify the number of 'tests' is A_tb'range, which happens to be 5 downto 0, or six tests, i is assigned 5,4,3,2,1 and 0 successively.
You want to specify i in 0 to 2**A-tb'length-1
or i in 0 to 63
to get all 64 possible A_tb 'binary' values.
(A_tb'length = 6, 2 **
6-1 = 63, where **
is the exponentiation operator, 2 to the 6th power minus 1 equals 63)
I found two syntax errors in your test bench, 20ns where the standard requires a space between 20 and ns:
constant period: time := 20 ns;
And entity ent where that should either be just ent (you have a component declaration ent) or entity work.ent and no need for a component declaration:
uut: ent port map(A=>A_tb, B=>B_tb);
or
uut: entity work.ent port map(A=>A_tb, B=>B_tb);
And in keeping with Russell's answer there is no implied logic replication in a loop other than through synthesis which unravels loop iterations by paralleling logic (the replication). Not all loop statements are intended as synthesis targets.
Test benches are generally not synthesized and are used to write tests (as in your case) for a VHDL model that might be used as a synthesis target.
You really should not be using a for loop for this. For loops in VHDL are used to REPLICATE LOGIC, not to do something some number of times. Try something like this in your test bench:
signal r_CLOCK : std_logic := '0';
signal r_INDEX : unsigned(5 downto 0) := (others => '0');
begin
r_CLOCK <= not r_CLOCK after period/2;
process (r_CLOCK)
begin
if rising_edge(r_CLOCK) then
r_INDEX <= r_INDEX + 1;
end if;
end process;
Now simply cast r_INDEX as std_logic_vector and pass it to your ent
component.
First, loops are just fine, and common, in testbenches. @Russell's comment applies to RTL code. You can adapt his approach for this problem and make it work. You would need to use 64 as a sentinel (ending) value and do your end of test checks then. Keep in mind though that the most important thing you do is code for readability. Test cases generally run from top to bottom of a process one time.
You loop has some issues in addition to the recommendations @DavidKoontz gave. Specifically,
So the modified code is:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.numeric_std_unsigned.all;
entity tb is
end tb;
architecture arch_tb of tb is
constant period: time := 20 ns;
...
begin
...
tb: process
variable ErrorCount :
begin
for i in i in 0 to 2**A-tb'length-1
A_tb <= to_slv(i,6);
wait for period;
if i >= 30 and i <= 35 then
if B_tb /= 3 then
ErrorCount := Error Count + 1 ;
report "B_tb = " & to_string(B_tb) & " Expecting: 0011" severity ERROR ;
end if;
else
if B_tb /= 0 then
ErrorCount := Error Count + 1 ;
report "B_tb = " & to_string(B_tb) & " Expecting: 0000" severity ERROR ;
end if;
end loop;
if ErrorCount = 0 then
report "Test Passed" severity NOTE ;
else
report "Test FAILED. There were " & to_string(ErrorCount) & " Errors " severity NOTE;
end if;
std.env.stop(0) ; -- testbench stops here
end process;
Note that the rules about using (or forbidding usage of) numeric_std_unsigned do not apply to testbenches.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.