Search code examples
countervhdlclockfrequency

VHDL Clock Divider: Counter - Duty Cycle


I am new to VHDL. I was given this code on how to generate a clock signal of 1Hz (50 % duty cycle) from input clock signal of 24 MHz. I have some questions for more clarification.

  1. How is the counter limit chosen? in the below case, 12000000. What would this limit be if I want generate an 8Hz clock signal.
  2. How should the code be adjusted if I wanted to change the duty cycle to 80% ?

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;
    entity clock is
       port ( CLKin: in std_logic;
              reset: in std_logic;
              CLKout: out std_logic);
    end clock;
    architecture arch of clock is
    
      signal counter: integer:=0;
      signal temp : std_logic := '1';
    begin
    process(CLKin,counter,reset)
    begin
       if(reset='0') then counter<=0; temp<='1';
        elsif(CLKin'event and CLKin='1') then counter <=counter+1;
         if (counter = 12000000) then temp <= NOT temp; counter<=0;
         end if;
        end if;
       CLKout <= temp;
    end process;
    end arch;
    

Solution

  • You want to divide a clock of 24MHz, being 24000000 Hz, to 1 Hz. So you create a counter that will count up every rising edge of the CLKin (24 MHz). After 24000000/2=12000000 counts, you are in the middle. That's where you change the level value of the output signal (temp <= not temp). Because you spec say it has to be a duty cycle of 50%. When doing so, you also starts counting again from the start.

    For 8MHz, you have have a counter to (24000000/8)/2 = 1500000.

    And just a small remark: it's better to use the ieee.numeric_std library i.s.o the ieee_logic_arith and the ieee.std_logic_unsigned

    Note: the code is first assigning to a signaltemp. And then the signal temp to output clkout. The reason behind this is that in VHDL it is not allowed to read from an output port (clkout). And you should read from it when doing the output <= not output;. From a signal, reading is allowed.

    And one more note: in the sensitivity list of the process, there is no need to have the counter signal there.

    process(CLKin, reset) -- no counter needed
    

    And, another thing... Counting 12000000 cycles is: 0 -> (12000000-1) = 11999999