systemverilog的interface内的信号和clocking块内的信号区别与调度

参考文献1:Setup and Hold time and clocking block in system verilog
参考文献2:https://verificationguide.com/systemverilog/systemverilog-scheduling-semantics/
参考文献3:SystemVerilog Event Regions,Race Avoidance & Guidelines

interface内的clocking block用来进行信号的同步,具体说明如下:
Clocking blocks have been introduced in SystemVerilog to address the problem of specifying the timing and synchronisation requirements of a design in a testbench.

A clocking block is a set of signals synchronised on a particular clock. It basically separates the time related details from the structural, functional and procedural elements of a testbench. It helps the designer develop testbenches in terms of transactions and cycles. Clocking blocks can only be declared inside a module, interface or program.

先说结论:

  1. clocking块内的输入信号是对接口信号的采样,即clocking块内的信号是采样后的输出信号。如果input delay非0,则clocking内的采样后的信号和接口信号从仿真波形上看差1拍
  2. clocking块内的输出信号由testbench进行驱动,如果output delay非0,则clocking块内的输出信号延迟输出指定的delay时间后反应在接口的输出信号上,即二者在波形上为同一拍,但是存在output delay的延迟

即:

 1. The input will be sampled before #setup_time @posedge of CLK. 
 2. Output will be driven after #hold_time @posedge of CLK

setup和hold非零

仿真代码如下:

interface master_interface();
	logic pclk;
	logic prest_n;
	logic [31:0] pwdata;
	logic [31:0] prdata;
	
	clocking drv_cb @(posedge pclk);
		default input #1 output #1;
		output pwdata;
		input prdata;
	endclocking
	
	clocking mon_cb @(posedge pclk);
		default input #1 output #1;
		input pwdata;
		input prdata;
	endclocking
	
endinterface

module harness;
	logic clk;
	logic rst_n;
	logic [31:0] prdata;

	master_interface m_if();

	assign m_if.pclk = clk;
	assign m_if.prest_n = rst_n;
	assign m_if.prdata = prdata;

    always #5 clk = ~clk;
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            prdata <= 32'h5a5a_5a5a;
        end else begin
            prdata <= ~prdata;
        end
    end

	initial begin
		clk = 'b0;
		rst_n = 'b0;
		#12;
		rst_n = 'b1;
	end

	initial begin
        repeat(1000) @(m_if.mon_cb);    
		$finish();
	end

	initial begin
        $display("@%0t: n0", $realtime);
        @(posedge rst_n);
        $display("@%0t: n2", $realtime);
        repeat (100) begin
            repeat(1) @(m_if.drv_cb);    
            m_if.drv_cb.pwdata <= 32'h5555_5555;
            $display("@%0t: pwdata = 32'h5555_5555", $realtime);
            repeat(1) @(m_if.drv_cb);    
            m_if.drv_cb.pwdata <= 32'haaaa_aaaa;
            $display("@%0t: pwdata = 32'haaaa_aaaa", $realtime);
        end
	end

	initial begin
		$fsdbDumpfile("wave.fsdb");
		$fsdbDumpvars;
	end
endmodule

仿真脚本如下:

comp:
	@vcs \
	-full64 \
	-kdb -lca \
	-sverilog \
	-debug_access+all \
	+libext+.sv+.v \
	-timescale=1ns/1ps \
	-l cmp.log \
	*.sv

run:
	@./simv \
 	+fsdb+delta \
 	-l simv.log	

all:
	@make clean && make comp && make run

verdi:
	@verdi -ssf wave.fsdb &

clean:
	@rm -rf simv* csrc ucli* vc_hdrs.h

仿真波形:

在这里插入图片描述

setup和hold全零

在这里插入图片描述

可以看到在monitor的clocking块内部,采到pwdata(drv_cb中的输出信号)为上一拍的值,而prdata(drv_cb中的输入信号)为当前拍的值。

打开region mode和event sequence,显示如下:
在这里插入图片描述
事件的调度如下:
在这里插入图片描述
从上面仿真波形可以看出,在NBA region,非阻塞赋值被调度,/harness/m_if/prdata[31:0]变为0xa5a5_a5a5,在Active(1)region,更新/harness/m_if/mon_cb/prdata[31:0],变为0xa5a5_a5a5,因此波形上看到的mon_cb内的prdata的值为0xa5a5_a5a5.

而mon_cb内的pwdata在Active(1)region更新为0xaaaa_aaaa。

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

sunvally

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

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

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

打赏作者

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

抵扣说明:

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

余额充值