Electronic – Clock divider VHDL

clockfpgavhdl

I created a clock divider with the code below. i followed steps in prof chu's book.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity clock_divider is
Port ( reset : in  STD_LOGIC;
       clk : in  STD_LOGIC;--Clock in
       out_red : out  STD_LOGIC);--Reduced freq clock out
end clock_divider;

architecture Behavioral of clock_divider is

constant DVSR : INTEGER := 5000000;--for 1 ms tick at 50mhz clk input
signal ms_reg, ms_next : unsigned (22 downto 0);
signal ms_tick : std_logic;--tick at every 1ms

begin

process (clk)
begin
  if (clk'event and clk = '1') then
    ms_reg <= ms_next;
  end if;
end process;

ms_next <= 
       (others => '0') when (reset = '1' or ms_reg = DVSR) else
          ms_reg + 1;

ms_tick <= 
       '1' when ms_reg = DVSR else '0';

out_red <= ms_tick;
end Behavioral;

out_red is my reduced freq clock out.
Test bench shows clock_out hanging at 0.
Can anyone figure out where i went wrong?

Best Answer

Your code works if you init DVSR to 50000 instead of 5000000. It will generate a pulse every 1ms with a width of clk period, this will be 0.000...01% high and 99.99..99% low To generate a clock with 50% high 50% low I would do the following.

library ieee;
use ieee.std_logic_1164.all;

entity clock_divider is

  generic (
    divider : positive := 50000);       -- for 1 ms tick at 50mhz clk input

  port (
    reset, clk : in  std_logic;         -- reset and clock in
    out_red    : out std_logic);        -- Reduced freq clock out
end entity clock_divider;

architecture implementation of clock_divider is
 signal ClockDiv : natural range 0 to divider/2 := 0;    -- clock divide counter
 signal clk_out  : std_logic;
begin  -- architecture implementation

 clock_div_p : process (clk, reset) is

 begin  -- process clock_div_p
   if reset = '1' then                 -- asynchronous reset (active high)
     ClockDiv <= 0;
     clk_out  <= '0';
   elsif clk'event and clk = '1' then  -- rising clock edge
     if (ClockDiv = divider/2) then    -- switch polarity every half period
       ClockDiv <= 0;
       clk_out  <= not clk_out;
     else
       ClockDiv <= ClockDiv +1;
       clk_out  <= clk_out;
     end if;
   end if;
 end process clock_div_p;

 out_red <= clk_out;

end architecture implementation;
Related Topic