Jump to content

Recommended Posts

Hi,

I have just started to work with b-transport and nb-transport interfaces and I have a few simple questions:

- What is the meaning of time quantum when we have b-transport? As I know, SystemC has a run-to-completion scheduling policy and it should not terminate any processes!

- Who manages the time in each time quantum, since the local time is not tracked by the SystemC scheduler? If the scheduler does not track the local time, could an initiator send several transactions (b-transports) in its quantum?

- I cannot understand the meaning of the delay parameter in a b-transport! I have read the user manual but it made me more confused! For example, in Figure 5 page 18 of the user manual, in both the forward and return transactions, we have b_transport(t,0ns). What does that mean? If the target waits 40ns, why it sends b_transport(t,0ns)?

Thank you,

Reza

Share this post


Link to post
Share on other sites

Hi Reza,

The idea of the quantum is that a process does *not* give up to the scheduler until it decides enough local time has passed. For instance, imagine the current time (as returned by sc_time_stamp()) is 1000ns.

My initiator has a local sc_time variable t. I initialise t to e.g. 10 ns.

An initiator thread executes b_transport(tx, t);

That means my local time is now 1010ns (but sc_time_stamp() has not changed, and no other process has run).

The target which implements b_transport, now updates t by 100ns i.e. t now contains 110ns. In other words, the target is "pretending" it took 100ns to process my request, and my local "pretend" time is 1110ns.

I can then call b_transport again with t = 110 + 10 = 120 ns;

The target returns with 220 ns;

and so on. So in answer to one of your questions, yes there can be many calls to b_transport within a quantum.

Let's now suppose the global quantum is set to 500 ns.

Eventually, my local time offset is greater than 500 ns. At that point my initiator calls wait(), and another initiator can run. SystemC time is still at 1000 ns, sc_time_stamp() hasn't changed.

The second initiator runs sending calls back and forth until its local time offset exceeds the global quantum. It then calls wait().

Eventually all initiators have run and suspended. sc_time_stamp() increases, and off we go again.

Now to keep track of that yourself would be possible, but boring to write the code - so in tlm_utils there is a utility called the tlm_quantum_keeper. The idea is that each initiator has its own tlm_quantum_keeper instance, and that's what keeps track of the local time offset.

So the answer to "who manages the time" is either "you do - good luck!". Or use tlm_utils::tlm_quantum_keeper (much easier).

In your third example, the idea of the delay parameter is that this represents the offset from systemc time (sc_time_stamp()). In my description above, I assumed the target did *not* call wait. However if the target *does* call wait, then the offset must be reset to 0 ns, because sc_time_stamp() has increased.

I hope this helps,

regards

Alan

P.S. I suppose I should really try and sell you a training course http://www.doulos.com/content/training/systemc_tlm2.php :)

Share this post


Link to post
Share on other sites

Hi,

I am not sure if I understand the meaning of delay in b_transport and nb_transport interfaces completely. Imagine, for example, we have the following piece of code in initiator:

socket->b_transport( *trans, delay );

wait(delay);

  • What does the "wait(delay)" mean here?
  • Does delay describe the point of time in the future where the communication actually start?
  • What does that mean if we have "wait(delay)" in target?
  • Does the delay returned by the target describe the point in time the communication end?

What if we have nb_transport instead of b_transport? For example, assume we have the following piece of code:

for (int i = 0; i < 1000; i++)

{

delay = sc_time(rand_ps(), SC_PS);

status = socket->nb_transport_fw( *tran, phase, delay );

if (status == tlm::TLM_UPDATED)

{ m_peq.notify( *tran, phase, delay );}

else if (status == tlm::TLM_COMPLETED)

{

request_in_progress = 0;

check_transaction( *tran );

}

wait(sc_time(rand_ps(), SC_PS));

} // end of for

wait(100, SC_NS);

Thank you,

Reza

Share this post


Link to post
Share on other sites

Regarding your questions about blocking transport...

wait(delay) means that the initiator has chosen to synchronise to sc_time_stamp() by calling wait.

In the target, the delay parameter represents the time at which the target should consider the request to have been received.

In the initiator, the delay parameter contains the time at which the initiator should consider the response to have been received.

