顯示具有 SystemC 標籤的文章。 顯示所有文章
顯示具有 SystemC 標籤的文章。 顯示所有文章

2012年1月7日 星期六

Accellera、OSCI合併 推動EDA邁向整合



轉貼自電子工程專輯
http://www.eettaiwan.com/ART_8800658972_480102_NT_542f28bc.HTM?8800089207&8800658972&click_from=8800089207,9950038858,2012-01-06,EETOL,ARTICLE_ALERT 

根據這個新聞可以得知,Co-simulation機制與systemC的結合,將是未來EDA發展的方向。因此IC-Design將越來越像是Software Design,HW/SW界線將開始模糊,好像陰陽開始調合了。呵呵!!!


電子設計自動化(EDA)領域向整合再邁出了一大步。日前,Accellera與開放式SystemC促進會(OSCI)這兩個EDA和智財標準制定組織宣佈將合併,共同組成Accellera系統促進會(Accellera Systems Initiative)。合併後的組織將致力於推動系統與半導體設計領域的標準制定,目標是讓電子設計產業間能更有效率地進行合作。
隨著系統晶片的複雜度不斷攀升,系統、軟體與半導體等設計工作將高度整合,這是為何Accellera與OSCI有必要合併,的主因,因為業界需要一個能加快整合的組織,來制訂相關智財與電子設計自動化的標準,Cadence Design Systems公司的EDA/IP標準暨互通性組織主管Stanley Krolikoski說。Krolikoski是Accellera Systems Initiative董事會成員,他目前也擔任IEEE設計自動化標準委員會(DASC)主席。
“這項合併與標準制訂計畫的整合,呼應了系統與半導體業界需求的重大進展,” OSCI主席 Eric Lish強調,Accellera系統促進會將透過提供可貫穿從系統層、暫存器轉換層(RTL)到閘級設計(Gate)以及智財的設計標準,來協助電子設計產業提升設計生產力。
Accellera系統促進會主席 Shishpal Rawat表示,合併後的新組織能更有效率地加速跨越多元設計環境的系統與智財設計標準制定,以提升電子設計產業生產力並降低積體電路與嵌入式系統的設計成本。資深產業分系師Gary Smith看好這項合併,他認為Accellera與OSCI的合併,將加速跨越不同電子設計領域的設計標準制定與推廣。
組織合併後,現有分屬Aellera與OSCI的標準制定工作將在合併的組織中繼續進行並基於彼此互補性加強合作。Accellera系統促進會並將持續與IEEE的夥伴關係,將轉移所制定之標準給IEEE予以正規化及後續管理。
Accellera和OSCI旗下都擁有各自的技術委員會,這些工作小組負責不同的標準制定工作。Accellera目前擁有的技術委員會包括:負責共同模擬(Co-emulation)與基於交易層(transaction-based)之加速器上SCE-MI標準的介面技術委員會;負責智財整合中介標準的IP-XACT工作組;負責智財使用追蹤標準的智財標籤(IP Tagging)技術委員會;負責制定OVL聲明庫的開放式驗證庫技術委員會;負責驗證覆蓋率共通性的整合覆蓋率共通標準(Unified Coverage Interoperability Standard;UCIS);負責通用驗證方法(UVM)標準的驗證智財委員會;以及負責Verilog類比及混和訊號延伸標準的Verilog-AMS技術委員會。
目前OSCI所屬的技術委員會包括:類比及混和訊號──SystemC類比及混和信號延伸標準;組態、控制及檢測──SystemC與設計工具間之資訊交換標準;語言──SystemC語言標準;合成──SystemC 可合成子集;交易層模型 (Transaction Level Modeling ,TLM)──OSCI TLM 1.0 及 2.0模型標準;以及驗證──主要負責SystemC驗證庫。
未來在整合後,這些小組將更緊密的合作。另外,Accellera系統促進會也將與電機電子工程師會(IEEE)共同合作加速標準制定工作。所制定之標準將轉移給IEEE予以正規化及後續管理。

2011年11月16日 星期三

SystemC Linux開發環境配置

可參考
http://stenlyho.blogspot.com/2008/10/systemc-linux.html

將systemc從官網下載回來後,找個地方把你的systemc-2.2.0.tgz解開

tar xvf systemc-2.2.0.tgz

然後cd systemc-2.2.0

