Jump to content
sheridp@umich.edu

Hierarchical Channel Implementation

Recommended Posts

 

I'm trying to create a hierarchical channel, derived from sc_channel, that includes blocking reads/writes.  My class contains two events

sc_core::sc_event data_read;
sc_core::sc_event data_written;

And an outline of the  blocking read and write functions:

write(std::shared_ptr<UserObject> obj){
	
  while(num_items >= max_items){
    wait(data_read);
  }
  
  insert_userobject_into_internal_data_structure(obj)
  
  num_items++;
  data_written.notify(SC_ZERO_TIME);
  
}
  
std::shared_ptr<UserObject> read(int filter){
  while( search_internal_data_structure_for_item_maching_filter(filter) == false ){
  	wait(data_written)
  }
  num_items--;
  data_read.notify(SC_ZERO_TIME);
  
  return UserObject_matching_filter;
}

A few questions:

(1) While this seems to work, I'm wondering how this differs from the sc_prim_channel approach using request_update() and update().  In other words, why is sc_fifo implemented the way it is -- ie. keeping track of m_num_read, m_num_written,  and m_num_readable in a delta-cycle rather than just using a single variable like num_available, and issuing the notify() in the update().

(2) What is the function of register_port()?

 

 

 

Share this post


Link to post
Share on other sites

Both questions are answered in SystemC standard (http://standards.ieee.org/getieee/1666/download/1666-2011.pdf)

Quote

(1) While this seems to work, I'm wondering how this differs from the sc_prim_channel approach using request_update() and update(). 

sc_prim_channel interface is used to avoid race conditions when two or more processes access channel in same delta cycle.

Example: Suppose that you have non-empty fifo, and you have two processes scheduled in same delta cycle: one wants to write fifo, second wants to read.  Standard does not specify any ordering for processes running in the same delta cycle.

So we have two possible scenarios: 1) write first, read second; 2) read first, write second.  Depending on order either old or new data will be read.  

So we have undefined behavior here.  In general however you want simulations to be deterministic. 

SystemC channels have "delayed write" semantics, so that write is not executed immediately, but instead performed in a special scheduling phase called "update phase". So simulations that use SystemC channels for IPC are always deterministic: when two processes are executed in a same delta cycle, it is guaranteed that consumer process always reads "old data". 

I highly recommend reading chapter "4. Elaboration and simulation semantics" of standard, to understand how SystemC scheduler and sc_prim_channel interface work.

 

Quote

(2) What is the function of register_port()?

It is called when port is bound to channel.  See "5.14.4 register_port".    Personally I don't generally use it, by default it just does nothing.

Share this post


Link to post
Share on other sites

Hi Roman,

Thank you for your reply.  I think I understand the argument for delta cycles as it applies to an sc_signal:  the consumer should get the old value of signal in the current delta cycle, even if another process writes to it in the same delta cycle.

For sc_fifo, however, the consumer should always be getting the first-in data, regardless of execution order, by the nature of FIFOs, right?  Ie. lets say our non-empty fifo contains {1, 2, 3}  and a process is attempting to write a 6, and another process is attempting to read.  Then if write executes first the fifo will look like {6, 1, 2, 3} and then when the read executes it will look {6, 1, 2}.  Whereas if the read executed first it would look like {1, 2} and then after the write {6, 1, 2}.  In either case the reader got 3, and the fifo looks the same at the end.  Now, I can see that if the fifo were full, and the writer executed first, it would have to wait for the next delta cycle, whereas if the reader executed first, it wouldn't ( and vice versa on an empty fifo ), but since the notify is for SC_ZERO_TIME, I don't see why this matters too much.

 

Share this post


Link to post
Share on other sites

Indeed, my reasoning was wrong for fifo case. Thanks for correction!

Ordering is also important however. If you have more than two communicating processes in a system, non-determinism in execution timing can eventually lead to non-determinism of processing results.

Also, reader for example can be implemented like this:

while(!fifo.num_available()){
   // change model state ...
   wait(1,SC_SEC);
}

But at the end, it's up to you to decide what should be semantics of your FIFO, depending on your particular modeling case.  In SystemC you can also use immediate notifications, instead of delta-notifications.  In that case, when reader is blocked on empty fifo, it will be executed in same delta cycle when writer puts new data.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×