VHDL coding tips and tricks: counters
Showing posts with label counters. Show all posts
Showing posts with label counters. Show all posts

Monday, September 13, 2010

VHDL: 4 bit Johnson Counter with Testbench

    A Johnson counter is a digital circuit which consists of a series of flip flops connected together in a feedback manner. This is very similar to a ring counter with just one tiny difference. The circuit is special type of shift register where the complement output of the last flipflop is fed back to the input of first flipflop. When the circuit is reset, all the flipflop outputs are made zero. With a n-flipflop Johnson counter we get a MOD-2n counter. That means the counter has 2n different states.

Block Diagram:


The circuit diagram for a 3 bit Johnson counter is shown below:

block diagram for 3 bit johnson counter

     
    The counter goes through the following states over and over when the reset is not applied: 001  -   011  -  111   -   110  -  100  - 000  ...

Johnson Counter:


library ieee;
use ieee.std_logic_1164.all;

entity johnson_counter is
port(clk : in std_logic;
    reset : in std_logic;
    count : out std_logic_vector(3 downto 0)
    );
end johnson_counter;

architecture Behavioral of johnson_counter is

signal temp : std_logic_vector(3 downto 0) := (others => '0');

begin

--assign the temparary signal to output port.
--In VHDL-1997, output ports cannot be read. Thats why we use temp here.
count <= temp; 

process(clk)
begin
if(rising_edge(clk)) then
    if (reset = '1') then ---synchronous reset
        temp <= (others => '0');
    else
        --these are concurrent statements. 
        --which means they all execute at the same time.
        temp(1) <= temp(0);
        temp(2) <= temp(1);
        temp(3) <= temp(2);
        temp(0) <= not temp(3);
    end if;
end if;
end process;
   
end Behavioral;

Testbench for the Johnson Counter:


library ieee;
use ieee.std_logic_1164.all;

--testbench has empty entity
entity tb_johnson_counter is
end entity tb_johnson_counter;

architecture behavioral of tb_johnson_counter is

signal clk,reset : std_logic := '0';
signal count :std_logic_vector(3 downto 0) := "0000";
constant clk_period : time := 10 ns;

begin

--entity instantiation with named association port mapping
counter_uut: entity work.johnson_counter
    port map(clk => clk,
        reset => reset,
        count => count);

--generate clock
Clk_generation: process
begin
    wait for clk_period/2;
    clk <= not clk; --toggle clock when half of clk_period is over
end process;

stimulus: process
begin 
    reset <= '1';  wait for clk_period;
    reset <= '0';   wait for Clk_period*10;
    reset <= '1';   wait for Clk_period;
    reset <= '0';   
    wait;  --testing done. wait endlessly
end process;

end behavioral;

Lets take a look at the simulation waveform from modelsim.

Simulation Waveform from Modelsim:


johnson counter simulation waveform from modelsim vhdl

Post Synthesis Schematic from Xilinx Vivado:


The schematic looks quite simple, few flipflops connected in a sequence, along with some input and output buffers.

technology schematic for 4 bit johnson counter

VHDL: 4 bit Ring Counter with Testbench

    A ring counter is a digital circuit which consists of a series of flip flops connected together in a feedback manner. This circuit is a special type of shift register where the output of the last flipflop is fed back to the input of the first flipflop. When the circuit is reset, except one of the flipflop output, all others are made zero. For n-flipflop ring counter we have a MOD-n counter. That means the counter has n different states.

Block Diagram:


The circuit diagram for a 4 bit ring counter is shown below:

block diagram for ring counter

     
    The counter goes through the following states over and over when the reset is not applied: 0001  -   0010   -  0100   -   1000 ...

Ring Counter:


library ieee;
use ieee.std_logic_1164.all;

entity ring_counter is
port(clk : in std_logic;
    reset : in std_logic;
    count : out std_logic_vector(3 downto 0)
    );
end ring_counter;

architecture Behavioral of ring_counter is

signal temp : std_logic_vector(3 downto 0) := (others => '0');

begin

--assign the temparary signal to output port.
--In VHDL-1997, output ports cannot be read. Thats why we use temp here.
count <= temp; 

process(clk)
begin
if(rising_edge(clk)) then
    if (reset = '1') then ---synchronous reset
        temp <= (0=> '1', others => '0');
    else
        --these are concurrent statements. 
        --which means they all execute at the same time.
        temp(1) <= temp(0);
        temp(2) <= temp(1);
        temp(3) <= temp(2);
        temp(0) <= temp(3);
    end if;
end if;
end process;
   
end Behavioral;

Testbench for the Ring Counter:


library ieee;
use ieee.std_logic_1164.all;

--testbench has empty entity
entity tb_ring_counter is
end entity tb_ring_counter;

architecture behavioral of tb_ring_counter is

signal clk,reset : std_logic := '0';
signal count :std_logic_vector(3 downto 0) := "0000";
constant clk_period : time := 10 ns;

begin

