简体   繁体   中英

Simple test bench in vhdl with generic

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM