Jump to content

Bind failure when passing an sc_fifo_in port through 2 hierarchies to a dymanic process


Recommended Posts

Apologies for the poorly worded Title...

I am experiencing an odd (to me) issue when constructing a model in which I have a hierarchy more than 1 level deep. ie: I have an sc_module instantiated within another sc_module, and I am attempting to bind an sc_fifo_in (also an out, but I've simplified to a single port for a testcase) from a testbench through the first sc_module to a second. The lowest-level module within the hierarchy has no static process defined by the constructor but instead spawns dynamic processes only which process the fifo.

I can make this code work by either:

  • defining a static process and not using the dynamic process (not ideal for my actual application as I have multiple of these to spawn)
  • only have a single level of hierarchy such that I'm not passing the sc_fifo_in port through an sc_module to the second

I created 3 examples on EDA Playground rather than posting 70+ lines of code here. If anyone prefers to see the code here instead, I'm happy to paste it.

Here is the first example which works (only a single hierarchy level and using a dynamic process only): Working example

Here is a second example which works (two levels of hierarchy and uses a static process only): Working example

Here is the second example which fails (two levels of hierarchy and uses a dynamic process only): Failing example

I have been trying to determine what I am doing wrong all day, and I have drastically simplified my actual code down to this very simple (not terribly interesting) example. In the Failing case, SystemC reports error E112 - port is not bound (I am building with SystemC 2.3.4).

I assumed that there was an issue with not having a static process in my BottomHier module and only having a dynamic process, but when I remove the TopHier level as in my first Working Example above, the code compiles and binds ok. And the second example demonstrates that I can successfully pass an sc_fifo_in port through 2 sc_modules without issue. 

Is there some limitation I am experiencing when attempting to pass the sc_fifo_in through the TopHier module and binding it to the BottomHier module related to the use of a dynamic process? I simply want TopHier to be a pass-through in this example.

I appreciate any advice here.

Link to comment
Share on other sites

The root cause of the problem is the following: in your constructor your are trying to call a function of the sc_fifo_in_if which is not yet bound when having a hierarchical binding.

Why is then example 2 woring? There is a difference in your example 2 (working with static process) and 3 (non-working): you use a thread in example 2 and a methoid in example 3. To react on the event in example 3 you need to access the interface during construction (where it is not being bound) while in example 2 the thread accesses the port during simulation (where the port is bound.

I see 3 options:

  • use sc_fifo_in::data_written() which returns an sc_event_finder instead of an event (this would be the correct way)
  • use a dynamic thread instead of a dynamic method
  • spawn your method in the end_of_elaboration() call, port are then bound
Link to comment
Share on other sites


Thank you very much not only for the quick reply but also the great information. I do have a followup question.

You state that I use a method in example 3 vs. a thread in example 2. In my spawn options I did not define the process as a method. And given that the read() function is a blocking function, I believe that the process_fifo_in process is actually a thread. Can you please clarify if I am incorrect?

Regardless of that, I was able to make both suggestion 1 and and suggestion 3 work.

Is there a preference for spawning the processes in before_end_of_elaboration vs. end_of_elaboration?

Link to comment
Share on other sites

Actually you are right, sc_spawn_options default is SC_THREAD.

For spawning there is no preference or even difference. But for your ports there is a difference: only in end_of_elaboration ports are completely bound and you can access the events of the associated channel. If you do this in before_end_of_elaboration() you will run into the same problems you had initially Pls. check also the LRM wrt this.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...