SystemVerilog 并发断言序列动态长度
SystemVerilog Concurrent Assertion Sequence Dynamic Length
我有一个长度为 x 的数组。给定测试平台的信号输出将是数组中的每个值,顺序为 0:x-1.
特别是在我的问题中,数组是滤波器系数,测试平台是脉冲响应。
测试需要自检,这将需要一个具有动态长度的序列,因为系数会随着测试的不同而变化。
我想要的序列应该是这样的:
always @(posedge clk) begin
assert_sequence : assert property (
(data_out == array_1[0])
|=> (data_out == array_1[1])
|=> (data_out == array_1[2])
|=> (data_out == array_1[3])
|=> (data_out == array_1[4])
|=> (data_out == 0) )
$info("Seen the sequence");
else
$error("Sequence was incorrect");
end
这可以动态地做吗?我试过一个 genvar for 循环,但它会抛出错误。我已经搜索了论坛,但找不到任何符合我要求的东西。
可能像这样的东西可以给出正确的答案?
always @(posedge clk) begin
assert_sequence : assert property (
(data_out == array1[0][0])
for(genvar i = 1; i < 5, i++) begin
|=> (data_out == array1[i])
end
|=> (data_out == 0) )
$info("Seen the sequence");
else
$error("Sequence was incorrect");
end
评论非常有用,并且记录了我为解决此问题所采取的方向。刚刚重新审视了这个问题并提出了这个不优雅的解决方案。
for(genvar i = 1; i < 5; i++) begin
always @(posedge clk) begin
assert_sequence : assert property (
(data_out == array1[0])
|-> ##i (data_out == array1[i])
|-> ##(5-i) (data_out == 0) //This line prevents error
//as my coefficients are symmetric
)
$info("Impulse response Coefficient %0d seen", i);
else
$error("Impulse response Coefficient %0d not seen", i);
end
end
这段代码创建了多个断言,并描述了当我看到第一个系数时,我希望在 i 个时钟周期内看到 (i+1) 系数,并且由于我的对称性问题,在 (5-i)时钟周期我会看到一个 0.
如前所述,SVA 可能不是这里的自然选择。不过,确实是一个有趣的问题所以想了一下:
您尝试过使用递归属性吗?大致如下:
property check_sequence(coefficients);
(data_out == coefficients[0]) ##0
((coefficients.size() == 1) or
(##1 check_sequence(coefficients[1:coefficient.size()]));
endproperty
assert_label: check_sequence(array_1);
仍需要触发器 - 原始问题中未指定。
它是否是最有效或可读性最强的解决方案是另一回事。
我有一个长度为 x 的数组。给定测试平台的信号输出将是数组中的每个值,顺序为 0:x-1.
特别是在我的问题中,数组是滤波器系数,测试平台是脉冲响应。 测试需要自检,这将需要一个具有动态长度的序列,因为系数会随着测试的不同而变化。
我想要的序列应该是这样的:
always @(posedge clk) begin
assert_sequence : assert property (
(data_out == array_1[0])
|=> (data_out == array_1[1])
|=> (data_out == array_1[2])
|=> (data_out == array_1[3])
|=> (data_out == array_1[4])
|=> (data_out == 0) )
$info("Seen the sequence");
else
$error("Sequence was incorrect");
end
这可以动态地做吗?我试过一个 genvar for 循环,但它会抛出错误。我已经搜索了论坛,但找不到任何符合我要求的东西。
可能像这样的东西可以给出正确的答案?
always @(posedge clk) begin
assert_sequence : assert property (
(data_out == array1[0][0])
for(genvar i = 1; i < 5, i++) begin
|=> (data_out == array1[i])
end
|=> (data_out == 0) )
$info("Seen the sequence");
else
$error("Sequence was incorrect");
end
评论非常有用,并且记录了我为解决此问题所采取的方向。刚刚重新审视了这个问题并提出了这个不优雅的解决方案。
for(genvar i = 1; i < 5; i++) begin
always @(posedge clk) begin
assert_sequence : assert property (
(data_out == array1[0])
|-> ##i (data_out == array1[i])
|-> ##(5-i) (data_out == 0) //This line prevents error
//as my coefficients are symmetric
)
$info("Impulse response Coefficient %0d seen", i);
else
$error("Impulse response Coefficient %0d not seen", i);
end
end
这段代码创建了多个断言,并描述了当我看到第一个系数时,我希望在 i 个时钟周期内看到 (i+1) 系数,并且由于我的对称性问题,在 (5-i)时钟周期我会看到一个 0.
如前所述,SVA 可能不是这里的自然选择。不过,确实是一个有趣的问题所以想了一下:
您尝试过使用递归属性吗?大致如下:
property check_sequence(coefficients);
(data_out == coefficients[0]) ##0
((coefficients.size() == 1) or
(##1 check_sequence(coefficients[1:coefficient.size()]));
endproperty
assert_label: check_sequence(array_1);
仍需要触发器 - 原始问题中未指定。
它是否是最有效或可读性最强的解决方案是另一回事。