1. Loops

这一部分没有什么特别语法,和 C/C++ 语法基本一致,只多了一个 repeat 语法方便了直接设置多次循环。

稍微需要注意的是,在每次执行循环时,内部需要包括时钟边沿检测,如下第 2 行所示

1
2
3
4
initial begin
repeat (5) @(posedge clk);
$finish;
end

2. if-else-if

有两个比较特别的 if,分别是 unique-if 和 priority-if。

对于 unique-if,在没有 else 并且全部 option 都不匹配的情况下,就会报错提示。如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
module tb;
int x = 4;

initial begin
unique if (x == 3)
$display("x is %0d", x);
else if (x == 5)
$display("x is %0d", x);
else
$display("x is neither 3 nor 5");


unique if (x == 3)
$display("1");
else if (x == 5)
$display("2");
end
endmodule

此时报错信息如下

1
2
3
4
5
x is neither 3 nor 5

Warning-[RT-NCMUIF] No condition matches in statement
testbench.sv, 13
No condition matches in 'unique if' statement. 'else' statement is missing

对于 priority_if 而言,我暂时没有明白它的作用,一般当出现多个 option 可以 match 时,只会选择最靠前的 option。

1
2
3
4
5
6
7
8
9
10
module tb;
int x = 4;

initial begin
priority if (x == 4) // equal to direct if
$display("1");
else priority if (x != 5)
$display("2");
end
endmodule

3. Case

Case 里 unique 和 priority 使用也是类似的,有两点稍有不同。第一是 unique case 不仅可以查看是否存在匹配 (No items match for given expression), 而且还可以查看是否存在 overlapping (More than one case item matches)。第二是 priority 的功能更容易理解了,当存在多个 match 时优先匹配第一个。

4. Blocking & Non-Blocking

a. Blocking

和 Verilog 下相同,使用 = 实现阻塞赋值。这种赋值方式下每个变量是依次实现赋值的,但在并行块中仍然是并行的。如下图中的例子

image-20240315210658172

可以看到这里存在两个 block,在每个 block 中存在阻塞赋值的几个语句。为了便于区分,在语句中加入了 delay,来更清晰地进行对比。输入结果如下图所示

image-20240315210711887

可以看到在每个 block 中变量之间的赋值都是依次串行的($display 也是正常执行打印的),但两个 block 之间是并行运行的(存在交叉打印)。

b. Non-blocking

使用 <== 实现非阻塞赋值。此时