2008年12月31日 星期三

SystemC Modules and Processes(1)

這個章節包含了一個完整的基本設計用以展示如何在SystemC裏使用modules及processes.
為了淺顯易懂,它是屬於非常低階的設計,這種設計方式並不是一個你在做系統層級設計時所希望的。
主要的展示重點:
  1. 建立階層架構

  2. 使用內建的sc_signal通道

  3. (特殊)ports

  4. Processes(SC_METHOD, SC_THREAD, SC_CTHREAD)

  5. 一個簡單的測試程式
SystemC的背景
為什麼要看Modules及Processes呢?這是因為System的主要目的是想要解決軟體及硬體的同時設計,並且希望能對大型的系統建立模型。
Process是程式裏的最小單位,系統裏的每個Process皆是平行運作的。機乎所有的高階系統層級設計(high-level system level design:SLD)工具都是以網絡行程(network of processes)的基礎模型(underlying model)來開發設計的。
SystemC提供了Processes(行程)來支援建構網絡裏的每個獨立(同時/平行)的程式碼區塊(pieces of code)。

SLD常會遇到大型的設計需求。為了滿足這個目的,它通常都是使用階層式(Hierarchy)的架構來設計。階層式架構在SystemC裏會以module來實現它,一個類別(class)和其它的modules的連接方式必需使用ports。
Modules允許被分割進行設計開發。Modules可能包含其它的processes以及實體化(instances)其它的modules。

一個設計範例
這個範例是以4個NAND閘組成1個EXOR閘。再次說明,這個範例並不是一個典型設計的風格,但是它可以很容易的讓大家了解SystemC。
範例電路圖如下:

第一步當然就是去建構NAND閘的模型囉。NAND閘是一種組合電路,它的輸出完全取決於輸入端,它完全沒有記憶功能,也不需要時脈。
所以這個模型(model)可以使用SystemC裏最簡單的process SC_METHOD 來設計。

SC_METHOD是一個簡單的C++函式,因此SystemC class library將它拿來展現processes的行為。
比較特別的:
SystemC class library包含了一個模擬核心(simulation kernel) - 處理每個模型的時間推移,以及當有輸入改變時呼叫函式去處理相應的輸出。
SC_METHOD需要定義function給它及觸發function的輸入值條件。(The function must be declared as an SC_METHOD and made sensitive to its inputs.)

底下是NAND閘的範例程式(nand.h)
#include "systemc.h"

SC_MODULE(nand2) // declare nand2 sc_module

{
sc_in<bool> A, B; // input signal ports
sc_out<bool> F; // output signal ports

void do_nand2() // a C++ function
{
F.write( !(A.read() && B.read()) );
}

SC_CTOR(nand2) // constructor for nand2
{
SC_METHOD(do_nand2); // register do_nand2 with kernel
sensitive << A << B; // sensitivity list
}
};
程式說明:

階層架構在SystemC裏是使用class sc_module來實現。sc_module 可能會被直接拿來使用,也可能會被使用巨集SC_MODULE指令所隱藏起來。
上面的範例裏就是使用SC_MODULE來建立一個sc_module名字叫nand2的類別物件。

接下來宣告輸入及輸出埠。一般來說,一個埠的宣告都是使用類別sc_port。
再進一步的例子,input ports還會需要使用sc_signal來宣告型態。如:
sc_port<sc_signal_in_if<bool>,1> A,B;
所以就如同你看到的,會有很多很多的形態耶。所以為了方便,也可以使用特別的ports.
sc_in就是一個特殊的埠用以快速的使用sc_signal。

ports可以是C++或SystemC的任何一種形態,範例裏是使用C++內建的bool形態。

再接下來介紹,input及output ports都包含了read()/write()的方法(methods),使用它們來讀/寫埠的資料。
A和B都是被拿來讀資料的,do_nand2()是拿來計算的函式,而計算結果將透過write()寫入到F裏。

注意一下你也可以不使用read()/write()來讀/寫資料,用=來進行操做,如:
F = !(A && B);
但是使用read()/write()是比較好的作法,它比較容易讓C++的編譯程式進行分析。

在看完do_nand2()後,接著是建構式sc_module,它實體化了nand2這個物件。SystemC提供了簡單的方法來完成這件事,那就是SC_CTOR。
這個建構式處理的事情如下:
  1. 建立階層(不過在這個範例中沒有)

  2. 在simulation kernel裏註冊我們這個新的process

  3. 宣告這個的觸發條件清單列表


它也可能在建構式裏做一些初使化的的行為 - 比如說:類別資料成員就可以在建構式裏進行初使化。

所以在上面的範例程式裏,建構式宣告了do_nand2是一個SC_METHOD,並且告訴kernel當port A/B值發生改變時去執行do_nand2()。

資料來源:
http://www.doulos.com/knowhow/systemc/tutorial/modules_and_processes/

沒有留言:

一個小故事讓我們明白資金流通的意義

“又是炎熱小鎮慵懶的一天。太陽高掛,街道無人,每個人都債台高築,靠信用度日。這時,從外地來了一位有錢的旅客,他進了一家旅館,拿出一張1000 元鈔票放在櫃檯,說想先看看房間,挑一間合適的過夜,就在此人上樓的時候---- 店主抓了這張1000 元鈔,跑到隔壁屠戶那裡支付了他欠的肉錢...