C Side Library Functions
A number of library functions are available that help you get information about the SystemVerilog side from the C side. Some of these library functions are also useful in controlling the SystemVerilog side of the interface. Some of these functions are described below.
Library functions related to scope
Function: svGetScope
Use: Gets the current SystemVerilog scope of an imported function.
Function prototype: svScope svGetScope();
Function: svSetScope
Use: Sets the current SystemVerilog scope of an imported function.
Function prototype: svScope svSetScope(const svScope);
Function: svGetNameFromScope
Use: Gets the fully qualified current SystemVerilog path of an imported function from a scope handle.
Function prototype: const char* svGetNameFromScope(const svScope);
Function: svGetScopeFromName
Use: Sets the current SystemVerilog scope of an imported function.
Function prototype: svScope svGetScopeFromName(const char*);
Library functions related to packed arrays
Function: svGetSelectBit
Use: Reads a bit-select index i of an array reference svBitPackedArrRef of type Bit.
Function prototype: svBit svGetSelectBit(const svBitPackedArrRef s, int i);
Function: svPutSelectBit
Use: Writes the value of a bit s to a bit-select index i of an array reference svBitPackedArrRef of type Bit.
Function prototype: void svPetSelectBit(svBitPackedArrRef d, int i, svBit s);
Function: svGetSelectLogic
Use: Reads a bit-select index i of an array reference svLogicPackedArrRef of type Logic.
Function prototype: svLogic svGetSelectLogic(const svLogicPackedArrRef s, int i);
Function: svPutSelectLogic
Use: Writes the value of a bit s to a bit-select index i of an array reference svLogicPackedArrRef of type Logic.
Function prototype: void svPutSelectLogic(svLogicPackedArrRef d, int i, svLogic s);
Function: svSizeOfArray
Use: Returns the total size of an array in bytes or 0 if the array is not in C layout.
Function prototype: int svSizeOfArray(const svOpenArrayHandle);
Function: svGetArrElemPtr
Use: Returns a pointer to an element [index1][index2]... of an array or NULL if the array is not in C layout. The array does not have to be packed.
Function prototype: void *svGetArrElemPtr(const svOpenArrayHandle, int index1, int index2,...);
Function: svGetArrElemPtr
Use: Returns a pointer to an element [index1][index2]... of an array or NULL if the array is not in C layout.
Function prototype: void *svGetArrElemPtr(const svOpenArrayHandle, int index1, int index2,...);
We wrap up our DPI tutorial with this. One word of caution: although this tutorial has covered materials that will help you kick start your DPI knowledge, this is only tip of the iceberg. DPI provides more facilities in addition to what have been discissed here. You are encouraged to explore those advanced topics from a SystemVerilog text or the Language Reference Manual.
參考http://www.project-veripage.com/dpi_tutorial_10.php
2011年5月14日 星期六
淡定
指有泰山崩于前而面不改色的镇定程度,遇事沉稳中又积极果断,老练里却又重视有佳,胜不骄,败不馁; 淡定形容一种勇气。 淡定,是一种思想境界,是一种心态,是生活的一种状态。
<引自百度: http://baike.baidu.com/view/240772.htm>
wiki查不到,但比較接近的英文為Calm
<引自百度: http://baike.baidu.com/view/240772.htm>
wiki查不到,但比較接近的英文為Calm
C variable types and declarations
可參考維基百科
裡面有詳細的敘訴
http://en.wikipedia.org/wiki/C_variable_types_and_declarations
裡面有詳細的敘訴
http://en.wikipedia.org/wiki/C_variable_types_and_declarations
C++ 的friend
C++類別的存取限制 如private, protected, public 等
另外還有一個東西 可以超越這一切的限制 這就是friend
friend 可以用來宣告另外一個類別 或者是一個函式(function)
任何被宣告為 friend 的類別或函式 都可以無視存取限定 直接存取所有的變數或函式
friend的使用方法如下所示
class A;
void SetValue(A *pObjA,int n);
class A
{
friend void SetValue(A *pObjA,int n);
private:
int m_nValue;
}
void SetValue(A *pObjA,int n)
{
pObjA->m_nValue = n;
}
類別A中的 m_nValue是宣告為private
本來是無法讓SetValue()來存取的 但由於SetValue()也被宣告為friend
所以我們可以在SetValue中來存取m_nValue;
friend也可以用在類別身上 被宣告為friend的類別其成員函式可以無視存取限制
任意存取所有的變數或者是函式
從前 不知道是誰的簽名檔上寫著
private就好像是你的老婆 protected就好像是你的小孩 public就好像是你家的狗
但這個講法的破洞就是
只要是friend 不管是老婆 小孩 還是狗 通通都可以碰
參考自http://blog.yam.com/swwuyam/article/11865502
另有一篇關於friend 重載
http://caterpillar.onlyfun.net/Gossip/CppGossip/friendOverLoadOperator.html
另外還有一個東西 可以超越這一切的限制 這就是friend
friend 可以用來宣告另外一個類別 或者是一個函式(function)
任何被宣告為 friend 的類別或函式 都可以無視存取限定 直接存取所有的變數或函式
friend的使用方法如下所示
class A;
void SetValue(A *pObjA,int n);
class A
{
friend void SetValue(A *pObjA,int n);
private:
int m_nValue;
}
void SetValue(A *pObjA,int n)
{
pObjA->m_nValue = n;
}
類別A中的 m_nValue是宣告為private
本來是無法讓SetValue()來存取的 但由於SetValue()也被宣告為friend
所以我們可以在SetValue中來存取m_nValue;
friend也可以用在類別身上 被宣告為friend的類別其成員函式可以無視存取限制
任意存取所有的變數或者是函式
從前 不知道是誰的簽名檔上寫著
private就好像是你的老婆 protected就好像是你的小孩 public就好像是你家的狗
但這個講法的破洞就是
只要是friend 不管是老婆 小孩 還是狗 通通都可以碰
參考自http://blog.yam.com/swwuyam/article/11865502
另有一篇關於friend 重載
http://caterpillar.onlyfun.net/Gossip/CppGossip/friendOverLoadOperator.html
How to Know Random Seed Value
在跑systemverilog 模擬時使用random seed 要如何知道這個random Seed 的值是多少
Cadence IUS: 在IUS的Shell script 使用+svseed = random, 這樣它的seed就會在每次模擬時自動改變, 這樣我們要如何知道變動後的Seed Number是多少
Answer
在Log 上就可以看到svseed : set randomly command line from tcl : xxxxxx
看到的xxxxxx就是compiler階段產生的Seed Number
如果要Debug 就可以將xxxxxx放到Script 中 +svseed=xxxxxx
就會與上次使用+svseed = random產生一樣的模擬結果
據資料顯示
Synopsys 的VCS也是顯示在Log檔上面
Cadence IUS: 在IUS的Shell script 使用+svseed = random, 這樣它的seed就會在每次模擬時自動改變, 這樣我們要如何知道變動後的Seed Number是多少
Answer
在Log 上就可以看到svseed : set randomly command line from tcl : xxxxxx
看到的xxxxxx就是compiler階段產生的Seed Number
如果要Debug 就可以將xxxxxx放到Script 中 +svseed=xxxxxx
就會與上次使用+svseed = random產生一樣的模擬結果
據資料顯示
Synopsys 的VCS也是顯示在Log檔上面
IUS Merge Coverage
以前用過
但臨時要再用時又要查過
現在寫出來以免又忘記了
在IUS的模擬路徑下
如果沒有額外設定
就會看到一個放coverage的路徑
./cov_work
./cov_work/design/xxx
xxx代表目錄名稱
每一個目錄都代表一個模擬的項目
test_name或test_pattern
然後使用
iccr
進入command mode
使用load_test *
可以將所有的coverage項目吃進來
如xxx, xxx1, xxx2, ...
再用
merge xxx * -output all
就會產生合成後的coverage
放再./cov_work/design/all這個目錄下
再用iccr -gui就可以很容易看到合併後的coverage
但臨時要再用時又要查過
現在寫出來以免又忘記了
在IUS的模擬路徑下
如果沒有額外設定
就會看到一個放coverage的路徑
./cov_work
./cov_work/design/xxx
xxx代表目錄名稱
每一個目錄都代表一個模擬的項目
test_name或test_pattern
然後使用
iccr
進入command mode
使用load_test *
可以將所有的coverage項目吃進來
如xxx, xxx1, xxx2, ...
再用
merge xxx * -output all
就會產生合成後的coverage
放再./cov_work/design/all這個目錄下
再用iccr -gui就可以很容易看到合併後的coverage
DPI再了解(十三)
Cadence 使用export 在CPP的模式
參考例如下
#include "svdpi.h"
#include "veriuser.h"
extern "C" {
extern void ex_task();
void import_task() {
io_printf("C: Before calling export function\n");
ex_task();
io_printf("C: After calling export function\n");
}
}
`timescale 1ns/100ps
module main();
export "DPI-C" ex_task = function export_task;
import "DPI-C" context function void import_task();
function export_task();
$display("SV: Entered the export function, wait for some time: %0d", $time);
endfunction
initial begin
$display("SV: Before calling import function %0d", $time);
#1;
import_task();
#1;
$display("SV:After calling function %0d", $time);
end
endmodule
參考例如下
#include "svdpi.h"
#include "veriuser.h"
extern "C" {
extern void ex_task();
void import_task() {
io_printf("C: Before calling export function\n");
ex_task();
io_printf("C: After calling export function\n");
}
}
`timescale 1ns/100ps
module main();
export "DPI-C" ex_task = function export_task;
import "DPI-C" context function void import_task();
function export_task();
$display("SV: Entered the export function, wait for some time: %0d", $time);
endfunction
initial begin
$display("SV: Before calling import function %0d", $time);
#1;
import_task();
#1;
$display("SV:After calling function %0d", $time);
end
endmodule
Verdi 從2010.04之後提供全新架構的FSDB PLI
這是從官網上得到的
我們一般都是使用Method 3
另外兩種做法是否好用就見仁見智了
新的FSDB PLI針對System Verilog有更完整的support,有比較好的perfo rmance。
另外也支援同時dump不同的fsdb檔案。
針對dump options的設定,可以透過
simulator command line、environment variable以及FSDB dump command三種方式指定。
例如要指定一個dump的fsdb檔名, 可以用三種不同的方式來達成:
1.Specify the file name on the simulator command line:
> simv +fsdbfile+dump1.fsdb
2. Specify the file name via an environment variable
> setenv FSDB_FILE dump1.fsdb
3. Specify the file name in a FSDB dumping command
$fsdbDumpvars(“+fsdbfile+ dump1.fsdb”);
優先順序為:Method 1 > Method 2 > Method 3
Cadence IUS simulator link新dumper的方式:
Set share library path
setenv LD_LIBRARY_PATH ${NOVAS_INSTDIR}/share/PLI/ IUS/${PLATFORM}
其中$NOVAS_INSTDIR是Verdi安裝目錄
$PLATFORM為工作站平台:如LINUX或LINUX64 或SOL7_32bit或SOL7_62bit
Compile design and run simulation
ncverilog –f run.f +ncaccess+r
Synopsys VCS simulator link新dumper的方式:
Set share library path
setenv LD_LIBRARY_PATH ${NOVAS_INSTDIR}/share/PLI/ VCS/${PLATFORM}
Compile design and run simulation
vcs –f run.f -debug_pp +vcsd +vpi -P ${NOVAS_INSTDIR}/share/PLI/ VCS/${PLATFORM}/novas.tab \
${NOVAS_INSTDIR}/share/PLI/ VCS/${PLATFORM}/pli.a
Mentor ModelSim simulator link新dumper的方式:
Set share library path
setenv LD_LIBRARY_PATH ${NOVAS_INSTDIR}/share/PLI/ MODELSIM/${PLATFORM}
Compile design and run simulation
vsim -pli ${NOVAS_INSTDIR}/share/PLI/ MODELSIM/${PLATFORM}/novas_ fli.so system -c -do mti.do
我們一般都是使用Method 3
另外兩種做法是否好用就見仁見智了
新的FSDB PLI針對System Verilog有更完整的support,有比較好的perfo rmance。
另外也支援同時dump不同的fsdb檔案。
針對dump options的設定,可以透過
simulator command line、environment variable以及FSDB dump command三種方式指定。
例如要指定一個dump的fsdb檔名, 可以用三種不同的方式來達成:
1.Specify the file name on the simulator command line:
> simv +fsdbfile+dump1.fsdb
2. Specify the file name via an environment variable
> setenv FSDB_FILE dump1.fsdb
3. Specify the file name in a FSDB dumping command
$fsdbDumpvars(“+fsdbfile+ dump1.fsdb”);
優先順序為:Method 1 > Method 2 > Method 3
Cadence IUS simulator link新dumper的方式:
Set share library path
setenv LD_LIBRARY_PATH ${NOVAS_INSTDIR}/share/PLI/ IUS/${PLATFORM}
其中$NOVAS_INSTDIR是Verdi安裝目錄
$PLATFORM為工作站平台:如LINUX或LINUX64 或SOL7_32bit或SOL7_62bit
Compile design and run simulation
ncverilog –f run.f +ncaccess+r
Synopsys VCS simulator link新dumper的方式:
Set share library path
setenv LD_LIBRARY_PATH ${NOVAS_INSTDIR}/share/PLI/ VCS/${PLATFORM}
Compile design and run simulation
vcs –f run.f -debug_pp +vcsd +vpi -P ${NOVAS_INSTDIR}/share/PLI/ VCS/${PLATFORM}/novas.tab \
${NOVAS_INSTDIR}/share/PLI/ VCS/${PLATFORM}/pli.a
Mentor ModelSim simulator link新dumper的方式:
Set share library path
setenv LD_LIBRARY_PATH ${NOVAS_INSTDIR}/share/PLI/ MODELSIM/${PLATFORM}
Compile design and run simulation
vsim -pli ${NOVAS_INSTDIR}/share/PLI/ MODELSIM/${PLATFORM}/novas_ fli.so system -c -do mti.do
verilog 如何設定初始值
$deposit — Deposit a value onto a net
$deposit(top.module.net, value);
Modelsim
force –deposit top.module.net value
VCS似乎以上兩種都支援
Verilog
Wire net;
Initial begin
#10 force top.module.net = 1;
#20 release top.module.net;
End
$deposit(top.module.net, value);
Modelsim
force –deposit top.module.net value
VCS似乎以上兩種都支援
Verilog
Wire net;
Initial begin
#10 force top.module.net = 1;
#20 release top.module.net;
End
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。
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。
SystemC hdl connect
一個synopsys的例子
如何連結systemC 與 verilog
現在惟一的限制在只能針對simulator作設定
如VCS 有其專用之法
IUS也有專用之法
這樣要寫大型的model會被限制住
top.v
`define W 31
module my_top();
parameter PERIOD = 20;
reg clock;
reg [`W:0] value1;
reg [`W:0] value2;
wire [`W:0] add_wire;
reg [`W:0] systemc_signal;
wire [`W:0] sub_wire;
wire [`W:0] control_out;
reg [`W:0] control_out_reg;
integer counter;
integer direction;
integer cycle;
// SystemC model
sc_top_w add1(value1, value2, add_wire); //當作是一個verilog block
// SystemC model
sc_subtracter sub1(value2, value1, sub_wire);//當作是一個verilog block
// 要記得將wire 接好
// Verilog model
v_controller controller1(value1, value2, control_out);
initial begin
value1 = 32'b010; // starts at 2
value2 = 32'b000; // starts at 0
counter = 0;
direction = 1;
cycle = 0;
end
// clock generator
always begin
clock = 1'b0;
#PERIOD
forever begin
#(PERIOD/2) clock = 1'b1;
#(PERIOD/2) clock = 1'b0;
end
end
// stimulus generator
always @(posedge clock) begin
value1 <= counter+2;
value2 <= 32'b010; // stays at 2 after here.
control_out_reg <= control_out;
if (direction == 1) // incrementing...
if (counter == 9) begin
counter = counter - 1;
direction = 0;
end
else
counter = counter + 1;
else // decrementing...
if (counter == 0) begin
counter = counter + 1;
direction = 1;
end
else
counter = counter - 1;
end
// display generator
always @(posedge clock) begin
$display("--------------------------------");
$display("Cycle %0d for values A=%0d and B=%0d", cycle, value1, value2);
$display("Res: A+/-B=%0d A-B=%0d \nController=%0d Systemc_signal=%0d",
add_wire, sub_wire, control_out,systemc_signal);
$display("--------------------------------");
// end after 100 cycles are executed
cycle = cycle + 1;
if (cycle == 100)
$finish;
end
endmodule
module v_controller(ina, inb, outx);
input [31:0] ina;
input [31:0] inb;
output [31:0] outx;
reg [31:0] outx_reg;
always @(ina or inb) begin
outx_reg <= ina * inb;
end
assign outx = outx_reg;
endmodule
#include "systemc.h"
#include "hdl_connect.h"
SC_MODULE(sc_addsub)
{
public:
sc_in > ina;
sc_in > inb;
sc_out > outx;
sc_signal > outM;
sc_signal sc_control_sig;
SC_CTOR(sc_addsub):ina("ina"), inb("inb"), outx("outx"),outM("outM"),sc_control_sig("sc_control_sig")
{
SC_METHOD(sc_addsub_action);
sensitive << ina << inb << sc_control_sig;
}
void sc_addsub_action() {
if((( sc_control_sig ).read() %3) == 0) {
outx.write(ina.read().get_word(0) + inb.read().get_word(0));
outM.write(ina.read().get_word(0) + inb.read().get_word(0));
} else {
outx.write(ina.read().get_word(0) - inb.read().get_word(0));
outM.write(ina.read().get_word(0) + inb.read().get_word(0));
}
}
};
#endif
SC_MODULE(sc_subtracter)
{
public:
sc_in > ina;
sc_in > inb;
sc_out > outx;
SC_CTOR(sc_subtracter):ina("ina"),inb ("inb"), outx("outx")
{
SC_METHOD(sc_subtracter_action);
sensitive << ina << inb;
}
void sc_subtracter_action() {
sc_lv<32> val;
val = ina.read();
val = val.get_word(0) - inb.read().get_word(0);
outx.write( val );
}
};
SC_MODULE(sc_top_w)
{
public:
sc_in > ina;
sc_in > inb;
sc_out > outx;
sc_addsub *m_add1;
SC_CTOR(sc_top_w): ina ("ina"), inb ("inb"), outx ("Outx")
{
m_add1 = new sc_addsub("add1");
m_add1->ina(ina);
m_add1->inb(inb);
m_add1->outx(outx);
hdl_connect_v(m_add1->sc_control_sig, "my_top.controller1.outx_reg", HDL_INPUT, 1);
hdl_connect_v(m_add1->outM, "my_top.systemc_signal", HDL_OUTPUT,1);
}
};
如何連結systemC 與 verilog
現在惟一的限制在只能針對simulator作設定
如VCS 有其專用之法
IUS也有專用之法
這樣要寫大型的model會被限制住
top.v
`define W 31
module my_top();
parameter PERIOD = 20;
reg clock;
reg [`W:0] value1;
reg [`W:0] value2;
wire [`W:0] add_wire;
reg [`W:0] systemc_signal;
wire [`W:0] sub_wire;
wire [`W:0] control_out;
reg [`W:0] control_out_reg;
integer counter;
integer direction;
integer cycle;
// SystemC model
sc_top_w add1(value1, value2, add_wire); //當作是一個verilog block
// SystemC model
sc_subtracter sub1(value2, value1, sub_wire);//當作是一個verilog block
// 要記得將wire 接好
// Verilog model
v_controller controller1(value1, value2, control_out);
initial begin
value1 = 32'b010; // starts at 2
value2 = 32'b000; // starts at 0
counter = 0;
direction = 1;
cycle = 0;
end
// clock generator
always begin
clock = 1'b0;
#PERIOD
forever begin
#(PERIOD/2) clock = 1'b1;
#(PERIOD/2) clock = 1'b0;
end
end
// stimulus generator
always @(posedge clock) begin
value1 <= counter+2;
value2 <= 32'b010; // stays at 2 after here.
control_out_reg <= control_out;
if (direction == 1) // incrementing...
if (counter == 9) begin
counter = counter - 1;
direction = 0;
end
else
counter = counter + 1;
else // decrementing...
if (counter == 0) begin
counter = counter + 1;
direction = 1;
end
else
counter = counter - 1;
end
// display generator
always @(posedge clock) begin
$display("--------------------------------");
$display("Cycle %0d for values A=%0d and B=%0d", cycle, value1, value2);
$display("Res: A+/-B=%0d A-B=%0d \nController=%0d Systemc_signal=%0d",
add_wire, sub_wire, control_out,systemc_signal);
$display("--------------------------------");
// end after 100 cycles are executed
cycle = cycle + 1;
if (cycle == 100)
$finish;
end
endmodule
module v_controller(ina, inb, outx);
input [31:0] ina;
input [31:0] inb;
output [31:0] outx;
reg [31:0] outx_reg;
always @(ina or inb) begin
outx_reg <= ina * inb;
end
assign outx = outx_reg;
endmodule
#include "systemc.h"
#include "hdl_connect.h"
SC_MODULE(sc_addsub)
{
public:
sc_in
sc_in
sc_out
sc_signal
sc_signal
SC_CTOR(sc_addsub):ina("ina"), inb("inb"), outx("outx"),outM("outM"),sc_control_sig("sc_control_sig")
{
SC_METHOD(sc_addsub_action);
sensitive << ina << inb << sc_control_sig;
}
void sc_addsub_action() {
if((( sc_control_sig ).read() %3) == 0) {
outx.write(ina.read().get_word(0) + inb.read().get_word(0));
outM.write(ina.read().get_word(0) + inb.read().get_word(0));
} else {
outx.write(ina.read().get_word(0) - inb.read().get_word(0));
outM.write(ina.read().get_word(0) + inb.read().get_word(0));
}
}
};
#endif
SC_MODULE(sc_subtracter)
{
public:
sc_in
sc_in
sc_out
SC_CTOR(sc_subtracter):ina("ina"),inb ("inb"), outx("outx")
{
SC_METHOD(sc_subtracter_action);
sensitive << ina << inb;
}
void sc_subtracter_action() {
sc_lv<32> val;
val = ina.read();
val = val.get_word(0) - inb.read().get_word(0);
outx.write( val );
}
};
SC_MODULE(sc_top_w)
{
public:
sc_in
sc_in
sc_out
sc_addsub *m_add1;
SC_CTOR(sc_top_w): ina ("ina"), inb ("inb"), outx ("Outx")
{
m_add1 = new sc_addsub("add1");
m_add1->ina(ina);
m_add1->inb(inb);
m_add1->outx(outx);
hdl_connect_v(m_add1->sc_control_sig, "my_top.controller1.outx_reg", HDL_INPUT, 1);
hdl_connect_v(m_add1->outM, "my_top.systemc_signal", HDL_OUTPUT,1);
}
};
2011年5月10日 星期二
EDA 在virtual PC 上的使用限制(一)
如果使用分享硬碟/目錄的方式
常會使得link的過程發生錯誤
只要將執行目錄放在Linux的硬碟目錄下
就可以執行成功
可能是分享硬碟/目錄的磁區格式不合之故
常會使得link的過程發生錯誤
只要將執行目錄放在Linux的硬碟目錄下
就可以執行成功
可能是分享硬碟/目錄的磁區格式不合之故
DPI再了解(十二)
VCS直接使用 DPI
方法一
vcs –sverilog top.sv c_test.c
vcs –sverilog top.sv c_test.cpp
方法二
gcc –shared –fPIC test.c –o test/libtest.so
vcs –sverilog model.v test/libtest.so
方法一
vcs –sverilog top.sv c_test.c
vcs –sverilog top.sv c_test.cpp
方法二
gcc –shared –fPIC test.c –o test/libtest.so
vcs –sverilog model.v test/libtest.so
2011年5月9日 星期一
DPI再了解(十一)
// Class style to SV
typedef bit [31:0] u_int32;
class myTrans;
rand u_int32 addr;
rand u_int32 data;
constraint c_addr { addr inside {[0:100]}; }
endclass // myTrans
import "DPI-C" function chandle model_new();
import "DPI-C" function void model_process(input chandle inst, inout u_int32 addr, data);
class Model;
chandle inst;
function new();
this.inst = model_new();
endfunction : new
function void proc(myTrans trans); // "process" is reserved keyword
model_process(this.inst, trans.addr, trans.data);
endfunction : proc
endclass : Model
class stimGen;
myTrans trans;
Model model;
function new();
model = new();
endfunction : new
task run();
trans = new();
trans.randomize();
$display("SV : pre_process : trans.addr=%x, trans.data=%x", trans.addr, trans.data);
model.proc(trans);
$display("SV : post_process: trans.addr=%x, trans.data=%x", trans.addr, trans.data);
endtask // run
endclass // stimGen
module test();
stimGen sg;
initial begin
sg = new();
sg.run();
end
endmodule
#include
#include
#include "systemc.h"
//#include // Needed for io_printf
//#include "vc_hdrs.h" // VCS specific header
typedef unsigned int u_int32;
class myTrans {
public:
u_int32 addr;
u_int32 data;
};
class model {
public:
model();
void process(u_int32* addr, u_int32* data);
};
model::model()
{
printf("C++: Constructing a model\n");
}
void model::process(u_int32* addr, u_int32* data)
{
printf("C++: processing %x %x\n", addr, data);
*addr = *addr + 1;
*data = *data + 2;
}
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////
// The DPI needs a static C routine to communicate with.
// This one constructs the model object and returns a handle
void* model_new()
{
return new model;
}
////////////////////////////////////////////////////////////////////////
// Tell the model to process a transaction
void model_process(void* inst, u_int32* addr, u_int32* data)
{
model* m = (model *) inst;
/* Pass the individual trans properties over.
You could also construct a trans and pass it instead */
m->process(addr, data);
}
#ifdef __cplusplus
}
#endif
typedef bit [31:0] u_int32;
class myTrans;
rand u_int32 addr;
rand u_int32 data;
constraint c_addr { addr inside {[0:100]}; }
endclass // myTrans
import "DPI-C" function chandle model_new();
import "DPI-C" function void model_process(input chandle inst, inout u_int32 addr, data);
class Model;
chandle inst;
function new();
this.inst = model_new();
endfunction : new
function void proc(myTrans trans); // "process" is reserved keyword
model_process(this.inst, trans.addr, trans.data);
endfunction : proc
endclass : Model
class stimGen;
myTrans trans;
Model model;
function new();
model = new();
endfunction : new
task run();
trans = new();
trans.randomize();
$display("SV : pre_process : trans.addr=%x, trans.data=%x", trans.addr, trans.data);
model.proc(trans);
$display("SV : post_process: trans.addr=%x, trans.data=%x", trans.addr, trans.data);
endtask // run
endclass // stimGen
module test();
stimGen sg;
initial begin
sg = new();
sg.run();
end
endmodule
#include
#include
#include "systemc.h"
//#include
//#include "vc_hdrs.h" // VCS specific header
typedef unsigned int u_int32;
class myTrans {
public:
u_int32 addr;
u_int32 data;
};
class model {
public:
model();
void process(u_int32* addr, u_int32* data);
};
model::model()
{
printf("C++: Constructing a model\n");
}
void model::process(u_int32* addr, u_int32* data)
{
printf("C++: processing %x %x\n", addr, data);
*addr = *addr + 1;
*data = *data + 2;
}
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////
// The DPI needs a static C routine to communicate with.
// This one constructs the model object and returns a handle
void* model_new()
{
return new model;
}
////////////////////////////////////////////////////////////////////////
// Tell the model to process a transaction
void model_process(void* inst, u_int32* addr, u_int32* data)
{
model* m = (model *) inst;
/* Pass the individual trans properties over.
You could also construct a trans and pass it instead */
m->process(addr, data);
}
#ifdef __cplusplus
}
#endif
一個簡單的SystemC在Linux下的Makefile
systemC環境
SystemC安裝在/usr/systemc
我們設計的systemC範例為
hello.cpp
在目錄下執行make
就會得到一個執行檔
hello
Makefile檔如下
LIB_DIR=-L/usr/systemc/lib-linux
INC_DIR=-I/usr/systemc/include
LIB=-lsystemc
APP=hello
all:
g++ -o $(APP).so -g $(APP).cpp $(LIB_DIR) $(INC_DIR) $(LIB)
###g++前面要加一個TAB
clean:
rm -rf $(APP)
###rm 前面要加一個TAB
-g 非必要時可以不用
Commands:(即為要執行的 Shell 指令)
SystemC安裝在/usr/systemc
我們設計的systemC範例為
hello.cpp
在目錄下執行make
就會得到一個執行檔
hello
Makefile檔如下
LIB_DIR=-L/usr/systemc/lib-linux
INC_DIR=-I/usr/systemc/include
LIB=-lsystemc
APP=hello
all:
g++ -o $(APP).so -g $(APP).cpp $(LIB_DIR) $(INC_DIR) $(LIB)
###g++前面要加一個TAB
clean:
rm -rf $(APP)
###rm 前面要加一個TAB
-g 非必要時可以不用
Commands:(即為要執行的 Shell 指令)
必須以 <Tab> 開頭。使用 Shell Script 語法。在 Makefile 裡,只要以 <Tab> 開頭都將會被視為 Shell Script 執行。每條法則必須寫在同一行。每條 Command 會啟動一個新的 Shell,預設為 /bin/sh。若執行完某條 Command 但傳回了錯誤值,make 就會中斷執行。
2011年5月8日 星期日
DPI再了解(十)
struct在DPI上的使用例
從VCS上改過來的例子
module main();
typedef struct {
int a;
int b;
} mystruct;
import "DPI" function void mydisplay(inout mystruct s1);
mystruct s1;
initial begin
s1.a =10;
s1.b =20;
$display("SV: s1.a=%0d,s1.b=%0d",s1.a,s1.b);
mydisplay(s1);
$display("SV after DPI call: s1.a=%0d,s1.b=%0d",s1.a,s1.b);
end
endmodule
#include "svdpi.h"
//#include "vcsuser.h"
#include <stdlib.h>
#include <stdio.h>
extern "C" {
typedef struct {
int a;
int b;
} mystruct;
void mydisplay(mystruct *s1) {
int s2;
printf("C: gets values from SV, s1.a=%d, s1.b=%d\n",s1->a,s1->b);
s1->a = 100;
s1->b = 200;
printf("C: set values, s1.a=%d, s1.b=%d\n",s1->a,s1->b);
}
}
從VCS上改過來的例子
module main();
typedef struct {
int a;
int b;
} mystruct;
import "DPI" function void mydisplay(inout mystruct s1);
mystruct s1;
initial begin
s1.a =10;
s1.b =20;
$display("SV: s1.a=%0d,s1.b=%0d",s1.a,s1.b);
mydisplay(s1);
$display("SV after DPI call: s1.a=%0d,s1.b=%0d",s1.a,s1.b);
end
endmodule
#include "svdpi.h"
//#include "vcsuser.h"
#include <stdlib.h>
#include <stdio.h>
extern "C" {
typedef struct {
int a;
int b;
} mystruct;
void mydisplay(mystruct *s1) {
int s2;
printf("C: gets values from SV, s1.a=%d, s1.b=%d\n",s1->a,s1->b);
s1->a = 100;
s1->b = 200;
printf("C: set values, s1.a=%d, s1.b=%d\n",s1->a,s1->b);
}
}
訂閱:
文章 (Atom)