IEEE Standard for SystemVerilog—Chapter 25.7 Tasks and functions in interfaces
子例程(任务和函数)可以在接口中定义,也可以在连接的一个或多个模块中定义。这允许更抽象的建模级别。例如,“读”和“写”可以定义为任务,而不需要引用任何连线,主模块只能调用这些任务。在modport中,这些任务被声明为导入任务( import tasks)。
函数原型指定参数的类型和方向,以及在其他地方定义的函数的返回值。类似地,任务原型指定了在其他地方定义的任务的参数的类型和方向。在modport中,导入和导出构造可以使用子例程原型,也可以只使用标识符。唯一的例外是当使用modport从另一个模块导入子例程时,以及当使用默认参数值或按名称绑定参数时,在这种情况下,应使用完整的原型。
原型中参数的数量和类型应与子程序声明中的参数类型相匹配。6.22.1中介绍了类型匹配的规则。如果子程序调用中需要默认参数值,则应在原型中指定。如果参数在原型和声明中都指定了默认值,则指定的值不必相同,但使用的默认值应为原型中指定的值。原型中的正式参数名称应是可选的,除非使用默认参数值或按名称绑定的参数,或者声明了额外的未封装维度。原型中的形式参数名称应与声明中的形式变量名称相同。
如果一个模块连接到包含导出子例程的modport,而该模块没有定义该子例程,则会发生elaboration错误。类似地,如果modport包含导出的子例程原型,而模块中定义的子例程与该原型不完全匹配,则会发生elaboration错误。
如果在模块中使用层次名称定义子例程,则它们也应在接口中声明为extern或在modport中声明为export。
任务(而非函数)可以在实例化两次的模块中定义,例如,由同一CPU驱动的两个存储器。接口中的extern forkjoin声明允许这样的多个任务定义。
25.7.1 Example of using tasks in interface
interface simple_bus (input logic clk); // Define the interfacelogic req, gnt;logic [7:0] addr, data;logic [1:0] mode;logic start, rdy;task masterRead(input logic [7:0] raddr); // masterRead method// ...
endtask: masterReadtask slaveRead; // slaveRead method// ...
endtask: slaveReadendinterface: simple_busmodule memMod(interface a); // Uses any interfacelogic avail;always @(posedge a.clk) // the clk signal from the interfacea.gnt <= a.req & avail // the gnt and req signals in the interfacealways @(a.start)a.slaveRead;
endmodulemodule cpuMod(interface b);enum {read, write} instr;logic [7:0] raddr;always @(posedge b.clk)if (instr == read)b.masterRead(raddr); // call the Interface method...
endmodulemodule top;logic clk = 0;simple_bus sb_intf(clk); // Instantiate the interfacememMod mem(sb_intf);cpuMod cpu(sb_intf);
endmodule
25.7.2 Example of using tasks in modports
这个接口示例展示了如何在完整的读/写接口中使用modports来控制信号方向和任务访问。
interface simple_bus (input logic clk); // Define the interfacelogic req, gnt;logic [7:0] addr, data;logic [1:0] mode;logic start, rdy;modport slave (input req, addr, mode, start, clk,output gnt, rdy,ref data,import slaveRead,slaveWrite);// import into module that uses the modport
modport master(input gnt, rdy, clk,output req, addr, mode, start,ref data,import masterRead,masterWrite);// import into module that uses the modport
task masterRead(input logic [7:0] raddr); // masterRead method// ...
endtasktask slaveRead; // slaveRead method// ...
endtasktask masterWrite(input logic [7:0] waddr);//...
endtasktask slaveWrite;//...
endtaskendinterface: simple_busmodule memMod(interface a); // Uses just the interfacelogic avail;
always @(posedge a.clk) // the clk signal from the interfacea.gnt <= a.req & avail; // the gnt and req signals in the interfacealways @(a.start)if (a.mode[0] == 1'b0)a.slaveRead;elsea.slaveWrite;
endmodulemodule cpuMod(interface b);enum {read, write} instr;logic [7:0] raddr = $random();
always @(posedge b.clk)if (instr == read)b.masterRead(raddr); // call the Interface method// ...elseb.masterWrite(raddr);
endmodulemodule omniMod( interface b);//...
endmodule: omniModmodule top;logic clk = 0;simple_bus sb_intf(clk); // Instantiate the interfacememMod mem(sb_intf.slave); // only has access to the slave taskscpuMod cpu(sb_intf.master); // only has access to the master tasksomniMod omni(sb_intf); // has access to all master and slave tasks
endmodule
25.7.3 Example of exporting tasks and functions
这个接口示例展示了如何在一个模块中定义任务,并在另一个模块调用它们,使用modports来控制任务访问。
interface simple_bus (input logic clk); // Define the interfacelogic req, gnt;logic [7:0] addr, data;logic [1:0] mode;logic start, rdy;modport slave( input req, addr, mode, start, clk,output gnt, rdy,ref data,export Read,Write);// export from module that uses the modportmodport master(input gnt, rdy, clk,output req, addr, mode, start,ref data,import task Read(input logic [7:0] raddr),task Write(input logic [7:0] waddr));// import requires the full task prototype
endinterface: simple_busmodule memMod(interface a); // Uses just the interface keywordlogic avail;task a.Read; // Read methodavail = 0;...avail = 1;endtasktask a.Write;avail = 0;...avail = 1;endtask
endmodulemodule cpuMod(interface b);enum {read, write} instr;logic [7:0] raddr;always @(posedge b.clk)if (instr == read)b.Read(raddr); // call the slave method via the interface...elseb.Write(raddr);endmodulemodule top;logic clk = 0;simple_bus sb_intf(clk); // Instantiate the interfacememMod mem(sb_intf.slave); // exports the Read and Write taskscpuMod cpu(sb_intf.master); // imports the Read and Write tasks
endmodule
25.7.4 Example of multiple task exports
多个模块导出(export)相同的任务名称通常是错误的。然而,相同modport类型的几个实例可以连接到一个接口,例如前面示例中的内存模块。为了让它们仍然可以导出它们的读写任务,这些任务应该在接口中使用extern forkjoin关键字声明。对extern forkjoin任务countslaves()的调用;在以下示例中,行为如下:
forktop.mem1.a.countslaves;top.mem2.a.countslaves;
join
对于读取任务,只有一个模块应该主动响应任务调用,例如,包含适当地址的模块。其他模块中的任务应返回而不产生任何效果。只有这样,活动任务才能写入结果变量。与任务不同,不允许多次导出函数,因为它们总是写入结果。
禁用对外部forkjoin任务的影响如下:
--如果通过接口实例引用任务,则应禁用所有任务调用。
--如果任务是通过模块实例引用的,则只应禁用对该模块实例的任务调用。
--如果一个接口包含一个外部forkjoin任务,并且没有连接到该接口的模块定义该任务,那么对该任务的任何调用都将报告运行时错误,并立即返回而不产生任何影响。这个接口示例展示了如何在多个模块中定义任务,并使用extern forkjoin在另一个模块中调用它们。多任务导出机制还可以用于统计连接到每个接口实例的特定modport的实例。
interface simple_bus (input logic clk); // Define the interfacelogic req, gnt;logic [7:0] addr, data;logic [1:0] mode;logic start, rdy;int slaves = 0;// tasks executed concurrently as a fork-join blockextern forkjoin task countSlaves();extern forkjoin task Read (input logic [7:0] raddr);extern forkjoin task Write (input logic [7:0] waddr);modport slave (input req,addr, mode, start, clk,output gnt, rdy,ref data, slaves,export Read, Write, countSlaves);// export from module that uses the modportmodport master ( input gnt, rdy, clk,output req, addr, mode, start,ref data,import task Read(input logic [7:0] raddr),task Write(input logic [7:0] waddr));// import requires the full task prototypeinitial beginslaves = 0;countSlaves;$display ("number of slaves = %d", slaves);end
endinterface: simple_busmodule memMod #(parameter int minaddr=0, maxaddr=0;) (interface a);logic avail = 1;logic [7:0] mem[255:0];task a.countSlaves();a.slaves++;endtasktask a.Read(input logic [7:0] raddr); // Read methodif (raddr >= minaddr && raddr <= maxaddr) beginavail = 0;#10 a.data = mem[raddr];avail = 1;endendtasktask a.Write(input logic [7:0] waddr); // Write methodif (waddr >= minaddr && waddr <= maxaddr) beginavail = 0;#10 mem[waddr] = a.data;avail = 1;endendtask
endmodulemodule cpuMod(interface b);typedef enum {read, write} instr;instr inst;logic [7:0] raddr;integer seed;always @(posedge b.clk) begininst = instr'($dist_uniform(seed, 0, 1));raddr = $dist_uniform(seed, 0, 3);if (inst == read) begin$display("%t begin read %h @ %h", $time, b.data, raddr);callr:b.Read(raddr);$display("%t end read %h @ %h", $time, b.data, raddr);
endelse begin$display("%t begin write %h @ %h", $time, b.data, raddr);b.data = raddr;callw:b.Write(raddr);$display("%t end write %h @ %h", $time, b.data, raddr);
end
end
endmodulemodule top;logic clk = 0;function void interrupt();disable mem1.a.Read; // task via module instancedisable sb_intf.Write; // task via interface instanceif (mem1.avail == 0) $display ("mem1 was interrupted");if (mem2.avail == 0) $display ("mem2 was interrupted");endfunctionalways #5 clk++;initial begin#28 interrupt();#10 interrupt();#100 $finish;endsimple_bus sb_intf(clk);memMod #(0, 127) mem1(sb_intf.slave);memMod #(128, 255) mem2(sb_intf.slave);cpuMod cpu(sb_intf.master);
endmodule
25.8 Parameterized interfaces
接口定义可以以与模块定义相同的方式利用参数和参数重新定义。以下示例显示如何在接口定义中使用参数。
interface simple_bus #(AWIDTH = 8, DWIDTH = 8)(input logic clk); // Define the interfacelogic req, gnt;logic [AWIDTH-1:0] addr;logic [DWIDTH-1:0] data;logic [1:0] mode;logic start, rdy;modport slave( input req, addr, mode, start, clk,output gnt, rdy,ref data,import task slaveRead,task slaveWrite);// import into module that uses the modportmodport master(input gnt, rdy, clk,output req, addr, mode, start,ref data,import task masterRead(input logic [AWIDTH-1:0] raddr),task masterWrite(input logic [AWIDTH-1:0] waddr));// import requires the full task prototype
task masterRead(input logic [AWIDTH-1:0] raddr); // masterRead method...
endtasktask slaveRead; // slaveRead method...
endtasktask masterWrite(input logic [AWIDTH-1:0] waddr);...
endtasktask slaveWrite;...
endtaskendinterface: simple_busmodule memMod(interface a); // Uses just the interface keywordlogic avail;always @(posedge a.clk) // the clk signal from the interfacea.gnt <= a.req & avail; //the gnt and req signals in the interfacealways @(a.start)if (a.mode[0] == 1'b0)a.slaveRead;elsea.slaveWrite;
endmodulemodule cpuMod(interface b);enum {read, write} instr;logic [7:0] raddr;always @(posedge b.clk)if (instr == read)b.masterRead(raddr); // call the Interface method// ...elseb.masterWrite(raddr);
endmodulemodule top;logic clk = 0;simple_bus sb_intf(clk); // Instantiate default interfacesimple_bus #(.DWIDTH(16)) wide_intf(clk); // Interface with 16-bit datainitial repeat(10) #10 clk++;memMod mem(sb_intf.slave); // only has access to the slaveRead taskcpuMod cpu(sb_intf.master); // only has access to the masterRead taskmemMod memW(wide_intf.slave); // 16-bit wide memorycpuMod cpuW(wide_intf.master); // 16-bit wide cpu
endmodule
相关文章:
IEEE Standard for SystemVerilog—Chapter 25.7 Tasks and functions in interfaces
子例程(任务和函数)可以在接口中定义,也可以在连接的一个或多个模块中定义。这允许更抽象的建模级别。例如,“读”和“写”可以定义为任务,而不需要引用任何连线,主模块只能调用这些任务。在modport中&…...
一台服务器最大能支持多少条 TCP 连接
文章目录 1. 一台服务器最大能打开的文件数1.1 限制参数1.2 调整服务器能打开的最大文件数示例 2. 一台服务器最大能支持多少连接3. 一台客户端机器最多能发起多少条连接4. 其他5. 相关实际问题5.1 "too many open files" 报错是怎么回事,该如何解决5.2 一…...

