systemverilog中的bind

本文详细介绍了SystemVerilog中的bind关键字,展示了如何用它将断言模块与DUT连接,以及如何用于模块间的连接。通过多个示例说明了bind可以用于将包含断言的interface与module绑定,并且在存在多个实例时的绑定行为。同时,讨论了bind语句在不同文件和模块实例化情况下的应用和效果,强调了bind时信号名称的重要性。
摘要由CSDN通过智能技术生成

最早接触 bind 关键字是在assertion 当中,将assertion 与 dut 进行绑定连接,如下例子:

bind cpu fpu_props fpu_rules_1(a,b,c);
//cpu 是module 名字
//fpu_props 是内部包含 property 以及断言的模块,可以是 module 或者 program 甚至 interface
//fpu_rules_1 是 fpu_props 的实例名
//括号中的信号 a b c 是 cpu 的端口信号,并且连接到 fpu_props 的对应端口

来看下面一个将 interface bind 到 module 的例子:

interface range (input clk,enable, input int minval,expr);
    property crange_en;
        @(posedge clk) enable |-> (minval <= expr);
    endproperty
    range_chk: assert property (crange_en);
endinteface

bind cr_unit range r1(c_clk,c_en,v_low,(in1&&in2));

可以看到,包含断言的 interface ,其端口信号的方向均为 input ,也就是说 property 中包含的信号都是从 interface 的外部给进来的;

实际上, bind 不仅仅 可以进行 断言 与 dut 之间的连接,两个 module 之间也能进行连接,如下面例子:

有 dut.v :

module dut(clk, rst_n, vld, rdy, data);
  input clk;
  input rst_n;
  input vld;
  output reg rdy;
  output reg[31:0] data; 
  
  bit[31:0] count;
  
  always @(posedge clk) begin
    if(rst_n == 0)begin
    end
    else begin
      count ++;
      data <= count; 
      if(count == 150)begin
        $finish;
      end
    end
  end
endmodule

dut_assert.sv :

module dut_assert(clk_sva, rst_n_sva, vld_sva, rdy_sva, data_sva);//这里全都是 input 
  input clk_sva,rst_n_sva,vld_sva;
  input rdy_sva;
  input reg[31:0] data_sva; 
  
  
  always @(posedge clk_sva)begin
    
    @(posedge clk_sva);
    
  	if(data_sva == 10)begin
    	$display("++++canli data_sva is %d at %0t",data_sva, $time);
  	end
  	if(data_sva == 13)begin
    	$display("****canli data_sva is %d at %0t",data_sva, $time);
  	end
  end
endmodule

test.sv :

