-1

我试图让我的系统 verilog 代码与我的 c 代码一起工作,但我得到一个奇怪的输出。我的 exp_data_out 应该是我的编码器的输出,但它是 zzzzxzzzzzxzxzz。有人可以告诉我为什么输出是这样的吗?

C

void encoder(
            int data_in,
            int* data_out,
            int* parity_out

    )
{
int i, a[10], c[4], r[14], clk[4], n, sum = 0;
printf("%d\n", data_in);
a[0]= data_in & 1;
a[1]= data_in>>1 & 1;
a[2]= data_in>>2 & 1;
a[3]= data_in>>3 & 1;
a[4]= data_in>>4 & 1;
a[5]= data_in>>5 & 1;
a[6]= data_in>>6 & 1;
a[7]= data_in>>7 & 1;
a[8]= data_in>>8 & 1;
a[9]= data_in>>9 & 1;
a[10] =data_in>>10 & 1;
printf("%x\n", data_in&(512));    
printf("%x\n", a[0]);
c[0]=(a[0] + a[1] + a[3] + a[4] + a[6] + a[8] + a[10])%2;
c[1]=(a[0] + a[2] + a[3] + a[5] + a[6] + a[9] + a[10])%2;
c[2]=(a[1] + a[2] + a[3] + a[7] + a[8] + a[9] + a[10])%2;
c[3]=(a[4] + a[5] + a[6] + a[7] + a[8] + a[9] + a[10])%2;

printf("data bits after hamming code is\n");

for(i=10;i>=0;i--) {
    printf("%d",a[i]&1);
}
printf("\n");
for(i=3;i>=0;i--) {
    printf("%d",c[i]);
}
printf("\n");
*data_out = data_in;
*parity_out = ((c[3]&1) << 3) | ((c[2]&1) << 2) | ((c[1]&1) << 1) | ((c[0]&1));
 }

系统 Verilog

  import "DPI-C" context encoder= function void encoder(input int data, output logic [14:0] outData,  output int parity );


module dpi_example ();
  parameter size = 15;
  parameter p_size = 4;
   logic   [10:0] rtl_data_in;
   logic   [14:0] rtl_data_out;
   logic   [14:0] exp_data_out;
   logic   [p_size-1:0] parity_out;
   bit clk;       

   initial begin
      clk =0;
      #80;
      $finish;
   end

   always #1 clk = ~clk;

   always @(posedge clk) begin

      rtl_data_in = $urandom % 2048; //generate random data
      $display("rtl_data_in: %b", rtl_data_in); 
      encoder(rtl_data_in, exp_data_out, parity_out); 

   end

   // generate the rtl output
   ham_enc L1( .enc_data_in(rtl_data_in), .enc_data_out(rtl_data_out));
   ham_dec L2( .data_in(rtl_data_out), .data_out(decoder_data_out));

   //compare expected data and encoder output
   always @(negedge clk) begin
       if (exp_data_out == rtl_data_out) begin
           $display("%t: PASS, Input: %b, Output (EXP/RTL) (%b/%b)", $time, rtl_data_in, exp_data_out, rtl_data_out);
       end else begin
           $display("%t: FAIL, Input: %b, Output (EXP/RTL) (%b/%b)", $time, rtl_data_in, exp_data_out, rtl_data_out);
       end
   end


endmodule

这是输出

78: FAIL, Input: 10000010100, Output (EXP/RTL) (zzzzxzzzzzxzxzz/100000100100000)
4

1 回答 1

3

data_out您的问题是SystemVerilog 语句中参数的原型import与 C 代码不匹配。您已将其声明为logic [14:0]在导入和intC 代码中。它应该int在两者中。由于输出参数是按值复制的,因此 data_out 在分配给 时将被强制转换为 15 位exp_data_out。现在编写代码的方式,您将 data_out 作为 int 类型,但是 SystemVerilog 编译器期望参数的格式是 4 状态逻辑向量,需要编写的是特殊结构。

使用 DPI 时,我强烈建议保持所有参数与 C 兼容(int、char/byte 以及这些类型的数组或结构)。您将获得更好的性能,并且在处理 C 端的非 C 兼容类型时遇到的问题更少。

如果你使用的是 Modelsim/Questa,你可以编译你的代码并生成一个 C 头文件

vlog mysource.sv -dpiheader dpi.h mysource.c

然后在你的C源代码中#include那个头文件。这样,如果原型不匹配,C 编译器会给你一个错误,而不是运行时错误,或者更糟糕的是一个可能很难找到的致命错误。

于 2015-11-01T15:21:12.063 回答