Wednesday, July 17, 2013

Divide By 7 Clock with 50% Duty Cycle

RTL Code


-----------------------------------------------------------------
-- File Name : divide_by7.vhd
-----------------------------------------------------------------

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE  IEEE.NUMERIC_STD.ALL;

ENTITY divide_by7 IS
PORT (
 clk      : IN  STD_LOGIC                              ;
 reset_n  : IN  STD_LOGIC                              ;
 o_clk_by7: OUT STD_LOGIC                      
 );
END divide_by7;

ARCHITECTURE Arch OF divide_by7 IS
SIGNAL COUNTER : UNSIGNED(2 DOWNTO 0);
SIGNAL div_1   : STD_LOGIC;
SIGNAL div_2   : STD_LOGIC;
SIGNAL clk_low_cnt   : STD_LOGIC;
SIGNAL clk_high_cnt   : STD_LOGIC;

BEGIN

-- Counter generation
PROCESS(clk,reset_n)
  BEGIN
    IF (reset_n = '0') THEN
      COUNTER <= "111";
    ELSIF RISING_EDGE(clk) THEN
      IF COUNTER = "110" THEN
        COUNTER <= "000";
      ELSE
        COUNTER <=  COUNTER + 1;
      END IF;
    END IF;
END PROCESS;

-- clk_r generation
PROCESS(clk,reset_n)
  BEGIN
    IF (reset_n = '0') THEN
      clk_low_cnt  <= '0';
      clk_high_cnt <= '0';
    ELSIF RISING_EDGE(clk) THEN
      IF COUNTER = "000" THEN
        clk_low_cnt <= '1';
      ELSE
        clk_low_cnt <= '0';
      END IF;
      IF COUNTER = "100" THEN
        clk_high_cnt <= '1';
      ELSE
        clk_high_cnt <= '0';
      END IF;
    END IF;
END PROCESS;

-- div_1 generation
PROCESS(clk,reset_n)
  BEGIN
    IF (reset_n = '0') THEN
      div_1 <= '0';
    ELSIF RISING_EDGE(clk) THEN
      IF clk_low_cnt = '1' THEN
        div_1 <= NOT div_1;
      END IF;
    END IF;
  END PROCESS;

-- clk_f generation
PROCESS(clk,reset_n)
  BEGIN
    IF (reset_n = '0') THEN
      div_2 <= '0';
    ELSIF FALLING_EDGE(clk) THEN
      IF clk_high_cnt = '1' THEN
        div_2 <= NOT div_2;
      END IF;
    END IF;
  END PROCESS;

o_clk_by7 <= div_1 XOR div_2;
   
END Arch;

Test Bench

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE  IEEE.NUMERIC_STD.ALL;

ENTITY divide_by7_tb IS
END divide_by7_tb;

ARCHITECTURE tb OF divide_by7_tb IS

SIGNAL clk          : STD_LOGIC;
SIGNAL reset_n      : STD_LOGIC;
SIGNAL o_clk_by7    : STD_LOGIC;
CONSTANT PERIOD     : TIME := 5 ns;


COMPONENT divide_by7 IS
PORT (
 clk      : IN  STD_LOGIC                              ;
 reset_n  : IN  STD_LOGIC                              ;
 o_clk_by7: OUT STD_LOGIC
 );
END COMPONENT;

BEGIN

inst_divide_by7 : divide_by7
PORT MAP (
 clk      => clk      ,
 reset_n  => reset_n  ,
 o_clk_by7=> o_clk_by7
 );

  
clk_process :process
  begin
    clk <= '0';
    wait for PERIOD/2;
    clk <= '1';
    wait for PERIOD/2;
  end process;
  
  -------------------------------------------
  -- Stimulus generation
  --------------------------------------------
  stimulus: process
  begin  
    -- Put initialisation code here
    reset_n <= '0';
    wait for PERIOD;
    reset_n <= '1';
    wait for PERIOD;
    wait;
  END process;  

END tb;

Simulation waveform

  

Divide By 5 Clock with 50% Duty Cycle

RTL code

-----------------------------------------------------------------
-- File Name : divide_by5.vhd
-----------------------------------------------------------------

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE  IEEE.NUMERIC_STD.ALL;

ENTITY divide_by5 IS
PORT (
 clk      : IN  STD_LOGIC                              ;
 reset_n  : IN  STD_LOGIC                              ;
 o_clk_by5: OUT STD_LOGIC                      
 );
END divide_by5;

ARCHITECTURE Arch OF divide_by5 IS
SIGNAL COUNTER : UNSIGNED(2 DOWNTO 0);
SIGNAL div_1   : STD_LOGIC;
SIGNAL div_2   : STD_LOGIC;
SIGNAL clk_low_cnt   : STD_LOGIC;
SIGNAL clk_high_cnt   : STD_LOGIC;

BEGIN

-- Counter generation
PROCESS(clk,reset_n)
  BEGIN
    IF (reset_n = '0') THEN
      COUNTER <= "111";
    ELSIF RISING_EDGE(clk) THEN
      IF COUNTER = "100" THEN
        COUNTER <= "000";
      ELSE
        COUNTER <=  COUNTER + 1;
      END IF;
    END IF;
END PROCESS;

-- clk_r generation
PROCESS(clk,reset_n)
  BEGIN
    IF (reset_n = '0') THEN
      clk_low_cnt  <= '0';
      clk_high_cnt <= '0';
    ELSIF RISING_EDGE(clk) THEN
      IF COUNTER = "000" THEN
        clk_low_cnt <= '1';
      ELSE
        clk_low_cnt <= '0';
      END IF;
      IF COUNTER = "011" THEN
        clk_high_cnt <= '1';
      ELSE
        clk_high_cnt <= '0';
      END IF;
    END IF;
END PROCESS;

-- div_1 generation
PROCESS(clk,reset_n)
  BEGIN
    IF (reset_n = '0') THEN
      div_1 <= '0';
    ELSIF RISING_EDGE(clk) THEN
      IF clk_low_cnt = '1' THEN
        div_1 <= NOT div_1;
      END IF;
    END IF;
  END PROCESS;

-- clk_f generation
PROCESS(clk,reset_n)
  BEGIN
    IF (reset_n = '0') THEN
      div_2 <= '0';
    ELSIF FALLING_EDGE(clk) THEN
      IF clk_high_cnt = '1' THEN
        div_2 <= NOT div_2;
      END IF;
    END IF;
  END PROCESS;

o_clk_by5 <= div_1 XOR div_2;
   

END Arch;

Testbench

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE  IEEE.NUMERIC_STD.ALL;

ENTITY divide_by5_tb IS
END divide_by5_tb;

ARCHITECTURE tb OF divide_by5_tb IS

SIGNAL clk          : STD_LOGIC;
SIGNAL reset_n      : STD_LOGIC;
SIGNAL o_clk_by5    : STD_LOGIC;
CONSTANT PERIOD     : TIME := 5 ns;


COMPONENT divide_by5 IS
PORT (
 clk      : IN  STD_LOGIC                              ;
 reset_n  : IN  STD_LOGIC                              ;
 o_clk_by5: OUT STD_LOGIC
 );
END COMPONENT;

BEGIN

inst_divide_by5 : divide_by5
PORT MAP (
 clk      => clk      ,
 reset_n  => reset_n  ,
 o_clk_by5=> o_clk_by5
 );

  
clk_process :process
  begin
    clk <= '0';
    wait for PERIOD/2;
    clk <= '1';
    wait for PERIOD/2;
  end process;
  
  -------------------------------------------
  -- Stimulus generation
  --------------------------------------------
  stimulus: process
  begin  
    -- Put initialisation code here
    reset_n <= '0';
    wait for PERIOD;
    reset_n <= '1';
    wait for PERIOD;
    wait;
  END process;  

END tb;

Simulation waveform



Divide By 3 Clock with 50% Duty Cycle

RTL code

