Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
How to drive /*verilator public*/ signals #835
Author Name: Jonathon Donaldson
I realize there are other forum posts and the wiki FAQ on this topic and they actually did help a lot. But I think I've exhausted the available existing resources at this point.
I have some internal signals in my design that I want to drive from my SystemC testbench. I have added the /verilator public/ as I'm supposed to and I see the signals show up in the verilated C++ code. I have also added the appropriate header files from the top all the way down (as is mentioned in one of the forum posts) so that I can compile the design without getting those "forward class declaration" errors. So I have something that looks like this:
The above syntax compiles and doesn't generate any errors or warnings.
However, my problem right now is that whenever I try to actually do anything with the signal, like read/write it the application keeps seg-faulting. For example, if I do either of these I get a core dump due to seg-fault:
I know I'm really close I just need a little bit more info...I'm sure I'm just doing something silly.
I'm new to SystemC so I'm wondering if I'm supposed to cast my_pub_signal to an sc_signal before using it or something? In the verilated code it is declared as a VL_SIG8 if that's helpful.
In the verilated my_submodule .h header file it looks like this:
Any ideas what I might be doing wrong?
Original Redmine Comment
Okay, fixed the seg fault. I was in fact doing something really silly. So now I can read or assign a value to the public signal without causing any runtime errors.
Then I had a new problem in which my assignments were not taking affect in the design and tracing them proved that to be true. Then I realized it was because I was making the assignment before the verilog initial block had executed (because I was initializing the signal to 0 i the verilog). So I would assign a 1, but then the initial block would execute and assign it back to 0 all before the first clock 'tick'. Whoops. Fell down that rabbit hole for a while. :-/ So I changed the assignment in my testbench to occur after the initial block execution and it all works now!! W00t!!!
I still have one question though. Right now I am assigning to my verilator public signals like so:
However, I'm thinking that maybe I should really be using the write() method...but of course that method only exists for SystemC ports as far as I can tell. So obviously that doesn't work with verilator's VL_SIG8.
Should I at some point be casting the VL_SIG8 to a SystemC signal/port so that I can use the read()/write() methods? If so, what would be the syntax to do that?
Original Redmine Comment
VL_SIG is basically making just a uint8_t, so there are no methods available; you can assign to the signal directly with an assignment. Of course as you noted you need to make sure that later assignments etc inside the verilog will not just override it.