Does it Race?

I’m not confident in simulation regions and have a question related to those.

Below code demonstrates an event check for a given interval. The question is, what happens if event is triggered exactly at 100 steps later where disable statement is about to kill the thread? We would not know which process is executed first by the simulator.
Is there a way to guarantee that EVENT_THREAD is executed after event is triggered even it’s already the 100th step.
I was thinking #0 delay before disable statement will get the job done but those are not encouraged mostly. And semaphores don’t look like the answer since we still can not guarentee that EVENT_THREAD’s statements are executed immediately after event trigger.

P.S I don’t want to consume extra simulation time. So Waiting for #101 is not desired.


        fork : ISO_FORK
            begin
                fork
                    EVENT_THREAD: begin
                        time t0;
                        @(some_event);
                        // might get a semaphore here
                        if ($time - t0 <= 100) begin
                            $display("");
                        end
                    end
                join_none
                #(100);
                // might have a #0 delay here
                disable fork;
            end
        join : ISO_FORK

In reply to emin:

Your description has a conflicts that creates a race condition. You cannot say that the check can happen up to and including time 100 AND also must happen before time 100. The problem with putting a #0 delay is that might fix this problem, but what happens if you have to put a #0 in the code that triggers some_event to fix another problem? Then you have to put in 2 #0’s here. And inserting #0’s could cause problems with the code that follows. It get very complicated quickly and difficult to maintain.

It’s hard to suggest improvements without understanding the requirements that led to this code.

Thank you Dave. I’ve got the point. So check can not cover 100th step, events occuring at 100th step covers 100+delta steps.
Requirement is like, signal can not change within 100ns. If changes, it’s an error. So fix should be putting “<” rather than “<=”.

On the other hand, there’s no way to move the simulator to postponed region, right?

In reply to emin:

I think using < instead of <= is what you need to do. Also, you should be using real numbers for simulation time. If your timescale is 1ns, but your time precision is 1ps, $time truncates to ns. Use $realtime and realtime variables. Then, dealing with real numbers is another reason not to use equality because of rounding errors.

There are ways to move certain operations to later regions, but I do not recommend doing that.

In reply to dave_59:

Thank you Dave. Always been curious about $time vs $realtime, can you direct me some resources in order to capture the reason?

For me, simulation regions are not %100 understood. Do we really need to be aware how it progress? There may not be situations where moving to later regions is really required? Or mostly unnecessary? Can you elaborate a little bit more? Also, please throw me some resources on techniques related to moving the region. That may help me to recognize the details.

In reply to emin:

For time/realtime see $time vs $realtime | Verification Academy

Not going to give you references for things I don’t recommend.