--entity instantiation with named association port mapping
counter_uut: entity work.ring_counter
    port map(clk => clk,
        reset => reset,
        count => count);

--generate clock
Clk_generation: process
begin
    wait for clk_period/2;
    clk <= not clk; --toggle clock when half of clk_period is over
end process;

stimulus: process
begin 
    reset <= '1';  wait for clk_period;
    reset <= '0';   wait for Clk_period*6;
    reset <= '1';   wait for Clk_period;
    reset <= '0';   
    wait;  --testing done. wait endlessly
end process;

end behavioral;

Lets take a look at the simulation waveform from modelsim.

Simulation Waveform from Modelsim:


ring counter simulation waveform from modelsim vhdl

Post Synthesis Schematic from Xilinx Vivado:


The schematic looks quite simple, few flipflops connected in a sequence, along with some input and output buffers.
technology schematic for 4 bit ring counter




Sunday, March 28, 2010

VHDL: 4 bit Synchronous UP counter(with reset) using JK flip-flops

    I want to share the VHDL code for a 4 bit synchronous UP counter which is positive edge triggered and has an asynchronous active high reset input. The counter is called synchronous, because all the output bits change their state simultaneously, with no ripple. The counter has two 1 bit inputs, Clk and reset. The output is count, which is a 4 bit signal.

    The counter is designed using four JK flip flops. The VHDL code for these JK flipflops were previously shared in this blog, you would need to copy it from JK flipflop in VHDL to make this counter work. You can read more about synchronous counters from this article. I have shared the relevant circuit diagram here which will help you understand the code better.

synchronous up counter


    The code is written using structural modelling. When the reset is low( '0' ) and the value of Clk changes from 0 to 1, the value of count gets incremented by 1. When the count reaches its maximum value of "1111", it gets rolled over to its initial value of "0000".

    The reset input in this JK flipflop is said to be asynchronous because its value affects count, independent of the state of the clock signal.

VHDL Code for Synchronous Counter:


--libraries to be used are specified here
library ieee;
use ieee.std_logic_1164.all;

--entity declaration with port definitions
entity sync_count4 is
port(Clk: in std_logic;
    reset: in std_logic;  --asynchronous reset for the counter
    count : out std_logic_vector(3 downto 0) --4 bit counter output
);
end sync_count4;
    
--architecture of entity
architecture Behavioral of sync_count4 is

--internal signal declaration.
signal J3,J4,Q1,Q2,Q3,Q4,Qbar1,Qbar2,Qbar3,Qbar4 : std_logic :='0';
    
begin

J3 <= Q1 and Q2;
J4 <= J3 and Q3;

--flip flops are instantiated here
--entity instantiations with named association
FF1 : entity work.JK_Flipflop port map 
    (Clk => Clk, J => '1', K => '1', reset => reset, Q => Q1, Qbar => Qbar1);
FF2 : entity work.JK_Flipflop port map 
    (Clk => Clk, J => Q1, K => Q1, reset => reset, Q => Q2, Qbar => Qbar2);
FF3 : entity work.JK_Flipflop port map 
    (Clk => Clk, J => J3, K => J3, reset => reset, Q => Q3, Qbar => Qbar3);
FF4 : entity work.JK_Flipflop port map 
    (Clk => Clk, J => J4, K =>J4, reset => reset, Q => Q4, Qbar => Qbar4);

--concatenate the outputs of the flipflops to form the count.
count <= Q4 & Q3 & Q2 & Q1; 
    
end Behavioral;

Testbench code for Synchronous Counter:


--library declarations
library ieee;
use ieee.std_logic_1164.all;

--this is how entity for your test bench code has to be declared.
entity testbench is
end testbench;

architecture behavior of testbench is

--Signal declarations
signal Clk,reset : std_logic := '0';
signal count : std_logic_vector(3 downto 0) := "0000";
-- Clock period definitions
constant Clk_period : time := 10 ns;

begin

-- Instantiate the Unit Under Test (UUT). 
--This style is known as entity instantiation with named association
UUT : entity work.sync_count4 
    port map(Clk => Clk,
        reset => reset,
        count => count);

--Generate Clk with a period of 'Clk_period'
Clk_generation: process
begin
    wait for Clk_period/2;
    Clk <= not Clk;  --toggle 'Clk' when half 'Clk_period' is over. 
end process;

-- Stimulus process
stimulus: process
begin        
    --Let the counter run for 20 clock cycles.
    reset <= '0';
    wait for Clk_period*20;
--apply reset for 2 clock cycles. reset <='1'; wait for Clk_period*2;
reset <='0'; wait; end process; end;

Simulation Waveform:


The codes were simulated in Modelsim. This is a screenshot of the waveform. You can see how the reset input makes the count value 0 when its high.

modelsim simulation waveform of synchronous up counter in vhdl

The code was synthesized using Xilinx ISE. The RTL schematic of the design is shown below:


Note :- Use RTL Viewer to get a closer look on how your design is actually implemented in hardware.