Wednesday, July 17, 2013

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



No comments:

Post a Comment