# VHDL - Issue with simulation of testbench - Modelsim PE Student 10.4

I'm very new to VHDL and got an issue with the simulation time in Modelsim PE Student Edition 10.4.

I wrote some files for a RTL-model such as multiplexer, demultiplexer and register.

To test my code I tried to implement a testbench for each file. The simulation for the multiplexer and demultiplexer works quite well but the testbench for the registers seems to simulate for ever. Whenever I try to simulate nothing happens and the simulation doesn't finish at any point. I tried to look at the wave forms but they change neither.

Following I will send you the corresponding code for my 4x1-MUX (which simulates quite well) and code for my 12bit register with synchronous reset (which doesn't simulate correctly).

I really can't find the problem in this code.

-- multiplexer for 4 inputs with 12 bit data width to 1 output with 12 bit data width
entity MULTIPLEXER_4TO1_12BIT is
port (
SELECT_IN: in bit_vector (1 downto 0);
D_IN_0: in bit_vector (11 downto 0);
D_IN_1: in bit_vector (11 downto 0);
D_IN_2: in bit_vector (11 downto 0);
D_IN_3: in bit_vector (11 downto 0);
D_OUT: out bit_vector (11 downto 0)
);
end MULTIPLEXER_4TO1_12BIT;

architecture RTL of MULTIPLEXER_4TO1_12BIT is
begin
D_OUT <= D_IN_0 when SELECT_IN = "00" else
D_IN_1 when SELECT_IN = "01" else
D_IN_2 when SELECT_IN = "10" else
D_IN_3;
end RTL;

-- testbench for multiplexer for 4 inputs with 12 bit data width to 1  output with 12 bit data width
entity TESTBENCH_MULTIPLEXER_4TO1_12BIT is
end TESTBENCH_MULTIPLEXER_4TO1_12BIT;

architecture BEHAVIOUR of TESTBENCH_MULTIPLEXER_4TO1_12BIT is
signal SELECT_IN: bit_vector (1 downto 0) := "00";
signal D_IN_0, D_IN_1, D_IN_2, D_IN_3, D_OUT : bit_vector (11 downto 0) := B"0000_0000_0000";
begin
UUT: entity work.MULTIPLEXER_4TO1_12BIT port map (SELECT_IN, D_IN_0, D_IN_1, D_IN_2, D_IN_3, D_OUT);
tb: process
begin
D_IN_0 <= B"0000_0000_0000";
D_IN_1 <= B"0001_0001_0001";
D_IN_2 <= B"0110_0110_0110";
D_IN_3 <= B"1111_1111_1111";

SELECT_IN <= "00";
wait for 2 ns;
SELECT_IN <= "01";
wait for 2 ns;
SELECT_IN <= "10";
wait for 2 ns;
SELECT_IN <= "11";
wait for 2 ns;

assert false report "end of simulation" severity failure;
end process tb;
end BEHAVIOUR;

-- register with 12 bit data width and synchronous reset
entity REG_SYNC_12BIT is
port (
D_IN: in bit_vector (11 downto 0);
CLK: in bit;
EN: in bit;
RST: in bit;
D_OUT: out bit_vector (11 downto 0)
);
end REG_SYNC_12BIT;

architecture RTL of REG_SYNC_12BIT is
begin
process
begin
if (rising_edge (CLK)) then
if (RST = '0') then
D_OUT <= B"0000_0000_0000";
else
if (EN = '1') then
D_OUT <= D_IN;
end if;
end if;
end if;
end process;
end RTL;

-- testbench for register with 12 bit data width and synchronous reset

entity TESTBENCH_REG_SYNC_12BIT is
end TESTBENCH_REG_SYNC_12BIT;

architecture BEHAVIOUR of TESTBENCH_REG_SYNC_12BIT is
signal D_IN, D_OUT: bit_vector (11 downto 0) := B"0000_0000_0000";
signal CLK, EN: bit := '0';
signal RST: bit := '1';

begin
UUT: entity work.REG_SYNC_12BIT port map (D_IN, CLK, EN, RST, D_OUT);
tb: process
begin
EN <= '1';
D_IN <= B"1111_1111_1111";
wait for 4 ns;
CLK <= '1';
wait for 2 ns;
D_IN <= B"0000_1111_1111";
wait for 2 ns;
CLK <= '1';
wait for 10 ns;

assert false report "end of simulation" severity failure;
end process tb;
end BEHAVIOUR;

• Did you mean for your CLK in the second example to only ever be set high? It would be more usual to have statements assigning it alternately to '0' and '1'. – scary_jeff Jun 21 '16 at 14:35
• I just set CLK high to test if my testbench works correctly. But you're right of course. The CLK signal has to be alternating. – Leo Renk Jun 22 '16 at 17:13

There are some typical errors that you should understand and avoid first.

When creating your process instantiating your register you didn't specify any sensitivity list. (If you don' t know what it is check there.) Since your process is synchronous to your clock CLK you need to put it into the sensitivity list.

Another thing that might be useful (it 's more a suggestion than a real mistake) is to put any of your register's reset signal asynchronous (at least in the process) and if you want it synchronous you can still synchronize it at the top level. It will take fewer elements to implement this.

 process (RST, CLK)
begin
if (RST = '0') then

D_OUT <= B"0000_0000_0000";

elsif (rising_edge (CLK)) then

if (EN = '1') then
D_OUT <= D_IN;
end if;

end if;
end process;


Then , in your testbench, like @scary_jeff commented, you didn't make your clock change its state. So your rising_edge condition is only valid one time. To avoid this I suggest that you always create a process apart generating your clock.

clk_gen : process (CLK)
begin

clk <= not clk after clk_period/2;

end process;


(Don't forget to initialize your clock)

Since you didn't really specify what problem you had in simulation I can't help more for now but you should try this first and come back with more information.

• Why does an async reset use less resources? I'm only familiar with Xilinx FPGAs, but in these, the usage is identical for either reset type, with the caveat that async resets cannot be merged with other logic if the tools want to utilise a register's SR pin to reduce LUT usage. Maybe it's different in ASIC world? – scary_jeff Jun 21 '16 at 15:48
• Well I guess that nowadays most of synthesizers can simplify it but to my mind it's preferable to use this syntax to ensure it will actually use the dedicated reset pin – A. Kieffer Jun 21 '16 at 16:00
• An async reset may use less resources in some architectures that lack a dedicated SET/RST (Xilinx parlance for synchronous set/clear). But this is rare if non-existent for today's FPGA (Xilinx and Altera both recommend synchronous resets). The FF's on Xilinx and Altera parts have both synchronous and asynchronous resets and clears (though they may not necessarily all be used together). Also, set/rst dominance can drive logic usage as well. – PlayDough Jun 22 '16 at 15:10
• Thank you very much for your tips. As you recommended I added the CLK and RST signals to the sensitivity list and changed the register to asynchronous reset. Now the simulation runs correctly. Thank you, you rock! :) – Leo Renk Jun 22 '16 at 17:18