I have modeled 4 bit Ring Counter using D Flip Flop.
The D flip flop is in separate file, included in my workspace. The D flip flop works correctly (gives correct output waveform).
This is the code of ring counter:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ring4counter is
port (
clk: std_logic;
output: out std_logic_vector(3 downto 0));
end ring4counter;
architecture ring4counter_arch of ring4counter is
component dff
port (
clk: std_logic;
d: in std_logic;
q: out std_logic;
qbar: out std_logic);
end component;
signal temp:std_logic_vector(3 downto 0):=(others=>'0');
begin
r1: dff port map(clk, temp(3), temp(0));
r2: dff port map(clk, temp(0), temp(1));
r3: dff port map(clk, temp(1), temp(2));
r4: dff port map(clk, temp(2), temp(3));
output <= temp;
end ring4counter_arch;
Here is the testbench code for Ring counter:
library ieee;
use ieee.std_logic_1164.all;
entity ring4_tb is end ring4_tb ;
architecture arch of ring4_tb is
component tbc is
port (
clk: std_logic;
output: out std_logic_vector(3 downto 0));
end component ;
component dff
port (
clk: std_logic;
d: in std_logic;
q: out std_logic;
qbar: out std_logic);
end component;
constant period : time := 50 ns ;
signal clk : std_logic := '0' ;
signal done : boolean := false ;
signal output : std_logic_vector(3 downto 0) ;
shared variable cycle : natural := 0 ;
signal temp:std_logic_vector(3 downto 0):=(others=>'0');
begin
-- this is the unit under test
u1: tbc
port map(
clk => clk,
output => output) ;
clkprocess: process(done, clk)
begin
if (not done) then
if (clk = '1') then
cycle := cycle + 1 ;
end if ;
clk <= not clk after period / 2 ;
end if ;
end process ;
r1: dff port map(clk, temp(3), temp(0));
r2: dff port map(clk, temp(0), temp(1));
r3: dff port map(clk, temp(1), temp(2));
r4: dff port map(clk, temp(2), temp(3));
output <= temp;
testbench: process
begin
wait until (clk = '0') ;
temp <= "1000";
wait for period*4 ;
done <= true ; -- force the clock process to shutdown
wait ; -- this waits forever
end process ;
end arch ;
But the waveform for 'output' is 'U' for all bits. Where am I going wrong?
In the testbench process when you are trying to initialize temp to "1000", the flip flops are still driving the temp signal as well, so you effectively have a bus fight going on.
Use the initialisation of
temp
in your ring counter to set up the signal.Note that this may not synthesize correctly depending on your architecture and synthesis tool.
The most general purpose way of doing it is to add a reset signal to all the DFFs except on, and put a preset signal on that one. Then you assert the reset at the start, which will set up the DFFs to a good value.
Here's a simpler version of your code which does that and avoid the need to use explicit DFFs. You can also change the width of
temp
and the code will do all the rest for you:(Note: code just typed into the message, there may be syntactic typos in there!)
BTW,
shared variable
s are a bad idea unless they are ofprotected
types. They can have race conditions.One thing to do is add a enable signal to D flipflops. when you want to reset the circuit make the enable signal go low and then change the temp to "1000".