SystemVerilog:如何创建一个接口,它是一个更简单接口的数组?
SystemVerilog: How to create an interface which is an array of a simpler interfaces?
我正在尝试创建一个接口,它是一个更简单接口的数组。在 VHDL 中,我可以简单地定义两种类型,一个记录和一个记录数组。但是如何在 SystemVerilog 中做到这一点呢?这是我尝试过的:
`define MAX_TC 15
...
interface scorecard_if;
score_if if_score [`MAX_TC];
endinterface
interface score_if;
integer tc;
integer pass;
integer fail;
bit flag_match;
real bandwidth;
endinterface
但是我从 Aldec Active-HDL 得到一个错误:
错误:VCP2571 TestBench/m3_test_load_tb_interfaces.sv : (53, 34):
实例化必须有方括号():if_score.
我也试过了
interface scorecard_if;
score_if [`MAX_TC] if_score;
endinterface
和
interface scorecard_if;
score_if [`MAX_TC];
endinterface
但这两个都导致了 "Unexpected token" 语法错误。
甚至可以这样做吗?如果没有办法做到这一点,我可以想到两种解决方法。首先,我可以将 score_if 的所有单个元素定义为未压缩的数组:
interface score_if;
integer tc [1:`MAX_TC];
integer pass [1:`MAX_TC];
integer fail [1:`MAX_TC];
bit flag_match [1:`MAX_TC];
real bandwidth [1:`MAX_TC];
endinterface
这可以编译,但它很难看,因为我不能再将单个乐谱作为一个整体来引用。
我也可能要实例化一个 score_if 的数组(使用原始代码),但我真的想在一个生成循环中实例化 scorecard_if,这样我就可以实例化一个可变数量的scorecard_if 基于参数的接口。
只是为了对我正在尝试做的事情提供一些解释,score_if 应该是给定测试用例的分数记录,而 scorecard_if 是一个数组所有的测试用例。但是我的测试台有多个独立的刺激发生器、监视器和记分卡来处理 DUT 内部的多个独立模块,其中倍数是一个参数。
第 1 部分:声明接口数组
在接口实例化的末尾添加括号。根据 IEEE Std 1800-2012,所有分层实例的实例化都需要端口列表的括号,即使端口列表为空也是如此。如果接口在声明中没有任何端口并且实例化很简单,一些工具允许删除括号;但这不是标准的一部分。最佳做法是对所有分层实例化使用括号。
解决方案:
score_if if_score [`MAX_TC] <b>()</b> ;
语法引用:
§ 25.3 接口语法 & § A.4.1.2 接口实例化
interface_instantiation ::= // from A.4.1.2
interface_identifier [ parameter_value_assignment ] hierarchical_instance { , hierarchical_instance } ;
§ A.4.1.1 模块实例化
hierarchical_instance ::= name_of_instance ( [ list_of_port_connections ] )
第 2 部分:访问该数组的元素
分层引用必须是常量。动态索引无法访问排列的分层实例。它是一个 rule/limitation,至少从 IEEE Std 1364 开始。在 IEEE Std 1800-2012 § 23.6 分层名称 中阅读更多关于它的信息,语法规则是:
hierarchical_identifier ::= [ $root . ] { identifier constant_bit_select . } identifier
您可以使用 generate-for-loop,因为它会在 compile/elaboration 时进行静态展开。限制是你不能使用你的显示消息,我们在循环中累积你的失败计数。您可以使用生成循环将数据复制到本地数组并对其求和,但这违背了您的意图。
接口通常是一组网络,用于连接模块与 class-base test-bench 或共享总线协议。您将其用作嵌套计分卡。 typedef struct
可能更适合您的目的。 struct
是一种数据类型,没有模块和接口那样的层次引用限制。看起来您已经在 previous question 中尝试溃败了。不确定为什么切换到嵌套界面。
看起来您正在尝试创建一个相当复杂的测试环境。如果是这样,我建议先学习 UVM,然后再花大量时间重新发明高级测试平台架构。从 1.1d 开始,因为 1.2 还不是主流。
这也有效:
1.定义一个"container"接口:
interface environment_if (input serial_clk);
serial_if eng_if[`NUM_OF_ENGINES](serial_clk);
virtual serial_if eng_virtual_if[`NUM_OF_ENGINES];
endinterface
2。在testbench中实例化env_if connect serial_if with generate,将virtual if与non virtual连接并将virtual if传递给验证env:
module testbench;
....
environment_if env_if(serial_clk);
.....
dut i_dut(...);
genvar eng_idx
generate
for(eng_idx=0; eng_idx<`NUM_OF_ENGINES; eng_idx++) begin
env_if.eng_if[eng_idx].serial_bit = assign i_dut.engine[eng_idx].serial_bit;
end
endgenerate
......
initial begin
env_if.eng_virtual_if = env_if.eng_if[0:`NUM_OF_ENGINES-1];
//now possible to iterate over eng_virtual_if[]
for(int eng_idx=0; eng_idx<`NUM_OF_ENGINES; eng_idx++)
uvm_config_db#(virtual serial_if)::set(null, "uvm_test_top.env", "tx_vif", env_if.env_virtual_if[eng_idx]);
end
endmodule
我正在尝试创建一个接口,它是一个更简单接口的数组。在 VHDL 中,我可以简单地定义两种类型,一个记录和一个记录数组。但是如何在 SystemVerilog 中做到这一点呢?这是我尝试过的:
`define MAX_TC 15
...
interface scorecard_if;
score_if if_score [`MAX_TC];
endinterface
interface score_if;
integer tc;
integer pass;
integer fail;
bit flag_match;
real bandwidth;
endinterface
但是我从 Aldec Active-HDL 得到一个错误:
错误:VCP2571 TestBench/m3_test_load_tb_interfaces.sv : (53, 34): 实例化必须有方括号():if_score.
我也试过了
interface scorecard_if;
score_if [`MAX_TC] if_score;
endinterface
和
interface scorecard_if;
score_if [`MAX_TC];
endinterface
但这两个都导致了 "Unexpected token" 语法错误。
甚至可以这样做吗?如果没有办法做到这一点,我可以想到两种解决方法。首先,我可以将 score_if 的所有单个元素定义为未压缩的数组:
interface score_if;
integer tc [1:`MAX_TC];
integer pass [1:`MAX_TC];
integer fail [1:`MAX_TC];
bit flag_match [1:`MAX_TC];
real bandwidth [1:`MAX_TC];
endinterface
这可以编译,但它很难看,因为我不能再将单个乐谱作为一个整体来引用。
我也可能要实例化一个 score_if 的数组(使用原始代码),但我真的想在一个生成循环中实例化 scorecard_if,这样我就可以实例化一个可变数量的scorecard_if 基于参数的接口。
只是为了对我正在尝试做的事情提供一些解释,score_if 应该是给定测试用例的分数记录,而 scorecard_if 是一个数组所有的测试用例。但是我的测试台有多个独立的刺激发生器、监视器和记分卡来处理 DUT 内部的多个独立模块,其中倍数是一个参数。
第 1 部分:声明接口数组
在接口实例化的末尾添加括号。根据 IEEE Std 1800-2012,所有分层实例的实例化都需要端口列表的括号,即使端口列表为空也是如此。如果接口在声明中没有任何端口并且实例化很简单,一些工具允许删除括号;但这不是标准的一部分。最佳做法是对所有分层实例化使用括号。
解决方案:
score_if if_score [`MAX_TC] <b>()</b> ;
语法引用:
§ 25.3 接口语法 & § A.4.1.2 接口实例化
interface_instantiation ::= // from A.4.1.2
interface_identifier [ parameter_value_assignment ] hierarchical_instance { , hierarchical_instance } ;§ A.4.1.1 模块实例化
hierarchical_instance ::= name_of_instance ( [ list_of_port_connections ] )
第 2 部分:访问该数组的元素
分层引用必须是常量。动态索引无法访问排列的分层实例。它是一个 rule/limitation,至少从 IEEE Std 1364 开始。在 IEEE Std 1800-2012 § 23.6 分层名称 中阅读更多关于它的信息,语法规则是:
hierarchical_identifier ::= [ $root . ] { identifier constant_bit_select . } identifier
您可以使用 generate-for-loop,因为它会在 compile/elaboration 时进行静态展开。限制是你不能使用你的显示消息,我们在循环中累积你的失败计数。您可以使用生成循环将数据复制到本地数组并对其求和,但这违背了您的意图。
接口通常是一组网络,用于连接模块与 class-base test-bench 或共享总线协议。您将其用作嵌套计分卡。 typedef struct
可能更适合您的目的。 struct
是一种数据类型,没有模块和接口那样的层次引用限制。看起来您已经在 previous question 中尝试溃败了。不确定为什么切换到嵌套界面。
看起来您正在尝试创建一个相当复杂的测试环境。如果是这样,我建议先学习 UVM,然后再花大量时间重新发明高级测试平台架构。从 1.1d 开始,因为 1.2 还不是主流。
这也有效: 1.定义一个"container"接口:
interface environment_if (input serial_clk);
serial_if eng_if[`NUM_OF_ENGINES](serial_clk);
virtual serial_if eng_virtual_if[`NUM_OF_ENGINES];
endinterface
2。在testbench中实例化env_if connect serial_if with generate,将virtual if与non virtual连接并将virtual if传递给验证env:
module testbench;
....
environment_if env_if(serial_clk);
.....
dut i_dut(...);
genvar eng_idx
generate
for(eng_idx=0; eng_idx<`NUM_OF_ENGINES; eng_idx++) begin
env_if.eng_if[eng_idx].serial_bit = assign i_dut.engine[eng_idx].serial_bit;
end
endgenerate
......
initial begin
env_if.eng_virtual_if = env_if.eng_if[0:`NUM_OF_ENGINES-1];
//now possible to iterate over eng_virtual_if[]
for(int eng_idx=0; eng_idx<`NUM_OF_ENGINES; eng_idx++)
uvm_config_db#(virtual serial_if)::set(null, "uvm_test_top.env", "tx_vif", env_if.env_virtual_if[eng_idx]);
end
endmodule