Qt重定向QDebug,Qt/C++开源作品39-日志输出增强版V2022
Qt重定向QDebug,自定义一个简易的日志管理类 Chapter1 Qt重定向QDebug,自定义一个简易的日志管理类0.前言1.最简单的操作运行结果2.实现一个简易的日志管理类 Chapter2 Qt::Qt Log日志模块Qt Log日志模块官方解释官方Demo思路 Chapter3 QT日志模块的个性…...

linux入门---多线程的控制
目录标题 线程库pthread_create如何一次性创建多个线程线程的终止线程的等待线程取消分离线程如何看待其他语言支持的多线程线程id的本质线程的局部存储线程的封装 线程库 要想控制线程就得使用原生线程库也可以将其称为pthread库,这个库是遵守posix标准的…...

基于android的 rk3399 同时支持多个USB摄像头
基于android的 rk3399 同时支持多个USB摄像头 一、前文二、CameraHal_Module.h三、CameraHal_Module.cpp四、编译&烧录Image五、App验证 一、前文 Android系统默认支持2个摄像头,一个前置摄像头,一个后置摄像头 需要支持数量更多的摄像头࿰…...

【Qt之控件QTreeView】设置单元格高度、设置图标尺寸
设置列宽 设置高度 自定义代理 继承QItemDelegate,实现sizeHint ()方法,设置自定义委托。 class itemDelegate : public QItemDelegate {Q_OBJECTpublic:explicit itemDelegate(QObject *parent 0) : QItemDelegate(parent){}~itemDelegate(){}virtua…...
力扣42.接雨水(java,暴力法、前缀和解法)
Problem: 42. 接雨水 文章目录 思路解题方法复杂度Code 思路 要能接住雨水,感性的认知就是要形成一个“下凹区域”,则此时我们就要比较当前柱子和其左右柱子高度的关系,易得一个关键的式子:当前小区域的积水 min(当前…...

hdlbits系列verilog解答(移位寄存器)-23
文章目录 一、问题描述二、verilog源码三、仿真结果 一、问题描述 您将获得一个具有两个输入和一个输出的模块 my_dff (实现 D 触发器)。实例化其中的三个,然后将它们链接在一起以形成长度为 3 的移位寄存器。端口 clk 需要连接到所有实例。…...
Linux命令记载
服务器基本操作 SSH登录服务器 ssh -p 端口号 用户名服务器IP 输入密码SFTP上传文件 #输入密码 #使用get命令下载远程服务器的文件,比如/usr/test.txt sftp>get /usr/test.txt#使用put命令上传本地文件到服务器,比如/usr/test1.txt sftp> put /…...

Flume 快速入门【概述、安装、拦截器】
文章目录 什么是 Flume?Flume 组成Flume 安装Flume 配置任务文件应用示例启动 Flume 采集任务 Flume 拦截器编写 Flume 拦截器拦截器应用 什么是 Flume? Flume 是一个开源的数据采集工具,最初由 Apache 软件基金会开发和维护。它的主要目的是…...

【pandas技巧】group by+agg+transform函数
目录 1. group by单个字段单个聚合 2. group by单个字段多个聚合 3. group by多个字段单个聚合 4. group by多个字段多个聚合 5. transform函数 studentsgradesexscoremoney0小狗小学部female958441小猫小学部male938362小鸭初中部male838543小兔小学部female909314小花小…...

一文解读WordPress网站的各类缓存-老白博客
缓存是一种重要的WordPress优化手段,用于提高网站的性能和加载速度。减少计算量,有效提升响应速度,让有限的资源服务更多的用户。本文老白博客便从自己的使用简单给大家介绍下WordPress的缓存,包括 站点缓存(Page Cach…...

从零开始:开发直播商城APP的技术指南
时下,直播商城APP已经成了线上购物、电子商务的核心组成,本文将为您提供一个全面的技术指南,帮助您从零开始开发一个直播商城APP。我们将涵盖所有关键方面,包括技术堆栈、功能模块、用户体验和安全性。 第一部分:技术…...

GZ035 5G组网与运维赛题第6套
2023年全国职业院校技能大赛 GZ035 5G组网与运维赛项(高职组) 赛题第6套 一、竞赛须知 1.竞赛内容分布 竞赛模块1--5G公共网络规划部署与开通(35分) 子任务1:5G公共网络部署与调试(15分) …...

分类预测 | Matlab实现KOA-CNN-GRU-selfAttention多特征分类预测(自注意力机制)
分类预测 | Matlab实现KOA-CNN-GRU-selfAttention多特征分类预测(自注意力机制) 目录 分类预测 | Matlab实现KOA-CNN-GRU-selfAttention多特征分类预测(自注意力机制)分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matla…...
【Qt】QString怎么转成int
2023年10月29日,周日晚上 第一种方法 这种方法会尝试将 QString 对象转换为 int 类型。如果转换成功,将返回转换后的 int 值;如果转换失败(例如,字符串中包含非数字字符),则返回 0。 QString…...
ubuntu 22.04 安装python-pcl
ubuntu 22.04 安装python-pcl 安装python-pcl修复bug 由于python-pcl库基本已经停止维护,所以Ubuntu22.04 在使用pip install python-pcl安装的时候会出现版本不适配的原因 安装python-pcl 使用Ubuntu22系统自带python3安装python-pcl,随后将下载的包拷…...
【题解】[GenshinOI Round 3 ]P9817 lmxcslD
题目传送门 分析 看到这道题我一开始是有点懵的,但是看了看数据范围,发现有几个点有 n 为质数 的特殊性质,结论先行,大胆猜测是不是可以贪心,所以先打了一个最傻的代码上去试试. void solve(){cin >> n >&…...

在pycharm中,远程操作服务器上的jupyter notebook
一、使用场景 现在我们有两台电脑,一台是拥有高算力的服务器,另一台是普通的轻薄笔记本电脑。如何在服务器上运行jupyter notebook,同时映射到笔记本电脑上的pycharm客户端中进行操作呢? 二、软件 pycharm专业版,jupy…...
SQL 运算符
SQL 运算符 运算符是保留字或主要用于 SQL 语句的 WHERE 子句中的字符,用于执行操作,例如:比较和算术运算。 这些运算符用于指定 SQL 语句中的条件,并用作语句中多个条件的连词。 常见运算符有以下几种: 算术运算符比…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...

如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...