DPI:direct program interface 在仿真环境中集成C, C++模型是一个遇见的问题,下面展示如何集成C++ model. 虽然项目环境是E-language的,但是顶层文件tb.sv 是SV语言,这里是在tb.sv中通过DPI集成C++的方式。
1、在tb.sv中直接通过这段代码引入C++ model中的函数,端口信号要与C model中定义的类型像匹配。
import "DPI-C" context function bit EIA3_CPP(input byte key[16], input int count, input int bearer, input int dir, input int length, input int data[], output int mac);
import "DPI-C" context function bit EIA2_CPP(input byte key[16], input int count, input int bearer, input int dir, input int length, input byte data[], output byte mac[4]);
import "DPI-C" context function bit EIA1_CPP(input byte key[16], input int count, input int bearer, input int dir, input int length, input byte data[], output byte mac[4]);
2、在tb.sv中定义function run_pdcp_core 可以直接调用EIA1_CPP、EIA2_CPP和EIA3_CPP。
function integer run_pdcp_core;
input [127:0] key;
input [31:0] count;
input [4:0] bearer;
input bit direction;
input integer length;
input [7:0] data[];
input [1:0] eia_mode;
output [31:0] tag;
byte mac[3:0];
begin
// tag = new[4];
byte mac[3:0];
byte key_t[15:0];
byte data_char[];
int data_int[];
int data_temp;
foreach(key_t[i])
key_t[i]={key[i*8+7],key[i*8+6],key[i*8+5],key[i*8+4],key[i*8+3],key[i*8+2],key[i*8+1],key[i*8]};
if(eia_mode == 1)begin
data_char = new[data.size()];
foreach (data[i]) begin
data_char[i] = byte'(data[i]);
end
EIA1_CPP(key_t, count,bearer,direction,length*8,data_char,mac);
tag = {mac[3],mac[2],mac[1],mac[0]};
end else if (eia_mode == 2) begin
data_char = new[data.size()];
foreach (data[i]) begin
data_char[i] = byte'(data[i]);
end
EIA2_CPP(key_t, count,bearer,direction,length*8,data_char,mac);
tag = {mac[3],mac[2],mac[1],mac[0]};
end else if(eia_mode == 3) begin
if((data.size()*8)%32 !=0 ) begin
data_int = new[((data.size()*8)/32)+1];
end else begin
data_int = new[((data.size()*8)/32)];
end
foreach(data_int[i])begin
data_int[i] = {data[i*4],data[i*4+1],data[i*4+2],data[i*4+3]};
end
EIA3_CPP(key_t, count,bearer,direction,length*8,data_int,tag);
data_temp = 0;
end else begin
end
run_pdcp_core = tag;
end
endfunction
3、在pdcp_driver中定义一个run_pdcp_core, 类型是out_method,通过约束hdl_path,将其指到tb.sv中的run_pdcp_core。
extend er_pdcp_driver_u {
run_pdcp_core : out method_port of run_pdcp_core_t is instance;
keep run_pdcp_core.hdl_path() == "~/tb/run_pdcp_core";
keep bind(run_pdcp_core, external);
};
4、在sequence 中调用模型
returned_tag = driver.run_pdcp_core$(integrity_key,count_field,bearer,direction,data_len,raw_data,eia_mode,returned_tag);
这样就完成了,通过DPI 集成C++ model 到验证环境的工作,最后一步别忘了要把C model的文件加到filelist中。如果简单的加在原有filelist 的后面,仿真时report 如下的error。 compile 过程中candence工具会在仿真目录下生成xcelium.d文件夹,这个文件夹下包含不同文件对应的物理映射lib ,仿真会调用里面的相应文件。 这里的error是在库中找不到EIA1_CPP的相应映射。
解决方法(from cadence support)
在tb.flt中做如下更改
@group gtx_wrapper
@grouptype systemc
@options -Wld,-L/vobs/asic/cab/src/acc_common/tb/c,-laccref_crypto
/vobs/asic/bpg/src/crypto/zuc/zuc.cpp
/vobs/asic/bpg/src/crypto/zuc/eea3.cpp
/vobs/asic/bpg/src/crypto/zuc/eia3.cpp
/vobs/fpga/cobra/src/getafix/tb/c/eia3_sv_wrapper.cpp
/vobs/asic/bpg/src/crypto/aes/cipher_aes.cpp
/vobs/asic/bpg/src/crypto/aes/eia2.cpp
/vobs/asic/bpg/src/crypto/aes/eea2.cpp
/vobs/fpga/cobra/src/getafix/tb/c/eia2_sv_wrapper.cpp
/vobs/asic/bpg/src/crypto/snow3G/eia1.cpp
/vobs/asic/bpg/src/crypto/snow3G/f9.cpp
/vobs/fpga/cobra/src/getafix/tb/c/eia1_sv_wrapper.cpp
@endgroup
From @group ... @endgroup constructs in FLT files the FLT parser will generate -makelib <library name> ... -endlib constructs in the irun_flt.args file.
xrun will create separate libraries for theses inside the xcelium.d folder.
Complex TBs are usually split into separate libraries to limit the scope of options.
@grouptype systemc will add some generic options required to compile a SystemC library.
With @options you can add more specific compiler/linker options required for building libraries.
In this case @options
-Wld,-/vobs/asic/cab/src/acc_common/tb/c,-laccref_crypto
adds an option telling the linker to add libaccref_crypto.a library from the (linker) search path /vobs/asic/cab/src/acc_common/tb/c to the resulting.
so file resolving the missing symbols.
@group …@endgroup 功能类似于-makelib -endlib,会在xcelium.d下生成一个lib 文件。复杂的tb通常被划分为不同的库,以利于功能的独立(我自己理解的)。
|