-
-
Notifications
You must be signed in to change notification settings - Fork 76
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
Axilite VVC #614
Comments
Hello @avelure , unrelated to this topic, I see that you are using NVC a lot and publishing a lot of |
Hi, @Blebowski. |
@avelure UVVM uses shared variables of an ordinary type for communication which was deprecated and removed from VHDL in the 2002 revision. Using variables of this sort introduces to VHDL the same race conditions that exist in Verilog and the result is that two compliant simulators can produce different simulation results due to it. Especially if you are expecting something to happen at an exact clock cycle. Let me explain. During a given simulation cycle, perhaps due to clock rising, if both the process that sets a communication variable runs and the process that reads the communication variable runs, then whether the process that reads the variable sees what was set during that clock cycle or the next clock cycle will depend on which process runs first. The LRM does not dictate the order in which simulators run a particular process and you will find that different simulators will indeed run the processes in different orders. It is even possible that due to optimization that a given simulator will run processes in different orders after recompiling a design. Your warnings from ModelSim,
are due to ModelSim doing port collapsing optimizations. What they are not clearly saying is that the result of this optimization modelsim may do something that is not in compliance with the standard. What it seams is happening in this sort of optimization is that the ports are removed from the design and the code is migrated up one level (sort of like unrolling a subprogram). As a result, the ports and any initializations (typically to Z) are gone. It should be noted that this sort of issue only potentially causes issues in simulators that do port collapsing optimizations (ie: modelsim). A long time ago, OSVVM interfaces initialized ports to all Z. I never saw an issue with it. There are other ways to communicate with Verification Components that are language legal - such as what OSVVM does. See https://osvvm.org/archives/1668. |
I looked at this a bit but I can't see anything obviously wrong. @avelure is there any way to spot the difference in behaviour in a waveform output? Does GHDL or another simulator give the same result as ModelSim? |
@Blebowski BTW I just enabled GitHub Discussions for this project. That can be used in future for feedback, Q&A, etc. |
Hi @nickg , thanks, I will use those for further questions. |
@bpadalino tested with RiveraPRO and got the same result as Modelsim so there is probably a bug here somewhere. |
Note that some of the transactions did happen in a different order. Attaching all logs here for posterity. |
I figured out how to fix the simulation. By adding another Unsure if this is a bug in h/t to @JimLewis for suggesting adding an extra delta cycle. |
Yes, I found the same earlier, there is a delta-cycle transition that can be filtered out by adding delta-cycle waits at various places, but I don't think that fixes the root cause. |
Just curious, what makes you say that it returns Do you know if there is something we can instrument to see if Just trying to understand the thought process and to verify that indeed the function should return true when it isn't. |
@avelure This was a curious problem to look at. I added to my notebook that when setting and reading flags in a shared variable - whether it is a protected type or ordinary type - you can run into process order issues. So you need to work though the details of when await_completion reads any activity indication and when axilite_write indicates it is doing activity. |
It's definitely to do with the order the processes are run in. Here's a very simple diff you can apply to NVC which causes the processes to be run in the reverse order to normal: diff --git a/src/thread.c b/src/thread.c
index 1ccf27e801a0..1428d1fcdc42 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -1020,7 +1020,7 @@ void workq_start(workq_t *wq)
nparallel += wptr.count;
}
else {
- for (int j = 0; j < wptr.count; j++)
+ for (int j = wptr.count - 1; j >= 0; j--)
execute_task(&(eq->tasks[j]));
nserial += wptr.count;
} If I apply that then the test has the same behaviour as Modelsim/RiveraPRO. The LRM doesn't specify which order the processes are to be run in (they might even be run concurrently) so UVVM shouldn't be relying on that. We do seem to be running them in a different order to every other simulator though, but I think that's just an implementation detail. |
I wonder if there is any value in being able to randomize this to help expose issues with verification frameworks? Maybe run forward, backward and random? Anyway, I'm glad the little insight @JimLewis had was able to resolve where the bug resides. |
This is a good idea. I've added a |
I'm running a testcase with the Axilite VVC from UVVM and I get a different result on NVC vs Modelsim.
Output from nvc:
Output from Modelsim:
As you can see the await_completion finishes at 1050 on NVC and 1102.5 on Modelsim, additionally the write_response_channel_check is run before on modelsim.
There are earlier test in the testcase that checks the passthrough of data, however I do see some warnings in modelsim, is it related to this?
The text was updated successfully, but these errors were encountered: