SystemC 提供了一組 C/C++ 的 Library 讓設計者可以使用 C/C++ 的語法來描述硬體;
使用同一種程式語言來開發 Software 和 Hardware 是 SystemC 的賣點之一。
但是原本 C/C++ 的語法是循序執行的,
所以各 Hardware Module 之間平行執行的特性就必須靠 SystemC Kernel 模擬出來。
使用 SystemC 來描述硬體時,尤其針對同步電路的系統,
程式設計者就必須先瞭解 SystemC 中 Delta Cycle 的特性。
在 SystemC 中,可以利用 Primitive Channel ( 例如 sc_signal<T> )
的 Evaluate-Update 特性來創造出 Delta Cycle。
當 SystemC Process 在某一個時間點對某個 Signal Channel 進行 write( ) 的動作時,
write( ) 的動作會被分成 Evaluate 和 Update 兩個 Phase,
在 Evaluate Phase 時,並不會立即將新的值覆蓋過原本的值,
會等到 Delta Cycle 的 Update Phase 才進行 Update 的動作。
詳細可參考 [1] 的 Chapter 9。
Delta Cycle 的特性可以讓邏輯上應該平行執行的所有 SystemC Process,
在循序執行的 C/C++ 環境下,不會因為 SystemC Process 執行順序的不同,造成不同的程式行為。
接下來我們使用兩條 SC_THREAD 來進行說明,完整的 Source Code 可由此下載。
首先我們建立四個 Data Type 為 uint32_t 的 sc_signal,如下圖:
另外我們建立兩條 SC_THREAD,如下圖:
a_thread 在每一個 Cycle 會對 a_value 的值累加 5,同時將目前 b_value 的值複製到 b_value_copy 中。
b_thread 在每一個 Cycle 會對 b_value 的值累加 3,同時將目前 a_value 的值複製到 a_value_copy 中。
模擬的結果如下:
我們可以觀察到,不管 SystemC Kernel 的 Scheduler 先讓 a_thread 或 b_thread 先執行,
複製到對方的值都是舊的值。
這就是因為 SystemC 的 Channel 提供了 Evaluate-Update 的特性。
接下來我們另外做一個小實驗,
因為使用 Native C/C++ Data Type 理論上在模擬的效能上會比較好,
所以我們將原本四個 sc_signal<uint32_t> 型態的變數改成 Native C/C++ 的 uint32_t 型態。
a_thread 和 b_thread 中的存取也改成正常 Native C/C++ 的寫法。
模擬的結果如下:
我們會發現 Native C/C++ Data Type 的變數並不具備 Evaluate-Update 的特性。
所以當 SystemC Kernel 的 Scheduler 先讓 b_thread 先跑,b_thread 就直接把 b_value 更新了,
然後 a_thread 再執行的時候,複製到的 b_value 已經是新的值了。
硬體的邏輯上,a_thread 和 b_thread 應該同時執行,他們的行為也應該一致,
但是上述的情況下,沒有使用 SystemC Channel 會讓程式的行為和預期的不同。
[1] SystemC: From The Ground Up (Second Edition) , David C. Black and Jack Donovan, Springr, 2010.