From: Evan L. <sa2...@cy...> - 2020-10-03 09:48:10
|
Apologies for asking a Verilog question here, but the rest of the Verilog world seems to have dumbed down so much that it can't be asked anywhere else... I have a difficult problem where I need to work around a race condition. Assume a tick of 1ns. Module A needs to make a decision every 8ns (for the sake of argument) on whether to initiate an 8ns sequence of events in module B. Most of the time, module A will regularly kick off the 8ns sequence, so it just happens continuously. Module A *must* complete the initiation in zero simulation time, so it calls a task in module B which just raises an event in module B, and an always block in module B responds to the event and calls the task which takes 8ns to complete. So, module A completes in zero time by raising the event, and module B completes in 8ns after responding to the event. The (very simple) code is at https://www.edaplayground.com/x/vGp9. Here's the problem: module B always schedules an event at the end of the sequence, at (($time % 8) == 0). However, module A always kicks off the next sequence at exactly the same time, so there's a race. In the relevant delta, the scheduler sometimes runs the module A code first, before the event at the end of the sequence, in which case the next sequence is lost, and the test code shows this. This is expected, and isn't surprising. Problem: is there some way to 'decouple' the event trigger from module A from the last event in module B to avoid this? Note that the sequence in module B doesn't have to be started at exactly the 8ns boundary, but can be started 1ns later. However, it must end at the 8ns boundary, at exactly the same time that module A needs to start the sequence. https://www.edaplayground.com/x/Xfeh is an attempt to do this. There are now two events. Module A triggers a simple task in module B, which waits 1n, and then raises a second event, which starts the sequence in another task. The reasoning here is that module A is now actually only triggering a 1ns sequence, and so there is no race with the final event 7ns later. However, this doesn't work - various simulators still report a race. Somehow, the initial trigger from module A is still 'locked out' for the complete 8ns. The scheduler still sees the the first trigger from module A and the end of the sequence at the same time, of course, but it has somehow effectively locks out the trigger for the complete 8ns, and not 1ns. Any thoughts on how to work around this? I have successfully used #0 elsewhere, but I don't want to make a habit of it... Thanks. |