SV学习(3)——接口interface、modport、时钟块clocking

  • 1. 接口interface
  • 2. modport
  • 3. 时钟块clocking
    • 3.1. 驱动和采用的竞争问题
    • 3.2. clocking待补充....

========

链接: interface中的clocking

========

1. 接口interface

SV引入了一个重要的数据类型:interface。主要作用有两个,一是简化模块之间的连接;二是实现类和模块之间的通信。

使用接口使得连接更加简洁而不易出差,如果需要在一个接口中放入一个新的信号,就只需要在接口定义和实际使用这个接口的模块中做对应的修改,而不需要改变其他模块。接口不可以例化,但是可以使用接口的指针,找到接口的实例,然后再找接口实例中的信号。

接口使用方法:

  1. 在interface的端口列表只需要定义时钟、复位等公共信号,或者不定义任何端口信号,转而在变量列表中定义各个需要跟DUT和TB连接的logic变量。
  2. interface可以用参数化方式提高复用性(parameter)
  3. 对于有对应interface的DUT和TB,在其例化的时候,也只需要传递匹配的interface变量名即可完成interface的变量传递

由于接口即可以在硬件上(module)使用,又可以在软件上(class)使用,interface作为SV中唯一的硬件和软件环境的媒介交互,modport可以进一步限定信号传输的方向,避免端口连接的错误。

接口中使用task和function:

  1. 接口可以包含task和function,也可以在接口外部或者内部
  2. 如果task和function定义在模块中,使用层次结构名称,它们必须在接口中声明为extern或在modport中声明为export
  3. 多个模块的任务名不可以重复

