SystemVerilog中interface的几点理解
最近吃了没文化的亏,想来就把interface好好看看。
在SV中常用interface连接端口,它的好处在于,方便了在sv中模块声明中不需要一个个的写端口,直接在端口中实例化一个interface即可。接口中还可以包含任务函数、断言等等。说多了咱也记不住,就说这点吧。不过我觉得最好用的还是第一点哈。
interface的推荐写法
interface v_if(input bit clk); logic [31:0] data; ..... clocking cb@(posedge clk) //需要包含resetn endclocking:cb ...... //需要几个写几个,个人觉得是有几个component写几个时钟块 modport TB(clocking cb,output resetn); ...... //modport和clocking块对应 endinterface
下面就是个人的几点扯淡了...
1.为什么clk要写在括号里?
我的理解是,clk是在顶层testbench中驱动的,其他component只会使用clk作为input,这样可以减少不必要的接口层次。而且,虽然clk和interface中的其他端口定义的位置不一样,但是在仿真环境中还是可以使用<接口实例名>.clk。这个仍然代表着interface中的clk信号。但是除了对DUT模块使用上述clk信号,对于在testbench,不建议使用这个clk,要用时钟块的名称替换,这样做的好处是避免在仿真时发生竞争冒险,使得各个信号是时钟同步信号。但是需要注意的是,使用时钟块时,不再需要添加上升沿或者下降沿关键字,给时钟块中的变量赋值时应当使用<=而不是=。
2.为什么resetn需要定义两次?一次在时钟块中,一次在modport中?
为了做到异步复位,同步释放。因此resetn有效时应当直接使用<接口实例名>.<modport名 style="margin: 0px; padding: 0px; outline: 0px; max-width: 100%; box-sizing: border-box; overflow-wrap: break-word !important;">resetn。释放时为<接口实例名>.<clocking名 style="margin: 0px; padding: 0px; outline: 0px; max-width: 100%; box-sizing: border-box; overflow-wrap: break-word !important;">.resetn。</clocking名></modport名>
<modport名 style="margin: 0px; padding: 0px; outline: 0px; max-width: 100%; box-sizing: border-box; overflow-wrap: break-word !important;"><clocking名 style="margin: 0px; padding: 0px; outline: 0px; max-width: 100%; box-sizing: border-box; overflow-wrap: break-word !important;">
</clocking名></modport名>
</clocking名></modport名>
3.时钟块什么时候采样?
时钟块默认输入偏斜为1step,也就是在上一个时钟片的结束部分。换句话说,就是在紧接着时钟上升沿之前采样信号,或者说是本时钟片的preponed区域。
如果显示使用#0输入,则会在相应的时钟事件同步进行采样,但是是在observed区域采样,这样可以避免竞争情况。同样的,在re-NBA区域进行输出。忘了的,不懂的看这个SystemVerilog中scheduler(调度)
如下代码所示:
clocking cb_0 @(posedge clk);
input #0 gnt;
endclocking
clocking cb_1 @(posedge clk);
input #1step gnt;
endclocking
begin
@(if0.cb_0);
$display ("cb_0.gnt = 0x%0h", if0.cb_0.gnt);
end
begin
@(if0.cb_1);
$display ("cb_1.gnt = 0x%0h", if0.cb_1.gnt);
end
最终结果是不一样的:
欢迎点赞,关注,分享~~, 本文原发于微信公众号【数字ic小站】