If you have wait(delay) in the target, it means the target has chosen not to use temporal decoupling and has instead decided to wait to the actual sc_time_stamp() when the request should be received.

The delay returned by the target does represent the time at which the response should be considered to have arrived (relative to sc_time_stamp()), which is the time at which the transaction ends.

You can think of b_transport as representing a protocol with only two timing points, the time at which the request is sent, and the time at which the response is received.

regards

Alan

Share this post


Link to post
Share on other sites

I still do not get the difference between delay argument in a b-transport interface and an nb-transport interface! I was wondering if the meanings are the same? For example, in the following line of code, is the meaning of the delay argument in the nb-transport the actual timing point that the begin-req is sent (imagine the phase is begin-req)?

 

socket->nb_transport_fw( *tran, phase, delay );    vs.     socket->b_transport( *tran, delay );

 

 

Thanks,

Reza

Share this post


Link to post
Share on other sites

If they are the same, what about the delay argument in the last transaction sending by the initiator with phase=end-resp? As I know, in the b-transport, this is the target who finishes the transaction. However, in the nb-transport this is the initiator who finished the transaction by sending end-resp. So if the meanings are the same, what is the meaning of the delay in the last transaction?

Share this post


Link to post
Share on other sites

Hi Reza,

  in non-blocking transport (base protocol) there are four phases (as I'm sure you know). Initiators send BEGIN REQ and END RESP, targets send END REQ and BEGIN RSP.

 

Each can have a timing annotation.

 

When a target receives BEGIN REQ it can delay sending END REQ. It does this by increasing the timing annotation. This indicates to the initiator that is cannot send a new request because the target is busy - sometimes known as "back pressure".

 

After the target has sent END REQ (it has accepted the request), it may take time to process a request (processing delay). It can model this by increasing the timing annotation when calling BEGIN RSP.

 

When the initiator receives BEGIN RSP, it may model its own accept delay (back pressure) by increasing the timing annotation when it calls END RSP.

 

There's a nice diagram on page 510 of the 1666-2011 manual.

 

regards

Alan

Share this post


Link to post
Share on other sites

Hi

 

In nb_transport_bw/nb_transport_fw, where we should cosume these timing annotations carried by delay argument.

I mean we keep add some delay and in the last we must call wait() to consume these delay.

Where we should call this wait(). in intitiator thread or target thread ?

 

Thanks

Share this post


Link to post
Share on other sites

You can't call wait inside nb_transport_fw or nb_transport_bw, so you need some parallel thread or callback, in both the initiator and the target. One approach is to use the payload event queues that are in the TLM2 utilities.

 

So in the target (for instance) as a transaction arrives, you post it into the payload event queue (peq). When the appropriate time has passed the peq notifies an event and a thread that's been waiting for that event calls nb_transport_bw with the response.

 

Or you can use the peq with callback. Then the callback is called at the appropriate time by the PEQ.

 

If you're using PEQ with callback in the target (for instance) then you might not need a thread in the target. But of course there's got to be a thread somewhere, or no time  will pass,

 

regards

Alan

Share this post


Link to post
Share on other sites

The idea of the quantum is that a process does *not* give up to the scheduler until it decides enough local time has passed. For instance, imagine the current time (as returned by sc_time_stamp()) is 1000ns.

My initiator has a local sc_time variable t. I initialise t to e.g. 10 ns.

An initiator thread executes b_transport(tx, t);

 

What's the local time for target when it received b_transport call, 1000ns or 1010ns?

 

 

 

The target which implements b_transport, now updates t by 100ns i.e. t now contains 110ns. In other words, the target is "pretending" it took 100ns to process my request, and my local "pretend" time is 1110ns.

 

the target executes b_transport(tx, t), in which, t should be 100ns or 110ns?

Share this post


Link to post
Share on other sites

For question 1, the target should pretend that the call arrived at 1010ns i.e. it's local time should be taken to be 1010ns.

 

For question 2 I was assuming that t contained 10ns when the call arrived. Adding this to sc_time_stamp gives a local time of 1010ns. The target is then pretending to take 100ns to implement the call, so it updates t by 100 ns, i.e. t = t + 100ns. So when the function returns, t contains 110 ns.

 

regards

Alan

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

×