然後mkdir /usr/systemc

然後./configure --prefix=/usr/systemc

最後make
make install


CentOS4會有example error
可以不予理會

CetnOS5就不會有問題

但是在安裝TLM2時
CentOS4不會有問題

但是CentOS5會有問題
問題如下

/home/systemc-2.2.0/include/sysc/packages/boost/bind/placeholders.hpp:54: warning: ‘<unnamed>::_1’ defined but not used
/home/systemc-2.2.0/include/sysc/packages/boost/bind/placeholders.hpp:55: warning: ‘<unnamed>::_2’ defined but not used
/home/systemc-2.2.0/include/sysc/packages/boost/bind/placeholders.hpp:56: warning: ‘<unnamed>::_3’ defined but not used
/home/systemc-2.2.0/include/sysc/packages/boost/bind/placeholders.hpp:57: warning: ‘<unnamed>::_4’ defined but not used

問題解決之法在修改
/home/systemc-2.2.0/include/sysc/packages/boost/bind/placeholders.hpp中的line 28

#if defined(__BORLANDC__)
改成
#if defined(__BORLANDC__) || defined(__GNUC__)

就可以過了

systemC如果make在64bits環境
記得將
/usr/systemc下的
lib-linux64作一個link到lib-linux

2011年11月15日 星期二

如何掛載SystemC TLM Library (Linux OS)

先從官網下載TLM-2.0.1.zip

放到systemC的安裝目錄再解壓縮

在解壓縮的目錄下的
examples/tlm/build-unix

Makefile.config開啟

其中第三行及第四行的
DEFAULT_SYSTEMC_HOME = “放入systemC的安裝目錄如 ~/systemC.2.2.0 “
DEFAULT_TLM_HOME     = “放入TLM的解壓縮目錄如~systemc-2.2.0/TLM”

儲存後,可以到examples/tlm目錄下的其他次目錄如at_1_phase
其下有另一個build-unix 目錄

可以看到Makefile

直接執行make就會得到一個*.exe

make check就可以確認是否正確
正確會得到下面的message

...
           SystemC 2.2.0 --- Sep 28 2011 11:38:21
        Copyright (c) 1996-2006 by all Contributors
                    ALL RIGHTS RESERVED
OK
...


執行*.exe就會看到執行結果了

2011年10月20日 星期四

Digital Circuit Functional Verification(二十)

 验证工具總結

1. 尽管 Lint 和其他静态代码检查工具可能报告很多的伪错,但它们对于某些错误仍然是最
有效的检测工具。

2. 仿真器的好坏取决于被仿真的模型。同时仿真器还提供了许多提高仿真性能的选项,可以
支持联合仿真或者混合语言仿真。

3. 基于断言的验证对任何验证方法都是强大的工具,通过它可以很快地发现问题的位置和
发生时间。(SVA)

4. 硬件验证语言由于其对验证任务和覆盖率驱动的随机验证的支持,它对提高设计效率很有
帮助。(UVM, systemverilog, systemC...)

5. 由代码和功能覆盖数据可以对设计质量进行量化的评估。但要注意的是:不必付出所有
代价去达到 100% 的覆盖率,即使达到了预期的覆盖率目标也不能说明设计工作已经完成。
(spec. -> functional items -> function coverage -> code coverage)

6. 源码控制系统和问题追踪系统可以管理代码并报告错误。(Project manager 要試著與member 討論可行的作法)

2011年9月30日 星期五

risc cpu @ systemc

risc cpu @ systemc
轉貼自http://funningboy.blogspot.com/2010/09/risc-cpu-systemc.html?showComment=1317181463530#c126477895408032611


因為原來在systemc-2.2.0的example下的risc_cpu
Compile後,run simulation,會有錯誤發生
所以作者將它修正後,提供下載


hi all, If you are interest in the CPU architecture design,i think the 'rsic cpu' is a good choice.It is a sample package in systemc example, but it contain some problems with multi-drive. What's the multi-drive, it means the multi inputs drive the same output. you can image the data in this point is unstable, it should be 1 or 0 or x.... ,so the compiler would confuse what's the data in it.Because in systemc is no wire definition, in 'sc_signal' declare it like the register or buffer design, it would keep the current data until the next trigger to change it's data. we use a very sample way to avoid it, to create a new module and change the declare of 'sc_signal' to 'sc_in' and 'sc_out' . all new packages and version is release in here please use this command to compile our package.




