Concurrency 2010


Published on

SystemC Concurrency : sc_event how to do?

Published in: Technology
  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Concurrency 2010

  1. 1. Concurrency 林敬倫, 蘇文鈺 成大資訊 2010/11
  2. 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. 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();
  4. 4. Simplified Simulation Kernel [From SystemC From the Groud Up]
  5. 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.
  6. 6. Process execution and Event Pools [From SystemC From the Groud Up]
  7. 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. 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. 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. 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. 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.
  12. 12. Syntax of wait() • • • • • wait(time); wait(name_of_event); wait(name_of_event1&name_of_event2&…); wait(timeout, name_of_event); wait(timeout, name_of_event1 | name_of_event2 | …….); • wait();// static sensitivity • …. And so on.
  13. 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. 14. Simulation Scenarios in Different Perspects User Perceives Actual in SystemC Kernel [From SystemC From the Groud Up]
  15. 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. 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. 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. 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. 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. 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, …);
  21. 21. Example:using event & next_trigger • Hello_module: – Thread1:執行五次後會對thread2發出通知,執行 八次後會對method發出通知並將記數器歸零. – Thread2:執行兩次後會等待thread1的通知再繼 續進行;執行三次後會對method發出通知並將記 數器歸零. – Method:等待thread1及thread2的通知,並在 thread2通知執行過後,將只接受thread1的通知 (即thread2的通知將被忽略).
  22. 22. Main.cpp #include <systemc.h> #include "hello_module.h" int sc_main(int argc, char* argv[]) { // signal declaration sc_clock clk("clk", 10, SC_NS, 0.5); // module declaration hello_module module0("hello_word"); // signal connection module0.clk(clk); // run simulation sc_start(1000, SC_NS); return 0; }
  23. 23. Hello_module.h //Constructor SC_CTOR(hello_module) { count1 = 0; count2 = 0; #include <systemc.h> SC_MODULE(hello_module) { // signal declaration sc_in_clk clk; SC_THREAD(thread_func1); sensitive << clk.pos(); // fuction declaration void thread_func1(); void thread_func2(); void method_func(); SC_METHOD(method_func); sensitive << T1toM; sensitive << T2toM; SC_THREAD(thread_func2); sensitive << clk.pos(); } //event declaration sc_event T1toT2, T1toM, T2toM; int count1, count2; };
  24. 24. Hello_moule.cpp(1/3) #include "hello_module.h" void hello_module::thread_func1() { while(1){ wait(); count1++; sc_time_stamp().print(); printf(" Thread1 : n"); if(count1 == 5){ printf(" Thread1 : T1toT2.notify() n"); T1toT2.notify(); } if(count1 == 8){ printf(" Thread1 : T1toM.notify() n"); T1toM.notify(); count1 = 0; }}}
  25. 25. Hello_moule.cpp(2/3) void hello_module::thread_func2() { while(1){ wait(); count2++; sc_time_stamp().print(); printf(" Thread2 : n"); if(count2 == 2){ printf(" Thread2 : wait for T1.notify1 n"); wait(T1toT2); } if(count2 == 3){ printf(" Thread2 : T2toM.notify() n"); T2toM.notify(); count2 = 0; } } }
  26. 26. Hello_moule.cpp(3/3) void hello_module::method_func() { if(clk){ sc_time_stamp().print(); printf(" Method : Hello Word! n"); //當T2toM叫起methodu第一次之後,T2toM將會失去作用. next_trigger(T1toM); } }
  27. 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結果會 有何不同呢?
  28. 28. 上一頁裡提出的問題 • 若沒有wait(SC_ZERO_TIME),則無法確定 turn_knob_thread()會在stop_signal_thread() 執行後才執行,若是turn_knob_thread()先執 行,所做出event.notify()的動作將會因為 stop_signal_thread()之中的event尚未執行 wait(event)因此出現模擬錯誤. • 因此需要wait(SC_ZERO_TIME)將 turn_knob_thread()放置整個cycle最後才執 行,否則執行結果將不是正確的模擬結果.
  29. 29. HW3 • 請設計以下四個模組: – 模組一: 系統一開始時讀入一文字檔(純英文),並讀入要搜尋的兩 個關鍵字。 – 模組二: 每個時脈時自模組一接收一個word,遇標點符號時丟棄 之。 – 模組三: 每當模組二接到一個非標點符號的word時,自模組二接收 此一word,並檢查是否為第一個關鍵字,若是,則計數器加一。 – 模組四: 每當模組二接到一個非標點符號的word時,自模組二接收 此一word,並檢查是否為第二個關鍵字,若是,則計數器加一。 – 文件結束時,模組三與模組數四通知模組一其個別之數目,模組 一印出數目後,讀入新的檔案。此處理直到該目錄下之檔案均被 檢查完後結束。 • 模組中必須含有method與thread,其他你可能需要再設計其他 模組來進行四個模組的控制,此一模組之設計則無限制。 • 模組間之資料傳輸此次不限定要用SystemC的預設介面 • 請用OpenESL作此一作業。2010/12/9,11:59PM繳交。