Refactor V3Delay for extensibility (#5516)

* Refactor V3Delay for extensibility

Introduce the concept of an "NBA Scheme", which is the lowering pattern
we can use for various variables that are the targets of NBAs.
E.g.:
 - ShadowVariable (old default scheme)
 - FlagShared (old array set flag scheme)
 - ValueQueueWhole (recent dynamic commit queue)

We now analyse all AstAssignDly before making any decisions on which
scheme to apply. We then choose a specific scheme for each variable that
is the target of an NBA, and then all NBAs targeting that variable use
the same scheme. This enables easy mix and match of schemes as needed,
while remaining consistent by design after extensions.

Output is perturbed due to node insertion order, but no functional
or performance change is intended.
This commit is contained in:
Geza Lore 2024-10-09 10:39:40 +01:00 committed by GitHub
parent 920c8012de
commit 5acced1e33
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 935 additions and 745 deletions

View File

@ -1,6 +1,6 @@
.. comment: generated by t_lint_multidriven_bad
.. code-block::
%Warning-MULTIDRIVEN: example.v:1:22 Signal has multiple driving blocks with different clocking: 't.mem'
%Warning-MULTIDRIVEN: example.v:1:22 Signal has multiple driving blocks with different clocking: 'out2'
example.v:1:7 ... Location of first driving block
example.v:1:7 ... Location of other driving block

File diff suppressed because it is too large Load Diff

View File

@ -4,8 +4,8 @@
t/t_assign_on_rhs_of_nonblocking_unsup.v:24:18: ... Location of blocking assignment
24 | y <= (x = 2);
| ^
t/t_assign_on_rhs_of_nonblocking_unsup.v:21:10: ... Location of nonblocking assignment
t/t_assign_on_rhs_of_nonblocking_unsup.v:21:12: ... Location of nonblocking assignment
21 | x <= 1;
| ^
| ^~
... For error description see https://verilator.org/warn/BLKANDNBLK?v=latest
%Error: Exiting due to

View File

@ -1141,13 +1141,13 @@
]}
],
"thensp": [
{"type":"STMTEXPR","name":"","addr":"(KR)","loc":"d,65:10,65:11",
{"type":"STMTEXPR","name":"","addr":"(KR)","loc":"d,23:17,23:20",
"exprp": [
{"type":"CCALL","name":"","addr":"(LR)","loc":"d,65:10,65:11","dtypep":"(CB)","funcName":"_nba_sequent__TOP__0","funcp":"(MR)","argsp": []}
{"type":"CCALL","name":"","addr":"(LR)","loc":"d,23:17,23:20","dtypep":"(CB)","funcName":"_nba_sequent__TOP__0","funcp":"(MR)","argsp": []}
]}
],"elsesp": []}
],"finalsp": []},
{"type":"CFUNC","name":"_nba_sequent__TOP__0","addr":"(MR)","loc":"d,65:10,65:11","slow":false,"isStatic":false,"dpiExportDispatcher":false,"dpiExportImpl":false,"dpiImportPrototype":false,"dpiImportWrapper":false,"dpiContext":false,"isConstructor":false,"isDestructor":false,"isVirtual":false,"isCoroutine":false,"needProcess":false,"scopep":"(Y)","argsp": [],
{"type":"CFUNC","name":"_nba_sequent__TOP__0","addr":"(MR)","loc":"d,23:17,23:20","slow":false,"isStatic":false,"dpiExportDispatcher":false,"dpiExportImpl":false,"dpiImportPrototype":false,"dpiImportWrapper":false,"dpiContext":false,"isConstructor":false,"isDestructor":false,"isVirtual":false,"isCoroutine":false,"needProcess":false,"scopep":"(Y)","argsp": [],
"initsp": [
{"type":"VAR","name":"__Vdly__t.cyc","addr":"(NR)","loc":"d,23:17,23:20","dtypep":"(R)","origName":"__Vdly__t__DOT__cyc","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":true,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"BLOCKTEMP","dtypeName":"integer","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
{"type":"CRESET","name":"","addr":"(OR)","loc":"d,23:17,23:20",
@ -1164,19 +1164,19 @@
{"type":"VAR","name":"__Vtemp_3","addr":"(VR)","loc":"d,88:123,88:124","dtypep":"(RB)","origName":"__Vtemp_3","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"STMTTEMP","dtypeName":"string","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}
],
"stmtsp": [
{"type":"ASSIGNPRE","name":"","addr":"(WR)","loc":"d,65:10,65:11","dtypep":"(AC)",
{"type":"ASSIGNPRE","name":"","addr":"(WR)","loc":"d,23:17,23:20","dtypep":"(R)",
"rhsp": [
{"type":"VARREF","name":"t.e","addr":"(XR)","loc":"d,65:10,65:11","dtypep":"(AC)","access":"RD","varp":"(L)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"t.cyc","addr":"(XR)","loc":"d,23:17,23:20","dtypep":"(R)","access":"RD","varp":"(Q)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"lhsp": [
{"type":"VARREF","name":"__Vdly__t.e","addr":"(YR)","loc":"d,65:10,65:11","dtypep":"(AC)","access":"WR","varp":"(QR)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vdly__t.cyc","addr":"(YR)","loc":"d,23:17,23:20","dtypep":"(R)","access":"WR","varp":"(NR)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],"timingControlp": []},
{"type":"ASSIGNPRE","name":"","addr":"(ZR)","loc":"d,62:7,62:10","dtypep":"(R)",
{"type":"ASSIGNPRE","name":"","addr":"(ZR)","loc":"d,24:9,24:10","dtypep":"(AC)",
"rhsp": [
{"type":"VARREF","name":"t.cyc","addr":"(AS)","loc":"d,62:7,62:10","dtypep":"(R)","access":"RD","varp":"(Q)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"t.e","addr":"(AS)","loc":"d,24:9,24:10","dtypep":"(AC)","access":"RD","varp":"(L)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"lhsp": [
{"type":"VARREF","name":"__Vdly__t.cyc","addr":"(BS)","loc":"d,62:7,62:10","dtypep":"(R)","access":"WR","varp":"(NR)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vdly__t.e","addr":"(BS)","loc":"d,24:9,24:10","dtypep":"(AC)","access":"WR","varp":"(QR)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],"timingControlp": []},
{"type":"ASSIGNDLY","name":"","addr":"(CS)","loc":"d,62:11,62:13","dtypep":"(R)",
"rhsp": [
@ -2510,19 +2510,19 @@
]}
]}
]},
{"type":"ASSIGNPOST","name":"","addr":"(KKB)","loc":"d,62:7,62:10","dtypep":"(R)",
{"type":"ASSIGNPOST","name":"","addr":"(KKB)","loc":"d,23:17,23:20","dtypep":"(R)",
"rhsp": [
{"type":"VARREF","name":"__Vdly__t.cyc","addr":"(LKB)","loc":"d,62:7,62:10","dtypep":"(R)","access":"RD","varp":"(NR)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vdly__t.cyc","addr":"(LKB)","loc":"d,23:17,23:20","dtypep":"(R)","access":"RD","varp":"(NR)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"lhsp": [
{"type":"VARREF","name":"t.cyc","addr":"(MKB)","loc":"d,62:7,62:10","dtypep":"(R)","access":"WR","varp":"(Q)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"t.cyc","addr":"(MKB)","loc":"d,23:17,23:20","dtypep":"(R)","access":"WR","varp":"(Q)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],"timingControlp": []},
{"type":"ASSIGNPOST","name":"","addr":"(NKB)","loc":"d,65:10,65:11","dtypep":"(AC)",
{"type":"ASSIGNPOST","name":"","addr":"(NKB)","loc":"d,24:9,24:10","dtypep":"(AC)",
"rhsp": [
{"type":"VARREF","name":"__Vdly__t.e","addr":"(OKB)","loc":"d,65:10,65:11","dtypep":"(AC)","access":"RD","varp":"(QR)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vdly__t.e","addr":"(OKB)","loc":"d,24:9,24:10","dtypep":"(AC)","access":"RD","varp":"(QR)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],
"lhsp": [
{"type":"VARREF","name":"t.e","addr":"(PKB)","loc":"d,65:10,65:11","dtypep":"(AC)","access":"WR","varp":"(L)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"t.e","addr":"(PKB)","loc":"d,24:9,24:10","dtypep":"(AC)","access":"WR","varp":"(L)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
],"timingControlp": []}
],"finalsp": []},
{"type":"CFUNC","name":"_eval_phase__act","addr":"(QKB)","loc":"a,0:0,0:0","slow":false,"isStatic":false,"dpiExportDispatcher":false,"dpiExportImpl":false,"dpiImportPrototype":false,"dpiImportWrapper":false,"dpiContext":false,"isConstructor":false,"isDestructor":false,"isVirtual":false,"isCoroutine":false,"needProcess":false,"scopep":"(Y)","argsp": [],

View File

@ -1,17 +1,17 @@
%Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:19:22: Signal has multiple driving blocks with different clocking: 'out2'
t/t_lint_multidriven_bad.v:35:7: ... Location of first driving block
35 | out2[15:8] <= d0;
| ^~~~
t/t_lint_multidriven_bad.v:32:7: ... Location of other driving block
32 | out2[7:0] <= d0;
| ^~~~
... For warning description see https://verilator.org/warn/MULTIDRIVEN?v=latest
... Use "/* verilator lint_off MULTIDRIVEN */" and lint_on around source to disable this message.
%Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:21:22: Signal has multiple driving blocks with different clocking: 't.mem'
t/t_lint_multidriven_bad.v:27:7: ... Location of first driving block
27 | mem[a0] <= d1;
| ^~~
t/t_lint_multidriven_bad.v:24:7: ... Location of other driving block
t/t_lint_multidriven_bad.v:24:7: ... Location of first driving block
24 | mem[a0] <= d0;
| ^~~
t/t_lint_multidriven_bad.v:27:7: ... Location of other driving block
27 | mem[a0] <= d1;
| ^~~
... For warning description see https://verilator.org/warn/MULTIDRIVEN?v=latest
... Use "/* verilator lint_off MULTIDRIVEN */" and lint_on around source to disable this message.
%Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:19:22: Signal has multiple driving blocks with different clocking: 'out2'
t/t_lint_multidriven_bad.v:32:7: ... Location of first driving block
32 | out2[7:0] <= d0;
| ^~~~
t/t_lint_multidriven_bad.v:35:7: ... Location of other driving block
35 | out2[15:8] <= d0;
| ^~~~
%Error: Exiting due to

View File

@ -14,7 +14,7 @@ test.scenarios('simulator')
test.compile(verilator_flags2=["--stats"])
if test.vlt_all:
test.file_grep(test.stats, r'Optimizations, Delayed shared-sets\s+(\d+)', 14)
test.file_grep(test.stats, r'Optimizations, NBA flags shared\s+(\d+)', 14)
test.execute()

View File

@ -15,9 +15,7 @@ test.compile(verilator_flags2=["-unroll-count 1", "--stats"])
test.execute()
test.file_grep(test.stats,
r'Dynamic NBA, variables needing commit queue without partial updates\s+(\d+)', 6)
test.file_grep(test.stats,
r'Dynamic NBA, variables needing commit queue with partial updates\s+(\d+)', 3)
test.file_grep(test.stats, r'NBA, variables using ValueQueueWhole scheme\s+(\d+)', 6)
test.file_grep(test.stats, r'NBA, variables using ValueQueuePartial scheme\s+(\d+)', 3)
test.passes()

View File

@ -0,0 +1,21 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2024 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt_all')
test.compile(verilator_flags2=["--exe", "--main", "--timing", "-unroll-count 1", "--stats"])
test.execute()
test.file_grep(test.stats, r'NBA, variables using ValueQueueWhole scheme\s+(\d+)', 2)
test.file_grep(test.stats, r'NBA, variables using ValueQueuePartial scheme\s+(\d+)', 0)
test.passes()

View File

@ -0,0 +1,66 @@
// DESCRIPTION: Verilator: Test of select from constant
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2024 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0)
module t;
reg clk = 0;
always #50 clk = ~clk;
initial begin
#1000;
$write("*-* All Finished *-*\n");
$finish;
end
int cyc = 0;
always @(posedge clk) cyc <= cyc + 1;
localparam SIZE = 65536;
// Case 1: Array NBA inside suspendable
int array1 [SIZE];
always @ (posedge clk) begin
#1;
for (int i=0; i<SIZE; i++) array1[i] <= cyc + i;
if (cyc > 1) begin
for (int i=0; i<SIZE; i++) `checkh(array1[i], cyc - 1 + i);
end
#1;
for (int i=0; i<SIZE; i++) `checkh(array1[i], cyc + i);
end
// Case 2: Array NBA to array also assigned in suspendable
int array2 [SIZE];
always @ (posedge clk) begin
for (int i=0; i<SIZE; i++) array2[i] <= cyc + i;
end
always @(posedge clk) begin
#2 array2[1] <= 1111;
#2 array2[3] <= 3333;
#2 array2[5] <= 5555;
end
initial begin
@(posedge clk);
@(posedge clk);
@(posedge clk);
#1;
for (int i=0; i<SIZE; i++) `checkh(array2[i], cyc - 1 + i);
#2;
for (int i=0; i<SIZE; i++) `checkh(array2[i], i == 1 ? 1111 : cyc - 1 + i);
#2;
for (int i=0; i<SIZE; i++) `checkh(array2[i], i == 1 ? 1111 : i == 3 ? 3333 : cyc - 1 + i);
#2;
for (int i=0; i<SIZE; i++) `checkh(array2[i], i == 1 ? 1111 : i == 3 ? 3333 : i == 5 ? 5555 : cyc - 1 + i);
end
endmodule

View File

@ -1,18 +1,6 @@
%Error-BLKLOOPINIT: t/t_order_blkloopinit_bad.v:26:20: Unsupported: Non-blocking assignment to array inside loop in suspendable process or fork
%Error-BLKLOOPINIT: t/t_order_blkloopinit_bad.v:26:20: Unsupported: Non-blocking assignment to array with compound element type inside loop
: ... note: In instance 't'
26 | array1[i] <= 0;
26 | array2[i] <= null;
| ^~
... For error description see https://verilator.org/warn/BLKLOOPINIT?v=latest
%Error-BLKLOOPINIT: t/t_order_blkloopinit_bad.v:36:20: Unsupported: Non-blocking assignment to array with compound element type inside loop
: ... note: In instance 't'
36 | array2[i] <= null;
| ^~
%Error-BLKLOOPINIT: t/t_order_blkloopinit_bad.v:45:20: Unsupported: Non-blocking assignment to array in both loop and suspendable process/fork
: ... note: In instance 't'
t/t_order_blkloopinit_bad.v:50:20: ... Location of non-blocking assignment in suspendable process/fork
50 | #1 array3[0] <= 0;
| ^~
t/t_order_blkloopinit_bad.v:45:20: ... Location of non-blocking assignment inside loop
45 | array3[i] <= 0;
| ^~
%Error: Exiting due to

View File

@ -11,6 +11,6 @@ import vltest_bootstrap
test.scenarios('vlt')
test.lint(verilator_flags2=["--timing"], fails=True, expect_filename=test.golden_filename)
test.lint(verilator_flags2=[], fails=True, expect_filename=test.golden_filename)
test.passes()

View File

@ -17,17 +17,7 @@ module t (/*AUTOARG*/
localparam SIZE = 65536;
// Unsupported case 1: Array NBA inside suspendable
int array1 [SIZE];
always @ (posedge clk) begin
#1;
o <= array1[1];
for (int i=0; i<SIZE; i++) begin
array1[i] <= 0; // BLKLOOPINIT
end
end
// Unsupported case 2: Array NBA to compund type
// Unsupported case 1: Array NBA to compund type
class C; endclass
C array2[SIZE];
always @ (negedge clk) begin
@ -37,17 +27,4 @@ module t (/*AUTOARG*/
end
end
// Unsupported case 3: Array NBA to array also assigned in suspendable
int array3 [SIZE];
always @ (posedge clk) begin
o <= array3[1];
for (int i=0; i<SIZE; i++) begin
array3[i] <= 0; // BLKLOOPINIT
end
end
always @(posedge clk) begin
#1 array3[0] <= 0;
end
endmodule

View File

@ -697,13 +697,13 @@
</cmethodhard>
</and>
<begin>
<stmtexpr loc="d,65,10,65,11">
<ccall loc="d,65,10,65,11" dtype_id="7" func="_nba_sequent__TOP__0"/>
<stmtexpr loc="d,23,17,23,20">
<ccall loc="d,23,17,23,20" dtype_id="7" func="_nba_sequent__TOP__0"/>
</stmtexpr>
</begin>
</if>
</cfunc>
<cfunc loc="d,65,10,65,11" name="_nba_sequent__TOP__0">
<cfunc loc="d,23,17,23,20" name="_nba_sequent__TOP__0">
<var loc="d,23,17,23,20" name="__Vdly__t.cyc" dtype_id="4" vartype="integer" origName="__Vdly__t__DOT__cyc"/>
<creset loc="d,23,17,23,20">
<varref loc="d,23,17,23,20" name="__Vdly__t.cyc" dtype_id="4"/>
@ -715,13 +715,13 @@
<var loc="d,68,123,68,124" name="__Vtemp_1" dtype_id="10" vartype="string" origName="__Vtemp_1"/>
<var loc="d,78,123,78,124" name="__Vtemp_2" dtype_id="10" vartype="string" origName="__Vtemp_2"/>
<var loc="d,88,123,88,124" name="__Vtemp_3" dtype_id="10" vartype="string" origName="__Vtemp_3"/>
<assignpre loc="d,65,10,65,11" dtype_id="11">
<varref loc="d,65,10,65,11" name="t.e" dtype_id="11"/>
<varref loc="d,65,10,65,11" name="__Vdly__t.e" dtype_id="11"/>
<assignpre loc="d,23,17,23,20" dtype_id="4">
<varref loc="d,23,17,23,20" name="t.cyc" dtype_id="4"/>
<varref loc="d,23,17,23,20" name="__Vdly__t.cyc" dtype_id="4"/>
</assignpre>
<assignpre loc="d,62,7,62,10" dtype_id="4">
<varref loc="d,62,7,62,10" name="t.cyc" dtype_id="4"/>
<varref loc="d,62,7,62,10" name="__Vdly__t.cyc" dtype_id="4"/>
<assignpre loc="d,24,9,24,10" dtype_id="11">
<varref loc="d,24,9,24,10" name="t.e" dtype_id="11"/>
<varref loc="d,24,9,24,10" name="__Vdly__t.e" dtype_id="11"/>
</assignpre>
<assigndly loc="d,62,11,62,13" dtype_id="4">
<add loc="d,62,18,62,19" dtype_id="4">
@ -1514,13 +1514,13 @@
</if>
</begin>
</if>
<assignpost loc="d,62,7,62,10" dtype_id="4">
<varref loc="d,62,7,62,10" name="__Vdly__t.cyc" dtype_id="4"/>
<varref loc="d,62,7,62,10" name="t.cyc" dtype_id="4"/>
<assignpost loc="d,23,17,23,20" dtype_id="4">
<varref loc="d,23,17,23,20" name="__Vdly__t.cyc" dtype_id="4"/>
<varref loc="d,23,17,23,20" name="t.cyc" dtype_id="4"/>
</assignpost>
<assignpost loc="d,65,10,65,11" dtype_id="11">
<varref loc="d,65,10,65,11" name="__Vdly__t.e" dtype_id="11"/>
<varref loc="d,65,10,65,11" name="t.e" dtype_id="11"/>
<assignpost loc="d,24,9,24,10" dtype_id="11">
<varref loc="d,24,9,24,10" name="__Vdly__t.e" dtype_id="11"/>
<varref loc="d,24,9,24,10" name="t.e" dtype_id="11"/>
</assignpost>
</cfunc>
<cfunc loc="a,0,0,0,0" name="_eval_phase__act">