假设您打算执行以下操作:
genvar i;
generate
for(i=0; i<45; i=i+1) begin : gen_asrt
bind dut assertion a1( .a(in_bus[i]), .b(out_bus[i]), .* );
end
这不起作用有两个原因:
实例名称a1
在每个循环上都被破坏。模块中的每个实例名称都必须是唯一的。引用IEEE std 1800-2012 § 23.11 '将辅助代码绑定到范围或实例':
多个bind
语句将bind_instantiation绑定到同一目标范围是合法的。但是,bind_instantiation 引入与目标范围的模块名称空间中的另一个名称冲突的实例名称将是错误的(参见 3.13)。这适用于预先存在的名称以及其他bind
语句引入的实例名称。如果设计包含多个包含bind
语句的模块实例,则会出现后一种情况。
i
在bind 语句中是指i
范围内的变量名dut
,而不是genvar i
. 再次引用IEEE std 1800-2012 § 23.11 'Binding assistant code to scopes or instances':
当一个实例被绑定到一个目标作用域时,效果就像该实例出现在目标作用域的最末端一样。换句话说,目标范围内的所有声明或导入到目标范围内的所有声明对绑定实例都是可见的。已导入范围的通配符导入候选是可见的,但绑定语句不能导致通配符候选的导入。存在或导入$unit
的声明在绑定语句中不可见。
如何绑定这种检查器:
您可以创建一个处理生成语句的模块,然后使用绑定语句实例化该模块。例子:
module bind_assertions #(parameter SIZE=1) ( input clock, input [SIZE-1:0] a,b );
genvar i;
generate
for(i=0; i<SIZE; i=i+1) begin : gen_asrt
assertion a1_even( .a(a[i]), .b(b[i]), .* );
end
endgenerate
endmodule
bind dut bind_assertions#(45) a1( .a(in_bus), .b(out_bus), .* );
从技术上讲,您可以绑定一组实例。根据 § 23.11 的语法 23-9 加上附录 A.4.1.1“模块实例化”,它是合法的语法。然而,这似乎在我目前可以访问的所有模拟器上都失败了。示例(如果它适用于您的模拟器):
bind dut assertion a1[44:0]( .a(in_bus[44:0]), .b(out_bus[44:0]), .* );
可以bind
存在于一个generate
块中吗?
IEEE std 1800-2012 § 27.3“生成构造语法”bind_directive
在语法 27-1 中给出了生成构造的语法。与绑定实例数组一样,并非所有模拟器都支持此功能。IEEE std 1800-2009 § 27.3 也提到bind_directive
但 IEEE std 1800-2005(SystemVerilog 的第一个 IEEE 版本)没有。示例(如果它适用于您的模拟器):
parameter DO_BIND=1;
generate
if(DO_BIND==1) begin
bind dut bind_assertions#(45) a1( .a(in_bus), .b(out_bus), .* );
end
endgenerate