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
13 changed files with 935 additions and 745 deletions
+1 -1
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
+795 -655
View File
File diff suppressed because it is too large Load Diff
@@ -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
+15 -15
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": [],
+13 -13
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
+1 -1
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()
+2 -4
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()
+21
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()
@@ -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
+2 -14
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
+1 -1
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()
+1 -24
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
+15 -15
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">