SystemVerilog
Enum
typedef enum logic [2:0] {
RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW
} color_t;
color_t my_color = GREEN;
initial $display("The color is %s", my_color.name());
Struct and Union
typedef struct packed {
bit [10:0] expo;
bit sign;
bit [51:0] man;
} FP;
FP zero = 64'b0;
Procedural Block
- always_comb: 用于组合逻辑电路(相当于 Verilog 中对所有输入变量电平敏感的 always,但 always_comb 无需手动列出所有输入变量,系统会自动识别)
- always_ff: 用于触发器及相关的时序逻辑电路(相当于 Verilog 中对某个或某几个信号有效跳变沿敏感、并带有信号储存特性的 always)
- always_latch: 用于锁存器级相关的时序逻辑电路(相当于 Verilog 中对某个或某几个信号电平敏感、并带有信号储存特性的的 always)
always_comb begin
tmp = b * b - 4 * a * c;
no_root = (tmp < 0);
end
always_ff @(posedge clk)
count <= count + 1;
always_latch
if (en) q <= d;
Interface
interface interfaceName;
logic a;
logic b;
modport in (input a, output b);
modport out (input b, output a);
endinterface
module top;
interfaceName i ();
u_a m1 (.i1(i));
u_b m2 (.i2(i));
endmodule
module u_a (interfaceName.in i1);
endmodule
module u_b (interfaceName.out i2);
endmodule
Testing
module top;
integer num_packets = $random;
reg A, B, C, clk, reset_n;
wire D;
register_logic dut(A, B, C, clk, reset_n, D);
// generate clock
// ...
initial begin
run();
end
task run();
reset_n = 1;
#20 reset_n = 0;
@(posedge clk) reset_n <= #1 1;
repeat (num_packets) begin
A = $random; B = $random; C = $random;
@(posedge clk);
$display(A, B, C, D);
end
$finish;
endtask
endmodule
class Packet;
string name;
rand bit[3:0] sa, da;
rand reg A, B, C;
function void display(result);
$display(A, B, C, result);
endfunction
endclass: Packet
// inheritance
class Packet_da_3 extends Packet;
constraint da_3 {
da == 3;
}
function void display(result);
super.display(result);
$display(sa, da);
endfunction
endclass: Packet_da_3
class Generator;
Packet pkt;
Channel out_chan;
int num_packets;
function void gen();
pkt = new();
pkt.randomize();
out_chan.put(pkt);
endfunction
task run();
while (num_packets-- != 0)
gen();
endtask
endclass
class Driver;
Channel in_chan;
task send();
in_chan.get(pkt);
top.A = pkt.A;
top.B = pkt.B;
top.C = pkt.C;
@(posedge top.clk);
endtask
task run();
forever send();
endtask
endclass
module top;
initial begin
build();
run();
end
task build();
Config cfg = new();
Channel chan = new();
Generator gen = new();
Driver drv = new();
gen.out_chan = chan;
drv.in_chan = chan;
cfg.randomize() with { num_packets > 1500; }
gen.num_packets = cfg.num_packets;
endtask
task run();
fork
gen.run();
drv.run();
join
$finish;
endtask
endmodule