Skip to content
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

Tweak ibex_tracer.sv to build with recent versions of Verilator #2075

Closed
wants to merge 2 commits into from

Conversation

rswarbrick
Copy link
Contributor

These currently fail, complaining about accesses to decoded_str and data_accessed. Verilator doesn't trace through far enough to see that these all come from the same always_comb process and can't race with each other.

This PR switches things so that we update those two variables with a non-blocking assignment on a clock negedge, then use them on the following posedge. It satisfies Verilator, and should be equivalent in any sensible system.

@rswarbrick rswarbrick added the Component:DV Design verification (DV) or testing issue label Aug 15, 2023
@rswarbrick rswarbrick requested a review from GregAC August 15, 2023 11:44
rtl/ibex_tracer.sv Outdated Show resolved Hide resolved
Recent versions of Verilator complain about the existing code because
it updates decoded_str and data_accessed in functions, and Verilator
doesn't trace the call graph far enough to realise that these are only
triggered from a single process. It then warns that unpredictable
scheduling of always_comb makes this hard to predict.

To avoid the warning, we schedule explicitly! The trick is to update
the two variables with non-blocking assignments on the previous
negedge.

This works... sort of. Unfortunately, the older version of Verilator
that we use in CI was upset with what I originally wrote because it
(I think incorrectly) thought I was mixing blocking and non-blocking
assignments to the file_handle variable.

Gah! This version skirts around that problem by deleting the final
block that was calling $fclose() to cleanly close the file handle. As
far as I can tell, this happens at the end of simulation anyway so
there's no real need to keep it.

I suspect this isn't quite true if the Verilator simulation is running
inside some other process. In that case, maybe the "I'm finishing a
simulation" logic might not call the equivalent of C's atexit(). But I
suspect we'll have other problems too, that aren't caused by this
change, so I'm not too worried :-)
This seems a little silly, but Verible's "always_ff_nonblocking" check
tries to ensure that there are no variable updates using blocking
assignments from within an always_ff block. An initialisation as part
of a declaration (like we do for file_name_base) is allowed, but the
update to the "fh" local variable from the previous commit is not.

This seems a little silly to me, but we can cheat here too! We don't
want to open the output file until we have something to write, so we
run the code that opens the file on the preceding negedge and use a
nonblocking assignment to update file_handle, which will have the
right value so that we can write out an instruction on the posedge
that follows.

Bleurgh.
@rswarbrick
Copy link
Contributor Author

Darn. This ain't gonna work. The cunning trick was to use a non-blocking assignment in always_ff blocks to "thread the needle" and find something that was acceptable to several Verilator versions and Verible too.

But it turns out that VCS doesn't allow non-blocking assignments to dynamic types (here: string). That's quite reasonable of VCS, but it scuppers my grand plan! I'll try to come up with another approach, but I'll drop this PR for now.

@rswarbrick rswarbrick closed this Aug 30, 2023
@rswarbrick rswarbrick deleted the ibex-tracer-verilator branch August 30, 2023 11:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component:DV Design verification (DV) or testing issue
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant