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

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年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年10月16日 星期日

Digital Circuit Functional Verification(十六)

 测试语言( VERIFICATlON  LANGUAGES)

•  Verification languages can raise the level of abstraction.

驗證語言的重要功能需求
1. Multiple runs, Multiple seeds
2. Random Generation
3. Functional Coverage
4. Minimal code modifications
5. Identify holes
6. Constraints



•  VHDL and Verilog are simulation languages, not verification
languages.
Verilog偏重的是初级应件结构,所以它不能支持高级数据结
构,也不具备面向对象的特征。VHDL比较适合于大型项目,它
封装了所有的信息,并严格按定义好的接口传送。有必要创造一
能克服Verilog和VHDL的这些缺点的专门的测试语言 。

•  Proprietary verification languages exist.
三种企业专用的测试语言:Verisity的elSpecman, Synopsys
的VERA,Chronology的Rave。(2005)

另外有以C為基礎所開發的systemC,亦是另一種驗證語言

為了因應驗證的需求,verilog加入了一些C語言的精神,
延生出systemverilog,為了充分利用systemverilog來驗證IC design,
又開發出了驗證方法從VMM/OVM而到了統一的UVM(2011)

systemverilog也提供 DPI的介面,可以方便的連結其它的語言來做
聯合驗證(co-sim)

2011年10月15日 星期六

Digital Circuit Functional Verification(十五)

斷言ASSERTIONS


Simulation Assertions 
簡單來說就是利用簡單的語義描述來驗證signals protocol
而這個驗證語法是基於一個或多個clock來確認signals之間的關係

断言被分为两大类:一类是由设计者定义,另一类由验证工程师定义。
● 由设计者定义的设计断言(Implementation Assertion)
    通常寫成embedded Mode,而嵌入到RTL中,因為Assertion 不會被合成
● 由验证工程师定义的规范断言(Specification Assertion)
   通常會使用blockbox方式來驗證design,常放在design的外部

由於assertion只能指出錯誤,但不能指出少驗了那些項目
因此必須搭配code coverage相關的方法來使用


Formal Assertion Proving
Formal tools called model checker or assertion provers can mathe-
matically  prove that,  given an  RTL design  and  some  assumptions
about the relationships of the input signals, an assertion will always
hold  true.  If a counter  example  is  found,  the  formal  tool  will  pro-
vide  details  on  the  sequence  of events  that leads  to  the  assertion
violation. It is then up to you to decide if this sequence of events is
possible, given additional knowledge about the environment of the
design.

 形式验证领域将这些输入断言称为约束(constraint),这里作者使用术语“假设”(assumption)将其与随机发生
的约束区分开来,后者是一种随机的概念。

這個驗證觀念在2008之後似乎不再有人再提了,

現在的觀念應該是
Formal verification就用formal tools(LEC, formality)之類來作靜態驗證
Assertion就用SVA, PSL, OVL之類來作動態驗證

另一種原因可能是OVM/UVM的出現,而random input及constraints在其中的使用

2011年7月3日 星期日

typedef 在class上輸入的變數

class uvm_rgm_sfld_register #(int SIZE = 32,
string RAP = "REG_RD",
string WAP = "REG_WR")
extends uvm_rgm_sized_register#(SIZE);
...

class uvm_rgm_sized_register #(int SIZE=32) extends uvm_rgm_register_base;

typedef bit[SIZE-1:0] this_register_type;

....

// User register
typedef uvm_rgm_sfld_register#(16) user_reg;
將user_reg上對映的SIZE大小設為16

2011年6月20日 星期一

將Design package起來的例子

簡單的package方法

`ifndef APB__SV
`define APB__SV

`include "apb_if.sv"

package apb_pkg;

import uvm_pkg::*;

typedef virtual apb_if apb_vif;

typedef class apb_agent;

`include "apb_rw.sv"
`include "apb_config.sv"
`include "apb_master.sv"
`include "apb_monitor.sv"
`include "apb_sequencer.sv"
`include "apb_agent.sv"
endpackage

`endif


使用方法如下


`include "apb.sv" // 這是上面package的檔案
`include "dut.sv"

module tb_top;
...
endmoudle

2011年5月31日 星期二

沒有使用UVM的Class

Cadence's example

//------------------------------------------------------------------------------
// CLASS: apb_transfer
//------------------------------------------------------------------------------
typedef enum bit {APB_READ, APB_WRITE} apb_direction_enum;
class apb_transfer;
rand bit [31:0] addr;
rand bit [31:0] data;
rand apb_direction_enum direction;

