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
Extend verilator main loop to support clock generation in C++ #2275
base: master
Are you sure you want to change the base?
Conversation
Users may define a callback for toggling clock(s).
Codecov Report
@@ Coverage Diff @@
## master #2275 +/- ##
=======================================
Coverage 66.78% 66.78%
=======================================
Files 48 48
Lines 7969 7969
Branches 1322 1322
=======================================
Hits 5322 5322
Misses 2059 2059
Partials 588 588 Continue to review full report at Codecov.
|
IMHO, ideally, this should be handled transparently when using a |
@alexforencich that is the plan for #89. |
@garmin-mjames I guess I was hoping for a little more. Something where we could create multiple clock dynamically. I understand that is a good bit of work though. How does this approach handle users writing to the same clock signal from cocotb? |
@ktbarrett it doesn't. This is just the Verilator equivalent of a free running HDL clock in a testbench wrapper. A GPI clock should be the replacement for |
I'm fine with simpler methods we can accomplish now, but only if they are going to be forward compatible. If we add this support here and then have to remove it later once we have a better way that isn't compatible, then we are going to have some angry users. |
This PR is almost out of scope of cocotb, except that we provide the Verilator main loop in Again, it's equivalent to an HDL clock in a testbench. GPI clocks will essentially obsolete this approach, being almost as fast, more flexible, and controllable from cocotb, but there's no reason this would have to be removed later. Users would have to choose one approach, as they do now with Python vs HDL clocks. That being said, if the GPI clocks happen soon this isn't really necessary. |
I doubt GPI clocks are going to happen any time soon. I need to think it out some more, but I feel like it may require we duplicate some scheduler functionality in C. And then we have object lifetime issues to worry about as well that probably deserve a garbage collector. Maybe I'm overthinking it.
It was hard enough for us to get right. We probably should try to shield users from that. I'm coming around on this approach. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's certainly flexible. Users can manually manage multiple clocks if need be with a simple scheduling algo, and this allows the user to model skew as well.
if (current_time % CLK_HALFPERIOD == 0) { | ||
topp->clk = !topp->clk; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need this protection here since the main loop only calls the user_clock_cb on the next clock edge by design?
if (current_time % CLK_HALFPERIOD == 0) { | |
topp->clk = !topp->clk; | |
} | |
topp->clk = !topp->clk; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not in this single-clock example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps the example should be expanded for multiple clocks and skew? Something that users can copy-paste-modify for their own tests.
I'm thinking an array of next clock edge times mapped to clock handles and halfperiods. Upon entry of the callback, walk the array to see if any clocks need updating by comparing it to the current time. If they do, toggle the clock and update the time with the next time using the halfperiod and skew. Finally, return the min time in the updated clock edge time array.
Users could copy and paste and modify the array definition as they see fit.
@ktbarrett I think GPI clocks can be done fairly simply: #89 (comment) |
I mean, if cocotb has a simulation loop for verilator and implementing it there means lower overhead than doing it in GPI, then I see no problem with doing both so long as the APIs are similar. The clock object can use the Verilator version when running under Verilator, and the GPI version otherwise. At least Verilator is open source so it's simple to include in regression tests, etc. Also, we could possibly implement this now and make sure the API makes sense, since the GPI clock issue has been open for 7 years now. |
@garmin-mjames Are you still interested in following this PR to completion? |
If the GPI clocks get in 1.5 then I would close this rather than have two options for C++ clocks. |
@ktbarrett thoughts on getting this in 1.5 now that GPI clocks are postponed to 2.0? |
Is it ready for a final review? If so, we can bring this in with 1.5. |
I can update the example in the docs and the test per your previous review. |
Well this didn't make it into 1.5. Still interested in bringing it in @marlonjames? |
I still think it's useful. I was focusing on fixing Verilator regression tests, then 4.108 broke compat, so I hadn't gotten around to finishing this. Adding jitter to the example was making it pretty complex. It may be better left as an exercise for the user, or at least put only in the test but not the docs. |
Closes #2108.
Provide a user callback declaration for toggling clock(s).
User defines the callback and provides the file for compiling/linking.
I'm not sure that this is the best approach, but it was the simplest in terms of additional work for users and cocotb that I could come up with.
Tagging @alexforencich, @wallento.