原作者修正問題後的Package下載點
https://sites.google.com/site/funningboy/c/2010_1003_risc_cpu.tar.gz?attredirects=0&d=1


使用以下指令去compile risc_cpu files
g++ *.cpp -I/usr/systemc/include -L/usr/systemc/lib-linux -o cpu -lsystemc

如果是64bits
g++ *.cpp -I/usr/systemc/include -L/usr/systemc/lib-linux64 -o cpu -lsystemc 


修正的方法
1 fix lists 1. multi drive example Error: (E115) sc_signal cannot have more than one driver: signal `STALL_FETCH' (sc_signal) first driver `PAGING_BLOCK.port_13' (sc_out) second driver `BIOS_BLOCK.port_6' (sc_out) In file: ..\..\src\sysc\communication\sc_signal.cpp:126 2. data cache miss the environment of dcache is unconnected, we replace it by mem architecture,that can be work on "lw,sw" commands 3. branch && jump conditions not work fix the program counter to jump && branch condition  

執行的方法
2. how to use
//1 use this command to load our asm code 2 icache file
perl assembler.pl test2.asm -code > icache
//2 use this command to get visible asm code
perl assembler.pl test2.asm  > view
//3 run and check
./cpu

2011年7月1日 星期五

另一個用SystemC寫的Counter

與前一個相同,指是改用class方式來寫

#include

//SC_MODULE (counter) {
class counter : public sc_module {

public:
sc_in reset;
sc_in clock;
sc_out out_value;
sc_unit<4> cout;

void counter_in(){
if (reset)
cout = 0;
else
cout ++;

out_value.write(cout);
}

SC_CTOR(counter) {
SC_MODULE(counter_in);
sensitive << clock.pos();
sensitive << reset;
}
};

//SC_MODULE (power_on) {
class power_on : public sc_module {

public:

sc_signal reset;

void por() {
wait (3, SC_NS);
reset = sc_bit('1');
wait (5, SC_NS);
reset = sc_bit('0');
}

SC_CTOR(power_on) {
SC_THREAD(por);
}
};

int sc_main (int argc, char* argv[]) {

sc_signal cout_value;
sc_signal reset;

sc_clock clock ("my_clock", 3, 0.5, SC_NS);

counter my_cnt("My_COUNTER");

power_on my_power_on("My_POWER_ON");

my_power_on.reset(reset);

my_cnt.clock (clock);
my_cnt.reset (reset);
my_cnt.out_value(cout_value);


sc_trace_file *wf = sc_create_vcd_trace_file ("sc_test");
sc_trace(wf, clock, "clock");
sc_trace(wf, reset, "reset");

sc_trace(wf, my_cnt.cout, "my_cnt_value");
sc_trace(wf, cout_value, "count_value");

sc_start(150, SC_NS);

sc_close_vcd_trace_file(wf);

return 0;

}

2011年5月22日 星期日

Example Threads

#include "systemc.h"

SC_MODULE (first_counter) {
sc_in_clk clock ; // Clock input of the design
sc_in reset ; // active high, synchronous Reset input
sc_in enable; // Active high enable signal for counter
sc_out(sc_uint<4> ) counter_out; // 4 bit vector output of the counter

//------------Local Variables Here---------------------
sc_uint<4> count;

//------------Code Starts Here-------------------------
// Below function implements actual counter logic
void incr_count () {
// For threads, we need to have while true loop
while (true) {
// Wait for the event in sensitivity list to occure
// In this example - positive edge of clock
wait();
if (reset.read() == 1) {
count = 0;
counter_out.write(count);
// If enable is active, then we increment the counter
} else if (enable.read() == 1) {
count = count + 1;
counter_out.write(count);
}
}
} // End of function incr_count

// Below functions prints value of count when ever it changes
void print_count () {
while (true) {
wait();
cout << "@" << sc_time_stamp() <<
" :: Counter Value " << counter_out.read() << endl;
}
}


// Constructor for the counter
// Since this counter is a positive edge trigged one,
// We trigger the below block with respect to positive
// edge of the clock
SC_CTOR(first_counter) {
// Edge sensitive to clock
SC_THREAD(incr_count);
sensitive << clock.pos();
// Level Sensitive to change in counter output
SC_THREAD(print_count);
sensitive << counter_out;
} // End of Constructor

}; // End of Module counter

