0

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?

3
  • 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. Commented Sep 27, 2018 at 4:57
  • @RaymondChen Done! Commented Sep 27, 2018 at 5:59
  • 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? Commented Sep 27, 2018 at 6:02

2 Answers 2

1

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 
Sign up to request clarification or add additional context in comments.

6 Comments

I see you edited your question as I was typing. Use the forever loop as I have shown
Thanks Dave, I realized all 3 errors that you pointed out after posting my question here. How will I initialize the sys_clk_tp to some value which does not defeat the purpose of the always block?
Why do you insist on using an always block. This is not synthesizable code,
I am not insisting on using always. I can use forever.
Because the forever statement does not start until after the previous blocking assignment to sys_clk_tp has updated.
|
-1

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.