01-20-2018 01:22 PM
I'm trying to create a simple shift reg in vhdl and a test bench to test it.
here is my code:
library ieee ; use ieee.std_logic_1164.all ; use ieee.std_logic_unsigned.all ; entity Shift_Reg is port ( resetN : in std_logic ; clk : in std_logic ; din : in std_logic_vector (7 downto 0) ; write_din : in std_logic ; ena_load : buffer std_logic ; ena_shift : in std_logic ; LSB : out std_logic) ; end Shift_Reg ; architecture arc_Shift_Reg of Shift_Reg is signal dint : std_logic_vector (7 downto 0) ; begin process ( clk, resetN ) begin if resetN = '0' then dint <= (others => '0') ; elsif rising_edge(clk) then if write_din = '1' and ena_load = '1' then dint <= din ; elsif ena_shift = '1' then -- shifting bits LSB <= dint(0) ; dint (6 downto 0) <= dint (7 downto 1 ) ; dint(7) <= '0' ; end if ; end if ; end process ; end arc_Shift_Reg ;
and the test bench:
library ieee ; use ieee.std_logic_1164.all ; use ieee.std_logic_unsigned.all ; entity tb_Shift is end tb_Shift ; architecture arc_tb_Shift of tb_Shift is component Shift_Reg is port ( resetN : in std_logic ; clk : in std_logic ; din : in std_logic_vector (7 downto 0) ; write_din : in std_logic ; ena_load : buffer std_logic ; ena_shift : in std_logic ; LSB : out std_logic) ; end component ; signal resetN, clk , write_din : std_logic ; signal din : std_logic_vector (7 downto 0 ) ; signal ena_load , ena_shift , LSB : std_logic; begin u: Shift_Reg port map ( resetN , clk , din , write_din , ena_load , ena_shift ,LSB ); -- clock generator process begin clk <= '0' ; wait for 50 ns ; clk <= '1' ; wait for 50 ns ; end process ; -- asnyc reset input (active low) resetN <= '0' , '1' after 100 ns ; -- sync inputs generator process begin ena_load <= '1' ; din <= "11000101" ; wait for 200 ns ; write_din <= '0' ; wait for 200 ns ; write_din <= '1' ; ena_load <= '0' ; wait for 200 ns ; ena_shift <= '1' ; wait for 200 ns ; ena_load <= '1' ; wait for 200 ns ; ena_shift <= '1' ; wait for 300 ns ; ena_shift <= '0' ; wait for 200 ns ; ena_shift <= '1' ; wait for 600 ns ; assert false report "end of test" severity note ; wait ; end process ; end arc_tb_Shift ;
But the signal ena_load remains uninitialized. What could be the problem here?
Any help would be very much appreciated.
P.S. I'm using ModelSim as a simulator
01-20-2018 02:16 PM - edited 01-20-2018 02:20 PM
Xilinx has some old warnings out there in the internet about not using buffer. Maybe they still aren't able to properly use buffer. The quickest way to test this is to change your buffer to output.
Other unrelated to your question feedback:
Also, you may want to consider using the stop or finish procedures in env package of the std library, instead of a fake warning or failure to terminate your simulation.
Also, you may want to consider using named association in your port map instead of positional association.
Also, if you're targeting a Xilinx device, you may want to consider using a synchronous reset (or just signal initialization for those signals that infer registers).
Also you may want to consider using the rising_edge() function.
01-21-2018 04:53 AM
Using buffer ports can often cause problems, and pretty much redundant in VHDL 2008 now as you can read out ports. Basically, dont use buffer. You're not even driving it from within the shift reg, so why did you make it a buffer?
In the testbench, you're going to get confused. You are driving the stimulus with absolute time delays, rather than synchronising it to the clock. You're going to be very confused when it looks like your first input isnt registering properly because your stimulus is actually changing 1 delta cycle before the clock edge. Synchronise your stimulus to the clock using:
wait until rising_edge(clk);
to ensure simulation behaves as expected.
Similar thing for reset. It's usually safer to have the reset finish outside of a clock edge.
And as the other poster mentioned, using false assertions is a very old school way to end a testbench. Best practice is to use std.env package (from VHDL 2008) or turn the clock off or have all processes stuck at a wait;