(3)systemverilog 接口

systemverilog 接口

一、前言

验证一个设计需要经过几个步骤:生成输入激励,捕获输出响应,决定对错和衡量进度。但是,首先你需要一个合适的测试平台,并将它连接到设计上。

测试平台包裹着设计,发送激励并且捕获设计的输出。测试平台组成了设计周围的"真实世界"。模仿设计的整个运行环境。

由于Verilog的端口描述繁琐,代码常会长达数页,并且容易产生连接错误,所以测试平台需要一种更高层次的方法来跟设计建立通信。你需要一种可靠的描述时序的方法,这样就可以在正确的时间点驱动和采样同步信号,避免Verilog模型中常见的竞争状态。

此时接口就应运而生了,接口可以看作是一捆智能的连接。接口包含了连接、同步、甚至两个或者更多块之间的通信功能,它们连接了设计块和测试平台。
在这里插入图片描述

module top;
	bit clk
	always #5 clk=~ clk;
	arb_if arbif(clk);
	test t1(arbif);
endmodule:top

使用接口使得连接更加简洁而不易出错。如果你希望在一个接口中放入一个新的信号,你只需要在接口定义和实际使用这个接口的模块中做修改。而不需要改变其他任何模块。

二、接口的优势

  1. 将有关信号封装在同一个接口中,对于设计和验证环境都便于维护和使用。如果你需要新添加信号,只需要在接口中定义这个信号,而在使用这个接口的模块或者验证环境中做出相应修改。

  2. 由于接口既可以在硬件世界(module)中使用,又可以在软件世界(class)中使用,interface作为sv中唯一的硬件和软件环境的媒介交互,它的地位不可取代,所以verifier一定要精通接口的使用。

  3. 在软件世界中,我们是不可以例化接口的,但可以利用接口的指针,找到接口的实例,进一步找到接口实例中的信号。

  4. 接口由于可以例化的特性,使得对于多组相同的总线,在例化和使用时变得更加灵活,不仅使得代码变得简洁,也更易于验证环境的管理和维护。

三、接口的使用

  • 在interface的端口列表中只需要定义时钟、复位等公共信号,或者不定义任何端口信号,转而在变量列表中定义各个需要跟DUT和TB连接的logic变量。为了简单易用,我们推荐使用logic。
  • interface也可以依靠参数化方式提高复用性。(parameter)
  • 对于有对应interface的DUT和TB组件,在其例化时,也只需要传递匹配的interface变量名即可完成interface的变量传递。

硬件时间和软件世界的连接可以通过灵活的interface来实现,也可以通过modport来进一步限定信号传输的方向,避免端口连接的错误。

clocking已经包括了modport中很重要的一部分即限定传输方向。所以一般情况下,多使用clocking,较少使用modport。

1.modport

在接口中使用modport结果能够将信号分组并指定方向。

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

在接口中使用modport的仲裁器模型

module arb(arb_if.DUT arbif);
...
endmodule

2.clocking

为了避免在RTL仿真行为中发生的信号竞争问题,我们建议通过非阻塞赋值或者特定的信号延迟来解决同步问题。但是测试程序不能确保采集到DUT产生的最新值。
在仿真行为中,为了尽量避免时序电路中时钟和驱动信号的时序竞争问题,我们需要给出尽量明确的驱动时序和采样时序。
默认情况下,时钟对于组合电路的驱动会添加一个无限最小时间(dalta-cycle)的延迟,而该延迟无法用绝对时间单位衡量,它要比最小时间单位精度还小。

接口块可以使用时钟块来指定同步信号相对于时钟的时序。时钟块中的任何信号都将同步地驱动或采样,这就保证了测试平台在正确的时间点与信号交互。

时钟块的默认时序是在#1step延时之后采样输入信号,在#0延时之后驱动输出信号。1step延时规定了信号在前一个时间片的postponed区域,在设计有任何新的动作之前采样。这样你就可以在时钟改变之前捕获输出值。因为时钟模块的原因,测试平台的输出信号是同步的,所以它们直接送入设计中。在Reactive区域运行的程序块在同一个时间片内再一次除触发Active区域。
在这里插入图片描述

区域名行为
Active仿真模块中的设计代码
Observed执行system verilog断言
Reactive执行程序中的测试平台部分
Postponed为测试平台的输入采样信号
interface arb_if(input bit clk);
	logic[1:0]grant,request;
	logic rst;
	clocking cb@(posedge clk);
		output request;
		input grant;
	endclocking
	modport TEST(clocking cb,
				output rst);
	modport DUT(input request,rst,output,
				output grant);
endinterface

module test(arb_if.TEST arbif);
	initial begin
		arbif_cb.request<=0;
		@arbif.cb;
		$display("");
	end
endmodule
  • 一个接口可以包含多个时钟块,因为每个块中都只有一个时钟表达式,所以每一个对应一个时钟域。典型的时钟表达式如@(posedge clk)定义了单时钟沿,而@(clk)定义了DDR时钟。
  • 你可以在时钟块中使用default语句指定一个时钟偏移,但是默认情况下输入信号仅在设计执行前被采样,并且设计的输出信号在当前时间片又被驱动回当前设计。
  • 一旦定义了时钟块,测试平台就可以用@arbif.cb表达式等待时钟,而不需要描述确切的时钟信号和边沿。这样即使改变了时钟块中的时钟或者边沿,也不需要修改测试平台的代码。
    测试平台需要模仿测试仪的行为,应当在有效时钟边沿或边沿之后驱动待测设计,然后在有效时钟边沿到达之前,在满足协议时序的前提下,尽可能晚地采样。

3.clocking模板

clocking块基于时钟周期对信号进行驱动或者采样的方式,使得testbench不再苦恼于如何准确及时地对信号驱动或者采样,消除了信号竞争的问题。
在这里插入图片描述
代码解析:

  • 第一行定义了一个clocking块bus,由clock1的上升沿来驱动和采样。
  • 第二行指出了在clocking块中所有的信号,默认情况下会在clocking时间(clock1上升沿)
    的前10ns来对其进行输入采样,在事件的后2ns对其进行输出驱动。
  • 第三行声明了要对其采样的三个输入信号,data,ready和enable信号,这三个信号作为输入,它们的采样事件即采用了默认输入时间(clock1上升沿前的10ns)。
  • 第四行声明了要驱动的ack信号,而驱动该信号的事件是时钟clock1的下降沿,即覆盖了原有的默认输出事件(clock1上升沿后的2ns)。//还是带着两个2ns
  • 第五行的addr,也采用了自身定义的采样事件,即clock1上升沿前的1step。这里的step会使得采样发生在clock1上升沿前的1step。这里的1step会使得采样发生在clock1上升沿的上一个时间片采样区域,即可以保证采样到的数据是上一个时钟周期的数据。

4.同步

可以使用verilog的@和wait来同步测试平台中的信号。

@bus.cb.grant;  //在任何边沿继续,有变化即可
@(posedge bus.cb.grant); //上升沿继续
@(negedge bus.cb.grant); //下降沿继续
wait(bus.cb.grant==1);//等待表达式被执行,如果已经是真,不做任何延时

5.连接

接口需要将设计与测试平台连接起来,下面给一个简单的例子,尤其需要重视" .* "(隐式端口连接)的使用,能自动在当前级别自动连接模块实例的端口到具体信号,主要端口和信号的名字和数据类型相同。

module top;
	bit clk;
	always #4 clk=~clk;
	arb_if arbif(.*);
	arb a1 (.*);
	test t1(.*);
endmodule:top

五、建议

  • 使用接口时需要确保在你的模块和程序块之外声明接口变量。
  • 接口信号必须使用非阻塞赋值来驱动。
  • 建议将接口中的信号定义为logic
  • 为了避免可能的采样竞争问题,verifier应该在验证环境的驱动环节就添加固定延迟,使得在仿真波形中更容易体现出时钟与被驱动信号之间的时序前后关系,同时这样也便于DUT的准确处理和TB的准确采样。
  • 如果TB在采样从DUT送出的数据,,在时钟与被驱动信号之间存在delta-cycle时,应该考虑在时钟采样沿的更早时间段去模拟建立时间要求采样,这种方法也可以避免由于delta-cycle问题带来的采样竞争问题。
  • 当我们把clocking运用到interface中,用来声明各个接口与时钟的采样和驱动关系后,可以大大提高数据驱动和采样的准确性,从根本上消除采样竞争的可能性。

关注作者

  • 自述
    作者是一位中科大数字设计专业的研究生,水平有限,如有错误,请大家指正,想要与大家一同进步。
  • 经历
    曾获得国家奖学金,“高教社杯”数学建模国家二等奖等
  • 陆续更新:
    1.与UVM验证相关的system verilog后续内容;
    2.与verilog数字设计相关的一些基础模块设计,例如FIFO,UART,I2C等的书写。
    3.保研与竞赛经历等
  • 微信公众号
    欢迎大家关注公众号“数字IC小白的日常修炼”,期待与大家一同仗剑遨游数字IC世界。
  • 10
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数字IC小白的日常修炼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值