2011年5月21日 星期六

一個加了Waveform Dump的pipe例子

這個例子是從systemC的例子改過來的

#include "systemc.h"

typedef sc_biguint<8> atom; // Value to be pipe delayed.


//==============================================================================
// dpipe - DELAY PIPELINE FOR AN ARBITRARY CLASS:
//==============================================================================
template
SC_MODULE(dpipe) {
typedef sc_export > in; // To pipe port type.
typedef sc_export > out; // From pipe port type.

SC_CTOR(dpipe)
{
m_in(m_pipe[0]);
m_out(m_pipe[N-1]);

SC_METHOD(rachet);
sensitive << m_clk.pos();
}

void rachet()
{

for ( int i = N-1; i > 0; i-- )
{
m_pipe[i].write(m_pipe[i-1].read());
}
}

sc_in_clk m_clk; // Pipe synchronization.
in m_in; // Input to delay pipe.
out m_out; // Output from delay pipe.
sc_signal m_pipe[N]; // Pipeline stages.
};


// Testbench reader of values from the pipe:

SC_MODULE(Reader)
{
public:
SC_CTOR(Reader)
{
SC_METHOD(extract)

//SC_THREAD(extract);

sensitive << m_clk.pos();
dont_initialize();
}

protected:
void extract()
{
read_out_data = m_from_pipe.read() ;

cout << "Time :" <<
sc_time_stamp().to_double() << ": " << m_from_pipe.read()
<< endl;
}

public:

sc_in_clk m_clk; // Module synchronization.
sc_in reset;
sc_in m_from_pipe; // Output from delay pipe.
sc_signal read_out_data;
};



// Testbench writer of values to the pipe:

SC_MODULE(Writer)
{
SC_CTOR(Writer)
{
SC_METHOD(insert)
sensitive << m_clk.pos();
m_counter = 0;
}

void insert()
{
//wait(2, SC_NS);

m_to_pipe.write(m_counter);
m_counter++;

cout << "Time :" << sc_time_stamp().to_double() <<
" write data => " << m_counter << endl;
}

sc_in_clk m_clk; // Module synchronization.
sc_in reset;
atom m_counter; // Write value.
sc_inout m_to_pipe; // Input for delay pipe.
};

// Main program

int sc_main(int argc, char* argv[])
{
//sc_clock clock(;
sc_signal reset;
sc_signal m_out_data;

sc_clock clock("clock", 3, SC_NS, 0.5, 7, SC_NS, 0);

sc_trace_file *wf = sc_create_vcd_trace_file("sc_cycle");
wf->set_time_unit(100, SC_PS);

sc_trace(wf, clock, "clock");
// sc_trace(wf, reset, "reset");

dpipe delay("pipe");
Reader reader("reader");
Writer writer("writer");

delay.m_clk(clock);

reader.m_clk(clock);
reader.m_from_pipe(delay.m_out);

writer.m_clk(clock);
writer.m_to_pipe(delay.m_in);

sc_trace(wf, reader.read_out_data, "fifo_out_data");
sc_trace(wf, writer.m_counter, "fifo_in_data");

sc_start(30, SC_NS);

sc_close_vcd_trace_file(wf);

return 0;
}

一個用SystemC寫的Power on reset

#include

SC_MODULE (power_on) {
sc_signal reset;

void por() {
wait (3, SC_NS);
reset = sc_bit('1');
wait (5, SC_NS);
reset = sc_bit('0');
}

SC_CTOR(power_on) {
SC_THREAD(por);
}
};

int sc_main (int argc, char* argv[]) {

sc_clock clock ("my_clock", 1, 0.5, SC_NS);

power_on my_power_on("My_POWER_ON");

sc_trace_file *wf = sc_create_vcd_trace_file ("sc_test");
sc_trace(wf, clock, "clock");
sc_trace(wf, my_power_on.reset, "reset");

sc_start(50, SC_NS);

sc_close_vcd_trace_file(wf);

return 0;

}

已經加上了Waveform Dump,以方便觀察變化

參考網頁

http://www.dzwu.net/eda/07117292008.html

一個兩個function的SC_Module

#include "systemc.h"

