尤莉 2022-01-31 10:36 采纳率: 0%
浏览 57
已结题

modelsim中PLI的调用

主要是想用C写一个verilog的系统函数调用,但是发现verilog不能向C传参,也不能打印 ;仿真环境modelsim;

代码如下:
C 代码:

// pch.cpp: 与预编译标头对应的源文件

#include "pch.h"
#include "stdlib.h"
// 当使用预编译的头时,需要使用此源文件,编译才能成功。
#include "acc_user.h"
#include "stdio.h"
//打印的字符串、整型数据、软件开始打印标志
char* str_mes;
unsigned int    int_mes;
int             flags = 0;

//======================= define print_my() used in C ==========================
void print_my(char* str_send, unsigned int int_send) {
    str_mes = str_send;
    int_mes = int_send;
    flags = 1;
}

PLI_INT32 call_c_print() {
    if (tf_getp(1) == 1)
        print_my("It's the first successfull print: ", 0x20170714);
    else if (tf_getp(1) == 2)
        print_my("2nd: ", 0x09070602);
    else
        print_my("", 0x1); //err

    return 0;
}

//===================== define send_my() used in rtl ========================
void byte2hexstr(char* str, char* dest, int len)
{
    char tmp;
    int  i;
    char stb[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
    for (i = 0; i < len; i++) {
        tmp = str[i];
        dest[i * 2] = stb[tmp >> 4];
        dest[i * 2 + 1] = stb[tmp & 15];
    }
    return;
}



char            str_mes_format[200];
void send_my() {
    int i = 0;
    if (flags && tf_nump() == 3) {
        flags = 0;
        byte2hexstr(str_mes, str_mes_format, 100);
        //send string and integer message
        tf_strdelputp(2, 1600, 'H', str_mes_format, 0, 0);
        tf_putp(3, int_mes);
        tf_putp(1, 1); //display flag, first arg = 1

        //for(i=0; i<20; i++) {
        //        io_printf("Data Conversion: %0x \n", str_test[i]);
        //}
        //io_printf("Data Conversion: %s \n", str_test);
        //io_printf("Data Conversion: %0x \n", str_send);
        //io_printf("Data Conversion: %s \n", str_send);
    }
}

s_tfcell veriusertfs[] =
{
    {usertask,      // type of PLI routine - usertask or userfunction
     0,                 // user_data value
     0,      // checktf() routine
     0,       // sizetf() routine
      call_c_print,       // calltf() routine
     0,                 // misctf() routine
     "$send_my"       // "$tfname" system task/function name
    },
    {usertask,      // type of PLI routine - usertask or userfunction
     0,                 // user_data value
     0,      // checktf() routine
     0,       // sizetf() routine
      0,       // calltf() routine
     0,                 // misctf() routine
     "$call_c_print"       // "$tfname" system task/function name
},
    {0}                 // final entry must be 0
};



```typescript
verilog:
`timescale 1ns/1ps
module test ;
   reg [1599:0]         str_my ;
   reg [31:0]           int_my ;
   reg                  flagh ;

   //send_my
   integer              i = 1599;
   integer              j = 1599;
   reg [7:0]            str_tmp ;
   initial begin
      flagh = 0 ;
      forever begin
         //@(posedge clk) ;
         #20 
         $send_my(flagh, str_my, int_my);
         if (flagh) begin
            #1 ;
            for(i=1599; i>=0; i= i-8) begin
               if (str_my[i -: 8] != 0)
                 $finish ;
            end
            $display("--DEBUG--- Valid data number: %d", i);
            //$display("--ERR--- String data structure: %h", str_my);

            //display
            if (i<=791) begin
               $display("--ERR--- PLEASE INPUT VALID STRING INFO!!!");
               $display("--ERR--- Default data number: %d", i);
               $display("--ERR--- String data structure: %h", str_my);
            end
            else begin
               $write("---YYY---");
               for(j=i; j>=0; j= j-8) begin
                  str_tmp = str_my[j -: 8] ;
                  if (str_tmp == "") begin
                     $finish;
                  end
                  else begin
                     $write("%s", str_tmp);
                  end
               end
               $write("%h \n", int_my);
            end

            /* $display cannot support str_my[i:144]
            else begin
               $display("--YYY--- %s%h", str_my[i : j], int_my);
            end
             */
            flagh = 0 ;
         end
      end
   end

   //c print
   initial begin
      #100 ;
      $call_c_print(1);
      #100 ;
      $call_c_print(2);
      #100 ;
      $call_c_print(3);
   end


   //stop
   initial begin
      forever begin
         #10000;
         if ($time >= 300)  $finish ;
      end
   end

endmodule // test


```

  • 写回答

5条回答 默认 最新

  • ilmss 2022-02-01 23:57
    关注
    获得0.70元问题酬金

    你的C文件编译成 .o文件命令用的是这样吗 :iverilog -vpi -mingw=xxx:\mingw -ivl=xxx:\iverilog yyy.c

    评论

报告相同问题?

问题事件

  • 系统已结题 2月8日
  • 创建了问题 1月31日

悬赏问题

  • ¥15 ogg dd trandata 报错
  • ¥15 高缺失率数据如何选择填充方式
  • ¥50 potsgresql15备份问题
  • ¥15 Mac系统vs code使用phpstudy如何配置debug来调试php
  • ¥15 目前主流的音乐软件,像网易云音乐,QQ音乐他们的前端和后台部分是用的什么技术实现的?求解!
  • ¥60 pb数据库修改与连接
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错