0

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?

ogarogar
  • 323
  • 2
  • 14
  • You need to drive the input signals. Have you tried to do this, and if so, what went wrong? – scary_jeff Feb 28 '18 at 10:02
  • What is your question? Are you looking for a simulation tool like Modelsim or GHDL? "unclear what you're asking Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question." – JHBonarius Feb 28 '18 at 10:17
  • @scary_jeff I think i did it, edited my question. woudl you mind looking at it again? – ogarogar Feb 28 '18 at 12:32
  • You define `B : in std_logic_vector(width-1 downto 0);`. Then you loop `j in 0 to width` so `j` will at some point be `width`. Thus, you are assigning `B(width)` which is out of range... – JHBonarius Feb 28 '18 at 14:24
  • Off topic, but this regarding the word 'to': it's usually not clear if the range includes or excludes the final number. You should actually write "up to and including", but this is impractical in programming. – JHBonarius Feb 28 '18 at 14:29
  • `for i in 0 to 2**width - 1 loop`, `for j in 0 to 2**width - 1 loop` and `j in 0 to width - 1`. The last one caused the bounds error. Move the last `wait for period;` inside the last loop after the assignment. https://i.stack.imgur.com/1JZDX.png . The image taken in gtkwave with GHW dump file format instead of VCD. –  Feb 28 '18 at 23:45

2 Answers2

4

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.

  • I added my question, woudl you mind looking at it again? – ogarogar Feb 28 '18 at 12:32
  • ..And of course `std_logic_vector(to_unsigned([number], [width]))`, to be able to input simple natural numbers (which you could put into a function, for less type work). – JHBonarius Feb 28 '18 at 14:32
  • B'RANGE would be B'REVERSE_RANGE to get the order from 0 to WIDTH-1. The OP is also doing `0 to 2**WIDTH` ranges for the outer for loops which for WIDTH=8 is 257 iterations. With operand ordering those should be 0 to 2**WIDTH - 1` ranges. The OP also has a `wait for period'` statement out of place. https://i.stack.imgur.com/xaq4P.jpg –  Feb 28 '18 at 23:54
0

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, i-e 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

grorel
  • 1,408
  • 15
  • 21
  • There are generic constants, generic types, generic packages and generic subprograms all of which can occur in a generic clause and be associated in a generic map. You seem to be addressing generic constants (the reserved word constant is optional here). As might gather the question is too broad or your answer isn't broad enough. –  Mar 01 '18 at 00:26