SC_MODULE (first_counter) {
sc_in_clk clock ; // Clock input of the design
sc_in reset ; // active high, synchronous Reset input
sc_in enable; // Active high enable signal for counter
sc_out(sc_uint<4>); counter_out; // 4 bit vector output of the counter

//------------Local Variables Here---------------------
sc_uint<4> count;

//第一個function
// Below function implements actual counter logic
void incr_count () {
if (reset.read() == 1) {
count = 0;
counter_out.write(count);
// If enable is active, then we increment the counter
}
else if (enable.read() == 1) {
count = count + 1;
counter_out.write(count);
}
} // End of function incr_count

// Below functions prints value of count when ever it changes
void print_count () {
cout << "@" << sc_time_stamp() <<
" :: Counter Value " << counter_out.read() << endl;
}

SC_CTOR(first_counter) {
// Edge and level sensitive
SC_METHOD(incr_count);
sensitive << reset;
sensitive << clock.pos();

// Level Sensitive method
SC_METHOD(print_count);
sensitive << counter_out;
} // End of Constructor

}; // End of Module counter




SC_MODULE的設計範例

#include "systemc.h"  SC_MODULE(dff) {

sc_in din; // Data input of FF
sc_in clk; // Clock input of FF
sc_out out; // Q output of FF

void implement() { // Process that implements DFF
dout = din;
}

SC_CTOR(dff) {

cout << "Executing new" << endl;

SC_METHOD(
implement);
sensitive << reset;
// sensitive << clock.pos();
兩種寫法皆可
sensitive_pos << clk; // Call implements() at every pos edge of clk
}
};

一個用SystemC寫的Counter

包含了Waveform Dump, Reset的機制

#include

SC_MODULE (counter) {
sc_in reset;
sc_in clock;
sc_out out_value;
sc_unit<4> cout;

void counter_in(){
if (reset)
cout = 0;
else
cout ++;

out_value.write(cout);
}

SC_CTOR(counter) {
SC_MODULE(counter_in);
sensitive << clock.pos();
sensitive << reset;
}
};

SC_MODULE (power_on) {
sc_signal reset;

void por() {
wait (3, SC_NS);
reset = sc_bit('1');
wait (5, SC_NS);
reset = sc_bit('0');
}

SC_CTOR(power_on) {
SC_THREAD(por);
}
};

int sc_main (int argc, char* argv[]) {

sc_signal cout_value;
sc_signal reset;

sc_clock clock ("my_clock", 3, 0.5, SC_NS);

counter my_cnt("My_COUNTER");

power_on my_power_on("My_POWER_ON");

my_power_on.reset(reset);

my_cnt.clock (clock);
my_cnt.reset (reset);
my_cnt.out_value(cout_value);


sc_trace_file *wf = sc_create_vcd_trace_file ("sc_test");
sc_trace(wf, clock, "clock");
sc_trace(wf, reset, "reset");

sc_trace(wf, my_cnt.cout, "my_cnt_value");
sc_trace(wf, cout_value, "count_value");

sc_start(150, SC_NS);

sc_close_vcd_trace_file(wf);

return 0;

}

SystemC 時序控制的方法

我是從UserGuide上整理出來的
也就是我們可以有下面兩種產生clock的方法
或者說是任意的波形

第一種方法
For examples, assume you have defined a clock as:
sc_clock clk(“my clock”, 20, 0.5);
You can simulate the generation of clocks for 200 default time units by calling
sc_start(200);

第二種方法
sc_signal clock;
sc_initialize(); //
使用此function to initialize the SystemC scheduler
for (int i = 0; i <= 200; i++)
clock = 1;
sc_cycle(10);
clock = 0;
sc_cycle(10);
}

另外關於非同步的時序
可參考我改寫的例子
此處可以寫出 VCD檔來

#include

int sc_main(int argc,char** argv){

// sc_clock clock;
sc_signal clock, reset;

sc_trace_file *wf = sc_create_vcd_trace_file("sc_cycle");
sc_trace(wf, clock, "clock");
sc_trace(wf, reset, "reset");

sc_initialize();
// Let the clock run for 10 cycles
for (int i = 0; i <= 200; i++) {
clock = 1;
sc_cycle(10);
clock = 0;
sc_cycle(10);
}
// Inject asynchronous reset
clock = 1;
sc_cycle(5);
reset = 1;
sc_cycle(5);
clock = 0;
sc_cycle(10);
clock = 1;
sc_cycle(5);
reset = 0;

sc_cycle(5);
clock = 0;
sc_cycle(10);
// Now let the clock run indefinitely
for (int i=0 ;i<300;i++) {
clock = 1;
sc_cycle(10);
clock = 0;
sc_cycle(10);
}


sc_close_vcd_trace_file(wf);

return 0;

}

