-
Notifications
You must be signed in to change notification settings - Fork 152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
First active edge of clock in testbench not half of clock period #2001
Comments
In a multi-clock design, all clocks currently have their first active edge at the same time. So simply setting the first active edge to half the period of the respective clock would break that expectation, we need to do something clever :-). [edit] |
Wouldn't it be as easy to set the first active edge of every clock at half period of that respective clock? Or do we depend on every clock starting at the same time for proper simulation results? |
Our synchronization model: clash-compiler/clash-prelude/src/Clash/Explicit/Signal.hs Lines 484 to 497 in 6f6ba35
assumes that the first active edges of all clocks coincide. So the clockgen code and that model are linked: change one, then you need to change the other. We will be adding phase rotation information to clock domains, which would also necessitate a change to the synchronization model. Hopefully we can then tackle this issue as well. Then if we want clocks that do have first active edges that coincide we can do something like https://hackage.haskell.org/package/clash-prelude-1.4.6/docs/Clash-Clocks.html allowing us to know which clock has the longest period. |
If our simulation in Haskell produces values without throwing exceptions, we generally require those values to be the same as when the design is run in HDL simulation. Our multi-clock primitives assume the first active edge coincides for all domains, so we require that for HDL simulation as well. By the way, why /half/ the clock period? Why not a full period? |
It needs to be a full period in order to meet setup time constraints. |
A more immediate solution is to collect information about domains before the netlist stage. Then we can instantiate the clockGen with a startdelay of the domain with the longest clock period. |
We already have information about domains from |
No, that's it. I didn't realize we already collected info. What do we use it for? I always assumed we just parsed the |
IIRC I added it a while back to start on an idea @martijnbastiaan had about making |
Looking around I think we pass these collected domain configurations to |
I think you are referring to #978 |
When generating a verilog testbench and a clock signal with a period of 20 ns the time to the first rising edge of the clock is set to 3 ns instead of the expected 10 ns. I have included the relevant part of the verilog code below. This results in problems with a post-synthesis simulation, as there is too little setup time before the first clock edge. Preferably this time to the first rising edge would be half of the clock period, or adjustable through a setting.
Verilog snippet:
// tbClockGen begin
// pragma translate_off
reg clk_0;
// 1 = 0.1ps
localparam half_period = (200000 / 2);
always begin
// Delay of 1 mitigates race conditions (steveicarus/iverilog#160)
#1 clk_0 = 0 ;
#30000 forever begin //<------------- Where does this number come from?
if (~ (~ c$result_rec)) begin
$finish;
end
clk_0 = ~ clk_0;
#half_period;
clk_0 = ~ clk_0;
#half_period;
end
end
The text was updated successfully, but these errors were encountered: