Fix DFG removing forceable signals (#4942)

DFG could remove forceable signals by replacing them with their
in-design driver. This is a bit of a pain to prevent, and ideally the
forcing transform should happen before DFG, but implementing it there is
a pain due to having to rewrite ports based on direction.  This is an
attempted fix in DFG. More cases might remain.
This commit is contained in:
Geza Lore 2024-03-03 16:22:41 +00:00 committed by GitHub
parent 0fbd4313b2
commit 745605efe3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 137 additions and 61 deletions

View File

@ -439,11 +439,14 @@ class AstToDfgVisitor final : public VNVisitor {
if (nodep->isSc()) return;
// No need to (and in fact cannot) handle variables with unsupported dtypes
if (!DfgVertex::isSupportedDType(nodep->dtypep())) return;
// Mark ports as having external references
if (nodep->isIO()) getNet(nodep)->setHasExtRefs();
// Mark variables that are the target of a hierarchical reference
// (these flags were set up in DataflowPrepVisitor)
if (nodep->user2()) getNet(nodep)->setHasExtRefs();
// Mark variables with external references
if (nodep->isIO() // Ports
|| nodep->user2() // Target of a hierarchical reference
|| nodep->isForceable() // Forceable
) {
getNet(nodep)->setHasExtRefs();
}
}
void visit(AstAssignW* nodep) override {

View File

@ -167,9 +167,14 @@ void V3DfgPasses::inlineVars(const DfgGraph& dfg) {
if (varp->hasSinks() && varp->isDrivenFullyByDfg() && !varp->varp()->isSc()) {
DfgVertex* const driverp = varp->source(0);
// If driven from a SystemC variable, don't inline this variable
// We must keep the original driver in certain cases, when swapping them would
// not be functionally or technically (implementation reasons) equivalent
if (DfgVertexVar* const driverVarp = driverp->cast<DfgVarPacked>()) {
if (driverVarp->varp()->isSc()) continue;
const AstVar* const varp = driverVarp->varp();
// If driven from a SystemC variable
if (varp->isSc()) continue;
// If the variable is forceable
if (varp->isForceable()) continue;
}
varp->forEachSinkEdge([=](DfgEdge& edge) {

View File

@ -248,7 +248,9 @@ public:
: DfgVertexVar{dfg, dfgType(), varp, 1u} {}
ASTGEN_MEMBERS_DfgVarPacked;
bool isDrivenFullyByDfg() const { return arity() == 1 && source(0)->dtypep() == dtypep(); }
bool isDrivenFullyByDfg() const {
return arity() == 1 && source(0)->dtypep() == dtypep() && !varp()->isForceable();
}
void addDriver(FileLine* flp, uint32_t lsb, DfgVertex* vtxp) {
m_driverData.emplace_back(flp, lsb);

View File

@ -32,41 +32,44 @@ module t (
assign net_1 = ~cyc[0];
assign net_8 = ~cyc[1 +: 8];
wire obs_1 = net_1;
wire [7:0] obs_8 = net_8;
always @ (posedge clk) begin
$display("%d: %x %x", cyc, net_8, net_1);
$display("%d: %x %x", cyc, obs_8, obs_1);
if (!rst) begin
case (cyc)
3: begin
`checkh (net_1, 0);
`checkh (net_8, ~cyc[1 +: 8]);
`checkh (obs_1, 0);
`checkh (obs_8, ~cyc[1 +: 8]);
end
4: begin
`checkh (net_1, 0);
`checkh (net_8, 8'h5f);
`checkh (obs_1, 0);
`checkh (obs_8, 8'h5f);
end
5: begin
`checkh (net_1, 1);
`checkh (net_8, 8'h5f);
`checkh (obs_1, 1);
`checkh (obs_8, 8'h5f);
end
6, 7: begin
`checkh (net_1, 1);
`checkh (net_8, 8'hf5);
`checkh (obs_1, 1);
`checkh (obs_8, 8'hf5);
end
8: begin
`checkh (net_1, ~cyc[0]);
`checkh (net_8, 8'hf5);
`checkh (obs_1, ~cyc[0]);
`checkh (obs_8, 8'hf5);
end
10, 11: begin
`checkh (net_1, 1);
`checkh (net_8, 8'h5a);
`checkh (obs_1, 1);
`checkh (obs_8, 8'h5a);
end
12, 13: begin
`checkh (net_1, 0);
`checkh (net_8, 8'ha5);
`checkh (obs_1, 0);
`checkh (obs_8, 8'ha5);
end
default: begin
`checkh ({net_8, net_1}, ~cyc[0 +: 9]);
`checkh ({obs_8, obs_1}, ~cyc[0 +: 9]);
end
endcase
end

View File

@ -1,6 +1,5 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module top $end
$var wire 1 # clk $end
$var wire 1 $ rst $end
@ -11,6 +10,8 @@ $timescale 1ps $end
$var wire 32 % cyc [31:0] $end
$var wire 1 & net_1 $end
$var wire 8 ' net_8 [7:0] $end
$var wire 1 & obs_1 $end
$var wire 8 ' obs_8 [7:0] $end
$upscope $end
$upscope $end
$enddefinitions $end

View File

@ -21,6 +21,19 @@ module t (
end
end
reg tmp_1;
reg [7:0] tmp_8;
always @(posedge clk) begin
if (rst) begin
tmp_1 <= 0;
tmp_8 <= 0;
end else begin
tmp_1 <= cyc[0];
tmp_8 <= cyc[1 +: 8];
end
end
`ifdef CMT
reg var_1 /* verilator forceable */;
reg [7:0] var_8 /* verilator forceable */;
@ -29,55 +42,54 @@ module t (
reg [7:0] var_8;
`endif
always @(posedge clk) begin
if (rst) begin
var_1 <= 0;
var_8 <= 0;
end else begin
var_1 <= cyc[0];
var_8 <= cyc[1 +: 8];
end
end
always @* var_1 = tmp_1;
always @* var_8 = tmp_8;
reg obs_1;
reg [7:0] obs_8;
always @* obs_1 = var_1;
always @* obs_8 = var_8;
always @ (posedge clk) begin
$display("%d: %x %x", cyc, var_8, var_1);
$display("%d: %x %x", cyc, obs_8, obs_1);
if (!rst) begin
case (cyc)
0: begin // Reset values
`checkh (var_1, 0);
`checkh (var_8, 0);
`checkh (obs_1, 0);
`checkh (obs_8, 0);
end
13: begin
`checkh (var_1, 1);
`checkh ({1'b0, var_8}, (cyc[0 +: 9] - 1) >> 1);
`checkh (obs_1, 1);
`checkh ({1'b0, obs_8}, (cyc[0 +: 9] - 1) >> 1);
end
14: begin
`checkh (var_1, 1);
`checkh (var_8, 8'hf5);
`checkh (obs_1, 1);
`checkh (obs_8, 8'hf5);
end
15: begin
`checkh (var_1, 0);
`checkh (var_8, 8'hf5);
`checkh (obs_1, 0);
`checkh (obs_8, 8'hf5);
end
16, 17: begin
`checkh (var_1, 0);
`checkh (var_8, 8'h5f);
`checkh (obs_1, 0);
`checkh (obs_8, 8'h5f);
end
18: begin
`checkh (var_1, ~cyc[0]);
`checkh (var_8, 8'h5f);
`checkh (obs_1, ~cyc[0]);
`checkh (obs_8, 8'h5f);
end
20, 21: begin
`checkh (var_1, 1);
`checkh (var_8, 8'h5a);
`checkh (obs_1, 1);
`checkh (obs_8, 8'h5a);
end
22, 23: begin
`checkh (var_1, 0);
`checkh (var_8, 8'ha5);
`checkh (obs_1, 0);
`checkh (obs_8, 8'ha5);
end
default: begin
`checkh ({var_8, var_1}, cyc[0 +: 9] - 1);
`checkh ({obs_8, obs_1}, cyc[0 +: 9] - 1);
end
endcase
end

View File

@ -1,6 +1,5 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module top $end
$var wire 1 # clk $end
$var wire 1 $ rst $end
@ -9,8 +8,12 @@ $timescale 1ps $end
$var wire 1 # clk $end
$var wire 1 $ rst $end
$var wire 32 % cyc [31:0] $end
$var wire 1 & var_1 $end
$var wire 8 ' var_8 [7:0] $end
$var wire 1 & tmp_1 $end
$var wire 8 ' tmp_8 [7:0] $end
$var wire 1 ( var_1 $end
$var wire 8 ) var_8 [7:0] $end
$var wire 1 ( obs_1 $end
$var wire 8 ) obs_8 [7:0] $end
$upscope $end
$upscope $end
$enddefinitions $end
@ -22,6 +25,8 @@ $enddefinitions $end
b00000000000000000000000000000000 %
0&
b00000000 '
0(
b00000000 )
#5
1#
0$
@ -36,6 +41,7 @@ b00000000000000000000000000000001 %
1#
b00000000000000000000000000000010 %
1&
1(
#30
0#
#35
@ -43,12 +49,15 @@ b00000000000000000000000000000010 %
b00000000000000000000000000000011 %
0&
b00000001 '
0(
b00000001 )
#40
0#
#45
1#
b00000000000000000000000000000100 %
1&
1(
#50
0#
#55
@ -56,12 +65,15 @@ b00000000000000000000000000000100 %
b00000000000000000000000000000101 %
0&
b00000010 '
0(
b00000010 )
#60
0#
#65
1#
b00000000000000000000000000000110 %
1&
1(
#70
0#
#75
@ -69,12 +81,15 @@ b00000000000000000000000000000110 %
b00000000000000000000000000000111 %
0&
b00000011 '
0(
b00000011 )
#80
0#
#85
1#
b00000000000000000000000000001000 %
1&
1(
#90
0#
#95
@ -82,12 +97,15 @@ b00000000000000000000000000001000 %
b00000000000000000000000000001001 %
0&
b00000100 '
0(
b00000100 )
#100
0#
#105
1#
b00000000000000000000000000001010 %
1&
1(
#110
0#
#115
@ -95,47 +113,59 @@ b00000000000000000000000000001010 %
b00000000000000000000000000001011 %
0&
b00000101 '
0(
b00000101 )
#120
0#
#125
1#
b00000000000000000000000000001100 %
1&
1(
#130
0#
#135
1#
b00000000000000000000000000001101 %
0&
b00000110 '
b00000110 )
#140
0#
#145
1#
b00000000000000000000000000001110 %
b11110101 '
1&
b11110101 )
#150
0#
#155
1#
b00000000000000000000000000001111 %
0&
b00000111 '
0(
#160
0#
#165
1#
b00000000000000000000000000010000 %
b01011111 '
1&
b01011111 )
#170
0#
#175
1#
b00000000000000000000000000010001 %
0&
b00001000 '
#180
0#
#185
1#
b00000000000000000000000000010010 %
1&
1(
#190
0#
#195
@ -143,37 +173,46 @@ b00000000000000000000000000010010 %
b00000000000000000000000000010011 %
0&
b00001001 '
0(
b00001001 )
#200
0#
#205
1#
b00000000000000000000000000010100 %
1&
b01011010 '
1(
b01011010 )
#210
0#
#215
1#
b00000000000000000000000000010101 %
0&
b00001010 '
#220
0#
#225
1#
b00000000000000000000000000010110 %
0&
b10100101 '
1&
0(
b10100101 )
#230
0#
#235
1#
b00000000000000000000000000010111 %
0&
b00001011 '
#240
0#
#245
1#
b00000000000000000000000000011000 %
1&
b00001011 '
1(
b00001011 )
#250
0#
#255
@ -181,12 +220,15 @@ b00001011 '
b00000000000000000000000000011001 %
0&
b00001100 '
0(
b00001100 )
#260
0#
#265
1#
b00000000000000000000000000011010 %
1&
1(
#270
0#
#275
@ -194,12 +236,15 @@ b00000000000000000000000000011010 %
b00000000000000000000000000011011 %
0&
b00001101 '
0(
b00001101 )
#280
0#
#285
1#
b00000000000000000000000000011100 %
1&
1(
#290
0#
#295
@ -207,12 +252,15 @@ b00000000000000000000000000011100 %
b00000000000000000000000000011101 %
0&
b00001110 '
0(
b00001110 )
#300
0#
#305
1#
b00000000000000000000000000011110 %
1&
1(
#310
0#
#315
@ -220,3 +268,5 @@ b00000000000000000000000000011110 %
b00000000000000000000000000011111 %
0&
b00001111 '
0(
b00001111 )