module test;
  
  bit clk;
  bit rst_n;
  bit [31:0] data;
  bit rdy;
  
  initial begin
    #10 rst_n = 1;
    forever begin
      #1 clk = ~clk;
    end
    
  end
  initial begin
  		$timeformat(-9, 0, "ns", 20);
		$fsdbDumpfile("top.fsdb");
		$fsdbDumpvars(0, test);
		$fsdbDumpflush;
		$fsdbDumpSVA;  
  end
  
  dut my_dut(.clk(clk),.rst_n(rst_n),.vld(1'd0),.rdy(rdy),.data(data));
  
endmodule

然后通过 bind 将 dut 与 dut_assert 连接起来,写在 assert.sv 中:

bind dut dut_assert my_assert(
	.clk_sva(clk), 
	.rst_n_sva(rst_n),
	.vld_sva(vld),
	.rdy_sva(rdy),
	.data_sva(data)
);

然后filelist 文件如下:

./dut.v
./dut_assert.sv
./assert.sv
./test.sv

运行结果如下:

 从上面的例子可以看到:即使 dut_assert.sv 中不包含 断言,bind 依旧可以将 dut_assert 与 dut 连接起来;不过一般来说,在 dut_assert 中一般添加断言来检测dut,否则这样的 bind 看上去似乎没啥子意义;

也可以将 bind 语句加到 test.sv 中,运行结果是一样的,如下:

module test;
  
  bit clk;
  bit rst_n;
  bit [31:0] data1;
  bit [31:0] data2;
  bit rdy1;
  bit rdy2;
  
  initial begin
    #10 rst_n = 1;
    forever begin
      #1 clk = ~clk;
    end
    
  end
  initial begin
  		$timeformat(-9, 0, "ns", 20);
		$fsdbDumpfile("top.fsdb");
		$fsdbDumpvars(0, test);
		$fsdbDumpflush;
		$fsdbDumpSVA;  
  end
  
  dut my_dut(.clk(clk),.rst_n(rst_n),.vld(1'd0),.rdy(rdy1),.data(data1));

	bind dut dut_assert my_assert(//这里的 dut 也可以是 my_dut
	.clk_sva(clk), 
	.rst_n_sva(rst_n),
	.vld_sva(vld),
	.rdy_sva(rdy),
	.data_sva(data)
);
  
endmodule

此时,如果将 dut 实例化2次,如下:

module test;
  
  bit cl;//注意这里名字变了
  bit rst_n;
  bit [31:0] data1;
  bit [31:0] data2;
  bit rdy1;
  bit rdy2;
  
  initial begin
    #10 rst_n = 1;
    forever begin
      #1 cl = ~cl;
    end
    
  end
  initial begin
  		$timeformat(-9, 0, "ns", 20);
		$fsdbDumpfile("top.fsdb");
		$fsdbDumpvars(0, test);
		$fsdbDumpflush;
		$fsdbDumpSVA;  
  end
  
  dut my_dut1(.clk(cl),.rst_n(rst_n),.vld(1'd0),.rdy(rdy1),.data(data1));
  dut my_dut2(.clk(cl),.rst_n(rst_n),.vld(1'd0),.rdy(rdy2),.data(data2));

	bind dut dut_assert my_assert(//注意这里 bind 的还是 dut
	.clk_sva(clk), //这里绑定的还是 clk
	.rst_n_sva(rst_n),
	.vld_sva(vld),
	.rdy_sva(rdy),
	.data_sva(data)
);
  
endmodule

运行结果如下:

可以看到,此时 bind dut,相当于 bind 了2次,所以打印语句打印2次;如果将上面的 bind dut 修改:

module test;
  
  bit cl;
  bit rst_n;
  bit [31:0] data1;
  bit [31:0] data2;
  bit rdy1;
  bit rdy2;
  
  initial begin
    #10 rst_n = 1;
    forever begin
      #1 cl = ~cl;
    end
    
  end
  initial begin
  		$timeformat(-9, 0, "ns", 20);
		$fsdbDumpfile("top.fsdb");
		$fsdbDumpvars(0, test);
		$fsdbDumpflush;
		$fsdbDumpSVA;  
  end
  
  dut my_dut1(.clk(cl),.rst_n(rst_n),.vld(1'd0),.rdy(rdy1),.data(data1));
  dut my_dut2(.clk(cl),.rst_n(rst_n),.vld(1'd0),.rdy(rdy2),.data(data2));

	bind my_dut1 dut_assert my_assert(// 这里 bind 的修改为 my_dut1
	.clk_sva(clk), 
	.rst_n_sva(rst_n),
	.vld_sva(vld),
	.rdy_sva(rdy),
	.data_sva(data)
);
  
endmodule

 运行结果如下:

也就是说,此时改为 dut 的实例名,相当于只 bind 了1次,所以打印1次;如果修改 bind 的端口信号名:

module test;
  
  bit cl;
  bit rst_n;
  bit [31:0] data1;
  bit [31:0] data2;
  bit rdy1;
  bit rdy2;
  
  initial begin
    #10 rst_n = 1;
    forever begin
      #1 cl = ~cl;
    end
    
  end
  initial begin
  		$timeformat(-9, 0, "ns", 20);
		$fsdbDumpfile("top.fsdb");
		$fsdbDumpvars(0, test);
		$fsdbDumpflush;
		$fsdbDumpSVA;  
  end
  
  dut my_dut1(.clk(cl),.rst_n(rst_n),.vld(1'd0),.rdy(rdy1),.data(data1));
  dut my_dut2(.clk(cl),.rst_n(rst_n),.vld(1'd0),.rdy(rdy2),.data(data2));

	bind my_dut1 dut_assert my_assert(
	.clk_sva(cl), //这里 bind 的信号改为 cl
	.rst_n_sva(rst_n),
	.vld_sva(vld),
	.rdy_sva(rdy),
	.data_sva(data)
);
  
endmodule

 此时运行会报错,如下:

 由此,可以得出结论,bind 时,bind 的 dut 中的信号必须是 dut module中的信号名,而不能是 dut 实例的输入输出信号名!!

最近看到一种bind 方式来大批量 bind ,语法如下:

bind module_name: module_inst_name1, module_inst_name2...  
checker_module[#(.Para(xx))]  checker_module_inst 
// checker_module 可以带 parameter

例子如下:

bind DUT: dut_inst1, dut_inst2  checker#(.a(1)) checker_inst(.*);

  • 7
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
There are some simple tricks that every design engineer should know to facilitate the usage of SystemVerilog Assertions. Although this paper is not intended to be a comprehensive tutorial on SystemVerilog Assertions, it is worthwhile to give a simplified definition of a property and the concurrent assertion of a property. 1.1 What is an assertion? An assertion is basically a "statement of fact" or "claim of truth" made about a design by a design or verification engineer. An engineer will assert or "claim" that certain conditions are always true or never true about a design. If that claim can ever be proven false, then the assertion fails (the "claim" was false). Assertions essentially become active design comments, and one important methodology treats them exactly like active design comments. More on this in Section 2. A trusted colleague and formal analysis expert[1] reports that for formal analysis, describing what should never happen using "not sequence" assertions is even more important than using assertions to describe always true conditions. 1.2 What is a property? A property is basically a rule that will be asserted (enabled) to passively test a design. The property can be a simple Boolean test regarding conditions that should always hold true about the design, or it can be a sampled sequence of signals that should follow a legal and prescribed protocol. For formal analysis, a property describes the environment of the block under verification, i.e. what is legal behavior of the inputs. 1.3 Two types of SystemVerilog assertions SystemVerilog has two types of assertions: (1) Immediate assertions (2) Concurrent assertions Immediate assertions execute once and are placed inline with the code. Immediate assertions are not exceptionally useful except in a few places, which are detailed in Section 3.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值