Search code examples
vhdlverilogfpgaquartusintel-fpga

The clock speed is two times faster when the clock duty cycle is 50%


I want to generate 102Hz clock on a FPGA board(the one with cyclone 3) the original clock on the hardware is 50MHz, so I divided it by 490196 to get 102Hz clock but the clock speed is two times faster when I set the duty cycle to 50%

    signal div_490196_counter: std_logic_vector(18 downto 0);
        ...
    process(clk,reset,div_490196_counter)
    begin
        if(reset='0') then
            div_490196_counter <= (others=>'0');
        elsif(rising_edge(clk)) then
            if(div_490196_counter = 490165) then
                div_490196_counter <= (others=>'0');
            else 
                div_490196_counter <= div_490196_counter+1;
            end if;
        end if;
    end process;
    clk_102Hz <= '1' when (div_490196_counter < 245098) else '0';

I tried to use Verilog but the result is the same:

reg[18:0] div_490196_counter;
...
always@(posedge clk or negedge reset)
begin
    if(reset == 1'b0)
        div_490196_counter = 0;
    else
        if(div_490196_counter == 490165)
            div_490196_counter = 0;
        else
            div_490196_counter = div_490196_counter + 1;
end

assign clk_102Hz = (div_490196_counter < 245098)? 1'b1 : 1'b0;

It is only with I switch to non 50% duty cycle clock that solves the problem:

clk_102Hz <= div_490196_counter(18);

or in verilog:

assign clk_102Hz=div_490196_counter[18];

but why is that the case? I thought the result should be the same


Solution

  • Your two versions of clk_102Hz should behave more or less identical in simulation. However, beware that this version will not work well as a clock in hardware:

    assign clk_102Hz = (div_490196_counter < 245098)? 1'b1 : 1'b0;
    

    The reason is that in real life, the comparator operator happens over a period of time (not instantly like in simulation), and so the clk_102Hz output may glitch during the calculation for certain div_490196_counter value transitions. I don't have a precise explanation for why you are observing exactly twice the frequency you expected, but this would generally be unpredictable.

    To solve this, it should work to simply send the clk_102Hz signal through a flip-flop clocked by clk.