# VHDL:CLOCK DIVIDER with duty cycle

I want to generate a 15MHz clock from a 60 MHz clock. The 60 MHz clock has a duty cycle of 50%. The output clock of 15 MHz must have 25% duty cycle. How the following code needs to be modified to vary duty cycle?

entity clkgen is
Port (
clk_in  :  in  STD_LOGIC;
reset   :  in  STD_LOGIC;
clk_out :  out STD_LOGIC
);
end clkgen;

architecture Behavioral of clkgen is
signal temp: STD_LOGIC;

signal count : integer range 0 to 1 := 0;

begin
Clock_out : process (reset, clk_in) begin
if (reset = '1') then
temp <= '0';
count <= 0;
elsif rising_edge(clk_in) then
if (count = 1) then
temp <= NOT(temp);
count <= 0;
else
count <= count + 1;
end if;
end if;
end process;

clk_out <= temp;

end Behavioral;


update:

@Dave this is what i got. Clk_out is not changing it's value

• So now you are toggling the output every two clock cycles on each level. You need to have the high level to last one clock cycle, but the low level to last 3 cycles. Now implement it. – Eugene Sh. Jun 22 '16 at 20:36
• "The output clock of 15 MHz must have 25% duty cycle" Why? – Bruce Abbott Jun 23 '16 at 21:29
• That's the requirement. – user114750 Jun 24 '16 at 13:06

The simplest thing is to have count counting the full period of the output clock, and then you can assert temp for any fraction of that period, like this:

entity clkgen is
Port (
clk_in  :  in  STD_LOGIC;
reset   :  in  STD_LOGIC;
clk_out :  out STD_LOGIC
);
end clkgen;

architecture Behavioral of clkgen is
signal temp: STD_LOGIC;
signal count : integer range 0 to 3 := 0;

begin
Clock_out : process (reset, clk_in) begin
if (reset = '1') then
count <= 0;
elsif rising_edge(clk_in) then
temp <= '1' when (count < 1) else '0';
count <= count + 1;
end if;
end process;

clk_out <= temp;

end Behavioral;

• "when else " is giving the following error "This construct is only supported in VHDL 1076-2008" – user114750 Jun 23 '16 at 18:25
• If you can't upgrade, you'll have to change it to if count<1 then temp <= '1' else temp <= '0' end if; – Dave Tweed Jun 23 '16 at 18:52
• i simulated the code. it is not generating the 15mhz clock with 25% dc. – user114750 Jun 23 '16 at 20:10
• Well, what IS it doing? Show us some waveforms: clk_in, reset, count and temp. This really shouldn't be hard to debug. – Dave Tweed Jun 23 '16 at 20:17
• If the simulator isn't respecting the range declaration on count, it might be necessary to change the count <= count + 1 statement to if count<3 then count <= count + 1 else count <= 0 end if; I'm relying on the implicit roll-over of a 2-bit counter. – Dave Tweed Jun 23 '16 at 20:22

• There's no reason to assume that the synthesis tools will treat the clk_out signal as data, unless they're very old or primitive. If the signal is used as a clock, modern tools will generally treat it as a clock. Another point: When a clock has special duty cycle requirements, that's a clue that it isn't meant to be used on-chip, but rather driven off-chip to some other device. In which case, it is a signal as far as the synthesis tools are concerned, and the usual methods for constraining its timing relative to other I/O apply. – Dave Tweed Jun 22 '16 at 22:36