This document discusses concurrency in SystemC simulations. It explains that SystemC uses events and processes to model concurrent systems. There are two main types of processes: threads and methods. Threads can wait for events using wait() and methods use next_trigger() to establish dynamic sensitivity. Events have no duration and are used to trigger processes. Notifying an event using notify() moves waiting processes to the ready queue. The SystemC kernel is event-driven and executes ready processes in non-deterministic order.
2. Why Concurrency?
•
•
•
•
Real-Life system is concurrent
Machines work concurrently
Circuits work concurrently
Software processes execute concurrently. Here, events
are usually used to handle concurrency problems.
• So, we use concurrent processes to model a system.
• Therefore, the simulation kernel has to handle the
execution of concurrent processes.
• In SystemC, thread and method are two main process
types.
3. sc_event
• An event happens at a specific time instant and carries no
value and duration. So, when it occurs, no trace of its
occurrence can be located except the effects it causes.
• SystemC simulation kernel is an event-driven simulator.
• SystemC uses sc_event which is responsible for launching and
triggering of events.
• sc_event happens at a single point of time.
• To observe an event, there must be processes waiting for it
and firing actions for it such that we know its occurrence.
• you can perform only two actions with an sc_event: wait for it
or cause it to occur.
• Syntax: sc_event name_of_event, …;
• A scheduled event can be cancelled by
name_of_event.cancel();
5. How SystemC simulation Kernel Works
• Process is ready for execution when the
events it waits are triggered.
• Processes waits for a certain time period to
return to their execution.
• This period can be zero delay or a certain
amount of cycles. If zero delay, they are ready
for execution. Otherwise, they will be placed
in waiting list until the amount of cycles
passes.
7. More on Kernel Operation
• SystemC kernel enters the waiting state
whenever it encounters an explicit wait(), or
in some cases performs a return.
– For zero delay, it is called a delta cycle delay.
Related processes are moved to ready list.
– For non-zero delay, processes are moved to the
ready list when the time is advanced to the
scheduled time is met.
– When no process is to be executed for a triggered
event, it simply returns to sc_main and finished.
8. Use SC_THREAD as Process
• An SC_THREAD is started once and only once.
• An sc_thread takes control when it is started and
returns (wait() inside of a loop) to the kernel or
simply exits (return) after its execution.
• When a SC_THREAD exits, it terminates
forever, so, SC_THREAD usually contains an
infinite loop.(while(1);) and at least one wait().
• An indirect method to invoke wait() is to call
blocking methods like sc_fifo read or write.
9. Trigger of an Event using .notify()
• To cause an event to occur, .notify() can be used.
• Usages:
– name_of_event .notify(); //immediate notification
– name_of_event .notify(SC_ZERO_TIME);//delayed
notification
– name_of_event .notify(time);//timed notification
– notify(name_of_event)
– notify(name_of_event, SC_ZERO_TIME);
– notify(name_of_event, time);
• Events can be cancelled by using .cancel(), but
immediate events, which happen at the present
notification time, cannot be cancelled.
10. Effects of notify
• When using notify(), kernel moves processes
waiting for the from the wait pool into the
ready list.
• Notified Processes will execute only after all
waiting processes have executed.
• An sc_event may have no more than a single
outstanding scheduled event, and only the
nearest time notification is allowed.
11. Dynamic Sensitivity of sc_thread using
wait()
• Wait() is used to suspend an sc_thread.
• When wait() is executed, the state of the
current sc_thread is saved and SystemC
simulation kernel takes back its control.
• Then, the kernel tries to activate the next
ready process.
• When the suspended thread resumes, its
saved context is restored before continuing its
execution.
13. Time_out()
• Use time_out() to test a system
sc_event event1, event2;
….
wait(time, event1|event2);
If(time_out()) break;
….
If(event2) printf(…..);
…….
14. Simulation Scenarios in Different
Perspects
User Perceives
Actual in SystemC Kernel
[From SystemC From the Groud Up]
15. Use SC_METHOD as Process
• It is like a function call in C. Therefore, it is less
suitable to modeling some behavior.
• It runs completely and returns and may not
suspend internally. Thus, wait() cannot be used
here.
• Based one sensitivity, it is called repeated by the
simulation kernel. Therefore, it is more like
Verilog always@() statement.
• There are also implied waits such as read/write of
sc_fifo, which should be avoided in sc_method.
16. Using SC_METHOD and its Sensitivity
• Syntax:
– SC_METHOD(name_of_process);
• Using an SC_METHOD, variables must be
declared and initialized each time when it is
invoked.
• Sensitivity: the way it can be called repeatedly
and synchronized with other processes
– Dynamic
– Static
17. Dynamic Sensitivity of SC_METHOD
• next_trigger()
–
–
–
–
–
next_trigger(time);
next_trigger(event);
next_trigger(name_of_event1&name_of_event2&…);
next_trigger(timeout, name_of_event);
next_trigger(timeout, name_of_event1 |
name_of_event2 | …….);
– next_trigger();// static sensitivity
– …. And so on.
• Looks exactly the same as wait();
18. Using next_trigger()
• It should be initialized and executed before the
return of this SC_METHOD.
• It is important to apply next_trigger() at every
exit path in a SC_METHOD. Otherwise, it will
never be invoked again.
• To avoid the situation that a method is never
called again, one can place a default next_trigger
as its first statement.
• It can be repeatedly called. Each time it is
called, the previous ones are override.
19. Processing Order
of wait() and next_trigger()
• wait(name_of_event1&name_of_event2&…)/nex
t_trigger(name_of_event1&name_of_event2&…)
;
– There is no knowing which event comes first:
name_of_event1 or name_of_event2. It can be
asserted that both events happen.
• wait(name_of_event1|name_of_event2&…)/next
_trigger(name_of_event1|name_of_event2&…);
– It can be asserted that either events or both events
happen. To know which event happen, additional
code is required, like the time_out() example.
20. Static Sensitivity
• Static sensitivity is established during the elaboration
stage and cannot be changed once it is established.
• It applies to the most recent process registration. It is
used when processes are handled for certain fixed
events without implementing the related codes in the
processes bodies.
• Thread: wait();// static sensitivity
• Method: next_trigger();// static sensitivity
• Syntax:
– sensitive << name_of_event1 [<< name_of_event2];
– sensitive (name_of_event, …);
27. Be Careful of Processing Order
• One must be sure of the processing order of
processes, because different processor orders
may cause different results.
• Sometimes, wrong process order may cause
simulation errors though the program can be
successfully compiled and no runtime error.
• 書中figure 7-16 to 7-19舉了一個例子. 請大家看
一下, 然後寫一個簡單的例子, 當沒有figure7-17
中的wait(SC_ZERO_TIME)時, simulation結果會
有何不同呢?