0
votes

I am trying to generate a clock which is (3/16) of the system clock. So, I have decided to generate a 3x clock from the system clk and then (1/16)x clock from that. Right now, I am stuck at generating just the 3x clock. I am doing this by calculating the time period of the system clock and then toggling the 3x clock every 1/6th of that period. But my simulation just stalls forever with that. I have not used the forever block anywhere, I have checked. Hence no timing construct. Following is the code that I am working on.

module eec_clk_gen (
    input logic arst,
    input logic sys_clk,
    output logic eec_clk
);

real t0;
real t1;
real sys_clk_tp;


logic eec_clk_x3;


//Calculating clock period of sys_clk
initial
begin
    @(posedge sys_clk) t0 = $realtime;
    @(posedge sys_clk) t1 = $realtime;
    sys_clk_tp = t1 - t0;
end



//Generating clock at 3 times sys_clk freq

initial
begin
    @(posedge sys_clk) eec_clk_x3 = 1'b1;
end

always
begin
    #(sys_clk_tp/6) eec_clk_x3 <= ~eec_clk_x3;
end

endmodule: eec_clk_gen

I am not concerned about the arst signal which is missing from my code. It will be implemented once the eec_clk is functional. Some help please?

2
Please make your title less vague so others with the same problem will be able to find it. "Why is the following code not working for me?" could apply to pretty much any question on this site.Raymond Chen
@RaymondChen Done!Timothy Grant
I have figured out that with no initialization for sys_clk_tp, my simulation is getting stalled. How do I fix this? I can initialize sys_clk_tp to some value but what value as that value is itself being computed in this module? Or calculate the value in testbench top or somewhere else and import it into this module?Timothy Grant

2 Answers

1
votes

There 2, possibly 3 problems with your code.

  1. The initial value of sys_clk_tp is 0.0. So your always block goes into an infinite 0-delay loop. Time cannot advance
  2. You are using non-blocking assignment to t1,t2, so t2 is still 0 when evaluating t1-t2
  3. You are using $time instead of $realtime If your input clock has any fractional delay due to different timescales, $time truncates. I would do

`

initial
     begin
        @(posedge sys_clk) t0 = $realtime;
        @(posedge sys_clk) t1 = $realtime;
        sys_clk_tp = t1 - t0;
        forever  #(sys_clk_tp/6) eec_clk_x3 = ~eec_clk_x3;
    end
0
votes

What you are trying to do is futile. Even if you manage to get this to work in simulation, it will never synthesize:

  • The $realtime function is only available in simulation. It is not available in synthesis; if you need a real-time clock, you will need to make your own.

  • The # operator is only effective in simulation. It is ignored during synthesis.

If you want to multiply a clock signal on an FPGA, most FPGAs have clock management hard macros (typically DLLs or PLLs) which can be used for this purpose. Consult your target part's reference manual for details.

If you are targeting an ASIC, contact your foundry.