I have very simple 'program' written in VHDL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std;
entity Xand is
generic(width : integer:=8);
port( clk : in std_logic;
A,B : in std_logic_vector(width-1 downto 0);
C : out std_logic_vector(width-1 downto 0)
);
end Xand;
architecture Behavioral of Xand is
begin
C<= A and B;
end Behavioral;
My actual test-bench looks like this:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
ENTITY Xand_tb IS
--generic(width : integer);
END Xand_tb;
ARCHITECTURE behavior OF Xand_tb IS
COMPONENT Xand IS
generic(width : integer);
port( clk : in std_logic;
A,B : in std_logic_vector(width-1 downto 0);
C : out std_logic_vector(width-1 downto 0)
);
end COMPONENT;
signal width : integer := 8;
-- inputs
signal clk : std_logic := '0';
signal A, B : std_logic_vector(width-1 downto 0) := (others => '0');
--Outputs
signal C : std_logic_vector(width-1 downto 0);
constant period : time := 10 ns;
BEGIN
-- instantiate the Unit Under Test (UUT)
uut: Xand generic map (width => 8)
PORT MAP (
clk => clk,
A => A,
B => B,
C => C
);
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 100 ns;
wait for period*10;
for i in 0 to 2**width loop
A <= std_logic_vector( unsigned(A) + 1 );
for j in 0 to 2**width loop
B <= std_logic_vector( unsigned(B) + 1 );
wait for period;
end loop;
for j in 0 to width loop
B(j) <= '0';
end loop;
wait for period;
end loop;
wait;
end process;
END;
Sadly I get error (when I want to simulate it with --vcd=xand.vcd).
ghdl:error: overflow detected
from: process work.xand_tb(behavior).stim_proc at Xand_tb.vhd:57
ghdl:error: simulation failed
It's B(j) <= '0';
line that don't work. From what I understand A and B are vectors that have 8 bits. So I want to test my Xand program with diffrent A and B values that are from [0,256). Sadly I have no idea how to make vector B equal 0 diffrent way than with the loop, which doesn't work. Can someone explain my what generic() does?
Typically you want to drive the input signals and verify the outputs have the expected values.
For example, after the component instantiation,
clk <= not clk after period/2;
stim : process is
begin
-- first test
A <= "00000010";
B <= "00000010";
wait for 10 ns;
assert C = "00000100" report "2 + 2 should be 4" severity ERROR;
-- second test
A <= "00000000";
-- etc
std.env.stop; -- in VHDL-2008, to end the simulation
end process;
Because it's self-checking, you don't normally need to bother inspecting waveforms unless one of the assertions reports an error. Then you have to analyze further to see why the output doesn't match the expected result, bearing in mind it's possible that the test is in error.
So I looked at it again.
I did. Line 57 is "end loop;"
which can't overflow.
But the line before obviously overflows, as ghdl says. Why are you writing to 9 elements in an 8 element array?
You could use the type system instead of fighting it.
for j in B'range loop
will loop over all the elements in B and nothing else .
But an aggregate like B <= (others => '0');
would eliminate the loop altogether.
As the solution for your overflow problem has already been answered by @Briandrummond, I will only answer the question:
Can someone explain me what generic() does?
GENERIC is used to define an entity behavior at instanciation time, ie the behavior that will be implemented on your hardware. It's declared in the entity with a default value the way you did in your example
entity Xand is
generic(
width : integer := 8 -- generic integer value, default is 8
);
port(
A,B : in std_logic_vector(width-1 downto 0); -- input signals, with length equal to generic value "width"
C : out std_logic_vector(width-1 downto 0) -- output signal, with length equal to generic value "width"
);
end Xand;
In your example, GENERIC defines the length of signals A, B and C. This means that when your compiler will create the netlist to implement on your ASIC or FPGA, it will create signals with the very length defined by your GENERIC value. Let's see two instanciations of this entity :
Xand_2bits : entity work.Xand
generic map(
width => 2
)
port map(
A => 2bits_signal_A
,B => 2bits_signal_B
,C => 2bits_signal_C
);
Xand_default : entity work.Xand
port map(
A => 8bits_signal_A
,B => 8bits_signal_B
,C => 8bits_signal_C
);
These two instantiation from the same entity will not be synthesized the same way by your compilation tool. Instance Xand_2bits
will be synthesized as the following equations :
2bits_signal_C(0) <= 2bits_signal_A(0) and 2bits_signal_B(0);
2bits_signal_C(1) <= 2bits_signal_A(1) and 2bits_signal_B(1);
Only 2 and
gate will be implemented on your hardware.
Instance Xand_default
will be synthesized as the following equations :
8bits_signal_C(0) <= 8bits_signal_A(0) and 8bits_signal_B(0);
8bits_signal_C(1) <= 8bits_signal_A(1) and 8bits_signal_B(1);
[...]
8bits_signal_C(6) <= 8bits_signal_A(6) and 8bits_signal_B(6);
8bits_signal_C(7) <= 8bits_signal_A(7) and 8bits_signal_B(7);
This time, 8 and
gate will be implemented on your hardware.
It's possible to define several different behavior using if-generate
statement. This is already explained here
It's also possible to define different type
. This is already explained here
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.