-----------------------------------------------------------------
-- File Name : divide_by3.vhd
-----------------------------------------------------------------

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE  IEEE.NUMERIC_STD.ALL;

ENTITY divide_by3 IS
PORT (
 clk      : IN  STD_LOGIC                              ;
 reset_n  : IN  STD_LOGIC                              ;
 o_clk_by3: OUT STD_LOGIC                      
 );
END divide_by3;

ARCHITECTURE Arch OF divide_by3 IS
SIGNAL COUNTER : UNSIGNED(1 DOWNTO 0);
SIGNAL div_1   : STD_LOGIC;
SIGNAL div_2   : STD_LOGIC;
SIGNAL clk_low_cnt   : STD_LOGIC;
SIGNAL clk_high_cnt   : STD_LOGIC;

BEGIN

-- Counter generation
PROCESS(clk,reset_n)
  BEGIN
    IF (reset_n = '0') THEN
      COUNTER <= "11";
    ELSIF RISING_EDGE(clk) THEN
      IF COUNTER = "10" THEN
        COUNTER <= "00";
      ELSE
        COUNTER <=  COUNTER + 1;
      END IF;
    END IF;
END PROCESS;

-- clk_r generation
PROCESS(clk,reset_n)
  BEGIN
    IF (reset_n = '0') THEN
      clk_low_cnt  <= '0';
      clk_high_cnt <= '0';
    ELSIF RISING_EDGE(clk) THEN
      IF COUNTER = "00" THEN
        clk_low_cnt <= '1';
      ELSE
        clk_low_cnt <= '0';
      END IF;
      IF COUNTER = "10" THEN
        clk_high_cnt <= '1';
      ELSE
        clk_high_cnt <= '0';
      END IF;
    END IF;
END PROCESS;

-- div_1 generation
PROCESS(clk,reset_n)
  BEGIN
    IF (reset_n = '0') THEN
      div_1 <= '0';
    ELSIF RISING_EDGE(clk) THEN
      IF clk_low_cnt = '1' THEN
        div_1 <= NOT div_1;
      END IF;
    END IF;
  END PROCESS;

-- clk_f generation
PROCESS(clk,reset_n)
  BEGIN
    IF (reset_n = '0') THEN
      div_2 <= '0';
    ELSIF FALLING_EDGE(clk) THEN
      IF clk_high_cnt = '1' THEN
        div_2 <= NOT div_2;
      END IF;
    END IF;
  END PROCESS;

o_clk_by3 <= div_1 XOR div_2;
   

END Arch;

Test Bench for the code

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE  IEEE.NUMERIC_STD.ALL;

ENTITY divide_by3_tb IS
END divide_by3_tb;

ARCHITECTURE tb OF divide_by3_tb IS

SIGNAL clk          : STD_LOGIC;
SIGNAL reset_n      : STD_LOGIC;
SIGNAL o_clk_by3    : STD_LOGIC;
CONSTANT PERIOD     : TIME := 5 ns;


COMPONENT divide_by3 IS
PORT (
 clk      : IN  STD_LOGIC                              ;
 reset_n  : IN  STD_LOGIC                              ;
 o_clk_by3: OUT STD_LOGIC
 );
END COMPONENT;

BEGIN

inst_divide_by3 : divide_by3
PORT MAP (
 clk      => clk      ,
 reset_n  => reset_n  ,
 o_clk_by3=> o_clk_by3
 );


clk_process :process
  begin
    clk <= '0';
    wait for PERIOD/2;
    clk <= '1';
    wait for PERIOD/2;
  end process;

  -------------------------------------------
  -- Stimulus generation
  --------------------------------------------
  stimulus: process
  begin
    -- Put initialisation code here
    reset_n <= '0';
    wait for PERIOD;
    reset_n <= '1';
    wait for PERIOD;
    wait;
  END process;


END tb;

Simulation waveform



Tuesday, May 28, 2013

4 :1 Multiplexer

-----------------------------------------------------------------
-- File Name : mux_4to1.vhd
-----------------------------------------------------------------


LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE  IEEE.NUMERIC_STD.ALL;

ENTITY mux_4to1 IS
 GENERIC (
    BIT_WIDTH :integer       
    );
PORT (
 clk      : IN  STD_LOGIC                              ;
 reset_n  : IN  STD_LOGIC                              ;
 i_in1    : IN  STD_LOGIC_VECTOR( BIT_WIDTH-1 DOWNTO 0);
 i_in2    : IN  STD_LOGIC_VECTOR( BIT_WIDTH-1 DOWNTO 0);
 i_in3    : IN  STD_LOGIC_VECTOR( BIT_WIDTH-1 DOWNTO 0);
 i_in4    : IN  STD_LOGIC_VECTOR( BIT_WIDTH-1 DOWNTO 0);
 i_mux_sel: IN  STD_LOGIC_VECTOR( 1 DOWNTO 0)          ;
 o_mux_out: OUT STD_LOGIC_VECTOR( BIT_WIDTH-1 DOWNTO 0)
 );
END mux_4to1;

ARCHITECTURE Arch OF mux_4to1 IS

BEGIN

P_mux : PROCESS(clk)
BEGIN
    IF (reset_n = '0') THEN
       o_mux_out <= (OTHERS => '0');
    ELSIF( rising_edge(clk) ) THEN
      CASE i_mux_sel IS
            WHEN "00" =>
              o_mux_out <= i_in1;
            WHEN "01" =>
              o_mux_out <= i_in2;
            WHEN "10" =>
              o_mux_out <= i_in3;
            WHEN OTHERS =>   
              o_mux_out <= i_in4;
      END CASE;          
    END IF;
END PROCESS P_mux;

END Arch;

Test bench:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE  IEEE.NUMERIC_STD.ALL;

ENTITY mux_4to1_tb IS
END mux_4to1_tb;

ARCHITECTURE tb OF mux_4to1_tb IS
CONSTANT BIT_WIDTH  : INTEGER := 18; 
SIGNAL clk          : STD_LOGIC;
SIGNAL reset_n      : STD_LOGIC;
SIGNAL i_in1        : STD_LOGIC_VECTOR( BIT_WIDTH-1 DOWNTO 0):= "00" & X"ABCD";
SIGNAL i_in2        : STD_LOGIC_VECTOR( BIT_WIDTH-1 DOWNTO 0):= "00" & X"FFFF";
SIGNAL i_in3        : STD_LOGIC_VECTOR( BIT_WIDTH-1 DOWNTO 0):= "11" & X"1000";
SIGNAL i_in4        : STD_LOGIC_VECTOR( BIT_WIDTH-1 DOWNTO 0):= "00" & X"1111";
SIGNAL i_mux_sel    : STD_LOGIC_VECTOR( 1 DOWNTO 0)          ;
SIGNAL o_mux_out    : STD_LOGIC_VECTOR( BIT_WIDTH-1 DOWNTO 0);
CONSTANT PERIOD     : TIME := 5 ns;

COMPONENT mux_4to1 IS
 GENERIC (
    BIT_WIDTH :integer       
    );
PORT (
 clk      : IN  STD_LOGIC                              ;
 reset_n  : IN  STD_LOGIC                              ;
 i_in1    : IN  STD_LOGIC_VECTOR( BIT_WIDTH-1 DOWNTO 0);
 i_in2    : IN  STD_LOGIC_VECTOR( BIT_WIDTH-1 DOWNTO 0);
 i_in3    : IN  STD_LOGIC_VECTOR( BIT_WIDTH-1 DOWNTO 0);
 i_in4    : IN  STD_LOGIC_VECTOR( BIT_WIDTH-1 DOWNTO 0);
 i_mux_sel: IN  STD_LOGIC_VECTOR( 1 DOWNTO 0)          ;
 o_mux_out: OUT STD_LOGIC_VECTOR( BIT_WIDTH-1 DOWNTO 0)
 );
END COMPONENT;
BEGIN

inst_mux_4to1 : mux_4to1
 GENERIC MAP(
    BIT_WIDTH => BIT_WIDTH
    )