function void print();
$display("%s transfer: addr=%h data=%h", direction.name(), addr, data);
endfunction : print

endclass : apb_transfer

module test;
apb_transfer transfer;
initial begin
transfer = new();
repeat (3) begin
void'(transfer.randomize());
transfer.print();
end
end
endmodule : test

import package

Cadence's example

package branda_pkg;
typedef enum {RED, BLUE, BLACK, WHITE} color_t;
class sports_car; // note that car is a virtual class
rand color_t color;
virtual function void print();
$display("I'm a %s branda sports car", color.name());
endfunction : print
endclass : sports_car
class m5 extends sports_car;
endclass : m5
endpackage : branda_pkg

package brandz_pkg;
typedef enum {SILVER, GOLD, WHITE} color_t;
class sports_car; // note that car is a virtual class
rand color_t color;
virtual function void print();
$display("I'm a %s brandz sports car", color.name());
endfunction : print
endclass : sports_car
class convertible extends sports_car;
endclass : convertible
endpackage : brandz_pkg

module race;
// 當使用import 之後,裡面的class就好像被include 進來一樣
// 但是,繼承的class或其它變數只能用到同一個package內部的
import branda_pkg::*;
import brandz_pkg::*;

m5 my_m5;
convertible my_convertible;

initial begin
my_m5 = new();
void'(my_m5.randomize());
my_m5.print();
my_convertible = new();
void'(my_convertible.randomize());
my_convertible.print();
end

endmodule : race

2011年5月30日 星期一

class in package

Cadence's example

package branda_pkg;
typedef enum {RED, BLUE, BLACK, WHITE} color_t;
class sports_car; // note that car is a virtual class
rand color_t color;
virtual function void print();
$display("I'm a %s branda sports car", color.name());
endfunction : print
endclass : sports_car
endpackage : branda_pkg

package brandz_pkg;
typedef enum {SILVER, GOLD, WHITE} color_t;
class sports_car; // note that car is a virtual class
rand color_t color;
virtual function void print();
$display("I'm a %s brandz sports car", color.name());
endfunction : print
endclass : sports_car
endpackage : brandz_pkg

module top;
branda_pkg::sports_car my_m5; // use class
brandz_pkg::sports_car my_convertible; // use class

initial begin
my_m5 = new();
void'(my_m5.randomize());
my_m5.print();
my_convertible = new();
void'(my_convertible.randomize());
my_convertible.print();
end

endmodule : top

Parameterized Classes

Cadence 的例子

module top;

class stack #(type T = int); // parameterized class syntax
local T items[$]; //使用Queues
task push( T a );
items.push_front(a); //Systemverilog queues function, inserts the given element at the front of the queue.
endtask
task pop (ref T a);
a = items.pop_back(); //Systemverilog queues function, inserts the given element at the end of the queue.
endtask
endclass

stack int_stack; // default: stack of ints
stack #(bit[9:0]) bit_stack; // stack of 10-bit vectors
stack #(real) real_stack; // stack of reals

int int_value;
bit[9:0] bit_value;
real real_value;