Module Instanciating的兩種方法

基本上與verilog 相似

refer web
#include "systemc.h"
#include "first_counter.cpp"

int sc_main (int argc, char* argv[]) {
sc_signal clock;
sc_signal reset;
sc_signal enable;
sc_signal ( sc_uint<4> )counter_out;
int i = 0;
// Connect the DUT
first_counter counter("COUNTER");
// Here ports are connected by position
counter(clock,reset,enable,counter_out);

// Rest of the body of the testbench

return 0;// Terminate simulation
}


#include "systemc.h"
#include "first_counter.cpp"

int sc_main (int argc, char* argv[]) {
sc_signal clock;
sc_signal reset;
sc_signal enable;
sc_signal > counter_out;
int i = 0;
// Connect the DUT
first_counter counter("COUNTER");
// Here ports are connected by name

counter.enable(enable);
counter.reset(reset);

counter.clock(clock);

counter.counter_out(counter_out);

// Rest of the body

return 0;// Terminate simulation
}

sc_bigint 及 sc_biguint

http://www.fpgastudy.com/a/course/SystemC/708.html

在实际设计中,有时候需要宽度大于64的整型数据类型,SystemC引入了sc_bigint和sc_biguint。sc_bigint和sc_biguint的宽度可以从1到任意值,与sc_int和sc_unit相比其仿真速度要慢的多,因此如果不是在实际设计中,有时候需要宽度大于64的整型数据类型,SystemC引入了sc_bigint和sc_biguint。sc_bigint和 sc_biguint的宽度可以从1到任意值,与sc_int和sc_unit相比其仿真速度要慢的多,因此如果不是必要,就不应该使用 sc_bigint和sc_biguint而是尽量使用sc_int和sc_unit。

由于要考虑任意精度,sc_bigint和sc_biguint仿真速度大大下降。在sc_constants.h中,用户可以根据自己的需要定义 SC_MAX_NBITS,以约束sc_bigint和sc_biguint的最大宽度,这样可以提供2~3倍的仿真速度增加,这个常量在默认的情况下是 没有定义的,用户可以根据自己的需要进行修改。SystemC推荐的SC_MAX_NBITS值应该为BITS_PER_DIGIT 的整数倍。BITS_PER_DIGIT在sc_nbdefs.h定义,它的值为30。

下面的代码将SC_MAX_NBITS定义为17倍的BITS_PER_DIGIT。

#define SC_MAX_NBITS 510 // 17 * BITS_PER_DIGIT

example
sc_biguint<128> b1;
sc_biguint<64> b2;
sc_biguint<152> b3;
b3 = b1*b2;

b1*b2运算的结果有192位,只有低152位被赋值给b3。
sc_bigint和sc_biguint、sc_int和sc_unit、C++固有整型数据可以混合使用。


下面是整理了例子
#include

int sc_main (int argc, char* argv[]) {
sc_bigint<128> large_size ;
// Shift operator
large_size = 1000 << 2;
cout <<"Value of large_size : " << large_size << endl;

large_size = 1000 << 31;
cout <<"Value of large_size : " << large_size << endl;

sc_biguint<128> a = 30000;
sc_biguint<128> b = 20000;
sc_biguint<256> c = 0;
sc_biguint<10> d = 0;
// multiplication operator
c = a * b*a*b*a*b*a*b*a*b;
d = a*b;
cout <<"Value of c : " << c << endl;

cout <<"Value of d : " << d << endl;

return 1;
}

Value of large_size : 4000 //放大四倍
Value of large_size : 0 ///雖然sc_bigint指定128bits,但是卻不能做operator運算超過32bits
Value of c : 77760000000000000000000000000000000000000000
Value of d : 512 //如果結果的bit數不足,則只會留存可記錄的bit結果


Example sc_uint

refer to http://www.asic-world.com/systemc/data_types5.html

#include