PORT MAP (
 clk      => clk      ,
 reset_n  => reset_n  ,
 i_in1    => i_in1    ,
 i_in2    => i_in2    ,
 i_in3    => i_in3    ,
 i_in4    => i_in4    ,
 i_mux_sel=> i_mux_sel,
 o_mux_out=> o_mux_out
 );

  
clk_process :process
  begin
    clk <= '0';
    wait for PERIOD/2;
    clk <= '1';
    wait for PERIOD/2;
  end process;
  
  -------------------------------------------
  -- Stimulus generation
  --------------------------------------------
  stimulus: process
  begin  
    -- Put initialisation code here
    reset_n <= '0';
    wait for PERIOD;
    reset_n <= '1';
    wait for PERIOD;
    wait;
  end process; 


  -------------------------------------------
  -- mux_sel stimulus generation
  --------------------------------------------
   process
  begin  
    -- Put initialisation code here
    i_mux_sel <= "01";
    wait for PERIOD * 30;
    i_mux_sel <= "00";
    wait for PERIOD * 10;
    i_mux_sel <= "11";
    wait;
  end process; 


END tb;

Simulation waveform :



Saturday, May 18, 2013

Johnson Counter



A Johnson counter is a digital circuit which consists of a series of flip flops connected together in a feedback way. The circuit is a special type of shift register, where the complement output of the  last flip flop is fed back to the input of first flip flop.

This is almost similar to ring counter with a few extra advantages.  When the circuit is reset all the flipflop outputs are made zero. For n-flipflop Johnson counter we have a MOD-2n counter. That means the counter has 2n different states.

4 bit johnson counter is shown in the below figure



The VHDL code for 4 bit Johnson counter is shown below:


LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE  IEEE.NUMERIC_STD.ALL;


ENTITY johnson_counter IS
PORT (
 clk     : IN STD_LOGIC;
 reset_n : IN STD_LOGIC;
 counter : OUT STD_LOGIC_VECTOR( 3 DOWNTO 0)
 );
END johnson_counter;

ARCHITECTURE Arch OF johnson_counter IS
SIGNAL s_counter : UNSIGNED(3 downto 0):=(others => '0');
BEGIN

counter <= STD_LOGIC_VECTOR(s_counter);

P_johnson_ctr : PROCESS(clk)
BEGIN
    IF (reset_n = '0') THEN
            s_counter <= (OTHERS => '0');
    ELSIF( rising_edge(clk) ) THEN
            s_counter(1) <= s_counter(0);
            s_counter(2) <= s_counter(1);
            s_counter(3) <= s_counter(2);
            s_counter(0) <= not s_counter(3);
    END IF;
END PROCESS P_johnson_ctr;


END Arch;

See the simulation waveform for the Johnson counter below..


Thursday, May 16, 2013

N- BIT COUNTER

See VHDL code for the N-Bit counter

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE  IEEE.NUMERIC_STD.ALL;

ENTITY nbit_counter IS
    GENERIC (
        BIT_WIDTH :integer    );
PORT (
 clk     : IN STD_LOGIC;
 reset_n : IN STD_LOGIC;
 up_down : IN STD_LOGIC;
 counter : OUT STD_LOGIC_VECTOR( BIT_WIDTH -1 DOWNTO 0)
 );
END nbit_counter;

ARCHITECTURE Arch OF nbit_counter IS
SIGNAL s_counter  : UNSIGNED( BIT_WIDTH -1 DOWNTO 0);
BEGIN

-- COMBINATIONAL ASSIGNMENTS
counter <= STD_LOGIC_VECTOR(s_counter);

P_counter : PROCESS(clk,reset_n)
  BEGIN
    IF (reset_n = '0') THEN
      s_counter <= (OTHERS => '0');
    ELSIF RISING_EDGE(clk) THEN
      IF ( up_down = '1' ) THEN
        s_counter <= s_counter + "1";
      ELSE
        s_counter <= s_counter - "1";
      END IF;
    END IF;
END PROCESS  P_counter;

 END Arch;

See simulation waveform below..