forked from github/verilator
Allow mismatched widths in operands of shifts in DFG
Fixes #3872. Testing this is a bit tricky, as the front-end fixes up the operand widths in shifts to match, and we need V3Const to introduce a mismatched one by reducing `4'd2 ** x` (with x being 2 2-bit wide signal) to `4'd1 << x`, but t_dfg_peephole runs with V3Const disabled exactly because it makes it hard to write tests. Rather than fixing this one case in V3Const (which we should do systematically at some point), I fixed DFG to accept these just in case V3Const generates more of them. The assertions were there only because of paranoia (as I thought these were not possible inputs), the code otherwise works.
This commit is contained in:
parent
3a8288b0f6
commit
3069860fdf
@ -1400,26 +1400,17 @@ class V3DfgPeephole final : public DfgVisitor {
|
||||
}
|
||||
|
||||
void visit(DfgShiftL* vtxp) override {
|
||||
UASSERT_OBJ(vtxp->dtypep() == vtxp->lhsp()->dtypep(), vtxp, "Mismatched width");
|
||||
|
||||
if (foldBinary(vtxp)) return;
|
||||
|
||||
optimizeShiftRHS(vtxp);
|
||||
}
|
||||
|
||||
void visit(DfgShiftR* vtxp) override {
|
||||
UASSERT_OBJ(vtxp->dtypep() == vtxp->lhsp()->dtypep(), vtxp, "Mismatched width");
|
||||
|
||||
if (foldBinary(vtxp)) return;
|
||||
|
||||
optimizeShiftRHS(vtxp);
|
||||
}
|
||||
|
||||
void visit(DfgShiftRS* vtxp) override {
|
||||
UASSERT_OBJ(vtxp->dtypep() == vtxp->lhsp()->dtypep(), vtxp, "Mismatched width");
|
||||
|
||||
if (foldBinary(vtxp)) return;
|
||||
|
||||
optimizeShiftRHS(vtxp);
|
||||
}
|
||||
|
||||
|
16
test_regress/t/t_dfg_3872.pl
Executable file
16
test_regress/t/t_dfg_3872.pl
Executable file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2022 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
|
||||
|
||||
scenarios(vlt => 1);
|
||||
|
||||
compile();
|
||||
|
||||
ok(1);
|
||||
1;
|
12
test_regress/t/t_dfg_3872.v
Normal file
12
test_regress/t/t_dfg_3872.v
Normal file
@ -0,0 +1,12 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2023 by Geza Lore.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module top(
|
||||
input wire [1:0] i,
|
||||
output wire [3:0] o
|
||||
);
|
||||
assign o = 4'd2 ** i;
|
||||
endmodule
|
@ -30,17 +30,20 @@ int main(int, char**) {
|
||||
uint64_t rand_a = 0x5aef0c8dd70a4497;
|
||||
uint64_t rand_b = 0xf0c0a8dd75ae4497;
|
||||
uint64_t srand_a = 0x00fa8dcc7ae4957;
|
||||
uint64_t srand_b = 0x0fa8dc7ae3c9574;
|
||||
|
||||
for (size_t n = 0; n < 200000; ++n) {
|
||||
// Update rngs
|
||||
rngUpdate(rand_a);
|
||||
rngUpdate(rand_b);
|
||||
rngUpdate(srand_a);
|
||||
rngUpdate(srand_b);
|
||||
|
||||
// Assign inputs
|
||||
ref.rand_a = opt.rand_a = rand_a;
|
||||
ref.rand_b = opt.rand_b = rand_b;
|
||||
ref.srand_a = opt.srand_a = srand_a;
|
||||
ref.srand_b = opt.srand_b = srand_b;
|
||||
|
||||
// Evaluate both models
|
||||
ref.eval();
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
module t (
|
||||
`include "portlist.vh" // Boilerplate generated by t_dfg_peephole.pl
|
||||
rand_a, rand_b, srand_a
|
||||
rand_a, rand_b, srand_a, srand_b
|
||||
);
|
||||
|
||||
`include "portdecl.vh" // Boilerplate generated by t_dfg_peephole.pl
|
||||
@ -16,9 +16,11 @@ module t (
|
||||
input rand_a;
|
||||
input rand_b;
|
||||
input srand_a;
|
||||
input srand_b;
|
||||
wire logic [63:0] rand_a;
|
||||
wire logic [63:0] rand_b;
|
||||
wire logic signed [63:0] srand_a;
|
||||
wire logic signed [63:0] srand_b;
|
||||
|
||||
wire logic randbit_a = rand_a[0];
|
||||
wire logic [127:0] rand_ba = {rand_b, rand_a};
|
||||
@ -179,6 +181,15 @@ module t (
|
||||
`signal(RIGHT_LEANING_ASSOC, (((rand_a + rand_b) + rand_a) + rand_b));
|
||||
`signal(RIGHT_LEANING_CONCET, {{{rand_a, rand_b}, rand_a}, rand_b});
|
||||
|
||||
// Operators that should work wiht mismatched widths
|
||||
`signal(MISMATCHED_ShiftL,const_a << 4'd2);
|
||||
`signal(MISMATCHED_ShiftR,const_a >> 4'd2);
|
||||
`signal(MISMATCHED_ShiftRS, const_a >> 4'd2);
|
||||
`signal(MISMATCHED_PowUU, rand_a ** 4'd5);
|
||||
`signal(MISMATCHED_PowSS, srand_a ** 4'sd5);
|
||||
`signal(MISMATCHED_PowSU, srand_b ** 4'd5);
|
||||
`signal(MISMATCHED_PowUS, rand_b ** 4'sd5);
|
||||
|
||||
// Some selects need extra temporaries
|
||||
wire [63:0] sel_from_cond = rand_a[0] ? rand_a : const_a;
|
||||
wire [63:0] sel_from_shiftl = rand_a << 10;
|
||||
|
Loading…
Reference in New Issue
Block a user