diff --git a/Changes b/Changes index 342b29182..3f180a002 100644 --- a/Changes +++ b/Changes @@ -15,7 +15,30 @@ Verilator 5.053 devel **Other:** +* Add covergroup runtime registry (#8134). [Matthew Ballance] +* Add initial support for solo `binsof` (#8298). [Marco Bartoli] * Change JSON dumps to suppress empty strings, etc. +* Support nested array and associative array element member access in constraint 1/4 - pre-cleanup (#8237). [Kamil Danecki, Antmicro Ltd.] +* Support unique constraint inside std::randomize (#8241). [Kornel Uriasz, Antmicro Ltd.] +* Support non-overlapped property implications correctly (#8268). [Artur Bieniek, Antmicro Ltd.] +* Optimize DFG synthesis symbol table ordering (#8282). [Geza Lore, Testorrent USA, Inc.] +* Optimize redundant vertex cache lookups in DFG peephole (#8283). [Geza Lore, Testorrent USA, Inc.] +* Optimize DFG vertex iteration callbacks (#8284). [Geza Lore, Testorrent USA, Inc.] +* Optimize redundant memoization in DFG CSE (#8285). [Geza Lore, Testorrent USA, Inc.] +* Optimize DFG synthesis of simple continuous assignments (#8286). [Geza Lore, Testorrent USA, Inc.] +* Optimize more selects in DFG (#8292). [Geza Lore, Testorrent USA, Inc.] +* Optimize netlist teardown when about to exit (#8294). [Geza Lore, Testorrent USA, Inc.] +* Optimize data-type type chain recursion (#8310). [Geza Lore, Testorrent USA, Inc.] +* Fix array slice crash when used as a bare value (#5132) (#8262). [Marco Frank] +* Fix covergroup-internal references multi-threaded ordering (#7779) (#8255). [Matthew Ballance] +* Fix detecting non-inlined awaits in V3Delayed.cpp (#7982). [Igor Zaworski, Antmicro Ltd.] +* Fix phased `solve...before` diversity (#8189) (#8194). [Aditya Shevade] +* Fix array-size constraint on arrays inside base class (#8219). [Kornel Uriasz, Antmicro Ltd.] +* Fix multidimensional packed array type handling (#8235). [Artur Bieniek, Antmicro Ltd.] +* Fix library method argument references (#8252). [Geza Lore, Testorrent USA, Inc.] +* Fix assignment pattern default fill of an array of unpacked structs (#8289). [Nick Brereton] +* Fix escape strings in pattern formatting (#8297). [Marco Bartoli] +* Fix DECLFILENAME warning on nested declarations (#8302). [Martijn Wobbes] Verilator 5.052 2026-09-05 @@ -1863,7 +1886,7 @@ Verilator 5.016 2023-09-16 * Optimize Verilator executable size by refactoring error reporting routines (#4446). [Anthony Donlon] * Optimize Verilation runtime pointers and graphs (#4396) (#4397) (#4398). [Krzysztof Bieganski, Antmicro Ltd] * Optimize preparations towards multithreaded Verilation (#4291) (#4463) (#4476) (#4477) (#4479). [Kamil Rakoczy, Antmicro Ltd] -* Fix Windows filename format, etc (#3873) (#4421). [Anthony Donlon]. +* Fix Windows filename format, etc (#3873) (#4421). [Anthony Donlon] * Fix t_dist_cppstyle Perl performance issue (#4085). [Srinivasan Venkataramanan] * Fix using type in parameterized classes without #() (#4281) (#4440). [Anthony Donlon] * Fix false INFINITELOOP on forever..mailbox.get() (#4323). [Srinivasan Venkataramanan] @@ -3648,7 +3671,7 @@ Verilator 3.880 2015-12-19 * Fix model restore crash. (#1013) [Jason McMullan] * Fix arrayed instances to unpacked of same size. (#1015) [Varun Koyyalagunta] * Fix slices of unpacked arrays with non-zero LSBs. -* Fix ternary operation with unpacked array. (#1017) [Varun Koyyalagunta]. +* Fix ternary operation with unpacked array. (#1017) [Varun Koyyalagunta] Verilator 3.878 2015-11-01 @@ -3738,7 +3761,7 @@ Verilator 3.870 2015-02-12 * Suppress COMBDLY when inside always_latch. (#864) [Iztok Jeras] * Support cast operator with expression size. (#865) [Iztok Jeras] -* Add warning on slice selection out of bounds. (#875) [Cong Van Nguyen]. +* Add warning on slice selection out of bounds. (#875) [Cong Van Nguyen] * Fix member select error broke in 3.868. (#867) [Iztok Jeras] * Fix $sccanf from string. (#866) [David Pierce] * Fix VM_PARALLEL_BUILDS broke in 3.868. (#870) [Hiroki Honda] diff --git a/docs/spelling.txt b/docs/spelling.txt index 90c6de3fe..894e820f0 100644 --- a/docs/spelling.txt +++ b/docs/spelling.txt @@ -627,6 +627,7 @@ benchmarking biguint binToOneHot bindir +binsof biops bisonpre bitOpTree @@ -947,6 +948,7 @@ makefile makefiles malloc manpages +memoization metacomment metacomments miree @@ -1182,6 +1184,7 @@ systemc taskify tcmalloc tcmalloc +teardown tenghtt testbench testbenches diff --git a/nodist/log_changes b/nodist/log_changes index c4632e355..022d386c2 100755 --- a/nodist/log_changes +++ b/nodist/log_changes @@ -25,8 +25,10 @@ def message_section(msg: str) -> int: return 50 if re.match(r'^Support', msg, flags=re.IGNORECASE): return 60 - if re.match(r'^Fix', msg, flags=re.IGNORECASE): + if re.match(r'^Optimize', msg, flags=re.IGNORECASE): return 70 + if re.match(r'^Fix', msg, flags=re.IGNORECASE): + return 80 if re.match(r'^(Internals|CI|Tests)', msg, flags=re.IGNORECASE): return -1 if re.match(r'^Bump.* from .* to .*', msg, flags=re.IGNORECASE): # dependabot diff --git a/test_regress/t/t_covergroup_inst_churn.v b/test_regress/t/t_covergroup_inst_churn.v index 2a58263dc..54a8e1082 100644 --- a/test_regress/t/t_covergroup_inst_churn.v +++ b/test_regress/t/t_covergroup_inst_churn.v @@ -55,7 +55,7 @@ module t ( if (cyc < CHURN) begin cg = new; - v = cyc[1:0]; + v = cyc[1:0]; cg.sample(); // Live when sampled, so a working registry reports >= 1. Zero would mean @@ -64,7 +64,8 @@ module t ( if (live > peak_live) peak_live = live; cg = null; // Last handle dropped; collected at the next eval_step - end else if (cyc == CHURN + 2) begin + end + else if (cyc == CHURN + 2) begin // Two edges after the final drop, so the last instance has been collected. live = $c32("Verilated::threadContextp()->covergroupRegistryp()->liveInstanceCount()"); created = $c32("Verilated::threadContextp()->covergroupRegistryp()->createdInstanceCount()"); diff --git a/test_regress/t/t_covergroup_inst_handle.v b/test_regress/t/t_covergroup_inst_handle.v index 2c80a8ac4..2f7d77560 100644 --- a/test_regress/t/t_covergroup_inst_handle.v +++ b/test_regress/t/t_covergroup_inst_handle.v @@ -32,7 +32,8 @@ module t ( g = new; v = 0; g.sample(); - end else if (g == null) begin + end + else if (g == null) begin // Never taken. It exists to *read* g: a covergroup handle that is written // and never read is localized into this block, and the instance would then // be dropped at the end of the edge that created it -- leaving nothing diff --git a/test_regress/t/t_covergroup_inst_lifetime.v b/test_regress/t/t_covergroup_inst_lifetime.v index 205309529..f78615227 100644 --- a/test_regress/t/t_covergroup_inst_lifetime.v +++ b/test_regress/t/t_covergroup_inst_lifetime.v @@ -41,14 +41,16 @@ module t ( cg.sample(); end cg = null; // last handle dropped; freed at the next eval_step - end else if (cyc < 20) begin + end + else if (cyc < 20) begin // Churn: each of these reuses the freed storage of an earlier instance, // so a stale count pointer reads a live instance's counter instead. cg = new; - v = 2'b11; + v = 2'b11; cg.sample(); cg = null; - end else if (cyc == 20) begin + end + else if (cyc == 20) begin $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_covergroup_inst_retain.v b/test_regress/t/t_covergroup_inst_retain.v index fb7c63c14..ade73c5a9 100644 --- a/test_regress/t/t_covergroup_inst_retain.v +++ b/test_regress/t/t_covergroup_inst_retain.v @@ -60,7 +60,8 @@ module t ( function int retired_cov_x100(); retired_cov_x100 = $c32( "(int)(Verilated::threadContextp()->covergroupRegistryp()", - "->retiredCoverage(\"cg_retain\") * 100.0 + 0.5)"); + "->retiredCoverage(\"cg_retain\") * 100.0 + 0.5)" + ); endfunction // Hit bins lo .. hi. Sampling from a loop, not straight-line assignments. diff --git a/test_regress/t/t_covergroup_inst_retire.v b/test_regress/t/t_covergroup_inst_retire.v index bc8859655..3185ee8dd 100644 --- a/test_regress/t/t_covergroup_inst_retire.v +++ b/test_regress/t/t_covergroup_inst_retire.v @@ -75,8 +75,8 @@ module t ( // observability, not an SV-visible surface, so they are reached through $c. // The type name is the covergroup's name as the code generator emits it. function int slot_live(); - slot_live = $c32( - "Verilated::threadContextp()->covergroupRegistryp()->liveInstanceCount(\"cg_slot\")"); + slot_live = + $c32("Verilated::threadContextp()->covergroupRegistryp()->liveInstanceCount(\"cg_slot\")"); endfunction function int slot_retired(); slot_retired = $c32( @@ -87,7 +87,8 @@ module t ( function int slot_retired_cov_x100(); slot_retired_cov_x100 = $c32( "(int)(Verilated::threadContextp()->covergroupRegistryp()", - "->retiredCoverage(\"cg_slot\") * 100.0 + 0.5)"); + "->retiredCoverage(\"cg_slot\") * 100.0 + 0.5)" + ); endfunction function int fold_retired(); fold_retired = $c32( @@ -96,7 +97,8 @@ module t ( function int fold_retired_cov_x100(); fold_retired_cov_x100 = $c32( "(int)(Verilated::threadContextp()->covergroupRegistryp()", - "->retiredCoverage(\"cg_fold\") * 100.0 + 0.5)"); + "->retiredCoverage(\"cg_fold\") * 100.0 + 0.5)" + ); endfunction function int none_retired(); none_retired = $c32( @@ -105,36 +107,42 @@ module t ( function int none_retired_cov_x100(); none_retired_cov_x100 = $c32( "(int)(Verilated::threadContextp()->covergroupRegistryp()", - "->retiredCoverage(\"cg_none\") * 100.0 + 0.5)"); + "->retiredCoverage(\"cg_none\") * 100.0 + 0.5)" + ); endfunction // retiredCoverage() reports "no data" as a negative, distinct from 0.0; the // x100 helpers cannot tell the two apart. function int slot_retired_cov_is_none(); slot_retired_cov_is_none = $c32( "(Verilated::threadContextp()->covergroupRegistryp()", - "->retiredCoverage(\"cg_slot\") < 0.0 ? 1 : 0)"); + "->retiredCoverage(\"cg_slot\") < 0.0 ? 1 : 0)" + ); endfunction // Queries against a type the registry has never heard of: 0 / 0 / 0 / negative. function int unknown_live(); unknown_live = $c32( "Verilated::threadContextp()->covergroupRegistryp()", - "->liveInstanceCount(\"cg_no_such_type\")"); + "->liveInstanceCount(\"cg_no_such_type\")" + ); endfunction function int unknown_created(); unknown_created = $c32( "Verilated::threadContextp()->covergroupRegistryp()", - "->createdInstanceCount(\"cg_no_such_type\")"); + "->createdInstanceCount(\"cg_no_such_type\")" + ); endfunction function int unknown_retired(); unknown_retired = $c32( "Verilated::threadContextp()->covergroupRegistryp()", - "->retiredInstanceCount(\"cg_no_such_type\")"); + "->retiredInstanceCount(\"cg_no_such_type\")" + ); endfunction function int unknown_cov_is_none(); unknown_cov_is_none = $c32( "(Verilated::threadContextp()->covergroupRegistryp()", - "->retiredCoverage(\"cg_no_such_type\") < 0.0 ? 1 : 0)"); + "->retiredCoverage(\"cg_no_such_type\") < 0.0 ? 1 : 0)" + ); endfunction // Hit every bin of one cg_slot instance, so get_inst_coverage() reads 100%. diff --git a/test_regress/t/t_covergroup_ref_bind.v b/test_regress/t/t_covergroup_ref_bind.v index 87890a4c1..6a2b4ef15 100644 --- a/test_regress/t/t_covergroup_ref_bind.v +++ b/test_regress/t/t_covergroup_ref_bind.v @@ -65,10 +65,10 @@ module t ( cg_w w_stale_hold; initial begin - z_alias = z_first; - z_alias2 = z_second; + z_alias = z_first; + z_alias2 = z_second; w_stale_hold = w_stale; - w_stale = w_real; + w_stale = w_real; end always @(posedge clk) x_inst.sample(); diff --git a/test_regress/t/t_covergroup_ref_bind_lvalue.v b/test_regress/t/t_covergroup_ref_bind_lvalue.v index 22d249957..a1a52e2d6 100644 --- a/test_regress/t/t_covergroup_ref_bind_lvalue.v +++ b/test_regress/t/t_covergroup_ref_bind_lvalue.v @@ -33,9 +33,7 @@ module t ( cg_a arr[2]; - typedef struct { - cg_b cg; - } struct_t; + typedef struct {cg_b cg;} struct_t; struct_t s0; struct_t s1; diff --git a/test_regress/t/t_covergroup_sample_comb_loop.v b/test_regress/t/t_covergroup_sample_comb_loop.v index d4b03d696..905cfd8f8 100644 --- a/test_regress/t/t_covergroup_sample_comb_loop.v +++ b/test_regress/t/t_covergroup_sample_comb_loop.v @@ -27,7 +27,7 @@ module t ( logic [1:0] dir_req; logic [1:0] dir_gnt; - covergroup cg_ref (ref logic [1:0] sig); + covergroup cg_ref(ref logic [1:0] sig); cp_ref: coverpoint sig { bins zero = {2'b00}; bins one = {2'b01}; bins two = {2'b10}; bins three = {2'b11}; } diff --git a/test_regress/t/t_covergroup_sample_order.v b/test_regress/t/t_covergroup_sample_order.v index a4f3d8e00..e1001ffd6 100644 --- a/test_regress/t/t_covergroup_sample_order.v +++ b/test_regress/t/t_covergroup_sample_order.v @@ -52,19 +52,19 @@ module t ( case (cyc) 0: begin - data <= 2'b00; + data <= 2'b00; refsig <= 2'b00; end 1: begin - data <= 2'b01; + data <= 2'b01; refsig <= 2'b01; end 2: begin - data <= 2'b10; + data <= 2'b10; refsig <= 2'b10; end 3: begin - data <= 2'b11; + data <= 2'b11; refsig <= 2'b11; end 4: begin diff --git a/test_regress/t/t_math_insert_bound_unaligned.v b/test_regress/t/t_math_insert_bound_unaligned.v index f48dd8386..b310fc5d8 100644 --- a/test_regress/t/t_math_insert_bound_unaligned.v +++ b/test_regress/t/t_math_insert_bound_unaligned.v @@ -11,64 +11,64 @@ // wide, where computing the index's maximum value can overflow. module t ( - clk + clk ); - input clk; + input clk; - // Each struct is 480 bits (15 words) with `dat` last, so a write to the - // nonexistent bit 500 lands on word 15, one past the end of the struct. - typedef struct packed { - logic [30:0] idx; - logic [448:0] dat; - } s31_t; + // Each struct is 480 bits (15 words) with `dat` last, so a write to the + // nonexistent bit 500 lands on word 15, one past the end of the struct. + typedef struct packed { + logic [30:0] idx; + logic [448:0] dat; + } s31_t; - typedef struct packed { - logic [31:0] idx; - logic [447:0] dat; - } s32_t; + typedef struct packed { + logic [31:0] idx; + logic [447:0] dat; + } s32_t; - typedef struct packed { - logic [32:0] idx; - logic [446:0] dat; - } s33_t; + typedef struct packed { + logic [32:0] idx; + logic [446:0] dat; + } s33_t; - s31_t s31; - s32_t s32; - s33_t s33; + s31_t s31; + s32_t s32; + s33_t s33; - always_ff @(posedge clk) begin : blk - logic [443:0] v; - int sel; + always_ff @(posedge clk) begin : blk + logic [443:0] v; + int sel; - sel = 440; - void'($value$plusargs("SEL=%d", sel)); + sel = 440; + void'($value$plusargs("SEL=%d", sel)); - // Writes bits 471:440: the top four bits of `v`, then 28 that do not exist. - v = '0; - v[sel +: 32] = 32'hcafef00d; + // Writes bits 471:440: the top four bits of `v`, then 28 that do not exist. + v = '0; + v[sel+:32] = 32'hcafef00d; - $write("v=%h\n", v[443:412]); + $write("v=%h\n", v[443:412]); - // Bit 500 of `dat` does not exist. Index it with widths around 32 bits. - s31 = '0; - s32 = '0; - s33 = '0; + // Bit 500 of `dat` does not exist. Index it with widths around 32 bits. + s31 = '0; + s32 = '0; + s33 = '0; - // verilator lint_off WIDTHTRUNC - s31.idx = 500; - s31.dat[s31.idx] = 1'b1; + // verilator lint_off WIDTHTRUNC + s31.idx = 500; + s31.dat[s31.idx] = 1'b1; - s32.idx = 500; - s32.dat[s32.idx] = 1'b1; + s32.idx = 500; + s32.dat[s32.idx] = 1'b1; - s33.idx = 500; - s33.dat[s33.idx] = 1'b1; - // verilator lint_on WIDTHTRUNC + s33.idx = 500; + s33.dat[s33.idx] = 1'b1; + // verilator lint_on WIDTHTRUNC - $write("dat=%h %h %h\n", s31.dat[446:415], s32.dat[445:414], s33.dat[444:413]); - $write("*-* All Finished *-*\n"); - $finish; - end + $write("dat=%h %h %h\n", s31.dat[446:415], s32.dat[445:414], s33.dat[444:413]); + $write("*-* All Finished *-*\n"); + $finish; + end endmodule diff --git a/test_regress/t/t_randomize_solve_before_diversity.v b/test_regress/t/t_randomize_solve_before_diversity.v index e598dacc8..3a98c3f34 100644 --- a/test_regress/t/t_randomize_solve_before_diversity.v +++ b/test_regress/t/t_randomize_solve_before_diversity.v @@ -15,12 +15,8 @@ class SolveBeforeDiversity; rand bit s; rand bit [7:0] d; - constraint c { - s -> d == 0; - } - constraint order { - solve s before d; - } + constraint c {s -> d == 0;} + constraint order {solve s before d;} endclass module t; diff --git a/test_regress/t/t_randomize_within_func.v b/test_regress/t/t_randomize_within_func.v index d17390857..6cbd4264e 100644 --- a/test_regress/t/t_randomize_within_func.v +++ b/test_regress/t/t_randomize_within_func.v @@ -13,7 +13,7 @@ class Cls; if (a != 1) $stop; // Problem 2 (Fixed): m_2 should be 3 or 4, but get out-of-range return if (!(m_2 > 2 && m_2 < 5)) $stop; - // Problem 1 (Fixed): Got %Warning: /svaha/wsnyder/SandBox/homecvs/v4/verilator/include/verilated_random.cpp:417: Internal: Solver error: (error "line 9 column 27: invalid empty $ + // Problem 1 (Fixed): Got %Warning: Internal: Solver error: (error "line 9 column 27: invalid empty... a = this.randomize() with {m_1 > 5 && m_1 < 10;}; $display("%d: a=%0d %0d", `__LINE__, a, m_1); if (a != 1) $stop; diff --git a/test_regress/t/t_slice_display.v b/test_regress/t/t_slice_display.v index a3568d321..4efb2fde9 100644 --- a/test_regress/t/t_slice_display.v +++ b/test_regress/t/t_slice_display.v @@ -20,13 +20,20 @@ module t; byte emem[5:12] = '{201, 202, 203, 204, 205, 206, 207, 208}; // Wide descending declaration with a non-zero low index - logic [95:0] memwide[10:6] = '{96'hE444_4444_4444_4444_4444_4444, 96'hA000_0000_0000_0000_0000_0001, - 96'hB111_1111_1111_1111_1111_1111, 96'hC222_2222_2222_2222_2222_2222, - 96'hD333_3333_3333_3333_3333_3333}; + logic [95:0] memwide[10:6] = '{ + 96'hE444_4444_4444_4444_4444_4444, + 96'hA000_0000_0000_0000_0000_0001, + 96'hB111_1111_1111_1111_1111_1111, + 96'hC222_2222_2222_2222_2222_2222, + 96'hD333_3333_3333_3333_3333_3333 + }; // For slicing the inner and outer dimensions of a 2D array - byte mem2d[3][8] = '{'{1, 2, 3, 4, 5, 6, 7, 8}, '{11, 12, 13, 14, 15, 16, 17, 18}, - '{21, 22, 23, 24, 25, 26, 27, 28}}; + byte mem2d[3][8] = '{ + '{1, 2, 3, 4, 5, 6, 7, 8}, + '{11, 12, 13, 14, 15, 16, 17, 18}, + '{21, 22, 23, 24, 25, 26, 27, 28} + }; task automatic check_arg(byte a[4]); `checkh(a[0], 8'd1);