From 3249fd8cc0aa3c2bc1141f2663b015627dac07a1 Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Sun, 1 Mar 2026 14:56:21 +0000 Subject: [PATCH 1/8] Internals: Mark Premit temporaries funcLocal, noReset (#7160) --- src/V3Premit.cpp | 2 ++ test_regress/t/t_json_only_debugcheck.out | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp index 6aaf86c4f..b64995044 100644 --- a/src/V3Premit.cpp +++ b/src/V3Premit.cpp @@ -91,6 +91,8 @@ class PremitVisitor final : public VNVisitor { // Keep as local temporary. const std::string name = "__Vtemp_" + std::to_string(++m_tmpVarCnt); varp = new AstVar{flp, VVarType::STMTTEMP, name, nodep->dtypep()}; + varp->funcLocal(true); + varp->noReset(true); m_cfuncp->addVarsp(varp); ++m_temporaryVarsCreated; diff --git a/test_regress/t/t_json_only_debugcheck.out b/test_regress/t/t_json_only_debugcheck.out index 580b84469..3bb6aa5b7 100644 --- a/test_regress/t/t_json_only_debugcheck.out +++ b/test_regress/t/t_json_only_debugcheck.out @@ -49,7 +49,7 @@ ]}, {"type":"CFUNC","name":"_eval_initial__TOP","addr":"(QB)","loc":"d,11:8,11:9","slow":true,"scopep":"(Z)","argsp": [], "varsp": [ - {"type":"VAR","name":"__Vtemp_1","addr":"(RB)","loc":"d,49:120,49:121","dtypep":"(SB)","origName":"__Vtemp_1","verilogName":"__Vtemp_1","direction":"NONE","lifetime":"NONE","varType":"STMTTEMP","dtypeName":"string","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} + {"type":"VAR","name":"__Vtemp_1","addr":"(RB)","loc":"d,49:120,49:121","dtypep":"(SB)","origName":"__Vtemp_1","verilogName":"__Vtemp_1","direction":"NONE","noReset":true,"isFuncLocal":true,"lifetime":"NONE","varType":"STMTTEMP","dtypeName":"string","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ], "stmtsp": [ {"type":"ASSIGN","name":"","addr":"(TB)","loc":"d,32:9,32:10","dtypep":"(UB)", @@ -868,9 +868,9 @@ "lhsp": [ {"type":"VARREF","name":"__Vdly__t.e","addr":"(XN)","loc":"d,24:9,24:10","dtypep":"(M)","access":"WR","varp":"(UN)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"} ],"timingControlp": []}, - {"type":"VAR","name":"__Vtemp_1","addr":"(YN)","loc":"d,70:123,70:124","dtypep":"(SB)","origName":"__Vtemp_1","verilogName":"__Vtemp_1","direction":"NONE","lifetime":"NONE","varType":"STMTTEMP","dtypeName":"string","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"__Vtemp_2","addr":"(ZN)","loc":"d,80:123,80:124","dtypep":"(SB)","origName":"__Vtemp_2","verilogName":"__Vtemp_2","direction":"NONE","lifetime":"NONE","varType":"STMTTEMP","dtypeName":"string","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"__Vtemp_3","addr":"(AO)","loc":"d,90:123,90:124","dtypep":"(SB)","origName":"__Vtemp_3","verilogName":"__Vtemp_3","direction":"NONE","lifetime":"NONE","varType":"STMTTEMP","dtypeName":"string","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} + {"type":"VAR","name":"__Vtemp_1","addr":"(YN)","loc":"d,70:123,70:124","dtypep":"(SB)","origName":"__Vtemp_1","verilogName":"__Vtemp_1","direction":"NONE","noReset":true,"isFuncLocal":true,"lifetime":"NONE","varType":"STMTTEMP","dtypeName":"string","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"__Vtemp_2","addr":"(ZN)","loc":"d,80:123,80:124","dtypep":"(SB)","origName":"__Vtemp_2","verilogName":"__Vtemp_2","direction":"NONE","noReset":true,"isFuncLocal":true,"lifetime":"NONE","varType":"STMTTEMP","dtypeName":"string","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"__Vtemp_3","addr":"(AO)","loc":"d,90:123,90:124","dtypep":"(SB)","origName":"__Vtemp_3","verilogName":"__Vtemp_3","direction":"NONE","noReset":true,"isFuncLocal":true,"lifetime":"NONE","varType":"STMTTEMP","dtypeName":"string","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ], "stmtsp": [ {"type":"ASSIGN","name":"","addr":"(BO)","loc":"d,23:17,23:20","dtypep":"(S)", From 6c48b3282ec6649b6920681a0a7c505e8797ad79 Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Sun, 1 Mar 2026 15:04:49 +0000 Subject: [PATCH 2/8] Enable V3LiftExpr with code coverage (#7164) --- src/Verilator.cpp | 10 +- test_regress/t/t_cover_line.out | 26 +- test_regress/t/t_cover_line_cc.info.out | 22 +- test_regress/t/t_cover_line_trace.out | 1109 +++++++++++------------ test_regress/t/t_cover_line_trace.py | 1 - 5 files changed, 542 insertions(+), 626 deletions(-) diff --git a/src/Verilator.cpp b/src/Verilator.cpp index 8d4ef283d..f30e13820 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -285,13 +285,9 @@ static void process() { } if (!v3Global.opt.serializeOnly()) { - // Lift expressions out of statements. Currently disabled for line and - // expression coverage, as otherwise later V3Split would further split - // combinational always blocks and alter counts (that needs to be fixed in V3Split) - if (v3Global.opt.fLiftExpr() // - && !v3Global.opt.coverageLine() && !v3Global.opt.coverageExpr()) { - V3LiftExpr::liftExprAll(v3Global.rootp()); - } + // Lift expressions out of statements. + if (v3Global.opt.fLiftExpr()) V3LiftExpr::liftExprAll(v3Global.rootp()); + // Move assignments from X into MODULE temps. // (Before flattening, so each new X variable is shared between all scopes of that // module.) diff --git a/test_regress/t/t_cover_line.out b/test_regress/t/t_cover_line.out index e04e40fbc..77bcb7402 100644 --- a/test_regress/t/t_cover_line.out +++ b/test_regress/t/t_cover_line.out @@ -449,12 +449,12 @@ logic unsigned [15:0] b; } pstruct; - 000021 function logic func_side_effect; -+000021 point: type=line comment=block hier=top.t.cond1 - 000021 $display("SIDE EFFECT"); -+000021 point: type=line comment=block hier=top.t.cond1 - 000021 return 1; -+000021 point: type=line comment=block hier=top.t.cond1 +%000001 function logic func_side_effect; +-000001 point: type=line comment=block hier=top.t.cond1 +%000001 $display("SIDE EFFECT"); +-000001 point: type=line comment=block hier=top.t.cond1 +%000001 return 1; +-000001 point: type=line comment=block hier=top.t.cond1 endfunction 000010 function arr_t get_arr; @@ -465,14 +465,14 @@ +000010 point: type=line comment=block hier=top.t.cond1 endfunction -~000031 assign a = (cyc == 0) ? clk : 1'bz; +~000011 assign a = (cyc == 0) ? clk : 1'bz; -000000 point: type=branch comment=cond_then hier=top.t.cond1 -+000031 point: type=branch comment=cond_else hier=top.t.cond1 ++000011 point: type=branch comment=cond_else hier=top.t.cond1 ~000028 assign b = (cyc == 1) ? clk : 0; -000003 point: type=branch comment=cond_then hier=top.t.cond1 +000028 point: type=branch comment=cond_else hier=top.t.cond1 -~000021 assign c = func_side_effect() ? clk : 0; -+000021 point: type=branch comment=cond_then hier=top.t.cond1 +%000001 assign c = func_side_effect() ? clk : 0; +-000001 point: type=branch comment=cond_then hier=top.t.cond1 -000000 point: type=branch comment=cond_else hier=top.t.cond1 000010 always @(posedge clk) begin +000010 point: type=line comment=block hier=top.t.cond1 @@ -500,9 +500,9 @@ assign m = tab[clk ? 3 : 4]; for (genvar i = 0; i < 2; i++) begin - 000011 assign g = clk ? 1 : 0; -+000010 point: type=branch comment=cond_then hier=top.t.cond1 -+000011 point: type=branch comment=cond_else hier=top.t.cond1 + 000022 assign g = clk ? 1 : 0; ++000020 point: type=branch comment=cond_then hier=top.t.cond1 ++000022 point: type=branch comment=cond_else hier=top.t.cond1 end 000011 always begin diff --git a/test_regress/t/t_cover_line_cc.info.out b/test_regress/t/t_cover_line_cc.info.out index 6e42f53a9..9c6059f0f 100644 --- a/test_regress/t/t_cover_line_cc.info.out +++ b/test_regress/t/t_cover_line_cc.info.out @@ -150,20 +150,20 @@ DA:304,1 DA:305,20 DA:306,20 DA:315,1 -DA:323,21 -DA:324,21 -DA:325,21 +DA:323,1 +DA:324,1 +DA:325,1 DA:328,10 DA:329,10 DA:330,10 -DA:333,31 +DA:333,11 BRDA:333,0,0,0 -BRDA:333,0,1,31 +BRDA:333,0,1,11 DA:334,28 BRDA:334,0,0,3 BRDA:334,0,1,28 -DA:335,21 -BRDA:335,0,0,21 +DA:335,1 +BRDA:335,0,0,1 BRDA:335,0,1,0 DA:336,10 DA:337,10 @@ -182,9 +182,9 @@ BRDA:340,0,3,5 DA:343,11 BRDA:343,0,0,11 BRDA:343,0,1,0 -DA:349,11 -BRDA:349,0,0,10 -BRDA:349,0,1,11 +DA:349,22 +BRDA:349,0,0,20 +BRDA:349,0,1,22 DA:352,11 DA:353,10 BRDA:353,0,0,0 @@ -218,5 +218,5 @@ DA:374,9 BRDA:374,0,0,1 BRDA:374,0,1,9 BRF:83 -BRH:33 +BRH:32 end_of_record diff --git a/test_regress/t/t_cover_line_trace.out b/test_regress/t/t_cover_line_trace.out index fee3a1c28..57c616be0 100644 --- a/test_regress/t/t_cover_line_trace.out +++ b/test_regress/t/t_cover_line_trace.out @@ -3,140 +3,140 @@ $timescale 1ps $end $scope module top $end $var wire 1 cyc_copy [7:0] $end - $var wire 32 ? vlCoverageLineTrace_t_cover_line__55_block [31:0] $end - $var wire 32 @ vlCoverageLineTrace_t_cover_line__56_else [31:0] $end - $var wire 32 A vlCoverageLineTrace_t_cover_line__56_if [31:0] $end - $var wire 32 B vlCoverageLineTrace_t_cover_line__60_else [31:0] $end - $var wire 32 C vlCoverageLineTrace_t_cover_line__60_if [31:0] $end - $var wire 32 D vlCoverageLineTrace_t_cover_line__61_else [31:0] $end - $var wire 32 E vlCoverageLineTrace_t_cover_line__61_if [31:0] $end - $var wire 32 F vlCoverageLineTrace_t_cover_line__66_else [31:0] $end - $var wire 32 G vlCoverageLineTrace_t_cover_line__66_if [31:0] $end - $var wire 32 H vlCoverageLineTrace_t_cover_line__67_else [31:0] $end - $var wire 32 I vlCoverageLineTrace_t_cover_line__67_if [31:0] $end - $var wire 32 J vlCoverageLineTrace_t_cover_line__73_else [31:0] $end - $var wire 32 K vlCoverageLineTrace_t_cover_line__73_if [31:0] $end - $var wire 32 L vlCoverageLineTrace_t_cover_line__74_else [31:0] $end - $var wire 32 M vlCoverageLineTrace_t_cover_line__74_if [31:0] $end - $var wire 32 N vlCoverageLineTrace_t_cover_line__83_elsif [31:0] $end - $var wire 32 O vlCoverageLineTrace_t_cover_line__87_elsif [31:0] $end - $var wire 32 P vlCoverageLineTrace_t_cover_line__91_else [31:0] $end - $var wire 32 Q vlCoverageLineTrace_t_cover_line__91_if [31:0] $end + $var wire 8 D cyc_copy [7:0] $end + $var wire 32 E vlCoverageLineTrace_t_cover_line__55_block [31:0] $end + $var wire 32 F vlCoverageLineTrace_t_cover_line__56_else [31:0] $end + $var wire 32 G vlCoverageLineTrace_t_cover_line__56_if [31:0] $end + $var wire 32 H vlCoverageLineTrace_t_cover_line__60_else [31:0] $end + $var wire 32 I vlCoverageLineTrace_t_cover_line__60_if [31:0] $end + $var wire 32 J vlCoverageLineTrace_t_cover_line__61_else [31:0] $end + $var wire 32 K vlCoverageLineTrace_t_cover_line__61_if [31:0] $end + $var wire 32 L vlCoverageLineTrace_t_cover_line__66_else [31:0] $end + $var wire 32 M vlCoverageLineTrace_t_cover_line__66_if [31:0] $end + $var wire 32 N vlCoverageLineTrace_t_cover_line__67_else [31:0] $end + $var wire 32 O vlCoverageLineTrace_t_cover_line__67_if [31:0] $end + $var wire 32 P vlCoverageLineTrace_t_cover_line__73_else [31:0] $end + $var wire 32 Q vlCoverageLineTrace_t_cover_line__73_if [31:0] $end + $var wire 32 R vlCoverageLineTrace_t_cover_line__74_else [31:0] $end + $var wire 32 S vlCoverageLineTrace_t_cover_line__74_if [31:0] $end + $var wire 32 T vlCoverageLineTrace_t_cover_line__83_elsif [31:0] $end + $var wire 32 U vlCoverageLineTrace_t_cover_line__87_elsif [31:0] $end + $var wire 32 V vlCoverageLineTrace_t_cover_line__91_else [31:0] $end + $var wire 32 W vlCoverageLineTrace_t_cover_line__91_if [31:0] $end $var wire 32 C! vlCoverageLineTrace_t_cover_line__100_block [31:0] $end $var wire 32 D! vlCoverageLineTrace_t_cover_line__101_block [31:0] $end $var wire 32 E! vlCoverageLineTrace_t_cover_line__104_block [31:0] $end $var wire 32 F! vlCoverageLineTrace_t_cover_line__105_block [31:0] $end - $var wire 32 R vlCoverageLineTrace_t_cover_line__107_block [31:0] $end - $var wire 32 S vlCoverageLineTrace_t_cover_line__110_elsif [31:0] $end - $var wire 32 T vlCoverageLineTrace_t_cover_line__113_elsif [31:0] $end - $var wire 32 U vlCoverageLineTrace_t_cover_line__120_else [31:0] $end - $var wire 32 V vlCoverageLineTrace_t_cover_line__120_if [31:0] $end + $var wire 32 X vlCoverageLineTrace_t_cover_line__107_block [31:0] $end + $var wire 32 Y vlCoverageLineTrace_t_cover_line__110_elsif [31:0] $end + $var wire 32 Z vlCoverageLineTrace_t_cover_line__113_elsif [31:0] $end + $var wire 32 [ vlCoverageLineTrace_t_cover_line__120_else [31:0] $end + $var wire 32 \ vlCoverageLineTrace_t_cover_line__120_if [31:0] $end $var wire 32 =! vlCoverageLineTrace_t_cover_line__127_block [31:0] $end $scope module a1 $end $var wire 1 ! m $end - $var wire 6 + tab [5:0] $end - $var wire 8 c data[0][0] [7:0] $end - $var wire 8 d data[0][1] [7:0] $end - $var wire 8 e data[1][0] [7:0] $end - $var wire 8 f data[1][1] [7:0] $end + $var wire 6 2 tab [5:0] $end + $var wire 8 h data[0][0] [7:0] $end + $var wire 8 i data[0][1] [7:0] $end + $var wire 8 j data[1][0] [7:0] $end + $var wire 8 k data[1][1] [7:0] $end $var wire 32 $ vlCoverageLineTrace_t_cover_line__315_block [31:0] $end - $var wire 32 g pstruct [31:0] $end - $var wire 32 , vlCoverageLineTrace_t_cover_line__323_block [31:0] $end - $var wire 32 h vlCoverageLineTrace_t_cover_line__328_block [31:0] $end - $var wire 8 H! get_arr__Vstatic__arr[0] [7:0] $end - $var wire 8 I! get_arr__Vstatic__arr[1] [7:0] $end - $var wire 32 4 vlCoverageLineTrace_t_cover_line__333_cond_else [31:0] $end - $var wire 32 5 vlCoverageLineTrace_t_cover_line__333_cond_then [31:0] $end - $var wire 32 6 vlCoverageLineTrace_t_cover_line__334_cond_else [31:0] $end - $var wire 32 7 vlCoverageLineTrace_t_cover_line__334_cond_then [31:0] $end - $var wire 32 - vlCoverageLineTrace_t_cover_line__335_cond_else [31:0] $end - $var wire 32 . vlCoverageLineTrace_t_cover_line__335_cond_then [31:0] $end - $var wire 32 i vlCoverageLineTrace_t_cover_line__336_block [31:0] $end - $var wire 32 j vlCoverageLineTrace_t_cover_line__337_cond_else [31:0] $end - $var wire 32 k vlCoverageLineTrace_t_cover_line__337_cond_then [31:0] $end - $var wire 32 l vlCoverageLineTrace_t_cover_line__338_cond_else [31:0] $end - $var wire 32 m vlCoverageLineTrace_t_cover_line__338_cond_then [31:0] $end - $var wire 32 8 vlCoverageLineTrace_t_cover_line__340_cond_else_1 [31:0] $end - $var wire 32 9 vlCoverageLineTrace_t_cover_line__340_cond_then_1 [31:0] $end - $var wire 32 : vlCoverageLineTrace_t_cover_line__340_cond_else [31:0] $end - $var wire 32 ; vlCoverageLineTrace_t_cover_line__340_cond_then [31:0] $end - $var wire 32 n vlCoverageLineTrace_t_cover_line__343_cond_else [31:0] $end - $var wire 32 o vlCoverageLineTrace_t_cover_line__343_cond_then [31:0] $end - $var wire 32 J! vlCoverageLineTrace_t_cover_line__349_cond_else [31:0] $end - $var wire 32 / vlCoverageLineTrace_t_cover_line__349_cond_else_1 [31:0] $end - $var wire 32 K! vlCoverageLineTrace_t_cover_line__349_cond_then [31:0] $end - $var wire 32 0 vlCoverageLineTrace_t_cover_line__349_cond_then_1 [31:0] $end - $var wire 32 % vlCoverageLineTrace_t_cover_line__352_block [31:0] $end - $var wire 32 p vlCoverageLineTrace_t_cover_line__353_else [31:0] $end - $var wire 32 q vlCoverageLineTrace_t_cover_line__353_if [31:0] $end - $var wire 32 r vlCoverageLineTrace_t_cover_line__353_cond_else [31:0] $end - $var wire 32 s vlCoverageLineTrace_t_cover_line__353_cond_then [31:0] $end - $var wire 32 t vlCoverageLineTrace_t_cover_line__356_cond_else [31:0] $end - $var wire 32 u vlCoverageLineTrace_t_cover_line__356_cond_then [31:0] $end - $var wire 32 & vlCoverageLineTrace_t_cover_line__359_block [31:0] $end - $var wire 32 v vlCoverageLineTrace_t_cover_line__362_block [31:0] $end - $var wire 32 w vlCoverageLineTrace_t_cover_line__362_cond_else [31:0] $end - $var wire 32 x vlCoverageLineTrace_t_cover_line__362_cond_then [31:0] $end - $var wire 32 y vlCoverageLineTrace_t_cover_line__366_else [31:0] $end - $var wire 32 z vlCoverageLineTrace_t_cover_line__366_if [31:0] $end + $var wire 32 l pstruct [31:0] $end + $var wire 32 % vlCoverageLineTrace_t_cover_line__323_block [31:0] $end + $var wire 32 m vlCoverageLineTrace_t_cover_line__328_block [31:0] $end + $var wire 8 & get_arr__Vstatic__arr[0] [7:0] $end + $var wire 8 ' get_arr__Vstatic__arr[1] [7:0] $end + $var wire 32 : vlCoverageLineTrace_t_cover_line__333_cond_else [31:0] $end + $var wire 32 ; vlCoverageLineTrace_t_cover_line__333_cond_then [31:0] $end + $var wire 32 < vlCoverageLineTrace_t_cover_line__334_cond_else [31:0] $end + $var wire 32 = vlCoverageLineTrace_t_cover_line__334_cond_then [31:0] $end + $var wire 32 I! vlCoverageLineTrace_t_cover_line__335_cond_else [31:0] $end + $var wire 32 ( vlCoverageLineTrace_t_cover_line__335_cond_then [31:0] $end + $var wire 32 n vlCoverageLineTrace_t_cover_line__336_block [31:0] $end + $var wire 32 o vlCoverageLineTrace_t_cover_line__337_cond_else [31:0] $end + $var wire 32 p vlCoverageLineTrace_t_cover_line__337_cond_then [31:0] $end + $var wire 32 q vlCoverageLineTrace_t_cover_line__338_cond_else [31:0] $end + $var wire 32 r vlCoverageLineTrace_t_cover_line__338_cond_then [31:0] $end + $var wire 32 > vlCoverageLineTrace_t_cover_line__340_cond_else_1 [31:0] $end + $var wire 32 ? vlCoverageLineTrace_t_cover_line__340_cond_then_1 [31:0] $end + $var wire 32 @ vlCoverageLineTrace_t_cover_line__340_cond_else [31:0] $end + $var wire 32 A vlCoverageLineTrace_t_cover_line__340_cond_then [31:0] $end + $var wire 32 s vlCoverageLineTrace_t_cover_line__343_cond_else [31:0] $end + $var wire 32 t vlCoverageLineTrace_t_cover_line__343_cond_then [31:0] $end + $var wire 32 3 vlCoverageLineTrace_t_cover_line__349_cond_else [31:0] $end + $var wire 32 4 vlCoverageLineTrace_t_cover_line__349_cond_else_1 [31:0] $end + $var wire 32 5 vlCoverageLineTrace_t_cover_line__349_cond_then [31:0] $end + $var wire 32 6 vlCoverageLineTrace_t_cover_line__349_cond_then_1 [31:0] $end + $var wire 32 ) vlCoverageLineTrace_t_cover_line__352_block [31:0] $end + $var wire 32 u vlCoverageLineTrace_t_cover_line__353_else [31:0] $end + $var wire 32 v vlCoverageLineTrace_t_cover_line__353_if [31:0] $end + $var wire 32 w vlCoverageLineTrace_t_cover_line__353_cond_else [31:0] $end + $var wire 32 x vlCoverageLineTrace_t_cover_line__353_cond_then [31:0] $end + $var wire 32 y vlCoverageLineTrace_t_cover_line__356_cond_else [31:0] $end + $var wire 32 z vlCoverageLineTrace_t_cover_line__356_cond_then [31:0] $end + $var wire 32 * vlCoverageLineTrace_t_cover_line__359_block [31:0] $end + $var wire 32 + vlCoverageLineTrace_t_cover_line__362_block [31:0] $end + $var wire 32 , vlCoverageLineTrace_t_cover_line__362_cond_else [31:0] $end + $var wire 32 - vlCoverageLineTrace_t_cover_line__362_cond_then [31:0] $end + $var wire 32 . vlCoverageLineTrace_t_cover_line__366_else [31:0] $end + $var wire 32 J! vlCoverageLineTrace_t_cover_line__366_if [31:0] $end $var wire 32 { vlCoverageLineTrace_t_cover_line__370_cond_else [31:0] $end $var wire 32 | vlCoverageLineTrace_t_cover_line__370_cond_then [31:0] $end $var wire 32 } vlCoverageLineTrace_t_cover_line__373_block [31:0] $end @@ -145,22 +145,22 @@ $timescale 1ps $end $upscope $end $scope module o1 $end $var wire 1 -b00000000000000000000000000000000 ? -b00000000000000000000000000000000 @ +b00000000000000000000000000000000 < +b00000000000000000000000000000010 = +b00000000000000000000000000000000 > +b00000000000000000000000000000010 ? +b00000000000000000000000000000010 @ b00000000000000000000000000000000 A -b00000000000000000000000000000000 B -b00000000000000000000000000000000 C -b00000000000000000000000000000000 D +0B +b00000000000000000000000000000001 C +b00000001 D b00000000000000000000000000000000 E b00000000000000000000000000000000 F b00000000000000000000000000000000 G @@ -248,32 +248,32 @@ b00000000000000000000000000000000 [ b00000000000000000000000000000000 \ b00000000000000000000000000000000 ] b00000000000000000000000000000000 ^ -0_ -1` -1a -0b -b00000000 c -b00000000 d -b00000000 e -b00000000 f -b00000000000000100000000000000000 g -b00000000000000000000000000000001 h -b00000000000000000000000000000000 i -b00000000000000000000000000000000 j -b00000000000000000000000000000000 k -b00000000000000000000000000000000 l -b00000000000000000000000000000000 m +b00000000000000000000000000000000 _ +b00000000000000000000000000000000 ` +b00000000000000000000000000000000 a +b00000000000000000000000000000000 b +b00000000000000000000000000000000 c +b00000000000000000000000000000000 d +0e +1f +1g +b00000000 h +b00000000 i +b00000000 j +b00000000 k +b00000000000000100000000000000000 l +b00000000000000000000000000000001 m b00000000000000000000000000000000 n -b00000000000000000000000000000001 o -b00000000000000000000000000000001 p +b00000000000000000000000000000000 o +b00000000000000000000000000000000 p b00000000000000000000000000000000 q b00000000000000000000000000000000 r b00000000000000000000000000000000 s b00000000000000000000000000000001 t -b00000000000000000000000000000000 u -b00000000000000000000000000000100 v -b00000000000000000000000000000011 w -b00000000000000000000000000000001 x +b00000000000000000000000000000001 u +b00000000000000000000000000000000 v +b00000000000000000000000000000000 w +b00000000000000000000000000000000 x b00000000000000000000000000000001 y b00000000000000000000000000000000 z b00000000000000000000000000000000 { @@ -319,63 +319,56 @@ b00000000000000000000000000000000 D! b00000000000000000000000000000000 E! b00000000000000000000000000000000 F! 0G! -b00000000 H! -b00000000 I! +0H! +b00000000000000000000000000000000 I! b00000000000000000000000000000000 J! b00000000000000000000000000000000 K! -b00000000000000000000000000000000 L! -b00000000000000000000000000000010 M! +b00000000000000000000000000000010 L! +b00000000000000000000000000000000 M! b00000000000000000000000000000000 N! b00000000000000000000000000000000 O! b00000000000000000000000000000000 P! b00000000000000000000000000000000 Q! -b00000000000000000000000000000000 R! #10 -1) -1* -b000011 + -b00000000000000000000000000000011 , -b00000000000000000000000000000011 . -b00000000000000000000000000000001 0 -13 -b00000000000000000000000000000100 4 +11 +b000011 2 +b00000000000000000000000000000001 5 b00000000000000000000000000000001 6 -b00000000000000000000000000000011 7 -b00000000000000000000000000000001 8 -b00000000000000000000000000000011 9 -b00000000000000000000000000000001 ; -b00000000000000000000000000000010 = -b00000010 > -b00000000000000000000000000000001 ? +19 +b00000000000000000000000000000100 : +b00000000000000000000000000000001 < +b00000000000000000000000000000011 = +b00000000000000000000000000000001 > +b00000000000000000000000000000011 ? b00000000000000000000000000000001 A -b00000000000000000000000000000001 B -b00000000000000000000000000000001 D -b00000000000000000000000000000001 F +b00000000000000000000000000000010 C +b00000010 D +b00000000000000000000000000000001 E +b00000000000000000000000000000001 G b00000000000000000000000000000001 H b00000000000000000000000000000001 J b00000000000000000000000000000001 L +b00000000000000000000000000000001 N b00000000000000000000000000000001 P b00000000000000000000000000000001 R -b00000000000000000000000000000001 U -b00000000000000000000000000000001 W +b00000000000000000000000000000001 V b00000000000000000000000000000001 X -b00000000000000000000000000000001 Z b00000000000000000000000000000001 [ -b00000000000000000000000000000001 \ +b00000000000000000000000000000001 ] b00000000000000000000000000000001 ^ -b00000010 c -b00000001 d -b00000000000000110000000000000000 g -b00000000000000000000000000000001 i -b00000000000000000000000000000001 j -b00000000000000000000000000000001 l -b00000000000000000000000000000010 o -b00000000000000000000000000000010 p -b00000000000000000000000000000001 u -b00000000000000000000000000001000 v -b00000000000000000000000000000110 w -b00000000000000000000000000000010 x -b00000000000000000000000000000010 y +b00000000000000000000000000000001 ` +b00000000000000000000000000000001 a +b00000000000000000000000000000001 b +b00000000000000000000000000000001 d +b00000010 h +b00000001 i +b00000000000000110000000000000000 l +b00000000000000000000000000000001 n +b00000000000000000000000000000001 o +b00000000000000000000000000000001 q +b00000000000000000000000000000010 t +b00000000000000000000000000000010 u +b00000000000000000000000000000001 z b00000000000000000000000000000001 { b00000000000000000000000000000001 } b00000000000000000000000000000001 ~ @@ -399,56 +392,48 @@ b00000000000000000000000000000001 ;! b00000000000000000000000000000001 ?! b00000000000000000000000000000001 @! #15 -0) -0* -b00000000000000000000000000000100 , -b00000000000000000000000000000100 . -b00000000000000000000000000000011 / -b00000000000000000000000000000101 4 -b00000000000000000000000000000010 6 -b00000000000000000000000000000010 8 +01 +b00000000000000000000000000000011 3 +b00000000000000000000000000000011 4 +b00000000000000000000000000000101 : +b00000000000000000000000000000010 < +b00000000000000000000000000000010 > 0 -b00000000000000000000000000000010 ? -b00000000000000000000000000000010 A -b00000000000000000000000000000010 B -b00000000000000000000000000000010 D -b00000000000000000000000000000010 F +11 +b00000000000000000000000000000010 5 +b00000000000000000000000000000010 6 +b00000000000000000000000000000111 : +b00000000000000000000000000000100 < +b00000000000000000000000000000100 > +b00000000000000000000000000000011 C +b00000011 D +b00000000000000000000000000000010 E +b00000000000000000000000000000010 G b00000000000000000000000000000010 H b00000000000000000000000000000010 J b00000000000000000000000000000010 L +b00000000000000000000000000000010 N b00000000000000000000000000000010 P b00000000000000000000000000000010 R -b00000000000000000000000000000010 U -b00000000000000000000000000000010 W +b00000000000000000000000000000010 V b00000000000000000000000000000010 X -b00000000000000000000000000000010 Z b00000000000000000000000000000010 [ -b00000000000000000000000000000010 \ +b00000000000000000000000000000010 ] b00000000000000000000000000000010 ^ -b00000000 c -b00000000 d -b00000000000000000000000000000010 h -b00000000000000000000000000000010 i -b00000000000000000000000000000010 j -b00000000000000000000000000000010 l -b00000000000000000000000000000011 o -b00000000000000000000000000000011 p -b00000000000000000000000000000010 t -b00000000000000000000000000001100 v -b00000000000000000000000000001001 w -b00000000000000000000000000000011 x -b00000000000000000000000000000011 y +b00000000000000000000000000000010 ` +b00000000000000000000000000000010 a +b00000000000000000000000000000010 b +b00000000000000000000000000000010 d +b00000000 h +b00000000 i +b00000000000000000000000000000010 m +b00000000000000000000000000000010 n +b00000000000000000000000000000010 o +b00000000000000000000000000000010 q +b00000000000000000000000000000011 t +b00000000000000000000000000000011 u +b00000000000000000000000000000010 y b00000000000000000000000000000010 { b00000000000000000000000000000010 } b00000000000000000000000000000001 !! @@ -473,58 +458,50 @@ b00000000000000000000000000000010 ;! b00000000000000000000000000000010 ?! b00000000000000000000000000000010 @! #25 -0) -0* -b00000000000000000000000000000110 , -b00000000000000000000000000000110 . -b00000000000000000000000000000100 / -b00000000000000000000000000001000 4 -b00000000000000000000000000000101 6 -b00000000000000000000000000000101 8 +01 +b00000000000000000000000000000100 3 +b00000000000000000000000000000100 4 +b00000000000000000000000000001000 : +b00000000000000000000000000000101 < +b00000000000000000000000000000101 > 0 -b00000000000000000000000000000011 ? -b00000000000000000000000000000011 A -b00000000000000000000000000000001 C -b00000000000000000000000000000001 E -b00000000000000000000000000000001 G +11 +b00000000000000000000000000000011 5 +b00000000000000000000000000000011 6 +b00000000000000000000000000001010 : +b00000000000000000000000000000111 < +b00000000000000000000000000000110 > +b00000000000000000000000000000100 ? +b00000000000000000000000000000010 A +1B +b00000000000000000000000000000100 C +b00000100 D +b00000000000000000000000000000011 E +b00000000000000000000000000000011 G b00000000000000000000000000000001 I b00000000000000000000000000000001 K b00000000000000000000000000000001 M -b00000000000000000000000000000001 N -b00000000000000000000000000000011 R +b00000000000000000000000000000001 O +b00000000000000000000000000000001 Q b00000000000000000000000000000001 S -b00000000000000000000000000000011 W +b00000000000000000000000000000001 T b00000000000000000000000000000011 X -b00000000000000000000000000000011 Z -b00000000000000000000000000000011 [ -b00000000000000000000000000000011 \ +b00000000000000000000000000000001 Y +b00000000000000000000000000000011 ] b00000000000000000000000000000011 ^ -1_ -b00000000000000000000000000000011 h -b00000000000000000000000000000011 i -b00000000000000000000000000000001 k -b00000000000000000000000000000011 l -b00000000000000000000000000000100 o -b00000000000000000000000000000100 p -b00000000000000000000000000000011 t -b00000000000000000000000000010000 v -b00000000000000000000000000001100 w -b00000000000000000000000000000100 x -b00000000000000000000000000000100 y +b00000000000000000000000000000011 ` +b00000000000000000000000000000011 a +b00000000000000000000000000000011 b +b00000000000000000000000000000011 d +1e +b00000000000000000000000000000011 m +b00000000000000000000000000000011 n +b00000000000000000000000000000001 p +b00000000000000000000000000000011 q +b00000000000000000000000000000100 t +b00000000000000000000000000000100 u +b00000000000000000000000000000011 y b00000000000000000000000000000011 { b00000000000000000000000000000011 } b00000000000000000000000000000010 ~ @@ -549,61 +526,53 @@ b00000000000000000000000000000011 ;! b00000000000000000000000000000011 ?! b00000000000000000000000000000011 @! #35 -0) -0* -b00000000000000000000000000001000 , -b00000000000000000000000000001000 . -b00000000000000000000000000000101 / -03 -b00000000000000000000000000001011 4 -b00000000000000000000000000001000 6 -b00000000000000000000000000000101 9 -b00000000000000000000000000000011 : +01 +b00000000000000000000000000000101 3 +b00000000000000000000000000000101 4 +09 +b00000000000000000000000000001011 : +b00000000000000000000000000001000 < +b00000000000000000000000000000101 ? +b00000000000000000000000000000011 @ 0 -b00000000000000000000000000000100 ? -b00000000000000000000000000000100 A -b00000000000000000000000000000011 B -b00000000000000000000000000000011 D -b00000000000000000000000000000011 F +11 +b00000000000000000000000000000100 5 +b00000000000000000000000000000100 6 +19 +b00000000000000000000000000001101 : +b00000000000000000000000000001010 < +b00000000000000000000000000000111 > +b00000000000000000000000000000110 ? +b00000000000000000000000000000011 A +0B +b00000000000000000000000000000101 C +b00000101 D +b00000000000000000000000000000100 E +b00000000000000000000000000000100 G b00000000000000000000000000000011 H b00000000000000000000000000000011 J b00000000000000000000000000000011 L -b00000000000000000000000000000001 O -b00000000000000000000000000000100 R -b00000000000000000000000000000011 U -b00000000000000000000000000000100 W -b00000000000000000000000000000001 Y -b00000000000000000000000000000100 [ -b00000000000000000000000000000001 ] -0_ -0a -b00000000000000000000000000000100 h -b00000000000000000000000000000100 i -b00000000000000000000000000000011 j -b00000000000000000000000000000100 l -b00000000000000000000000000000101 o -b00000000000000000000000000000001 q -b00000000000000000000000000000001 r -b00000000000000000000000000000100 t -b00000000000000000000000000010100 v -b00000000000000000000000000001111 w -b00000000000000000000000000000101 x -b00000000000000000000000000000101 y +b00000000000000000000000000000011 N +b00000000000000000000000000000011 P +b00000000000000000000000000000011 R +b00000000000000000000000000000001 U +b00000000000000000000000000000100 X +b00000000000000000000000000000011 [ +b00000000000000000000000000000100 ] +b00000000000000000000000000000001 _ +b00000000000000000000000000000100 a +b00000000000000000000000000000001 c +0e +0g +b00000000000000000000000000000100 m +b00000000000000000000000000000100 n +b00000000000000000000000000000011 o +b00000000000000000000000000000100 q +b00000000000000000000000000000101 t +b00000000000000000000000000000001 v +b00000000000000000000000000000001 w +b00000000000000000000000000000100 y b00000000000000000000000000000100 { b00000000000000000000000000000100 } b00000000000000000000000000000011 ~ @@ -627,55 +596,47 @@ b00000000000000000000000000000100 ;! b00000000000000000000000000000100 ?! b00000000000000000000000000000001 A! #45 -0) -0* -b00000000000000000000000000001010 , -b00000000000000000000000000001010 . -b00000000000000000000000000000110 / -b00000000000000000000000000001110 4 -b00000000000000000000000000001011 6 -b00000000000000000000000000001000 8 +01 +b00000000000000000000000000000110 3 +b00000000000000000000000000000110 4 +b00000000000000000000000000001110 : +b00000000000000000000000000001011 < +b00000000000000000000000000001000 > 0 -b00000000000000000000000000000101 ? -b00000000000000000000000000000101 A -b00000000000000000000000000000100 B -b00000000000000000000000000000100 D -b00000000000000000000000000000100 F +11 +b00000000000000000000000000000101 5 +b00000000000000000000000000000101 6 +b00000000000000000000000000010000 : +b00000000000000000000000000001101 < +b00000000000000000000000000001010 > +b00000000000000000000000000000110 C +b00000110 D +b00000000000000000000000000000101 E +b00000000000000000000000000000101 G b00000000000000000000000000000100 H b00000000000000000000000000000100 J b00000000000000000000000000000100 L -b00000000000000000000000000000001 Q -b00000000000000000000000000000101 R -b00000000000000000000000000000001 T -b00000000000000000000000000000101 W -b00000000000000000000000000000100 X -b00000000000000000000000000000100 Z -b00000000000000000000000000000101 [ -b00000000000000000000000000000100 \ +b00000000000000000000000000000100 N +b00000000000000000000000000000100 P +b00000000000000000000000000000100 R +b00000000000000000000000000000001 W +b00000000000000000000000000000101 X +b00000000000000000000000000000001 Z +b00000000000000000000000000000101 ] b00000000000000000000000000000100 ^ -1a -b00000000000000000000000000000101 h -b00000000000000000000000000000101 i -b00000000000000000000000000000100 j -b00000000000000000000000000000101 l -b00000000000000000000000000000110 o -b00000000000000000000000000000101 p -b00000000000000000000000000000101 t -b00000000000000000000000000011000 v -b00000000000000000000000000010010 w -b00000000000000000000000000000110 x -b00000000000000000000000000000110 y +b00000000000000000000000000000100 ` +b00000000000000000000000000000101 a +b00000000000000000000000000000100 b +b00000000000000000000000000000100 d +1g +b00000000000000000000000000000101 m +b00000000000000000000000000000101 n +b00000000000000000000000000000100 o +b00000000000000000000000000000101 q +b00000000000000000000000000000110 t +b00000000000000000000000000000101 u +b00000000000000000000000000000101 y b00000000000000000000000000000101 { b00000000000000000000000000000101 } b00000000000000000000000000000100 ~ @@ -702,57 +663,49 @@ b00000000000000000000000000000110 ?! b00000000000000000000000000000101 @! b00000000000000000000000000000001 B! #55 -0) -0* -b00000000000000000000000000001100 , -b00000000000000000000000000001100 . -b00000000000000000000000000000111 / -b00000000000000000000000000010001 4 -b00000000000000000000000000001110 6 -b00000000000000000000000000001011 8 +01 +b00000000000000000000000000000111 3 +b00000000000000000000000000000111 4 +b00000000000000000000000000010001 : +b00000000000000000000000000001110 < +b00000000000000000000000000001011 > 0 -b00000000000000000000000000000110 ? -b00000000000000000000000000000110 A -b00000000000000000000000000000101 B -b00000000000000000000000000000101 D -b00000000000000000000000000000101 F +11 +b00000000000000000000000000000110 5 +b00000000000000000000000000000110 6 +b00000000000000000000000000010011 : +b00000000000000000000000000010000 < +b00000000000000000000000000001100 > +b00000000000000000000000000000111 ? +b00000000000000000000000000000100 A +b00000000000000000000000000000111 C +b00000111 D +b00000000000000000000000000000110 E +b00000000000000000000000000000110 G b00000000000000000000000000000101 H b00000000000000000000000000000101 J b00000000000000000000000000000101 L -b00000000000000000000000000000011 P -b00000000000000000000000000000110 R -b00000000000000000000000000000100 U -b00000000000000000000000000000110 W -b00000000000000000000000000000101 X -b00000000000000000000000000000101 Z -b00000000000000000000000000000110 [ -b00000000000000000000000000000101 \ +b00000000000000000000000000000101 N +b00000000000000000000000000000101 P +b00000000000000000000000000000101 R +b00000000000000000000000000000011 V +b00000000000000000000000000000110 X +b00000000000000000000000000000100 [ +b00000000000000000000000000000110 ] b00000000000000000000000000000101 ^ -1_ -b00000000000000000000000000000110 h -b00000000000000000000000000000110 i -b00000000000000000000000000000010 k -b00000000000000000000000000000110 l -b00000000000000000000000000000111 o -b00000000000000000000000000000110 p -b00000000000000000000000000000110 t -b00000000000000000000000000011100 v -b00000000000000000000000000010101 w -b00000000000000000000000000000111 x -b00000000000000000000000000000111 y +b00000000000000000000000000000101 ` +b00000000000000000000000000000110 a +b00000000000000000000000000000101 b +b00000000000000000000000000000101 d +1e +b00000000000000000000000000000110 m +b00000000000000000000000000000110 n +b00000000000000000000000000000010 p +b00000000000000000000000000000110 q +b00000000000000000000000000000111 t +b00000000000000000000000000000110 u +b00000000000000000000000000000110 y b00000000000000000000000000000110 { b00000000000000000000000000000110 } b00000000000000000000000000000101 ~ @@ -777,60 +730,52 @@ b00000000000000000000000000000110 ;! b00000000000000000000000000000111 ?! b00000000000000000000000000000110 @! #65 -0) -0* -b00000000000000000000000000001110 , -b00000000000000000000000000001110 . -b00000000000000000000000000001000 / -03 -b00000000000000000000000000010100 4 -b00000000000000000000000000010001 6 -b00000000000000000000000000001000 9 -b00000000000000000000000000000100 : +01 +b00000000000000000000000000001000 3 +b00000000000000000000000000001000 4 +09 +b00000000000000000000000000010100 : +b00000000000000000000000000010001 < +b00000000000000000000000000001000 ? +b00000000000000000000000000000100 @ 0 -b00000000000000000000000000000111 ? -b00000000000000000000000000000111 A -b00000000000000000000000000000110 B -b00000000000000000000000000000110 D -b00000000000000000000000000000110 F +11 +b00000000000000000000000000000111 5 +b00000000000000000000000000000111 6 +19 +b00000000000000000000000000010110 : +b00000000000000000000000000010011 < +b00000000000000000000000000001101 > +b00000000000000000000000000001001 ? +b00000000000000000000000000000101 A +b00000000000000000000000000001000 C +b00001000 D +b00000000000000000000000000000111 E +b00000000000000000000000000000111 G b00000000000000000000000000000110 H b00000000000000000000000000000110 J b00000000000000000000000000000110 L -b00000000000000000000000000000100 P -b00000000000000000000000000000111 R -b00000000000000000000000000000101 U -b00000000000000000000000000000111 W -b00000000000000000000000000000110 X -b00000000000000000000000000000110 Z -b00000000000000000000000000000111 [ -b00000000000000000000000000000110 \ +b00000000000000000000000000000110 N +b00000000000000000000000000000110 P +b00000000000000000000000000000110 R +b00000000000000000000000000000100 V +b00000000000000000000000000000111 X +b00000000000000000000000000000101 [ +b00000000000000000000000000000111 ] b00000000000000000000000000000110 ^ -0_ -b00000000000000000000000000000111 h -b00000000000000000000000000000111 i -b00000000000000000000000000000101 j -b00000000000000000000000000000111 l -b00000000000000000000000000001000 o -b00000000000000000000000000000111 p -b00000000000000000000000000000111 t -b00000000000000000000000000100000 v -b00000000000000000000000000011000 w -b00000000000000000000000000001000 x -b00000000000000000000000000001000 y +b00000000000000000000000000000110 ` +b00000000000000000000000000000111 a +b00000000000000000000000000000110 b +b00000000000000000000000000000110 d +0e +b00000000000000000000000000000111 m +b00000000000000000000000000000111 n +b00000000000000000000000000000101 o +b00000000000000000000000000000111 q +b00000000000000000000000000001000 t +b00000000000000000000000000000111 u +b00000000000000000000000000000111 y b00000000000000000000000000000111 { b00000000000000000000000000000111 } b00000000000000000000000000000110 ~ @@ -855,54 +800,46 @@ b00000000000000000000000000000111 ;! b00000000000000000000000000001000 ?! b00000000000000000000000000000111 @! #75 -0) -0* -b00000000000000000000000000010000 , -b00000000000000000000000000010000 . -b00000000000000000000000000001001 / -b00000000000000000000000000010111 4 -b00000000000000000000000000010100 6 -b00000000000000000000000000001110 8 +01 +b00000000000000000000000000001001 3 +b00000000000000000000000000001001 4 +b00000000000000000000000000010111 : +b00000000000000000000000000010100 < +b00000000000000000000000000001110 > 0 -b00000000000000000000000000001000 ? -b00000000000000000000000000001000 A -b00000000000000000000000000000111 B -b00000000000000000000000000000111 D -b00000000000000000000000000000111 F +11 +b00000000000000000000000000001000 5 +b00000000000000000000000000001000 6 +b00000000000000000000000000011001 : +b00000000000000000000000000010110 < +b00000000000000000000000000010000 > +b00000000000000000000000000001001 C +b00001001 D +b00000000000000000000000000001000 E +b00000000000000000000000000001000 G b00000000000000000000000000000111 H b00000000000000000000000000000111 J b00000000000000000000000000000111 L -b00000000000000000000000000000101 P -b00000000000000000000000000001000 R -b00000000000000000000000000000110 U -b00000000000000000000000000001000 W -b00000000000000000000000000000111 X -b00000000000000000000000000000111 Z -b00000000000000000000000000001000 [ -b00000000000000000000000000000111 \ +b00000000000000000000000000000111 N +b00000000000000000000000000000111 P +b00000000000000000000000000000111 R +b00000000000000000000000000000101 V +b00000000000000000000000000001000 X +b00000000000000000000000000000110 [ +b00000000000000000000000000001000 ] b00000000000000000000000000000111 ^ -b00000000000000000000000000001000 h -b00000000000000000000000000001000 i -b00000000000000000000000000000110 j -b00000000000000000000000000001000 l -b00000000000000000000000000001001 o -b00000000000000000000000000001000 p -b00000000000000000000000000001000 t -b00000000000000000000000000100100 v -b00000000000000000000000000011011 w -b00000000000000000000000000001001 x -b00000000000000000000000000001001 y +b00000000000000000000000000000111 ` +b00000000000000000000000000001000 a +b00000000000000000000000000000111 b +b00000000000000000000000000000111 d +b00000000000000000000000000001000 m +b00000000000000000000000000001000 n +b00000000000000000000000000000110 o +b00000000000000000000000000001000 q +b00000000000000000000000000001001 t +b00000000000000000000000000001000 u +b00000000000000000000000000001000 y b00000000000000000000000000001000 { b00000000000000000000000000001000 } b00000000000000000000000000000111 ~ @@ -926,57 +863,49 @@ b00000000000000000000000000001000 ;! b00000000000000000000000000001001 ?! b00000000000000000000000000001000 @! #85 -0) -0* -b00000000000000000000000000010010 , -b00000000000000000000000000010010 . -b00000000000000000000000000001010 / -b00000000000000000000000000011010 4 -b00000000000000000000000000010111 6 -b00000000000000000000000000010001 8 +01 +b00000000000000000000000000001010 3 +b00000000000000000000000000001010 4 +b00000000000000000000000000011010 : +b00000000000000000000000000010111 < +b00000000000000000000000000010001 > 0 -b00000000000000000000000000001001 ? -b00000000000000000000000000001001 A -b00000000000000000000000000001000 B -b00000000000000000000000000001000 D -b00000000000000000000000000001000 F +11 +b00000000000000000000000000001001 5 +b00000000000000000000000000001001 6 +b00000000000000000000000000011100 : +b00000000000000000000000000011001 < +b00000000000000000000000000010010 > +b00000000000000000000000000001010 ? +b00000000000000000000000000000110 A +b00000000000000000000000000001010 C +b00001010 D +b00000000000000000000000000001001 E +b00000000000000000000000000001001 G b00000000000000000000000000001000 H b00000000000000000000000000001000 J b00000000000000000000000000001000 L -b00000000000000000000000000000110 P -b00000000000000000000000000001001 R -b00000000000000000000000000000111 U -b00000000000000000000000000001001 W -b00000000000000000000000000001000 X -b00000000000000000000000000001000 Z -b00000000000000000000000000001001 [ -b00000000000000000000000000001000 \ +b00000000000000000000000000001000 N +b00000000000000000000000000001000 P +b00000000000000000000000000001000 R +b00000000000000000000000000000110 V +b00000000000000000000000000001001 X +b00000000000000000000000000000111 [ +b00000000000000000000000000001001 ] b00000000000000000000000000001000 ^ -1_ -b00000000000000000000000000001001 h -b00000000000000000000000000001001 i -b00000000000000000000000000000011 k -b00000000000000000000000000001001 l -b00000000000000000000000000001010 o -b00000000000000000000000000001001 p -b00000000000000000000000000001001 t -b00000000000000000000000000101000 v -b00000000000000000000000000011110 w -b00000000000000000000000000001010 x -b00000000000000000000000000001010 y +b00000000000000000000000000001000 ` +b00000000000000000000000000001001 a +b00000000000000000000000000001000 b +b00000000000000000000000000001000 d +1e +b00000000000000000000000000001001 m +b00000000000000000000000000001001 n +b00000000000000000000000000000011 p +b00000000000000000000000000001001 q +b00000000000000000000000000001010 t +b00000000000000000000000000001001 u +b00000000000000000000000000001001 y b00000000000000000000000000001001 { b00000000000000000000000000001001 } b00000000000000000000000000001000 ~ @@ -1000,60 +929,52 @@ b00000000000000000000000000001001 ;! b00000000000000000000000000001010 ?! b00000000000000000000000000001001 @! #95 -0) -0* -b00000000000000000000000000010100 , -b00000000000000000000000000010100 . -b00000000000000000000000000001011 / -03 -b00000000000000000000000000011101 4 -b00000000000000000000000000011010 6 -b00000000000000000000000000001011 9 -b00000000000000000000000000000101 : +01 +b00000000000000000000000000001011 3 +b00000000000000000000000000001011 4 +09 +b00000000000000000000000000011101 : +b00000000000000000000000000011010 < +b00000000000000000000000000001011 ? +b00000000000000000000000000000101 @ 0 -b00000000000000000000000000001010 ? -b00000000000000000000000000001010 A -b00000000000000000000000000001001 B -b00000000000000000000000000001001 D -b00000000000000000000000000001001 F +11 +b00000000000000000000000000001010 5 +b00000000000000000000000000001010 6 +19 +b00000000000000000000000000011111 : +b00000000000000000000000000011100 < +b00000000000000000000000000010011 > +b00000000000000000000000000001100 ? +b00000000000000000000000000000111 A +b00000000000000000000000000001011 C +b00001011 D +b00000000000000000000000000001010 E +b00000000000000000000000000001010 G b00000000000000000000000000001001 H b00000000000000000000000000001001 J b00000000000000000000000000001001 L -b00000000000000000000000000000111 P -b00000000000000000000000000001010 R -b00000000000000000000000000000001 V -b00000000000000000000000000001010 W -b00000000000000000000000000001001 X -b00000000000000000000000000001001 Z -b00000000000000000000000000001010 [ -b00000000000000000000000000001001 \ +b00000000000000000000000000001001 N +b00000000000000000000000000001001 P +b00000000000000000000000000001001 R +b00000000000000000000000000000111 V +b00000000000000000000000000001010 X +b00000000000000000000000000000001 \ +b00000000000000000000000000001010 ] b00000000000000000000000000001001 ^ -0_ -b00000000000000000000000000001010 h -b00000000000000000000000000001010 i -b00000000000000000000000000000111 j -b00000000000000000000000000001010 l -b00000000000000000000000000001011 o -b00000000000000000000000000001010 p -b00000000000000000000000000001010 t -b00000000000000000000000000101100 v -b00000000000000000000000000100001 w -b00000000000000000000000000001011 x -b00000000000000000000000000001011 y +b00000000000000000000000000001001 ` +b00000000000000000000000000001010 a +b00000000000000000000000000001001 b +b00000000000000000000000000001001 d +0e +b00000000000000000000000000001010 m +b00000000000000000000000000001010 n +b00000000000000000000000000000111 o +b00000000000000000000000000001010 q +b00000000000000000000000000001011 t +b00000000000000000000000000001010 u +b00000000000000000000000000001010 y b00000000000000000000000000001010 { b00000000000000000000000000001010 } b00000000000000000000000000001001 ~ diff --git a/test_regress/t/t_cover_line_trace.py b/test_regress/t/t_cover_line_trace.py index 57efc031e..8fec71ba8 100755 --- a/test_regress/t/t_cover_line_trace.py +++ b/test_regress/t/t_cover_line_trace.py @@ -26,6 +26,5 @@ test.run(cmd=[ ], verilator_run=True) -test.files_identical(test.obj_dir + "/annotated/t_cover_line.v", "t/t_cover_line.out") test.vcd_identical(test.trace_filename, test.golden_filename) test.passes() From 192445097ac1e5413c7e1203aa4dc2eb7b1b4a07 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 1 Mar 2026 11:59:29 -0500 Subject: [PATCH 3/8] Internals: Fix non-determinism in V3Delayed, V3SplitVar, V3Task (#7120 partial) (#7165) --- src/CMakeLists.txt | 3 ++- src/V3Container.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++ src/V3Delayed.cpp | 2 +- src/V3Options.cpp | 20 +++++--------- src/V3PchAstMT.h | 1 + src/V3PchAstNoMT.h | 1 + src/V3SplitVar.cpp | 44 ++++++++++++++++++++++++------- src/V3Task.cpp | 13 +++++----- src/V3Task.h | 9 ++++--- 9 files changed, 123 insertions(+), 35 deletions(-) create mode 100644 src/V3Container.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7c0612dee..92bd02219 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -65,8 +65,9 @@ set(HEADERS V3Clock.h V3Combine.h V3Common.h - V3Control.h V3Const.h + V3Container.h + V3Control.h V3Coverage.h V3CoverageJoin.h V3Dead.h diff --git a/src/V3Container.h b/src/V3Container.h new file mode 100644 index 000000000..7644cbea6 --- /dev/null +++ b/src/V3Container.h @@ -0,0 +1,65 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// DESCRIPTION: Verilator: Generic container types +// +// Code available from: https://verilator.org +// +//************************************************************************* +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of either the GNU Lesser General Public License Version 3 +// or the Perl Artistic License Version 2.0. +// SPDX-FileCopyrightText: 2003-2026 Wilson Snyder +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 +// +//************************************************************************* + +#ifndef VERILATOR_V3CONTAINER_H_ +#define VERILATOR_V3CONTAINER_H_ + +#include "config_build.h" +#include "verilatedos.h" + +#include +#include +#include + +//============================================================================ + +// Similar to std::set, but ordered based on call order to emplace. Used +// when insertion order is desired (e.g. std::vector), but duplicates need removal. +// Keys may not be modified. (If needed in future, m_set could contain vector positions.) +template +class VInsertionSet final { + std::vector m_keys; // Elements by insertion order + std::unordered_set m_keySet; // Elements by key +public: + // METHODS + bool insert(const T_Key& key) { + // Returns if did insertion (second pair argument of traditional emplace) + const auto itFoundPair = m_keySet.insert(key); + if (itFoundPair.second) m_keys.push_back(key); + return itFoundPair.second; + } + void clear() { + m_keys.clear(); + m_keySet.clear(); + } + + // ACCESSORS + bool empty() const { return m_keys.empty(); } + bool exists(const T_Key& key) const { return m_keySet.find(key) != m_keySet.end(); } + + // ITERATORS + using const_iterator = typename std::vector::const_iterator; + const_iterator begin() const { return m_keys.begin(); } + const_iterator end() const { return m_keys.end(); } +}; + +//============================================================================ +// VInsertionMap: Not currently needed; prototype code exists, just ask. +// Similar to std::map, but ordered based on call order to emplace. Used +// when insertion order is desired (e.g. std::vector), but duplicates need removal. +// Values may be modified. + +#endif // Guard diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index 209218b8e..49aeb4705 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -263,7 +263,7 @@ class DelayedVisitor final : public VNVisitor { AstUser3Allocator> m_writeRefs; // STATE - across all visitors - std::set m_timingDomains; // Timing resume domains + VInsertionSet m_timingDomains; // Timing resume domains // STATE - for current visit position (use VL_RESTORER) AstActive* m_activep = nullptr; // Current activate diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 28c7d75b8..7018bc296 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -18,6 +18,7 @@ #include "V3Options.h" +#include "V3Container.h" #include "V3Error.h" #include "V3File.h" #include "V3Global.h" @@ -70,30 +71,26 @@ public: std::list m_lineArgs; // List of command line argument encountered // List of arguments encounterd, and a bool in needed for rerunning --dump-inputs std::list, bool>> m_allArgs; - std::list m_incDirUsers; // Include directories (ordered) - std::set m_incDirUserSet; // Include directories (for removing duplicates) + VInsertionSet m_incDirUsers; // Include directories (ordered) std::list m_incDirFallbacks; // Include directories (ordered) std::set m_incDirFallbackSet; // Include directories (for removing duplicates) std::map m_langExts; // Language extension map - std::list m_libExtVs; // Library extensions (ordered) - std::set m_libExtVSet; // Library extensions (for removing duplicates) + VInsertionSet m_libExtVs; // Library extensions (ordered) DirMap m_dirMap; // Directory listing // ACCESSOR METHODS void addIncDirUser(const string& incdir) { const string& dir = V3Os::filenameCleanup(incdir); - const auto itFoundPair = m_incDirUserSet.insert(dir); - if (itFoundPair.second) { + const bool inserted = m_incDirUsers.insert(dir); + if (inserted) { // cppcheck-suppress stlFindInsert // cppcheck 1.90 bug - m_incDirUsers.push_back(dir); m_incDirFallbacks.remove(dir); // User has priority over Fallback m_incDirFallbackSet.erase(dir); // User has priority over Fallback } } void addIncDirFallback(const string& incdir) { const string& dir = V3Os::filenameCleanup(incdir); - if (m_incDirUserSet.find(dir) - == m_incDirUserSet.end()) { // User has priority over Fallback + if (!m_incDirUsers.exists(dir)) { // User has priority over Fallback const auto itFoundPair = m_incDirFallbackSet.insert(dir); if (itFoundPair.second) m_incDirFallbacks.push_back(dir); } @@ -106,10 +103,7 @@ public: m_langExts[addext] = lc; } - void addLibExtV(const string& libext) { - const auto itFoundPair = m_libExtVSet.insert(libext); - if (itFoundPair.second) m_libExtVs.push_back(libext); - } + void addLibExtV(const string& libext) { m_libExtVs.insert(libext); } V3OptionsImp() = default; ~V3OptionsImp() = default; }; diff --git a/src/V3PchAstMT.h b/src/V3PchAstMT.h index 34f862088..751afd41d 100644 --- a/src/V3PchAstMT.h +++ b/src/V3PchAstMT.h @@ -26,6 +26,7 @@ #include "V3Ast.h" #include "V3Broken.h" +#include "V3Container.h" #include "V3Error.h" #include "V3FileLine.h" #include "V3FunctionTraits.h" diff --git a/src/V3PchAstNoMT.h b/src/V3PchAstNoMT.h index e778dab5d..d2ddc1d6e 100644 --- a/src/V3PchAstNoMT.h +++ b/src/V3PchAstNoMT.h @@ -28,6 +28,7 @@ #include "V3Ast.h" #include "V3Broken.h" +#include "V3Container.h" #include "V3Error.h" #include "V3FileLine.h" #include "V3FunctionTraits.h" diff --git a/src/V3SplitVar.cpp b/src/V3SplitVar.cpp index 62c386293..95bd05954 100644 --- a/src/V3SplitVar.cpp +++ b/src/V3SplitVar.cpp @@ -226,15 +226,37 @@ static void warnNoSplit(const AstVar* varp, const AstNode* wherep, const char* r // Split Unpacked Variables // Replacement policy: // AstArraySel -> Just replace with the AstVarRef for the split variable -// AstVarRef -> Create a temporary variable and refer the variable -// AstSliceSel -> Create a temporary variable and refer the variable +// AstVarRef -> Create a temporary variable and refer to the variable +// AstSliceSel -> Create a temporary variable and refer to the variable -// Compare AstNode* to get deterministic ordering when showing messages. +// Track order-of-encounter for nodes, so we are stable, versus comparing node pointers +// (fileline may be the same across multiple nodes, so is insufficient) +class SplitNodeOrder final { + // NODE STATE + // AstNode::user4() -> uint64_t. Order the node is in the tree + const VNUser4InUse m_user4InUse; + +public: + static uint64_t nextId() { + static uint64_t s_sequence = 0; + return ++s_sequence; + } + static uint64_t nodeOrder(const AstNode* const nodep) { + AstNode* const ncnodep = const_cast(nodep); + const uint64_t id = ncnodep->user4(); + if (VL_LIKELY(id)) return id; + ncnodep->user4(nextId()); + return ncnodep->user4(); + } +}; + +// Compare AstNode* to get deterministic ordering struct AstNodeComparator final { bool operator()(const AstNode* ap, const AstNode* bp) const { + // First consider lines, as makes messages to user more obvious const int lineComp = ap->fileline()->operatorCompare(*bp->fileline()); if (lineComp != 0) return lineComp < 0; - return ap < bp; + return SplitNodeOrder::nodeOrder(ap) < SplitNodeOrder::nodeOrder(bp); } }; @@ -247,6 +269,7 @@ class UnpackRef final { const int m_lsb; // for SliceSel const VAccess m_access; const bool m_ftask; // true if the reference is in function/task. false if in module. + public: UnpackRef(AstNode* stmtp, AstVarRef* nodep, bool ftask) : m_contextp{stmtp} @@ -587,12 +610,12 @@ class SplitUnpackedVarVisitor final : public VNVisitor, public SplitVarImpl { iterateChildren(nodep); } } - AstVarRef* createTempVar(AstNode* context, AstNode* nodep, AstUnpackArrayDType* dtypep, + AstVarRef* createTempVar(AstNode* contextp, AstNode* nodep, AstUnpackArrayDType* dtypep, const std::string& name_prefix, std::vector& vars, int start_idx, bool lvalue, bool /*ftask*/) { FileLine* const fl = nodep->fileline(); const std::string name = m_tempNames.get(nodep) + "__" + name_prefix; - AstNodeAssign* const assignp = VN_CAST(context, NodeAssign); + AstNodeAssign* const assignp = VN_CAST(contextp, NodeAssign); if (assignp) { // "always_comb a = b;" to "always_comb begin a = b; end" so that local // variable can be added. @@ -604,7 +627,7 @@ class SplitUnpackedVarVisitor final : public VNVisitor, public SplitVarImpl { << " is created lsb:" << dtypep->lo() << " msb:" << dtypep->hi()); // Use AstAssign if true, otherwise AstAssignW const bool use_simple_assign - = (context && VN_IS(context, NodeFTaskRef)) || (assignp && VN_IS(assignp, Assign)); + = (contextp && VN_IS(contextp, NodeFTaskRef)) || (assignp && VN_IS(assignp, Assign)); for (int i = 0; i < dtypep->elementsConst(); ++i) { AstNodeExpr* lhsp @@ -618,11 +641,11 @@ class SplitUnpackedVarVisitor final : public VNVisitor, public SplitVarImpl { AstAssign* const ap = new AstAssign{fl, lhsp, rhsp}; if (lvalue) { // If varp is LHS, this assignment must appear after the original - // assignment(context). - context->addNextHere(ap); + // assignment(contextp). + contextp->addNextHere(ap); } else { // If varp is RHS, this assignment comes just before the original assignment - context->addHereThisAsNext(ap); + contextp->addHereThisAsNext(ap); } UASSERT_OBJ(!m_contextp, m_contextp, "must be null"); setContextAndIterate(ap, refp); @@ -1364,6 +1387,7 @@ const char* SplitVarImpl::cannotSplitPackedVarReason(const AstVar* varp) { void V3SplitVar::splitVariable(AstNetlist* nodep) { UINFO(2, __FUNCTION__ << ":"); + SplitNodeOrder order; SplitVarRefs refs; { const SplitUnpackedVarVisitor visitor{nodep}; diff --git a/src/V3Task.cpp b/src/V3Task.cpp index a3fa624a8..a5da23eeb 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -1856,7 +1856,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp, if (!makeChanges) return tconnects; // Connect missing ones - std::set argWrap; // Which ports are defaulted, forcing arg wrapper creation + VInsertionSet argWrap; // Which ports are defaulted; need arg wrapper creation for (int i = 0; i < tpinnum; ++i) { AstVar* const portp = tconnects[i].first; if (!tconnects[i].second || !tconnects[i].second->exprp()) { @@ -1882,7 +1882,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp, if (statep) { portp->pinNum(i + 1); // Make sure correct, will use to build name UINFO(9, "taskConnects arg wrapper needed " << portp->valuep()); - argWrap.emplace(portp); + argWrap.insert(portp); } else { // statep = nullptr, called too late or otherwise to handle args // Problem otherwise is we might have a varref, task // call, or something else that only makes sense in the @@ -1956,7 +1956,8 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp, } void V3Task::taskConnectWrap(AstNodeFTaskRef* nodep, const V3TaskConnects& tconnects, - V3TaskConnectState* statep, const std::set& argWrap) { + V3TaskConnectState* statep, + const VInsertionSet& argWrap) { statep->setDidWrap(); // Make wrapper name such that is same iff same args are defaulted std::string newname = nodep->name() + "__Vtcwrap"; @@ -1973,7 +1974,7 @@ void V3Task::taskConnectWrap(AstNodeFTaskRef* nodep, const V3TaskConnects& tconn for (const auto& tconnect : tconnects) { const AstVar* const portp = tconnect.first; AstArg* const argp = tconnect.second; - if (argWrap.find(portp) != argWrap.end()) { // Removed arg + if (argWrap.exists(portp)) { // Removed arg statep->pushDeletep(argp->unlinkFrBack()); } } @@ -1985,7 +1986,7 @@ void V3Task::taskConnectWrap(AstNodeFTaskRef* nodep, const V3TaskConnects& tconn AstNodeFTask* V3Task::taskConnectWrapNew(AstNodeFTask* taskp, const string& newname, const V3TaskConnects& tconnects, - const std::set& argWrap) { + const VInsertionSet& argWrap) { std::map oldNewVars; // Old -> new var mappings AstNodeFTask* const newTaskp = taskp->cloneType(newname); @@ -2019,7 +2020,7 @@ AstNodeFTask* V3Task::taskConnectWrapNew(AstNodeFTask* taskp, const string& newn for (const auto& tconnect : tconnects) { AstVar* const portp = tconnect.first; AstVar* newPortp; - if (argWrap.find(portp) == argWrap.end()) { // Not removed arg + if (!argWrap.exists(portp)) { // Not removed arg newPortp = new AstVar{portp->fileline(), portp->varType(), portp->name(), portp}; newPortp->propagateWrapAttrFrom(portp); newPortp->funcLocal(true); diff --git a/src/V3Task.h b/src/V3Task.h index 378e87330..553af1f70 100644 --- a/src/V3Task.h +++ b/src/V3Task.h @@ -21,6 +21,7 @@ #include "verilatedos.h" #include "V3Ast.h" +#include "V3Container.h" #include "V3Error.h" #include @@ -58,10 +59,10 @@ public: bool makeChanges = true) VL_MT_DISABLED; static void taskConnectWrap(AstNodeFTaskRef* nodep, const V3TaskConnects& tconnects, V3TaskConnectState* statep, - const std::set& argWrap) VL_MT_DISABLED; - static AstNodeFTask* taskConnectWrapNew(AstNodeFTask* taskp, const string& newname, - const V3TaskConnects& tconnects, - const std::set& argWrap) VL_MT_DISABLED; + const VInsertionSet& argWrap) VL_MT_DISABLED; + static AstNodeFTask* + taskConnectWrapNew(AstNodeFTask* taskp, const string& newname, const V3TaskConnects& tconnects, + const VInsertionSet& argWrap) VL_MT_DISABLED; static string assignInternalToDpi(AstVar* portp, bool isPtr, const string& frSuffix, const string& toSuffix, const string& frPrefix = "") VL_MT_DISABLED; From 108d209bd7bedc2a6a00f19a2310a9f22c7da61c Mon Sep 17 00:00:00 2001 From: Yilou Wang Date: Sun, 1 Mar 2026 21:16:55 +0100 Subject: [PATCH 4/8] Support soft constraint solving with last-wins priority (#7124) (#7166) --- include/verilated_random.cpp | 33 ++++++++-- include/verilated_random.h | 5 +- src/V3AstAttr.h | 2 + src/V3Randomize.cpp | 6 +- test_regress/t/t_randomize_soft.py | 21 +++++++ test_regress/t/t_randomize_soft.v | 99 ++++++++++++++++++++++++++++++ 6 files changed, 159 insertions(+), 7 deletions(-) create mode 100755 test_regress/t/t_randomize_soft.py create mode 100644 test_regress/t/t_randomize_soft.v diff --git a/include/verilated_random.cpp b/include/verilated_random.cpp index 2a1f3d562..4ed746e86 100644 --- a/include/verilated_random.cpp +++ b/include/verilated_random.cpp @@ -496,6 +496,9 @@ bool VlRandomizer::next(VlRNG& rngr) { std::iostream& os = getSolver(); if (!os) return false; + // Soft constraint relaxation (IEEE 1800-2017 18.5.13, last-wins priority): + // Try hard + soft[0..N-1], then hard + soft[1..N-1], ..., then hard only. + // First SAT phase wins. If hard-only is UNSAT, report via unsat-core. os << "(set-option :produce-models true)\n"; os << "(set-logic QF_ABV)\n"; os << "(define-fun __Vbv ((b Bool)) (_ BitVec 1) (ite b #b1 #b0))\n"; @@ -520,9 +523,20 @@ bool VlRandomizer::next(VlRNG& rngr) { os << "(assert (= " << pair.first << " (_ bv" << pair.second << " " << w << ")))\n"; } - os << "(check-sat)\n"; + const size_t nSoft = m_softConstraints.size(); + bool sat = false; + for (size_t phase = 0; phase <= nSoft && !sat; ++phase) { + const bool hasSoft = (phase < nSoft); + if (hasSoft) { + os << "(push 1)\n"; + for (size_t i = phase; i < nSoft; ++i) + os << "(assert (= #b1 " << m_softConstraints[i] << "))\n"; + } + os << "(check-sat)\n"; + sat = parseSolution(os, /*log=*/phase == nSoft); + if (!sat && hasSoft) os << "(pop 1)\n"; + } - bool sat = parseSolution(os, true); if (!sat) { // If unsat, use named assertions to get unsat-core os << "(reset)\n"; @@ -541,8 +555,11 @@ bool VlRandomizer::next(VlRNG& rngr) { } int j = 0; for (const std::string& constraint : m_constraints) { - os << "(assert (! (= #b1 " << constraint << ") :named cons" << j << "))\n"; - j++; + os << "(assert (! (= #b1 " << constraint << ") :named cons" << j++ << "))\n"; + } + for (const auto& pair : randcPinned) { + const int w = m_vars.at(pair.first)->width(); + os << "(assert (= " << pair.first << " (_ bv" << pair.second << " " << w << ")))\n"; } os << "(check-sat)\n"; sat = parseSolution(os, true); @@ -550,6 +567,7 @@ bool VlRandomizer::next(VlRNG& rngr) { os << "(reset)\n"; return false; } + for (int i = 0; i < _VL_SOLVER_HASH_LEN_TOTAL && sat; ++i) { os << "(assert "; randomConstraint(os, rngr, _VL_SOLVER_HASH_LEN); @@ -723,15 +741,22 @@ void VlRandomizer::hard(std::string&& constraint, const char* filename, uint32_t } } +void VlRandomizer::soft(std::string&& constraint, const char* /*filename*/, uint32_t /*linenum*/, + const char* /*source*/) { + m_softConstraints.emplace_back(std::move(constraint)); +} + void VlRandomizer::clearConstraints() { m_constraints.clear(); m_constraints_line.clear(); m_solveBefore.clear(); + m_softConstraints.clear(); // Keep m_vars for class member randomization } void VlRandomizer::clearAll() { m_constraints.clear(); + m_softConstraints.clear(); m_vars.clear(); m_randcVarNames.clear(); m_randcValueQueues.clear(); diff --git a/include/verilated_random.h b/include/verilated_random.h index 53c09f071..993778b55 100644 --- a/include/verilated_random.h +++ b/include/verilated_random.h @@ -200,9 +200,10 @@ public: // Object holding constraints and variable references. class VlRandomizer VL_NOT_FINAL { // MEMBERS - std::vector m_constraints; // Solver-dependent constraints + std::vector m_constraints; // Solver-dependent hard constraints std::vector m_constraints_line; // fileline content of the constraint for unsat constraints + std::vector m_softConstraints; // Soft constraints std::map> m_vars; // Solver-dependent // variables ArrayInfoMap m_arr_vars; // Tracks each element in array structures for iteration @@ -593,6 +594,8 @@ public: void hard(std::string&& constraint, const char* filename = "", uint32_t linenum = 0, const char* source = ""); + void soft(std::string&& constraint, const char* filename = "", uint32_t linenum = 0, + const char* source = ""); void clearConstraints(); void clearAll(); // Clear both constraints and variables void markRandc(const char* name); // Mark variable as randc for cyclic tracking diff --git a/src/V3AstAttr.h b/src/V3AstAttr.h index e879adfed..bfe9ba1fb 100644 --- a/src/V3AstAttr.h +++ b/src/V3AstAttr.h @@ -815,6 +815,7 @@ public: RANDOMIZER_CLEARCONSTRAINTS, RANDOMIZER_CLEARALL, RANDOMIZER_HARD, + RANDOMIZER_SOFT, RANDOMIZER_UNIQUE, RANDOMIZER_MARK_RANDC, RANDOMIZER_SOLVE_BEFORE, @@ -951,6 +952,7 @@ inline std::ostream& operator<<(std::ostream& os, const VCMethod& rhs) { {RANDOMIZER_CLEARCONSTRAINTS, "clearConstraints", false}, \ {RANDOMIZER_CLEARALL, "clearAll", false}, \ {RANDOMIZER_HARD, "hard", false}, \ + {RANDOMIZER_SOFT, "soft", false}, \ {RANDOMIZER_UNIQUE, "rand_unique", false}, \ {RANDOMIZER_MARK_RANDC, "markRandc", false}, \ {RANDOMIZER_SOLVE_BEFORE, "solveBefore", false}, \ diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index b80679b27..f03093ca5 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -1906,12 +1906,14 @@ class ConstraintExprVisitor final : public VNVisitor { VL_DO_DANGLING(nodep->deleteTree(), nodep); return; } - // Only hard constraints are currently supported + // Emit as soft or hard constraint per IEEE 1800-2017 18.5.13 + const VCMethod method + = nodep->isSoft() ? VCMethod::RANDOMIZER_SOFT : VCMethod::RANDOMIZER_HARD; AstCMethodHard* const callp = new AstCMethodHard{ nodep->fileline(), new AstVarRef{nodep->fileline(), VN_AS(m_genp->user2p(), NodeModule), m_genp, VAccess::READWRITE}, - VCMethod::RANDOMIZER_HARD, nodep->exprp()->unlinkFrBack()}; + method, nodep->exprp()->unlinkFrBack()}; callp->dtypeSetVoid(); // Pass filename, lineno, and source as separate arguments // This allows EmitC to call protect() on filename, similar to VL_STOP diff --git a/test_regress/t/t_randomize_soft.py b/test_regress/t/t_randomize_soft.py new file mode 100755 index 000000000..db1adb3f9 --- /dev/null +++ b/test_regress/t/t_randomize_soft.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +if not test.have_solver: + test.skip("No constraint solver installed") + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_randomize_soft.v b/test_regress/t/t_randomize_soft.v new file mode 100644 index 000000000..2fe4cfa1c --- /dev/null +++ b/test_regress/t/t_randomize_soft.v @@ -0,0 +1,99 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 PlanV GmbH +// SPDX-License-Identifier: CC0-1.0 + +// Test soft constraint solving per IEEE 1800-2017 section 18.5.13 + +// verilog_format: off +`define stop $stop +`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); +`define check_range(gotv,minv,maxv) do if ((gotv) < (minv) || (gotv) > (maxv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d-%0d\n", `__FILE__,`__LINE__, (gotv), (minv), (maxv)); `stop; end while(0); +// verilog_format: on + +// Case 1: Only soft, no hard -- soft should be satisfied +class Case1; + rand int x; + constraint c_soft { soft x == 5; } +endclass + +// Case 2: Two soft on same var -- last-wins (c_b declared after c_a) +class Case2; + rand int x; + constraint c_a { soft x == 5; } + constraint c_b { soft x == 10; } +endclass + +// Case 3: Soft on different vars -- both should be satisfied +class Case3; + rand int x; + rand int y; + constraint c_x { soft x == 7; } + constraint c_y { soft y == 3; } +endclass + +// Case 4: Soft range partially covered by hard -- SAT at intersection +class Case4; + rand int x; + constraint c_soft { soft x inside {[1:10]}; } + constraint c_hard { x inside {[5:15]}; } +endclass + +// Case 5: Soft completely overridden by hard -- hard wins +class Case5; + rand int x; + constraint c_soft { soft x == 5; } + constraint c_hard { x > 10; } +endclass + +module t; + Case1 c1; + Case2 c2; + Case3 c3; + Case4 c4; + Case5 c5; + int rand_ok; + + initial begin + c1 = new; + c2 = new; + c3 = new; + c4 = new; + c5 = new; + + repeat (20) begin + // Case 1: only soft, no hard -- soft satisfied + rand_ok = c1.randomize(); + `checkd(rand_ok, 1) + `checkd(c1.x, 5) + + // Case 2: two soft on same var -- last-wins + rand_ok = c2.randomize(); + `checkd(rand_ok, 1) + `checkd(c2.x, 10) + + // Case 3: soft on different vars -- both satisfied + rand_ok = c3.randomize(); + `checkd(rand_ok, 1) + `checkd(c3.x, 7) + `checkd(c3.y, 3) + + // Case 4: soft range partially covered by hard -- intersection [5:10] + rand_ok = c4.randomize(); + `checkd(rand_ok, 1) + `check_range(c4.x, 5, 10) + + // Case 5: soft completely overridden by hard -- hard wins + rand_ok = c5.randomize(); + `checkd(rand_ok, 1) + if (c5.x <= 10) begin + $write("%%Error: %s:%0d: x=%0d should be > 10\n", `__FILE__, `__LINE__, c5.x); + `stop; + end + end + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule From 8a413b3ec7983e16c6f0598ecd40db8ee58e3f9d Mon Sep 17 00:00:00 2001 From: Yilou Wang Date: Mon, 2 Mar 2026 11:59:00 +0100 Subject: [PATCH 5/8] Fix std::randomize() in static function with static class members (#7167) (#7169) --- src/V3Randomize.cpp | 22 +++++++-- test_regress/t/t_randomize_std_static.py | 21 +++++++++ test_regress/t/t_randomize_std_static.v | 60 ++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 3 deletions(-) create mode 100755 test_regress/t/t_randomize_std_static.py create mode 100644 test_regress/t/t_randomize_std_static.v diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index f03093ca5..4e5e25eff 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -2180,6 +2180,7 @@ class CaptureVisitor final : public VNVisitor { std::map m_varCloneMap; // Map original var nodes to their clones std::set m_ignore; // Nodes to ignore for capturing AstVar* m_thisp = nullptr; // Variable for outer context's object, if necessary + bool m_staticContext = false; // True when capturing from a static function context // METHODS @@ -2252,6 +2253,11 @@ class CaptureVisitor final : public VNVisitor { if (varIsParam) return CaptureMode::CAP_VALUE; // Static var in function (will not be inlined, because it's in class) if (callerIsClass && varIsFuncLocal) return CaptureMode::CAP_VALUE; + // Static class members in static context don't need 'this' capture; + // V3Class will move both the function and the member to __Vclpkg + if (m_staticContext && callerIsClass && varIsFieldOfCaller + && varRefp->varp()->lifetime().isStatic()) + return CaptureMode::CAP_NO; if (callerIsClass && varIsFieldOfCaller) return CaptureMode::CAP_THIS; UASSERT_OBJ(!callerIsClass, varRefp, "Invalid reference?"); return CaptureMode::CAP_VALUE; @@ -2372,10 +2378,12 @@ class CaptureVisitor final : public VNVisitor { void visit(AstNode* nodep) override { iterateChildren(nodep); } public: - explicit CaptureVisitor(AstNode* const nodep, AstNodeModule* callerp, AstClass* const targetp) + explicit CaptureVisitor(AstNode* const nodep, AstNodeModule* callerp, AstClass* const targetp, + bool staticContext = false) : m_argsp{nullptr} , m_callerp{callerp} - , m_targetp{targetp} { + , m_targetp{targetp} + , m_staticContext{staticContext} { iterateAndNextNull(nodep); } @@ -3771,9 +3779,16 @@ class RandomizeVisitor final : public VNVisitor { if (nodep->classOrPackagep() && nodep->classOrPackagep()->name() == "std") { // Handle std::randomize; create wrapper function that calls basicStdRandomization on // each varref argument, then transform nodep to call that wrapper + const bool inStaticContext = m_ftaskp && m_ftaskp->isStatic(); AstVar* const stdrand = createStdRandomGenerator(m_modp); AstFunc* const randomizeFuncp = V3Randomize::newRandomizeStdFunc( m_memberMap, m_modp, m_inlineUniqueStdName.get(nodep)); + // When called from a static function, mark helper and stdrand as static + // so V3Class moves them to __Vclpkg alongside the calling function + if (inStaticContext) { + stdrand->lifetime(VLifetime::STATIC_EXPLICIT); + randomizeFuncp->isStatic(true); + } randomizeFuncp->addStmtsp( new AstAssign{nodep->fileline(), new AstVarRef{nodep->fileline(), VN_AS(randomizeFuncp->fvarp(), Var), @@ -3829,7 +3844,8 @@ class RandomizeVisitor final : public VNVisitor { } if (withp) { FileLine* const fl = nodep->fileline(); - withCapturep = std::make_unique(withp->exprp(), m_modp, nullptr); + withCapturep = std::make_unique(withp->exprp(), m_modp, nullptr, + inStaticContext); withCapturep->addFunctionArguments(randomizeFuncp); // Clear old constraints and variables for std::randomize with clause if (stdrand) { diff --git a/test_regress/t/t_randomize_std_static.py b/test_regress/t/t_randomize_std_static.py new file mode 100755 index 000000000..db1adb3f9 --- /dev/null +++ b/test_regress/t/t_randomize_std_static.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +if not test.have_solver: + test.skip("No constraint solver installed") + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_randomize_std_static.v b/test_regress/t/t_randomize_std_static.v new file mode 100644 index 000000000..7d56ac592 --- /dev/null +++ b/test_regress/t/t_randomize_std_static.v @@ -0,0 +1,60 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 PlanV GmbH +// SPDX-License-Identifier: CC0-1.0 + +// Test std::randomize() called from a static function referencing static +// class members in the 'with' clause. + +// verilog_format: off +`define stop $stop +`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); +// verilog_format: on + +module t; + + typedef enum bit [3:0] { + INSTR_ADD = 0, + INSTR_SUB = 1, + INSTR_MUL = 2, + INSTR_AND = 4 + } instr_name_t; + + class instr_base; + static instr_name_t allowed_instrs[$]; + + static function void init(); + allowed_instrs.push_back(INSTR_ADD); + allowed_instrs.push_back(INSTR_SUB); + allowed_instrs.push_back(INSTR_MUL); + allowed_instrs.push_back(INSTR_AND); + endfunction + + static function instr_name_t get_rand_instr(); + instr_name_t name; + int ok; + ok = std::randomize(name) with { + name inside {allowed_instrs}; + }; + `checkd(ok, 1); + return name; + endfunction + endclass + + initial begin + instr_name_t result; + + instr_base::init(); + + repeat (20) begin + result = instr_base::get_rand_instr(); + `checkd(result == INSTR_ADD || result == INSTR_SUB + || result == INSTR_MUL || result == INSTR_AND, 1); + end + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule From a3870c5e5e00640ace3f6c5c9b5e5262fabadccb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 10:52:53 -0500 Subject: [PATCH 6/8] CI: depandabot: Bump actions with 2 updates (#7172) --- .github/workflows/build-test.yml | 2 +- .github/workflows/coverage.yml | 10 +++++----- .github/workflows/reusable-build.yml | 2 +- .github/workflows/reusable-rtlmeter-build.yml | 2 +- .github/workflows/reusable-rtlmeter-run.yml | 4 ++-- .github/workflows/reusable-test.yml | 4 ++-- .github/workflows/rtlmeter-pr-results.yml | 4 ++-- .github/workflows/rtlmeter.yml | 16 ++++++++-------- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 1d61ec338..f2ad62009 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -155,7 +155,7 @@ jobs: - name: Zip up repository run: Compress-Archive -LiteralPath install -DestinationPath verilator.zip - name: Upload zip archive - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: path: ${{ github.workspace }}/repo/verilator.zip name: verilator-win.zip diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 148c7980c..55c7d0450 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -77,7 +77,7 @@ jobs: uses: actions/checkout@v6 - name: Download code coverage data - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: pattern: code-coverage-* path: obj_coverage @@ -114,7 +114,7 @@ jobs: sudo apt install lcov - name: Download repository archive - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: ${{ needs.build.outputs.archive }} path: ${{ github.workspace }} @@ -125,7 +125,7 @@ jobs: ls -lsha - name: Download code coverage data - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: pattern: code-coverage-* path: repo/obj_coverage @@ -170,14 +170,14 @@ jobs: fi - name: Upload report - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: path: repo/obj_coverage name: coverage-report - name: Upload notification if: ${{ github.event_name == 'pull_request' }} - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: path: repo/notification name: coverage-pr-notification diff --git a/.github/workflows/reusable-build.yml b/.github/workflows/reusable-build.yml index 2818c1455..7138a7cce 100644 --- a/.github/workflows/reusable-build.yml +++ b/.github/workflows/reusable-build.yml @@ -93,7 +93,7 @@ jobs: echo "archive=$ARCHIVE" >> "$GITHUB_OUTPUT" - name: Upload repository archive - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: path: ${{ github.workspace }}/${{ steps.create-archive.outputs.archive }} name: ${{ steps.create-archive.outputs.archive }} diff --git a/.github/workflows/reusable-rtlmeter-build.yml b/.github/workflows/reusable-rtlmeter-build.yml index 068729a0d..345abbee7 100644 --- a/.github/workflows/reusable-rtlmeter-build.yml +++ b/.github/workflows/reusable-rtlmeter-build.yml @@ -70,7 +70,7 @@ jobs: run: tar --posix -c -z -f verilator-rtlmeter.tar.gz install - name: Upload Verilator installation archive - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: path: verilator-rtlmeter.tar.gz name: verilator-rtlmeter-${{ inputs.runs-on }}-${{ inputs.cc }} diff --git a/.github/workflows/reusable-rtlmeter-run.yml b/.github/workflows/reusable-rtlmeter-run.yml index 95525125f..c2746209c 100644 --- a/.github/workflows/reusable-rtlmeter-run.yml +++ b/.github/workflows/reusable-rtlmeter-run.yml @@ -64,7 +64,7 @@ jobs: sudo apt install ccache mold libfl-dev libgoogle-perftools-dev libsystemc-dev - name: Download Verilator installation archive - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: verilator-rtlmeter-${{ inputs.runs-on }}-${{ inputs.cc }} @@ -117,7 +117,7 @@ jobs: ./rtlmeter report --steps '*' --metrics '*' ../results-${{ steps.results.outputs.hash }}.json - name: Upload results - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: path: results-${{ steps.results.outputs.hash }}.json name: rtlmeter-${{ inputs.tag }}-results-${{ steps.results.outputs.hash }} diff --git a/.github/workflows/reusable-test.yml b/.github/workflows/reusable-test.yml index d2fb687c3..7e20f292c 100644 --- a/.github/workflows/reusable-test.yml +++ b/.github/workflows/reusable-test.yml @@ -55,7 +55,7 @@ jobs: steps: - name: Download repository archive - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: ${{ inputs.archive }} path: ${{ github.workspace }} @@ -99,7 +99,7 @@ jobs: - name: Upload code coverage data if: ${{ inputs.dev-gcov }} - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: path: ${{ github.workspace }}/repo/obj_coverage/verilator-${{ inputs.suite }}.info name: code-coverage-${{ inputs.suite }} diff --git a/.github/workflows/rtlmeter-pr-results.yml b/.github/workflows/rtlmeter-pr-results.yml index 5ce1b0fdc..745267cab 100644 --- a/.github/workflows/rtlmeter-pr-results.yml +++ b/.github/workflows/rtlmeter-pr-results.yml @@ -20,13 +20,13 @@ jobs: pull-requests: write steps: - name: Download report - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: rtlmeter-pr-results run-id: ${{ github.event.workflow_run.id }} github-token: ${{ secrets.GITHUB_TOKEN }} - name: Download PR number - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: pr-number run-id: ${{ github.event.workflow_run.id }} diff --git a/.github/workflows/rtlmeter.yml b/.github/workflows/rtlmeter.yml index 3dee9f230..a5f43ef26 100644 --- a/.github/workflows/rtlmeter.yml +++ b/.github/workflows/rtlmeter.yml @@ -198,7 +198,7 @@ jobs: working-directory: rtlmeter run: make venv - name: Download all results - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: pattern: rtlmeter-${{ matrix.tag }}-results-* path: all-results-${{ matrix.tag }} @@ -208,7 +208,7 @@ jobs: run: | ./rtlmeter collate ../all-results-${{ matrix.tag }}/*.json > ../all-results-${{ matrix.tag }}.json - name: Upload combined results - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: path: all-results-${{ matrix.tag }}.json name: all-results-${{ matrix.tag }} @@ -227,13 +227,13 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Download combined results - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: pattern: all-results-* path: results merge-multiple: true - name: Upload published results - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: path: results/*.json name: published-results @@ -289,7 +289,7 @@ jobs: working-directory: rtlmeter run: make venv - name: Download combined results - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: pattern: all-results-* path: all-results @@ -308,7 +308,7 @@ jobs: DATE=$(gh run --repo ${{ github.repository }} view $ID --json createdAt --jq ".createdAt") echo "date=$DATE" >> $GITHUB_OUTPUT - name: Download scheduled run results - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: published-results path: nightly-results @@ -374,14 +374,14 @@ jobs: done cat report.txt - name: Upload report - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: path: report.txt name: rtlmeter-pr-results - name: Save PR number run: echo ${{ github.event.number }} > pr-number.txt - name: Upload PR number - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: path: pr-number.txt name: pr-number From 251d1835cf33bea53fd158cced56639141de782b Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 1 Mar 2026 10:36:53 -0500 Subject: [PATCH 7/8] Internals: Comment to explain stray emit semicolon --- src/V3EmitCFunc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/V3EmitCFunc.h b/src/V3EmitCFunc.h index 1ee0d3aa5..df70952c9 100644 --- a/src/V3EmitCFunc.h +++ b/src/V3EmitCFunc.h @@ -734,8 +734,8 @@ public: puts(";\n"); } void visit(AstCNew* nodep) override { - if (VN_IS(nodep->dtypep(), VoidDType)) { - // super.new case + if (VN_IS(nodep->dtypep(), VoidDType)) { // super.new case + putsDecoration(nodep, "/*super.new*/"); return; } // assignment case; From d406efdcf966218bbce0bc4834e6fde306f4cf53 Mon Sep 17 00:00:00 2001 From: jalcim Date: Mon, 2 Mar 2026 15:15:34 -0500 Subject: [PATCH 8/8] Fix recursive constant function in $unit scope (#7174) (#7178) --- docs/CONTRIBUTORS | 1 + src/V3Scope.cpp | 1 + test_regress/t/t_func_unit_recursive.py | 18 ++++++++++++ test_regress/t/t_func_unit_recursive.v | 38 +++++++++++++++++++++++++ 4 files changed, 58 insertions(+) create mode 100755 test_regress/t/t_func_unit_recursive.py create mode 100644 test_regress/t/t_func_unit_recursive.v diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 5ac1958e1..de64a9a88 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -99,6 +99,7 @@ Ivan Vnučec Iztok Jeras Jake Merdich Jakub Wasilewski +jalcim James Bailey James Hanlon James Hutchinson diff --git a/src/V3Scope.cpp b/src/V3Scope.cpp index b10ac4999..29c3cc534 100644 --- a/src/V3Scope.cpp +++ b/src/V3Scope.cpp @@ -259,6 +259,7 @@ class ScopeVisitor final : public VNVisitor { clonep = nodep->cloneTree(false); } nodep->user2p(clonep); + clonep->user2p(clonep); // For recursive self-references after cloneTree m_scopep->addBlocksp(clonep); // We iterate under the *clone* iterateChildren(clonep); diff --git a/test_regress/t/t_func_unit_recursive.py b/test_regress/t/t_func_unit_recursive.py new file mode 100755 index 000000000..8a938befd --- /dev/null +++ b/test_regress/t/t_func_unit_recursive.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_func_unit_recursive.v b/test_regress/t/t_func_unit_recursive.v new file mode 100644 index 000000000..40096c953 --- /dev/null +++ b/test_regress/t/t_func_unit_recursive.v @@ -0,0 +1,38 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 jalcim +// SPDX-License-Identifier: CC0-1.0 + +// Recursive constant function defined at file scope ($unit). +// Without the V3Scope.cpp fix, this triggers: +// %Error: Internal Error: V3Scope.cpp: No clone for package function + +function automatic integer gate_depth; + input integer way; + integer d1, d2, sc, n1, n2; + begin + if (way <= 1) gate_depth = 0; + else if (way <= 4) gate_depth = 1; + else begin + sc = $clog2(way); + n1 = 1 << (sc - 1); + n2 = way - n1; + d1 = gate_depth(n1); + d2 = gate_depth(n2); + gate_depth = ((d1 > d2) ? d1 : d2) + 1; + end + end +endfunction + +module t; + localparam D5 = gate_depth(5); + localparam D8 = gate_depth(8); + + initial begin + if (D5 !== 2) $stop; + if (D8 !== 2) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule