System Verilog——C语言调用SV对象中的方法

2023-05-16

本文接上一篇文章,即调用System Verilog 任务的C 任务,简介如下
https://blog.csdn.net/qq_31348733/article/details/101000399

如何在C语言中调用SV方法呢,显然定义在类中的方法我们无法直接调用,因为当SV编译器编译代码时,对象还不存在。为了解决这个问题,我们可以在SV和C之间传递一个对象引用。但是跟C指针不同的是,SV句柄不能通过DPI传递,不过可以定义一个句柄数据组,然后在两种语言之间传递数组的索引。

下面是一个实例:
带有内存模型类的System Verilog模块

//tb_top.sv
`timescale		1ns/1ns

module	tb_top;

//=====================================================================\
// ********** Define Parameter and Internal Signals *************
//=====================================================================/



//======================================================================
// ***************      Main    Code    ****************
//======================================================================
import "DPI-C" context task readFile(string fname);

export "DPI-C" task memRead;
export "DPI-C" task memWrite;
export "DPI-C" function memBuild;

initial begin
    readFile("mem.dat");
end

//类中的方法不能导出
class Memory;
    int mem[];

    function new(input int mSize);
        mem = new[mSize];
    endfunction:new 

    task memRead(input int addr, output int data);
        #20
        data = mem[addr];
        $display("reading data.----time:%0t", $time);
    endtask:memRead

    task memWrite(input int addr, input int data);
        #10
        mem[addr] = data;
        $display("write successfully!----addr = %0d, data = %0d----time:%0t", addr, data, $time);
    
    endtask:memWrite

endclass:Memory

Memory memq[$];
//创建一个新的内存实例并将其压入队列
function int memBuild(input int size);
    Memory m;
    m = new(size);
    memq.push_back(m);
     $display("SV:M%0d allocate memory----size = %0d----time:%0t", memq.size()-1, size, $time);
    return memq.size()-1;
endfunction:memBuild


task memRead(input int idx, addr, output int data);
    $write("M%0d: ",idx) ;
    memq[idx].memRead(addr, data);   
endtask:memRead

task memWrite(input int idx, addr, data);
    $write("M%0d: ",idx) ;
    memq[idx].memWrite(addr, data);  
endtask:memWrite

endmodule

下面是调用带OOP内存的导出任务的C代码:


#include <stdio.h>
extern int memBuild(int);
extern void memRead(int idx, int addr, int *data);
extern void memWrite(int idx, int addr, int data);

int readFile(char *fname){
    int cmd, idx;
    FILE *file;
    int addr, data, exp;
    file = fopen(fname, "r");
    while(!feof(file)){
        cmd = fgetc(file);
        fscanf(file, "%d", &idx);
        switch(cmd){
        	//分配内存
            case 'M':{
                int hi, qidx;
                fscanf(file, "%d", &hi);
                qidx = memBuild(hi);
                break;         
            }
            //读内存
            case 'R':{
                fscanf(file, "%c %d %d",&cmd, &addr, &data);
                memRead(idx, addr, &exp);
                if(exp == data){
                    io_printf("read successfully!----addr = %d data = %d\n", addr, data);
                }
                else{
                    io_printf("read error!---- addr = %d data should be %d, but it is %d now.\n", addr, exp, data);
                }    
                break;
            }
            //写内存
            case 'W':{
                fscanf(file, "%c %d %d",&cmd, &addr, &data);
                memWrite(idx, addr, data);
                break;
            }
        }
    }
    fclose(file);
}

下面是命令文件:

M0 1000
M1 2000
M2 3000

W0 1 1
W0 2 2
W0 3 3
W1 1 2
W1 2 3
W1 3 4
W2 1 3
W2 2 4
W2 3 5

R0 1 1
R0 1 2

R1 2 2
R1 2 3

R2 3 2
R2 3 5

程序运行结果:

# SV:M0 allocate memory----size = 1000----time:0
# SV:M1 allocate memory----size = 2000----time:0
# SV:M2 allocate memory----size = 3000----time:0
# M0: write successfully!----addr = 1, data = 1----time:10
# M0: write successfully!----addr = 2, data = 2----time:20
# M0: write successfully!----addr = 3, data = 3----time:30
# M1: write successfully!----addr = 1, data = 2----time:40
# M1: write successfully!----addr = 2, data = 3----time:50
# M1: write successfully!----addr = 3, data = 4----time:60
# M2: write successfully!----addr = 1, data = 3----time:70
# M2: write successfully!----addr = 2, data = 4----time:80
# M2: write successfully!----addr = 3, data = 5----time:90
# M0: reading data.----time:110
# read successfully!----addr = 1 data = 1
# M0: reading data.----time:130
# read error!---- addr = 1 data should be 1, but it is 2 now.
# M1: reading data.----time:150
# read error!---- addr = 2 data should be 3, but it is 2 now.
# M1: reading data.----time:170
# read successfully!----addr = 2 data = 3
# M2: reading data.----time:190
# read error!---- addr = 3 data should be 5, but it is 2 now.
# M2: reading data.----time:210
# read successfully!----addr = 3 data = 5
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

System Verilog——C语言调用SV对象中的方法 的相关文章

  • Java的Map中的map.keySet()方法

    该方法返回map中所有key值的列表 今天再代码中看到了Map集合中的HashMap的map keySet 方法 xff0c 首先看一下这个方法的定义 Returns a 64 link Set view of the keys conta
  • iOS集成七牛云(上传图片,视频,音频等文件)

    用的CocoaPods导入SDK platform ios 39 9 0 39 target 39 项目名 39 do pod 39 AFNetworking 39 pod 39 Qiniu 39 end 导入头文件 import lt Q
  • windows10 RDP 桌面远程 linux桌面 centos7 ghome

    windows系统桌面远程协议是RDP协议 xff0c 而linux的是VNC协议 xff0c 所以windows要远程Linux需要先安装XRDP协议 注 xff1a linux centos 系统不能是最小化安装 xff0c 需要有GN
  • 手把手教你获取x信本地数据库(利用Sqlcipher查看)

    最近一直在研究Xposed等一些hook框架 xff0c 进行学习做一些demo xff0c 这次就正好拿x信练练手 xff0c 学习学习 xff0c 也可以学习x信手机本地数据库的表结构设计等 好 xff0c 废话不多说 xff0c 直接
  • netperf使用笔记

    一 netperf是什么 netperf是一个基于client server模式的网络测试工具 xff0c 可以测量TCP和UDP传输的吞吐量 时延 CPU占用率等性能参数 它可以测试以下几种模式的TCP核UDP网络性能 xff1a TCP
  • 程序的几种常用格式文件

    span class hljs keyword int span span class hljs keyword global span span class hljs keyword int span calculate span cla
  • 2020年北航计算机学院面向对象第一单元总结

    文章目录 一 基于度量来分析自己的程序结构第一次作业第二次作业第三次作业 二 分析自己程序的bug三 分析自己发现别人程序bug所采用的策略四 应用对象创建模式来重构五 对比和心得体会 一 基于度量来分析自己的程序结构 第一次作业 第一次作
  • keil调试模式下能运行 烧录到板子中不能运行

    一 程序中使用了printf函数 1 现象 在debug模式下可以运行 xff0c 脱离debug模式无法运行 2 原因 在程序中使用了printf函数 xff0c 但是却没有包含keil的微库 xff0c 或者对于printf函数没有进行
  • 洛谷P4180 次小生成树学习

    题目链接 BJWC2010 严格次小生成树 洛谷 严格次小生成树是指第二小的生成树 总的思路是先求最小生成树 xff08 设最小生成树的总花费sum xff09 xff0c 把每条边都标记 xff0c 再遍历没被标记的边 xff0c 此时这
  • Codeforces 758D 贪心

    Ability To Convert time limit per test 1 second memory limit per test 256 megabytes input standard input output standard
  • Docker入门

    官网地址 概述 场景1 xff1a 不同语言开发的应用程序部署到同一操作系统上 xff0c 往往操作系统需要根据相应的语言来配置 xff0c 如果配置发生冲突就无法完成部署 这时候我们需要对这2个应用进行隔离 xff0c 使它们运行所依赖的
  • Debian11系统安装

    下载 下载地址 VMware创建虚拟机 1 Host only模式 xff1a 所有虚拟机可以相互访问 xff0c 但和真实的物理网络环境是隔离开的 xff0c 此模式下的IP信息是由host only虚拟网络的DHCP服务器来分配的 xf
  • Debian11之Jdk安装

    参考这里
  • Debian11之 Containerd1.7.x 安装及配置

    官网 介绍 1 K8S发布的CRI xff08 Container Runtime Interface xff09 统一了容器运行时接口 xff0c 凡是支持CRI的容器运行时的皆可作为K8S的底层容器运行时 xff0c 而Docker 没
  • Debian11之基于kubeadm安装K8S(v1.26.0) 集群

    硬件要求 1 Master主机 xff1a 2核CPU 4G内存 20G硬盘 2 Node主机 xff1a 4 43 核CPU 8G 43 内存 40G 43 硬盘 2 集群中的所有机器的网络彼此均能相互连接 xff08 公网和内网都可以
  • Debian11之Rancher2.7.x安装

    前言 Rancher 是一个为开源容器打造的容器管理平台 Kubernetes 管理工具 xff0c 使得开发者可以随处运行 Kubernetes xff08 Run Kubernetes Everywhere xff09 xff0c 满足
  • AirSim学习(1)-介绍,安装,unity测试

    home AirSim是一款基于虚幻引擎的无人机 汽车等模拟器 我们现在也有一个实验性的Unity版本 它是开源的 xff0c 跨平台的 xff0c 支持使用流行的飞行控制器 如PX4和ArduPilot 进行软件在环模拟 xff0c 并支
  • 华为设备默认console密码

    admin 64 huawei com Admin 64 huawei com Admin 64 huawei huawei com huawei 64 123 huawei Change Me
  • 华为交换机批量加入 Vlan 方法

    华为交换机单独加入vlan太麻烦 xff0c 思科有批量加入vlan的方法 xff0c 华为也有 要求 1 6口划分到vlan2 6 12口划分到vlan3 13 18口划分到vlan4 19 24口划分到vlan5 25 26 加入tru
  • [golang]Go常见问题:# command-line-arguments: ***: undefined: ***

    今天遇见一个很蛋疼的问题 xff0c 不知道是不是我配置的问题 xff0c IDE直接run就报错 问题描述 在开发代码过程中 xff0c 经常会因为逻辑处理而对代码进行分类 xff0c 放进不同的文件里面 xff1b 像这样 xff0c

随机推荐