Commentary: Changes update

This commit is contained in:
Wilson Snyder 2026-06-28 16:15:54 -04:00
parent 6006f91e2e
commit 276f2f344d
15 changed files with 161 additions and 92 deletions

32
Changes
View File

@ -32,7 +32,7 @@ Verilator 5.049 devel
* Improve `--coverage-fsm` (#7490) (#7529) (#7561) (#7573) (#7619). [Yogish Sekhar]
* Change `+verilator+seed` to default to 1, and 0 to randomly select (#7325) (#7516). [Miguel]
* Change JSON to include parameter constant mnemonics for FSM Coverage (#7531). [Yogish Sekhar]
* Support assert property 'default disable iff` (#4848) (#7723). [Artur Bieniek, Antmicro Ltd.]
* Support assert property `default disable iff` (#4848) (#7723). [Artur Bieniek, Antmicro Ltd.]
* Support printing enum names for %p and %s (#5523) (#7338 repair) (#7521) (#7527). [Nick Brereton]
* Support weak `until` / `until_with` property operators (#7290) (#7548) (#7685). [Yilou Wang]
* Support `s_eventually` (#7291) (#7508). [Bartłomiej Chmiel, Antmicro Ltd.]
@ -67,6 +67,7 @@ Verilator 5.049 devel
* Support property case (#7682) (#7721). [Artur Bieniek, Antmicro Ltd.]
* Support `s_until` and `s_until_with`(#7722). [Artur Bieniek, Antmicro Ltd.]
* Support covergroup runtime model Phase A1 (#7728). [Matthew Ballance]
* Support hierarchical reference cross members (#7749) (#7820). [Matthew Ballance]
* Support reduction XOR/AND operations in constraints (#7753). [Kornel Uriasz, Antmicro Ltd.]
* Support NBAs in initial blocks (#7754). [Igor Zaworski, Antmicro Ltd.]
* Support assertion control system tasks in classes and interfaces (#7761). [Yilou Wang]
@ -75,6 +76,11 @@ Verilator 5.049 devel
* Support $assertcontrol control_type from lock to kill (#7788). [Yilou Wang]
* Support unbounded always [m:$] and strong s_always liveness (#7798). [Yilou Wang]
* Support method calls on a sub-interface via a virtual interface (#7800). [Yilou Wang]
* Support global $assertcontrol (#7807). [Artur Bieniek, Antmicro Ltd.]
* Support VPI access to unpacked struct members (#7823). [Nick Brereton]
* Support variable-length intersect in SVA sequences (#7835). [Yilou Wang]
* Support dynamic loading of VPI extensions (#7727). [Matthew Ballance]
* Optimize DFG cycle breaking to do less work (#7210). [Geza Lore, Testorrent USA, Inc.]
* Optimize emitting to_string() for compiler speedup (#7468). [Jakub Michalski, Antmicro Ltd.]
* Optimize additional DFG peephole cases (#7553). [Varun Koyyalagunta, Testorrent USA, Inc.]
* Optimize forced signal handling (#7554 partial) (#7572) (#7594) (#7596). [Krzysztof Bieganski, Artur Bieniek, Antmicro Ltd.]
@ -97,7 +103,12 @@ Verilator 5.049 devel
* Optimize input combinational logic by change detection (#7784). [Geza Lore, Testorrent USA, Inc.]
* Optimize decoder case statements into lookup tables (#7795). [Geza Lore, Testorrent USA, Inc.]
* Optimize wide decoder case statements into decoder expressions (#7804). [Geza Lore, Testorrent USA, Inc.]
* Optimize DFG cycle breaking to do less work (#7210). [Geza Lore, Testorrent USA, Inc.]
* Optimize statically known oversize shifts (#7806). [Geza Lore, Testorrent USA, Inc.]
* Optimize generated function inlining (#7811). [Geza Lore, Testorrent USA, Inc.]
* Optimize bit-scan loops into most-set-bit or $countones (#7822). [Thomas Santerre]
* Optimize additional expression patterns (#7824). [Geza Lore, Testorrent USA, Inc.]
* Optimize module inlining heuristic (#7837). [Geza Lore, Testorrent USA, Inc.]
* Fix `$bits` on unpacked structs (#4521) (#7796). [Nick Brereton]
* Fix TSP variable ordering for mtasks (#5342) (#7610). [Muzaffer Kal]
* Fix inlining static initializer in V3Gate (#5381) (#7503). [Andrew Nolte] [Geza Lore, Testorrent USA, Inc.]
* Fix timed nested fork block with disable (#6720) (#7743). [Marco Bartoli]
@ -147,6 +158,7 @@ Verilator 5.049 devel
* Fix reference counting for modport task references (#7628). [Nick Brereton]
* Fix internal error when handling typedefs containing parameterized class type members (#7635) (#7661). [em2machine]
* Fix forceable signal with a procedural continuous assign (#7638) (#7639). [Zubin Jain]
* Fix scheduling of virtual interface method writes (#7641). [Artur Bieniek, Antmicro Ltd.]
* Fix implicit conversions of VlWide (#7642). [Geza Lore, Testorrent USA, Inc.]
* Fix CASEINCOMPLETE to not warn on `unique0 case` (#7647).
* Fix hierarchical coverage counts for duplicate no-inline module instances (#7649). [Yogish Sekhar]
@ -173,17 +185,27 @@ Verilator 5.049 devel
* Fix s_eventually in parameterized interfaces (#7741). [Nick Brereton]
* Fix dpi export pointers (#7742) (#7751). [Yilin Li]
* Fix force on unpacked bit select (#7744) (#7745). [Nikolai Kumar]
* Fix `$` as unsupported coverpoint-bin range bounds (#7750) (#7825). [Matthew Ballance]
* Fix FSM detect unchecked casts and variable redeclaration (#7758). [Adam Kostrzewski, Antmicro Ltd.]
* Fix no-scope internal error on virtual interface method calls (#7759). [Yilou Wang]
* Fix 'case (_) inside' with x wildcards (#7766). [Geza Lore, Testorrent USA, Inc.]
* Fix `case (_) inside` with x wildcards (#7766). [Geza Lore, Testorrent USA, Inc.]
* Fix not failing assertion when RHS of a range window rejects once (#7773). [Artur Bieniek, Antmicro Ltd.]
* Fix $fflush and autoflush with --threads (#7782).
* Fix out-of-bounds read value for 2-state types (#7785). [Jakub Michalski]
* Fix `cover property` of an implication counting vacuous matches (#7789). [Yilou Wang]
* Fix randomization of dynamic arrays of objects (#7790). [Ryszard Rozak, Antmicro Ltd.]
* Fix `$bits` on unpacked structs (#4521) (#7796). [Nick Brereton]
* Fix randomize() with skipping derived pre/post_randomize (#7799). [Yilou Wang]
* Fix skewed dist operator for arrays (#7802). [Jakub Wasilewski, Antmicro Ltd.]
* Fix assertion when loop unrolling failed (#7810). [Geza Lore, Testorrent USA, Inc.]
* Fix CASEINCOMPLETE for all uncovered enum items (#7815) (#7817). [Saksham]
* Fix split optimization nested-class crash (#7826). [Igor Zaworski, Antmicro Ltd.]
* Fix class/var named identically to an enclosing-scope type (#7827) (#7828). [Tom Jackson]
* Fix performance on large package-scoped structs (#7830). [Wolfgang Mayerwieser]
* Fix unclocked concurrent assertion misreported as unsupported (#7831). [Yilou Wang]
* Fix insertion of expression coverage statement (#7832). [Ryszard Rozak, Antmicro Ltd.]
* Fix lifetime of expression coverage variable (#7834). [Ryszard Rozak, Antmicro Ltd.]
* Fix disable iff ignored when its condition is held continuously true (#7841). [Yilou Wang]
* Fix constant pool cache after dead scope removal (#7845). [Nick Brereton]
Verilator 5.048 2026-04-26
@ -520,7 +542,7 @@ Verilator 5.044 2026-01-01
* Support clocking output delay `1step` (#6681). [Ondrej Ille]
* Support parsing of dotted `bins_expression` (#6683). [Pawel Kojma, Antmicro Ltd.]
* Support constant expression cycle delays in sequences (#6691). [Ryszard Rozak, Antmicro Ltd.]
* Support general global constraints (#6709) (#6711). [Yilou Wang]
* Support general global constraints (#6709) (#6711) (#7833) (#7838). [Yilou Wang]
* Support complex std::randomize patterns (#6736) (#6737). [Yilou Wang]
* Support `rand_mode` in global constraint gathering (#6740) (#6752). [Yilou Wang]
* Support reduction or in constraints (#6840). [Pawel Kojma, Antmicro Ltd.]

View File

@ -684,6 +684,7 @@ countones
cout
covergroup
covergroups
coverpoint
coverpoints
cpp
cppstyle
@ -1207,6 +1208,7 @@ typename
uint
un
unbased
unclocked
uncomment
undef
undefineall

View File

@ -36,7 +36,8 @@ interface AssertCtlIface;
$assertcontrol(3, 2, 1);
endfunction
function void fail_check();
assert (0) `stop; else fails++;
assert (0) `stop;
else fails++;
endfunction
function void run_checks();
assert_off();
@ -69,12 +70,13 @@ module t;
$assertcontrol(3, 2, 1);
endfunction
function void fail_check();
assert (0) `stop; else class_fails++;
assert (0) `stop;
else class_fails++;
endfunction
endclass
AssertCtlClass assert_ctl_class;
AssertCtlIface assert_ctl_iface();
AssertCtlIface assert_ctl_iface ();
virtual AssertCtlIface v_assert_ctl_iface = assert_ctl_iface;
always #5 clk = !clk;
@ -84,17 +86,17 @@ module t;
assert property (@(posedge clk) 1'b0 |-> ##1 1'b1) begin
vacuous_passes++;
end else
`stop;
end
else `stop;
assert property (@(posedge clk) 1'b1 |-> ##1 1'b1) begin
nonvacuous_passes++;
end else
`stop;
end
else `stop;
assert property (@(posedge clk) 1'b1 |-> ##1 1'b0) begin
end else
concurrent_fails++;
end
else concurrent_fails++;
task automatic tick_and_check(input int exp_vacuous, input int exp_nonvacuous,
input int exp_concurrent_fails);
@ -110,62 +112,73 @@ module t;
$assertcontrol(4, 16, 1);
$assertcontrol(5, 16, 1);
$assertcontrol(3*`IMPURE_ONE, 2*`IMPURE_ONE);
$assertcontrol(3 * `IMPURE_ONE, 2 * `IMPURE_ONE);
$assertcontrol(3, 255, 7);
$assertcontrol(6, 255, 7);
$assertcontrol(8, 255, 7);
assert (1) imm_passes++; else `stop;
assert (1) imm_passes++;
else `stop;
`checkd(imm_passes, 1);
$assertcontrol(1, 2, 1);
$assertcontrol(4, 2, 1);
assert (1) imm_passes++; else `stop;
assert (1) imm_passes++;
else `stop;
`checkd(imm_passes, 2);
$assertcontrol(2, 2, 1);
$assertcontrol(4, 2, 1);
assert (1) imm_passes++; else `stop;
assert (1) imm_passes++;
else `stop;
`checkd(imm_passes, 2);
$assertcontrol(3, 2, 1);
$assertcontrol(1, 2, 1);
$assertcontrol(7, 2, 1);
assert (1) imm_passes++; else `stop;
assert (1) imm_passes++;
else `stop;
`checkd(imm_passes, 3);
$assertcontrol(2, 2, 1);
$assertcontrol(7, 2, 1);
assert (1) imm_passes++; else `stop;
assert (1) imm_passes++;
else `stop;
`checkd(imm_passes, 3);
$assertcontrol(10, 2, 1);
assert (1) imm_passes++; else `stop;
assert (1) imm_passes++;
else `stop;
`checkd(imm_passes, 4);
$assertcontrol(11, 2, 1);
assert (1) imm_passes++; else `stop;
assert (1) imm_passes++;
else `stop;
`checkd(imm_passes, 5);
$assertcontrol(6, 2, 1);
assert (0) `stop; else imm_fails++;
assert (0) `stop;
else imm_fails++;
`checkd(imm_fails, 1);
$assertcontrol(1, 2, 1);
$assertcontrol(9, 2, 1);
assert (0) `stop; else imm_fails++;
assert (0) `stop;
else imm_fails++;
`checkd(imm_fails, 2);
$assertcontrol(2, 2, 1);
$assertcontrol(9, 2, 1);
assert (0) `stop; else imm_fails++;
assert (0) `stop;
else imm_fails++;
`checkd(imm_fails, 2);
$assertcontrol(8, 2, 1);
assert (0) `stop; else imm_fails++;
assert (0) `stop;
else imm_fails++;
`checkd(imm_fails, 3);
assert_ctl_class.assert_off();

View File

@ -14,7 +14,7 @@
module t;
initial begin
$assertcontrol(100*`IMPURE_ONE);
$assertcontrol(100 * `IMPURE_ONE);
$finish;
end
endmodule

View File

@ -16,10 +16,8 @@ module t (
integer action_hits = 0;
integer cyc = 0;
assert property (@(posedge clk) ##1 1'b1)
action_hits++;
else
action_hits--;
assert property (@(posedge clk) ##1 1'b1) action_hits++;
else action_hits--;
always @(posedge clk) begin
cyc++;

View File

@ -33,13 +33,12 @@ module t;
task automatic run_pass();
assert (1) begin
pass_count++;
end else
`stop;
end
else `stop;
endtask
task automatic run_fail();
assert (0)
`stop;
assert (0) `stop;
else begin
fail_count++;
end

View File

@ -21,7 +21,7 @@ class C;
endclass
class D;
my_t a; // second use of the type name after the shadowing variable...
my_t a; // second use of the type name after the shadowing variable...
my_t my_t; // ... is also legal; both resolve to the $unit typedef
endclass

View File

@ -13,12 +13,15 @@
// foreach (a[i]) if (gate) a[i] dist {...}
class ClsIf;
rand bit [3:0] a [4];
rand bit [3:0] a[4];
bit gate;
constraint c {
foreach (a[i]) {
if (gate == 1'b1) {
a[i] dist { 4'd0 := 3, [4'd1:4'd4] := 1 };
a[i] dist {
4'd0 := 3,
[4'd1 : 4'd4] := 1
};
}
}
}
@ -26,22 +29,30 @@ endclass
// foreach (a[i]) gate -> a[i] dist {...}
class ClsImpl;
rand bit [3:0] a [4];
rand bit [3:0] a[4];
bit gate;
constraint c {
foreach (a[i]) {
gate -> (a[i] dist { 4'd0 := 3, [4'd1:4'd4] := 1 });
gate ->
(a[i] dist {
4'd0 := 3,
[4'd1 : 4'd4] := 1
});
}
}
endclass
// foreach (a[i]) gateA -> (gateB -> a[i] dist {...}) -- doubly-nested implication
class ClsImplChained;
rand bit [3:0] a [4];
rand bit [3:0] a[4];
bit gateA, gateB;
constraint c {
foreach (a[i]) {
gateA -> (gateB -> (a[i] dist { 4'd0 := 3, [4'd1:4'd4] := 1 }));
gateA ->
(gateB -> (a[i] dist {
4'd0 := 3,
[4'd1 : 4'd4] := 1
}));
}
}
endclass
@ -59,8 +70,8 @@ module t;
`checkd(obj.randomize(), 1)
foreach (obj.a[i]) begin
if (obj.a[i] > 4) begin
$write("%%Error: %s:%0d: if: value out of dist range: %0d\n",
`__FILE__, `__LINE__, obj.a[i]);
$write("%%Error: %s:%0d: if: value out of dist range: %0d\n", `__FILE__, `__LINE__,
obj.a[i]);
$stop;
end
if (obj.a[i] == 0) seen_zero++;
@ -68,8 +79,9 @@ module t;
end
end
if (seen_zero == 0 || seen_nonzero == 0) begin
$write("%%Error: %s:%0d: dist inside foreach+if: not all buckets hit (zero=%0d nonzero=%0d)\n",
`__FILE__, `__LINE__, seen_zero, seen_nonzero);
$write(
"%%Error: %s:%0d: dist inside foreach+if: not all buckets hit (zero=%0d nonzero=%0d)\n",
`__FILE__, `__LINE__, seen_zero, seen_nonzero);
$stop;
end
end
@ -85,8 +97,8 @@ module t;
`checkd(obj.randomize(), 1)
foreach (obj.a[i]) begin
if (obj.a[i] > 4) begin
$write("%%Error: %s:%0d: ->: value out of dist range: %0d\n",
`__FILE__, `__LINE__, obj.a[i]);
$write("%%Error: %s:%0d: ->: value out of dist range: %0d\n", `__FILE__, `__LINE__,
obj.a[i]);
$stop;
end
if (obj.a[i] == 0) seen_zero++;
@ -94,8 +106,9 @@ module t;
end
end
if (seen_zero == 0 || seen_nonzero == 0) begin
$write("%%Error: %s:%0d: dist inside foreach+->: not all buckets hit (zero=%0d nonzero=%0d)\n",
`__FILE__, `__LINE__, seen_zero, seen_nonzero);
$write(
"%%Error: %s:%0d: dist inside foreach+->: not all buckets hit (zero=%0d nonzero=%0d)\n",
`__FILE__, `__LINE__, seen_zero, seen_nonzero);
$stop;
end
end
@ -112,8 +125,8 @@ module t;
`checkd(obj.randomize(), 1)
foreach (obj.a[i]) begin
if (obj.a[i] > 4) begin
$write("%%Error: %s:%0d: ->->: value out of dist range: %0d\n",
`__FILE__, `__LINE__, obj.a[i]);
$write("%%Error: %s:%0d: ->->: value out of dist range: %0d\n", `__FILE__, `__LINE__,
obj.a[i]);
$stop;
end
if (obj.a[i] == 0) seen_zero++;
@ -121,8 +134,9 @@ module t;
end
end
if (seen_zero == 0 || seen_nonzero == 0) begin
$write("%%Error: %s:%0d: dist inside foreach+->->: not all buckets hit (zero=%0d nonzero=%0d)\n",
`__FILE__, `__LINE__, seen_zero, seen_nonzero);
$write(
"%%Error: %s:%0d: dist inside foreach+->->: not all buckets hit (zero=%0d nonzero=%0d)\n",
`__FILE__, `__LINE__, seen_zero, seen_nonzero);
$stop;
end
end

View File

@ -14,13 +14,20 @@
// Scalar: uniform over [0:9] (10% each)
class DistScalarRange;
rand bit [3:0] x;
constraint c { x dist {[4'd0:4'd9] := 1}; }
constraint c {
x dist {
[4'd0 : 4'd9] := 1
};
}
endclass
// Array foreach: uniform over [0:4] (20% each per element)
class DistForeachUniform;
rand bit [2:0] a[5];
constraint c { foreach (a[i]) a[i] dist {[3'd0:3'd4] := 1}; }
constraint c {
foreach (a[i])
a[i] dist {[3'd0 : 3'd4] := 1};
}
endclass
// Array foreach: mixed single + range
@ -28,32 +35,50 @@ endclass
// 0: 5/14 ~= 35.7%, 1..9: 1/14 ~= 7.1% each
class DistForeachMixed;
rand bit [3:0] a[5];
constraint c { foreach (a[i]) a[i] dist {4'd0 := 5, [4'd1:4'd9] := 1}; }
constraint c {
foreach (a[i])
a[i] dist {
4'd0 := 5,
[4'd1 : 4'd9] := 1
};
}
endclass
// Scalar signed int: uniform over negative range [-9:0] (10% each)
class DistNegRange;
rand int x;
constraint c { x dist {[-9:0] := 1}; }
constraint c {
x dist {
[-9 : 0] := 1
};
}
endclass
// Non-constant unsigned range bounds: uniform over [lo_val:hi_val] = [2:7] (6 values)
class DistVarRangeUnsigned;
rand bit [3:0] x;
bit [3:0] lo_val = 4'd2, hi_val = 4'd7;
constraint c { x dist {[lo_val:hi_val] := 1}; }
constraint c {
x dist {
[lo_val : hi_val] := 1
};
}
endclass
// Mixed const/non-const bounds: lo is constant, hi is a variable [1:hi_val] = [1:7]
class DistMixedBounds;
rand bit [3:0] x;
bit [3:0] hi_val = 4'd7;
constraint c { x dist {[4'd1:hi_val] := 1}; }
constraint c {
x dist {
[4'd1 : hi_val] := 1
};
}
endclass
module t;
parameter int N = 2000; // randomize() calls per test
parameter int TOL_PCT = 30; // +-% tolerance on expected counts
parameter int N = 2000; // randomize() calls per test
parameter int TOL_PCT = 30; // +-% tolerance on expected counts
initial begin
@ -71,8 +96,7 @@ module t;
end
cnt[obj.x]++;
end
foreach (cnt[v])
`check_tol(cnt[v], N/10)
foreach (cnt[v]) `check_tol(cnt[v], N / 10)
end
// --- T2: array foreach uniform [0:4], 5 elements * N calls ---
@ -91,8 +115,7 @@ module t;
cnt[obj.a[i]]++;
end
end
foreach (cnt[v])
`check_tol(cnt[v], N)
foreach (cnt[v]) `check_tol(cnt[v], N)
end
// --- T3: array foreach mixed {0:=5, [1:9]:=1}, 5 elements * N calls ---
@ -113,9 +136,8 @@ module t;
cnt[obj.a[i]]++;
end
end
`check_tol(cnt[0], N*5*5/14)
for (int v = 1; v <= 9; v++)
`check_tol(cnt[v], N*5*1/14)
`check_tol(cnt[0], N * 5 * 5 / 14)
for (int v = 1; v <= 9; v++) `check_tol(cnt[v], N * 5 * 1 / 14)
end
// --- T4: signed int, uniform over negative range [-9:0] ---
@ -131,10 +153,9 @@ module t;
$write("%%Error: x=%0d outside valid range [-9:0]\n", obj.x);
`stop;
end
cnt[obj.x + 9]++;
cnt[obj.x+9]++;
end
foreach (cnt[v])
`check_tol(cnt[v], N/10)
foreach (cnt[v]) `check_tol(cnt[v], N / 10)
end
// --- T5: non-constant unsigned range bounds [lo_val:hi_val] = [2:7] ---
@ -151,8 +172,7 @@ module t;
end
cnt[obj.x]++;
end
for (int v = 2; v <= 7; v++)
`check_tol(cnt[v], N/6)
for (int v = 2; v <= 7; v++) `check_tol(cnt[v], N / 6)
end
// --- T6: mixed const/non-const bounds [4'd1:hi_val] = [1:7] ---
@ -169,8 +189,7 @@ module t;
end
cnt[obj.x]++;
end
for (int v = 1; v <= 7; v++)
`check_tol(cnt[v], N/7)
for (int v = 1; v <= 7; v++) `check_tol(cnt[v], N / 7)
end
$write("*-* All Finished *-*\n");

View File

@ -5,9 +5,7 @@
// SPDX-License-Identifier: CC0-1.0
package pkg;
typedef struct {
logic [7:0] value;
} field_t;
typedef struct {logic [7:0] value;} field_t;
typedef struct {
field_t f0;
field_t f1;
@ -19,11 +17,9 @@ package pkg;
} hwif_t;
endpackage
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
module t (
input clk
);
import pkg::*;

View File

@ -12,8 +12,8 @@
// (requires --public-flat-rw).
module t;
reg clk /*verilator public_flat_rw*/;
reg [31:0] count /*verilator public_flat_rw*/;
reg clk /*verilator public_flat_rw*/;
reg [31:0] count /*verilator public_flat_rw*/;
initial begin
clk = 0;

View File

@ -62,7 +62,7 @@ module t;
// V3Premit extracts this matching wide constant after V3Dead recached the
// const-pool contents created by V3Case.
logic [31:0] static_word;
assign static_word = TABLE[{idx, 5'b0} +: 32];
assign static_word = TABLE[{idx, 5'b0}+:32];
always @(posedge clk) begin
`checkh(case_word, static_word);

View File

@ -5,7 +5,7 @@
// SPDX-License-Identifier: CC0-1.0
module t (
input wire clk
input wire clk
);
integer cyc = 0;

View File

@ -5,7 +5,7 @@
// SPDX-License-Identifier: CC0-1.0
module t (
input wire clk
input wire clk
);
integer cyc = 0;

View File

@ -20,7 +20,10 @@ package helper_pkg;
endfunction
endpackage
interface intf(output logic a, output logic b);
interface intf (
output logic a,
output logic b
);
msg m;
event e;
@ -34,7 +37,7 @@ interface intf(output logic a, output logic b);
// verilator no_inline_task
m.set_context("go_helper");
helper_pkg::bump();
-> e;
->e;
a <= 1;
endtask
endinterface
@ -56,7 +59,10 @@ module t;
wire b;
virtual intf vif;
intf i(a, b);
intf i (
a,
b
);
initial begin
driver d;