initial begin
int_stack=new(); bit_stack=new(); real_stack=new();
int_stack.push(400);
bit_stack.push('h200);
real_stack.push(40.5);
int_stack.pop(int_value);
bit_stack.pop(bit_value);
real_stack.pop(real_value);

$display("int:%0d bit:%0h real:%g", int_value, bit_value, real_value);
end

endmodule : top

2011年5月29日 星期日

static methods in class

Cadence的例子

module top;

typedef enum {RED, BLUE, BLACK, WHITE} color_t;

virtual class car;
static int counter = 0; // shared by all instances
int car_id;
static local function void increment_counter();
counter++;
$display("creating item %0d ...", counter);
endfunction : increment_counter
function new();
increment_counter(); // increment on construction to a new class
car_id = counter;
endfunction : new
endclass : car

virtual class sports_car extends car; // note that car is a virtual class
rand color_t color;
virtual function void print();
$display("Car #%0d: I'm a %s sports car", car_id, color.name());
endfunction : print
endclass : sports_car

class plorsche extends sports_car;
virtual function void print();
$display("Car #%0d: I'm a %s plorsche", car_id, color.name());
endfunction : print
endclass : plorsche

class flerrari extends sports_car;
virtual function void print();
$display("Car #%0d: I'm a %s flerrari", car_id, color.name());
endfunction : print
endclass : flerrari

sports_car cars[];
plorsche p1, p2;
flerrari f1, f2;

initial begin
cars = new[4];
p1 = new(); p2 = new();
void'(p1.randomize());
void'(p2.randomize());
f1 = new(); f2 = new();
void'(f1.randomize());
void'(f2.randomize());
$cast(cars[0], p1);
$cast(cars[1], f1);
$cast(cars[2], p2);
$cast(cars[3], f2);
print_all(cars);
end

task print_all(sports_car cars[]);
for (int i=0; i cars[i].print();
endtask : print_all

endmodule : top

2011年5月16日 星期一

$value$plusargs 的測試例

這是從systemverilog IEEE1800-2009挖出的測試例

// IUS
使用irun test.sv +TEST=5 +TESTNAME=test001 +TESTG1=test01 +FREQ+=9.33

//VCS
vcs test.sv
simv +TEST=5 +TESTNAME=test001 +TESTG01=tes01 +FREQ=9.33


`define STRING logic [1024 * 8:1]

module goodtasks;
`STRING str;
integer i1;
logic [31:0] vect;
real realvar;

real frequency;
logic [8*32:1] testname;
logic [64*8:1] pstring;
logic clk;

// vcs2009 logic 不支援,要改成reg才能用

initial begin
if ($value$plusargs("TEST=%d", i1))
$display("value was %d", i1);
else
$display("+TEST= not found");

if ($value$plusargs("TESTNAME=%s",testname)) begin
$display(" TESTNAME= %s.",testname);
$finish;
end


pstring = "TESTG%d";

  // 此處IUS92及vcs2009.12未支援
if ($value$plusargs(pstring, testname))
$display("Running test number %0d.",testname);

  // 此處IUS92及vcs2009.12未支援
if (!($value$plusargs("FREQ+%0F",frequency)))
frequency = 8.33333; // 166 MHz

$display("frequency = %f",frequency);


#100 $finish;
end

endmodule

支援的變數列表如下
%d decimal conversion
%o octal conversion
%h, %x hexadecimal conversion
%b binary conversion
%e real exponential conversion
%f real decimal conversion
%g real decimal or exponential conversion
%s string (no conversion)

2011年5月14日 星期六

DPI再了解(十四)

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

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

2011年5月10日 星期二

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

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

2011年5月7日 星期六

Systemverilog與C變數對照表

SystemVerilog Type
C Type
byte char
int int
longint long long
shortint short int
real double
shortreal float
chandle void*
string char*

DPI再了解(九)

Chandle data type

The chandle data type represents storage for pointers passed using the DPI
The chandle data type allows you to store a C or C++ pointer in your SystemVerilog code. A chandle variable is wide enough to hold a pointer on the machine where the code was compiled, i.e. 32- or 64-bits.

The syntax to declare a handle is as follows:
chandle variable_name ; 

where variable_name is a valid identifier. Chandles shall always be initialized to the value null, which has  a  value  of  0  on  the  C  side.  Chandles  are  restricted  in  their  usage,  with  the  only  legal  uses  being  as follows:

Only the following operators are valid on chandle variables:
—  Equality (==), inequality (!=) with another chandle or with null 
—  Case  equality  (===),  case  inequality  (!==)  with  another  chandle  or  with  null  (same semantics as == and !=)

Only the following assignments can be made to a chandle:
—     Assignment from another chandle
—     Assignment to null

Chandles can be inserted into associative arrays , but the relative ordering of any two
entries in such an associative array can vary, even between successive runs of the same tool.

Chandles can be used within a class.
—     Chandles can be passed as arguments to subroutines.
—     Chandles can be returned from functions

Chandles shall not be used as follows:
—     In any expression other than as permitted in this subclause
—     As ports
—     In sensitivity lists or event expressions
—     In continuous assignments
—     In untagged unions
—     In packed types

就是說chandle只能當作pointer, 而不能當作一般變數來用

 請參考表格

Operation C pointer SV object
handle
SV chandle
Arithmetic operations (such as incrementing)  Allowed Not Allowed Not Allowed
For arbitrary data types Allowed Not Allowed Not Allowed
Dereference when null Error Not Allowed Not Allowed
Casting Allowed Limited Not Allowed
Assignment to an address of a data type Allowed
 
Not Allowed
 
Not Allowed
 
Unreferenced objects are garbage collected No Yes No
Default value Undefined Null Null
For classes (C++) Allowed Not Allowed
 



從書上剪下的例子
#include <svdpi.h>
#include <malloc.h>
#include <veriuser.h>
typedef struct {  // Structure to hold counter value
  unsigned char cnt;
} c7;
// Construct a counter structure
void* counter7_new() {
  c7* c = (c7*) malloc(sizeof(c7));
  c->cnt = 0;
  return c;
}
// Run the counter for one cycle
void counter7(c7 *inst,
              svBitVecVal* count,
              const svBitVecVal* i,
              const svBit reset,
              const svBit load) {
  if (reset)     inst->cnt = 0;  // Reset
  else if (load) inst->cnt = *i; // Load value
  else           inst->cnt++;    // Count
  inst->cnt &= 0x7f;             // Mask upper bit
  *count = inst->cnt;            // Write to output
  io_printf("C: count=%d, i=%d, reset=%d, load=%d\n",
            *count, *i, reset, load);
}

import "DPI-C" function chandle counter7_new();
import "DPI-C" function void counter7
      (input chandle inst,
       output bit [6:0] out,
       input  bit [6:0] in,
       input  bit  reset, load);

program automatic test;
// Test two instances of the counter
  initial begin
    bit [6:0] o1, o2, i1, i2;
    bit       reset, load, clk1;
    chandle   inst1, inst2;     // Points to storage in C
    inst1 = counter7_new();
    inst2 = counter7_new();
    fork
      forever #10 clk1 = ~clk1;
      forever @(posedge clk1) begin
        counter7(inst1, o1, i1, reset, load); // 傳入所配置的記憶體位址
        counter7(inst2, o2, i2, reset, load);
      end
    join_none
    reset = 0;
    load = 0;
    i1 = 120;
    i2 = 10;
    @(negedge clk1);
    load = 1;
    @(negedge clk1);
    load = 0;
    ...
  end
endprogram

 另一個書上的例子

import "DPI-C" function chandle counter7_new();
import "DPI-C" function void counter7_count(input chandle inst);
import "DPI-C" function void counter7_load(input chandle inst,
                                           input bit [6:0] i);
import "DPI-C" function void counter7_reset(input chandle inst);
import "DPI-C" function int counter7_get(input chandle inst);
// Wrap the counter interface with a class
// to hide the C++ instance handle
class Counter7;
   chandle inst;
   function new;
      inst = counter7_new();
   endfunction
   function void count();
      counter7_count(inst);
   endfunction
   function void load(bit [6:0] val);
      counter7_load(inst, val);
   endfunction
   function void reset();
      counter7_reset(inst);
   endfunction
   function bit [6:0] get();
      return counter7_get(inst);
   endfunction
endclass : Counter7

2011年5月6日 星期五

DPI再了解(八)

DPI long  常數資料的傳送
從VCS的example整理出來的

module main();
    longint i1;
   
    import "DPI" function void mydisplay(inout longint i1);
    initial begin
        i1=64'h1234_5678_9000;
        $display("SV: i1 is %0h",i1);
        mydisplay(i1);
        $display("SV(after DPI call): i1 is %0h",i1);
    end

endmodule

#include "svdpi.h"
//#include "vcsuser.h"

#include <stdlib.h>
#include <stdio.h>

extern "C" {
    void mydisplay(long long *i1) {
        printf("C: size of long long is %0d bytes\n",sizeof(long long));
        printf("C: i1 is %llx\n",*i1);
        (*i1) = (*i1) * 2;   
        printf("C: change i1 to %llx\n",*i1);
       
    }
}

2011年5月5日 星期四

pure_virtual

They have the same meaning as in C++. A virtual function can be overridden in a derived class. If a object of that derived class is accessed using a handle to its base class, the function call is performed polymorphically(可到需要時再定義) - the function called is determined by the type of the object pointed to, not the type of the handle (so the overridden function is called if the object pointed to is of the derived class type).

A pure virtual function is a member of an "abstract" base class. You cannot create an object of an abstract class. No implementation need be provided for the pure virtual function in the base class but it must be overridden in a derived class if you want to create objects of that type. Pure virtual functions are used to create "interface" classes (port, export…) (not to be confused with the SystemVerilog interface structure). You find examples of these in the OVM TLM classes where they are used to define the set of interface methods required by ports and provided by exports.

範例
virtual class BasePacket;
pure virtual function integer send(bit[31:0] data); // No implementation
endclass
這樣的好處在原始的base class不用特定去決定現在的function design
純粹只定義一個function 名字
到了沿用(extends)這個base class, 才去決定implement要用到的功能設計

class EtherPacket extends BasePacket;
virtual function integer send(bit[31:0] data);
// body of the function
...
endfunction
endclass

另一種定義模式的範例
pure virtual function void get_provided_to(ref uvm_port_list list);