int sc_main (int argc, char* argv[]) {
sc_uint<1> bit_size = 0;
sc_uint<4> nibble_size = 1;
sc_uint<8> byte_size = 2;
sc_uint<32> dword_size = 3;
//sc_int<128> addr; sc_int can not be more then 64
// Perform auto increment
dword_size ++;
cout <<"Value of dword_size : " << dword_size << endl;
// Terse method addition
byte_size += nibble_size;
cout <<"Value of byte_size : " << byte_size << endl;
// Bit selection
bit_size = dword_size[2];
cout <<"Value of bit_size : " << bit_size << endl;
// Range selection
nibble_size = dword_size.range(4,1); // 如果超過範圍只會影響到可用的bit
cout <<"Value of nibble_size: " << nibble_size << endl;
// Concatenated
dword_size = (byte_size,byte_size);
cout <<"Value of dword_size : " << dword_size << endl;

nibble_size.range(1,2) = nibble_size.range(2,1); //sc_uint不能反向使用
//此處要看IEEE1666-2005 page194
cout <<"Value of nibble_size: " << nibble_size << endl;
return 1;
}

SystemC 2.2.0 --- Mar 18 2011 18:40:28
Copyright (c) 1996-2006 by all Contributors
ALL RIGHTS RESERVED
Value of dword_size : 4
Value of byte_size : 3
Value of bit_size : 1
Value of nibble_size: 2
Value of dword_size : 771
Error: (E5) out of bounds: sc_uint[_base] part selection: left = 1, right = 2 violates 0 <= right <= left <= 3

example sc_int

refer to : http://www.asic-world.com/systemc/data_types4.html

另外可參考

http://www.fpgastudy.com/a/course/SystemC/707.html

#include "systemc.h"

int sc_main (int argc, char* argv[]) {
sc_int<1> bit_size = 0;
sc_int<4> nibble_size = 1;
sc_int<8> byte_size = 2;
sc_int<32> dword_size = 3;
//sc_int<128> addr; sc_int can not be more then 64
// Perform auto increment
dword_size ++;
cout <<"Value of dword_size : " << dword_size << endl;
dword_size(5,4) = dword_size(3,2);
cout <<"Value of dword_size : " << dword_size << endl;
// Terse method addition
byte_size += nibble_size;
cout <<"Value of byte_size : " << byte_size << endl;
// Bit selection
bit_size = dword_size[2]; //此處應該為1 可是結果為 -1 ???
cout <<"Value of bit_size : " << bit_size << endl;
// Range selection
nibble_size = dword_size.range(4,1); // Can not assign out of range
cout <<"Value of nibble_size: " << nibble_size << endl;
// Concatenated
dword_size = (byte_size,byte_size);
cout <<"Value of dword_size : " << dword_size << endl;


return 1;
}


SystemC 2.2.0 --- Mar 18 2011 18:40:28
Copyright (c) 1996-2006 by all Contributors
ALL RIGHTS RESERVED
Value of dword_size : 4 // 3++=4
Value of dword_size : 20 // 010100 =20
Value of byte_size : 3 //2 + 1 =3
Value of bit_size : -1 //
bit_size = dword_size[2];
Value of nibble_size: 2
Value of dword_size : 771 // = 00000011_00000011

bit_size = dword_size[2]; //此處應該為1 可是結果為 -1 ???
cout <<"Value of bit_size : " << bit_size << endl;
這個結果是有值的bit傳給 sc_int <1>
其結果都為-1



Arbitrary Width Logic Type

#include

int sc_main (int argc, char* argv[]) {
sc_lv<8> data_bus (sc_logic ('z')); // All bits are Z 設定初值為Z
sc_lv<16> addr_bus ; // All bits are X 沒有設的為X
sc_logic parity ;
// Print Default value of data_bus
cout <<"Value of data_bus : " << data_bus << endl;
// Assign value to sc_bv
data_bus = "00001011";
cout <<"Value of data_bus : " << data_bus << endl;
// Use range operator
addr_bus.range(7,0) = data_bus;
cout <<"Value of addr_bus : " << addr_bus << endl;
// Assign reverse to addr bus using range operator
addr_bus.range(0,7) = data_bus;
cout <<"Value of addr_bus : " << addr_bus << endl;
// Use bit select to set the value
addr_bus[10] = "1";
cout <<"Value of addr_bus : " << addr_bus << endl;
// Use reduction operator
parity = data_bus.xor_reduce();
cout <<"Value of parity : " << parity << endl;

return 1;
}

