* Fix #4832. Bit-op-tree opt. should not touch a subtree under NOT in AND/OR tree.
This commit is contained in:
parent
3a5248a919
commit
50df902b54
|
|
@ -541,6 +541,8 @@ class ConstBitOpTreeVisitor final : public VNVisitorConst {
|
|||
CONST_BITOP_RETURN_IF(m_failed, nodep->rhsp());
|
||||
restorer.disableRestore(); // Now all checks passed
|
||||
} else if (nodep->type() == m_rootp->type()) { // And, Or, Xor
|
||||
// subtree under NOT can be optimized only in XOR tree.
|
||||
CONST_BITOP_RETURN_IF(!m_polarity && !isXorTree(), nodep);
|
||||
incrOps(nodep, __LINE__);
|
||||
for (const bool right : {false, true}) {
|
||||
VL_RESTORER(m_leafp);
|
||||
|
|
@ -556,6 +558,7 @@ class ConstBitOpTreeVisitor final : public VNVisitorConst {
|
|||
// Reach past a cast then add to frozen nodes to be added to final reduction
|
||||
if (const AstCCast* const castp = VN_CAST(opp, CCast)) opp = castp->lhsp();
|
||||
const bool pol = isXorTree() || m_polarity; // Only AND/OR tree needs polarity
|
||||
UASSERT(pol, "AND/OR tree expects m_polarity==true");
|
||||
m_frozenNodes.emplace_back(opp, FrozenNodeInfo{pol, m_lsb});
|
||||
m_failed = origFailed;
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ module t(/*AUTOARG*/
|
|||
$write("[%0t] cyc==%0d crc=%x sum=%x\n", $time, cyc, crc, sum);
|
||||
if (crc !== 64'hc77bb9b3784ea091) $stop;
|
||||
// What checksum will we end up with (above print should match)
|
||||
`define EXPECTED_SUM 64'hf5498264b93d4b48
|
||||
`define EXPECTED_SUM 64'h7f4e4dade589ada1
|
||||
|
||||
if (sum !== `EXPECTED_SUM) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
|
|
@ -93,10 +93,11 @@ module Test(/*AUTOARG*/
|
|||
logic bug3786_out;
|
||||
logic bug3824_out;
|
||||
logic bug4059_out;
|
||||
logic bug4832_out;
|
||||
|
||||
output logic o;
|
||||
|
||||
logic [14:0] tmp;
|
||||
logic [15:0] tmp;
|
||||
assign o = ^tmp;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
|
|
@ -127,6 +128,7 @@ module Test(/*AUTOARG*/
|
|||
tmp[12]<= bug3786_out;
|
||||
tmp[13]<= bug3824_out;
|
||||
tmp[14]<= bug4059_out;
|
||||
tmp[15]<= bug4832_out;
|
||||
end
|
||||
|
||||
bug3182 i_bug3182(.in(d[4:0]), .out(bug3182_out));
|
||||
|
|
@ -138,6 +140,7 @@ module Test(/*AUTOARG*/
|
|||
bug3786 i_bug3786(.clk(clk), .in(d), .out(bug3786_out));
|
||||
bug3824 i_bug3824(.clk(clk), .in(d), .out(bug3824_out));
|
||||
bug4059 i_bug4059(.clk(clk), .in(d), .out(bug4059_out));
|
||||
bug4832 i_bug4832(.clk(clk), .in(d), .out(bug4832_out));
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -395,3 +398,27 @@ module bug4059(input wire clk, input wire [31:0] in, output wire out);
|
|||
wire _013_ = ~(_009_ ^ _012_);
|
||||
assign out = ~(_006_ ^ _013_);
|
||||
endmodule
|
||||
|
||||
/// See issue #4832
|
||||
// !(d[32 + 3] & in[3]) & d[32 + 22]
|
||||
// was wrongly transformed to
|
||||
// !d[32 + 3] & d[32 + 22] & !in[3]
|
||||
// A subtree under NOT should be untouched, but was not.
|
||||
// Testing OR subtree too.
|
||||
module bug4832(input wire clk, input wire [31:0] in, output out);
|
||||
logic [95:0] d;
|
||||
always_ff @(posedge clk)
|
||||
d <= {d[63:0], in};
|
||||
|
||||
logic [31:0] tmp_and;
|
||||
logic [31:0] tmp_or;
|
||||
logic result_and;
|
||||
logic result_or;
|
||||
assign tmp_and = (d[63:32] & in) >> 3;
|
||||
assign tmp_or = (d[63:32] | in) >> 8;
|
||||
always_ff @(posedge clk) begin
|
||||
result_and <= !tmp_and[0] & d[32 + 22];
|
||||
result_or <= !tmp_or[0] | d[32 + 21];
|
||||
end
|
||||
assign out = result_and ^ result_or;
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Reference in New Issue