下面举两个接口的例子:

  1. 使用interface接口的一位全加器

    `timescale  1ns / 1nsinterface if_port (input bit clk); // 声明接口logic    a, b, cin, sum, cout;   // 声明所有的连接线clocking cp @ (posedge clk);    // 声明在同一个时钟变化下,连接线的方向output  a, b, cin;endclockingclocking   cn @ (negedge clk);    // 下降沿出发input   a, b ,cin, sum, cout;endclockingmodport simulus (clocking cp);  // 声明端口的输入输出modport adder   (input a, b, cin,  output cout, sum);modport    monitor (clocking cn);endinterfacemodule    simulus (if_port.simulus port); // 使用接口的激励模块always @ (port.cp) beginport.cp.a  <=  $random() % 2;port.cp.b <=  $random() % 2;port.cp.cin   <=  $random() % 2;end
    endmodule:  simulusmodule   adder   (if_port.adder port);   // 一位加法器
    //  assign  {port.cout, port.sum} = {port.a + port.b + port.cin};    // 好久没写代码,犯了这样的错assign   {port.cout, port.sum} = port.a + port.b + port.cin;
    endmodule:  addermodule monitor (if_port.monitor mon);  // 检测模块,在时钟的下降沿打印结果always @ (mon.cn)    begin$display ("%d + %d + %d = %d %d", mon.cn.a, mon.cn.b, mon.cn.cin, mon.cn.cout, mon.cn.sum, $time);end
    endmodulemodule top ( );timeunit        1ns;timeprecision   1ns;bit clk = 0;;if_port   port (clk); // 实例化所有模块,并连接接口simulus  sim (port.simulus);adder    add (port.adder);monitor    mon (port.monitor);always #10 clk = ~clk;endmodule
    

  2. 使用interface接口的读存储器

    // interface_exampleinterface membus (   // 声明接口input    logic   clk
    );  // port和module的port一样,用于top的// 声明用于内部模块例化的连接logic            mrdy    ;logic          wen     ;logic          ren     ;logic  [ 7: 0] addr    ;logic  [ 7: 0] c2m_data;logic  [ 7: 0] m2c_data;wor                status  ;
    // 对于确定了方向的可以在interface的port里面声明,如clk,
    // 而对于随着模块不同、方向不同的用logic先声明,然后再用modport指明具体方向task    reply_read (input   logic   [ 7: 0]     data,integer    delay);#delay;@ (negedge clk)mrdy = 1'b0;m2c_data = data;   // slave回复数据@ (negedge clk)mrdy = 1'b1;  endtasktask read_memory (input  logic   [ 7: 0] raddr   ,output logic   [ 7: 0] data);@ (posedge clk);ren = 1'b0;addr = raddr;      // master申请读数据@ (negedge mrdy);@ (posedge clk);data = m2c_data;  // master得到数据ren = 1'b1;endtask// 在接口中使用modport,将信号分组并指定方向modport master (output   wen, ren, addr, c2m_data, status,input  mrdy, m2c_data,import   read_memory); modport   slave (input    wen, ren, addr, c2m_data, status,output mrdy, m2c_data,import   reply_read);endinterface/* *************** mem_core *************** */
    module mem_core (membus.slave mb);  // 用salve接口声明logic  [ 7: 0] mem [ 255: 0];initial   beginfor (int i = 0; i < 256; i++)mem[i] = i;endassign   mb.status = 1'b0;always @ (negedge mb.ren)mb.reply_read (mem[mb.addr], 100);
    endmodule/* *************** cpu_core *************** */
    module cpu_core (membus.master mb); // 用master接口声明assign    mb.status = 1'b0;initial  beginlogic  [ 7: 0] read_data;mb.read_memory (8'b0001_0000, read_data);$display ("Read Result", $time, read_data);end
    endmodule/* *************** top *************** */
    module top ();wor       status; // wor:当有多个驱动源驱动wor型数据时,将产生线或结构logic  clk = 1'b0;membus mb (clk);// mem_core mem (mb.slave);mem_core mem (mb);cpu_core cpu (mb.master);initial  beginfor (int i = 0; i <= 255; i++)#1 clk = ~clk;endendmodule
    


关于interface的使用,大概知道了怎么用,接口中端口的调用没问题,比如在顶层top中实例化mem模块和cpu模块,这俩的端口连接可以用接口实现,在interface接口中,把端口的变量名声明好,再用modport将信号分组并指定输入输出方向;
但是具体的细节不太了解,比如在接口中定义了任务,如何在各自的模块中调用任务,看别人博客说是要添加export声明,但是我却用了import解决了,不懂,但是成了


2. modport

使用modport将接口中的信号分组
实现一个简单的仲裁器接口,并在仲裁器中使用接口,

// 简单接口
interface arb_if (input bit clk);logic [1:0] grant, request;logic rst;
endinterface// 仲裁器
module arb (arb_if arbif);...always @(posedge arbif.clk or posedge arbif.rst) beginif (arbif.rst == 1'b1)arbif.grant <= 2'b00;elsearbif.grant <= next_grant;end...
endmodule// 测试平台
module test (arb_if arbif);...initial   begin...@(posedge arbif.clk);arbif.request <= 2'b01;$display ("@%0t: Drove req = 01", $time);repeat (2) @(posedge arbif.clk);if (arbif.grant != 2'b01)$display ("@%0t: a1: grant != 2'b01", $time);$finish;end...
endmodule// 顶层
module top; bit clk;always #5 clk = ~clk;arb_if arbif(clk);arb a1(arbif);test t1(arbif);
endmodule

上面arb在接口中使用了点对点的无信号方向的连接方式;
下面在接口中使用modport结构能将信号分组并指定方向;

// 使用mofport的接口
interface arb_if (input bit clk);logic [1:0] grant, request;logic rst;modport TEST (output request, rst,input grant, clk);modport DUT (input request, rst, clk,output grant);modport MONITOR (input request, grant, rst, clk);
endinterface// 仲裁器
module arb (arb_if.DUT arbif);...
endmodule// 测试平台
module test (arb_if.TEST arbif);...
endmodule // 顶层
module top;bit clk;always #5 clk = ~clk;arb_if arbif(clk);arb a1(arbif);test t1(arbif);
endmodule

两种顶层模块是一样的,因为modpoer在模块首部指明,在模块例化时就不需要指明;

在接口中不能例化模块,但是可以例化其他接口


3. 时钟块clocking

3.1. 驱动和采用的竞争问题

在RTL设计中,在同一个时间片内,可能会有一个信号同时被读取和写入,那么读取到的数据有可能会是旧数值也有可能是新数值,用非阻塞赋值 <= 就可以解决这个问题。但是在测试程序中,不能确保采集到DUT产生的最新值;

接口块可以使用时钟块来指定同步信号相对于时钟的时序。

在时钟上升沿采样信号,只看vld信号(1->0)就会疑惑采样到的是1还是0,在RTL仿真时,是看不到真实的物理时序信息的,但实际采样到的是1;真实电路对应的时vld_actual信号,它的变化会较clk有一个detal-cycle的延迟,这样看在时钟上升沿采集到的是1。

我们可以人为的设置加大delay,这样看波形的时候就会显示vld_actual的,让待采样数据的沿变不和时钟的沿变在一起。

还有一种方法就是,设置采样vld信号的时间,设置在时钟上升沿之前 #t 采样,这样采出来的数据也是准确的;
同样也可以设置信号输出时间,设置在时钟上升沿之后 #t 输出,这样输出的数据也是准确的;
就类似与模拟建立保存时间,在时序上在波形上,看到肉眼可见的延迟。

3.2. clocking待补充…

SV学习(3)——接口interface、modport、时钟块clocking相关推荐

  1. System Verilog学习笔记—接口interface

    目录 0.interface的直观理解 1.使用端口的TB与DUT通信 2.使用接口的TB与DUT通信 3.使用modport将interface中的信号分组 4.接口中的clocking block ...

  2. systemverilog-接口和时钟块

    目录 一.接口 1.1接口的意义 1.2接口的定义 1.3 modport 1.4 接口的优缺点 1.5 虚接口 二.时钟块 2.1 时钟块的意义 2.2 时钟块的声明 三.仿真调度机制 一.接口 1 ...

  3. SV知识点总结-接口

    接口 通过端口实现模块之间的连接 实际上的操作是,首先定义两个需要连接的模块A(变量为a,b)和模块B(变量为c,d).再定义一个interface C,其变量分别为e,f.在顶层中将模块C发别与模块 ...

  4. SV学习(8)——随机约束和分布、约束块控制

    SV学习(8)--随机约束和分布.约束块控制 1. 随即约束和分布 1.1. 为什么需要随机? 1.2. 要随机做什么? 1.3. 声明随机变量的类 1.4. 什么是约束 1.5. 权重分布 1.6. ...

  5. go struct 静态函数_Go语言学习笔记(四)结构体struct 接口Interface 反射reflect...

    加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959 结构体struct struct 用来自定义复杂数据结构,可以包含多个字段(属性),可以嵌套: go中的struc ...

  6. Go 学习笔记(35)— Go 接口 interface (接口声明、接口初始化、接口方法调用、接口运算、类型断言、类型查询、空接口)

    1. 接口概念 接口是双方约定的一种合作协议.接口实现者不需要关心接口会被怎样使用,调用者也不需要关心接口的实现细节.接口是一种类型,也是一种抽象结构,不会暴露所含数据的格式.类型及结构. 接口内部存 ...

  7. SV学习(2)——过程语句、函数和任务、变量声明周期

    SV学习(2)--过程语句.函数和任务 1. 过程语句 1.1. 硬件过程块 1.2. 赋值语句 1.3. 控制语句 1.3.1. for循环 1.3.2. while循循环 1.3.3. do-wh ...

  8. go学习笔记接口部分

    Go学习笔记 接口 接口定义方法 练习 11.1 simple_interface.go: 练习 11.2 interfaces_poly2.go: 接口嵌套接口 如何判断接口类型 方法一varI.( ...

  9. Java接口(interface)的概念及使用

    在抽象类中,可以包含一个或多个抽象方法:但在接口(interface)中,所有的方法必须都是抽象的,不能有方法体,它比抽象类更加"抽象". 接口使用 interface 关键字来声 ...

最新文章

  1. 可视化神经网络的网络结构并保存
  2. JQuery进阶学习
  3. Codevs 1049 棋盘染色
  4. 防止多重启动之调用Api [收集2005090201]
  5. 全国计算机等级考试题库二级C操作题100套(第82套)
  6. ASP.Net Core 3.1 中使用JWT认证
  7. NGINX 配置超时时间
  8. (译)2019年前端性能优化清单 — 上篇
  9. 利用ACS实现AAA服务的搭建
  10. 数字图像处理第三版中文版部分答案-冈萨雷斯
  11. Oxygen XML Editor Professional文档的强大工具
  12. UIUC 云计算概念:SWIM协议笔记
  13. 【python游戏】新的一年快来变身兔兔战士打败獾守护兔兔吧~
  14. Android如何快速创建启动动画
  15. 在Unity3D中使用泛型(上)
  16. These are the first 50 documents matching your search, refine your search to see others
  17. LeetCode 41
  18. 烟台大学—贺利坚的计算机课程教学链接
  19. Altium designer 备注手册
  20. 两种不同结构的永磁永磁同步电机特点说明——表贴式和内置式

热门文章

  1. 《约会专家》片尾【约会宝典】总结
  2. JavaWeb篇之一——使用原生JDBC对数据库进行操作
  3. js performance.timing:利用performance.timing进行性能分析
  4. java合成两张图片并在图片上写字
  5. 2019北航961考研初试经验之谈
  6. Epicor BPM - 在VS中编写BPM代码
  7. 苹果ipad有哪几款_2020年最新iPad选购指南
  8. 深度残差收缩网络简要解读
  9. 【Vue系列】vuex详解,一篇彻底搞懂vuex
  10. LeetCode 876 题解