SystemC 2.2.0 --- Mar 18 2011 18:40:28
Copyright (c) 1996-2006 by all Contributors
ALL RIGHTS RESERVED
Value of data_bus : ZZZZZZZZ
Value of data_bus : 00001011
Value of addr_bus : XXXXXXXX00001011
Value of addr_bus : XXXXXXXX11010000
Value of addr_bus : XXXXX1XX11010000
Value of parity : 1


Arbitrary Width Bit Type

從asic-world挖出來的例子
可以了解bus形態的操作

#include

int sc_main (int argc, char* argv[]) {
sc_bv<8> data_bus ;
sc_bv<16> addr_bus ;
sc_bit parity ;
// Assign value to sc_bv
data_bus = "00001011";
cout <<"Value of data_bus : " << data_bus << endl;
// Use range operator
addr_bus.range(7,0) = data_bus;
cout <<"Value of addr_bus : " << addr_bus << endl;
// Assign reverse to addr bus using range operator
addr_bus.range(0,7) = data_bus;
cout <<"Value of addr_bus : " << addr_bus << endl;
// Use bit select to set the value
addr_bus[10] = "1";
cout <<"Value of addr_bus : " << addr_bus << endl;
// Use reduction operator
parity = data_bus.xor_reduce();
cout <<"Value of parity : " << parity << endl;

return 1;
}

結果
SystemC 2.2.0 --- Mar 18 2011 18:40:28
Copyright (c) 1996-2006 by all Contributors
ALL RIGHTS RESERVED

Info: (I804) /IEEE_Std_1666/deprecated: sc_bit is deprecated, use bool instead
Value of data_bus : 00001011
Value of addr_bus : 0000000000001011 // addr_bus.range(7,0) = data_bus;
Value of addr_bus : 0000000011010000 // addr_bus.range(0,7) = data_bus;
Value of addr_bus : 0000010011010000 // addr_bus[10] = "1";
Value of parity : 1 // parity = data_bus.xor_reduce();

sc width Bit 的相關method可查SystemC-1666-2005 Chapter 7. Data types

2011年5月11日 星期三

SystemC-定点数据类型

參考 http://www.fpgastudy.com/a/course/SystemC/710.html

SystemC专门定义了有符号和无符号的定点数据类型,而且还允许设定定点数据类型的量化和溢出行为。

SystemC的4种基本定点数据类型为:

sc_fixed
sc_ufixed
sc_fix
sc_ufix

sc_fixed和sc_ufixed的参数是静态的,在程序中设定后不能再修改,而sc_fix和sc_ufix的参数是非静态的,其字长和整数部分长 度可以是变量。sc_fixed和sc_fix是有符号整数,而sc_ufixed和sc_ufix是无符号整数。

定点数据类型的定义方法如下:

sc_fixed x;
sc_ufixed y;
sc_fix x(list of options); //可选项较多,读者可以参考SystemC 库中的sc_fix.h文件
sc_ufix y(list of options); //可选项较多,读者可以参考SystemC 库中的sc_ufix.h文件

sc_fixed和sc_ufixed的参数的含义如下:

(1)wl——总字长,即用于表示一个定点数的总的比特数。

(2)iwl——整数部分字长,即小数点左边的比特数。

(3)q_mode——量化模式。当一个运算的结果的精度大于定点数所能表示的精度时就要根据量化模式将尾数进行取舍。

(4)o_mode——溢出模式。当一个运算的结果大于定点数所能够表示的最大值时,就要根据溢出模式将数据进行处理。

(5)n_bits——饱和比特的位数。该参数仅用于溢出模式,它定义了在特定的具有饱和行为的溢出模式下饱和比特的位数。

x、y是所定义的定点对象。定点数据类型在加法器、乘法器和FFT运算、滤波器等需要算术逻辑的设计中特别有用。定点数据类型声明的一个例子如下:

sc_fixed<16,8,SC_RND_ZERO,SC_SAT> fx_val;

字长和整数部分字长是定点数据的两个重要参数。字长wl是用于表示一个定点数的总的比特数,它必须是大于0的。整数部分长度iwl也称为整数字长,可以是 正数、负数,也可以大于总字长。下面列出了几种典型的情况,图中X代表任意值,S是符号扩展位,根据符号的情况,可以是0或者1。