diff options
-rw-r--r-- | frontends/ast/simplify.cc | 2 | ||||
-rw-r--r-- | passes/opt/opt_clean.cc | 31 | ||||
-rw-r--r-- | techlibs/common/cmp2lcu.v | 8 | ||||
-rw-r--r-- | techlibs/common/techmap.v | 29 | ||||
-rw-r--r-- | tests/opt/opt_clean_init.ys | 13 | ||||
-rw-r--r-- | tests/verilog/upto.ys | 4 |
6 files changed, 67 insertions, 20 deletions
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 318ffc1be..f629df387 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1080,7 +1080,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } if (old_range_valid != range_valid) did_something = true; - if (range_valid && range_left >= 0 && range_right > range_left) { + if (range_valid && range_right > range_left) { int tmp = range_right; range_right = range_left; range_left = tmp; diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 6271376f1..f7de02164 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -412,7 +412,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos return !del_wires_queue.empty(); } -bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose) +bool rmunused_module_init(RTLIL::Module *module, bool verbose) { bool did_something = false; CellTypes fftypes; @@ -445,9 +445,6 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose) for (auto wire : module->wires()) { - if (!purge_mode && wire->name[0] == '\\') - continue; - if (wire->attributes.count(ID::init) == 0) continue; @@ -464,11 +461,22 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose) if (wire_bit == mapped_wire_bit) goto next_wire; - if (qbits.count(sigmap(SigBit(wire, i))) == 0) - goto next_wire; + if (mapped_wire_bit.wire) { + if (qbits.count(mapped_wire_bit) == 0) + goto next_wire; - if (qbits.at(sigmap(SigBit(wire, i))) != init[i]) - goto next_wire; + if (qbits.at(mapped_wire_bit) != init[i]) + goto next_wire; + } + else { + if (mapped_wire_bit == State::Sx || mapped_wire_bit == State::Sz) + goto next_wire; + + if (mapped_wire_bit != init[i]) { + log_warning("Initial value conflict for %s resolving to %s but with init %s.\n", log_signal(wire_bit), log_signal(mapped_wire_bit), log_signal(init[i])); + goto next_wire; + } + } } if (verbose) @@ -512,7 +520,7 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool rmunused_module_cells(module, verbose); while (rmunused_module_signals(module, purge_mode, verbose)) { } - if (rminit && rmunused_module_init(module, purge_mode, verbose)) + if (rminit && rmunused_module_init(module, verbose)) while (rmunused_module_signals(module, purge_mode, verbose)) { } } @@ -611,8 +619,7 @@ struct CleanPass : public Pass { } break; } - if (argidx < args.size()) - extra_args(args, argidx, design); + extra_args(args, argidx, design); keep_cache.reset(design); @@ -627,7 +634,7 @@ struct CleanPass : public Pass { for (auto module : design->selected_whole_modules()) { if (module->has_processes()) continue; - rmunused_module(module, purge_mode, ys_debug(), false); + rmunused_module(module, purge_mode, ys_debug(), true); } log_suppressed(); diff --git a/techlibs/common/cmp2lcu.v b/techlibs/common/cmp2lcu.v index b6f4aeed6..e42f346d1 100644 --- a/techlibs/common/cmp2lcu.v +++ b/techlibs/common/cmp2lcu.v @@ -108,8 +108,12 @@ generate // Generate if any comparisons call for it wire [LCU_WIDTH-1:0] G_ = {G[LCU_WIDTH-1:1], G[0] | GG}; end - $__CMP2LCU #(.AB_WIDTH(AB_WIDTH-1), .AB_SIGNED(1'b0), .LCU_WIDTH(LCU_WIDTH), .BUDGET(BUDGET-COST), .CI(CI)) - _TECHMAP_REPLACE_ (.A(A[AB_WIDTH-2:0]), .B(B[AB_WIDTH-2:0]), .P(P_), .G(G_), .Y(Y)); + if (AB_WIDTH == 1) + $__CMP2LCU #(.AB_WIDTH(AB_WIDTH-1), .AB_SIGNED(1'b0), .LCU_WIDTH(LCU_WIDTH), .BUDGET(BUDGET-COST), .CI(CI)) + _TECHMAP_REPLACE_ (.A(), .B(), .P(P_), .G(G_), .Y(Y)); + else + $__CMP2LCU #(.AB_WIDTH(AB_WIDTH-1), .AB_SIGNED(1'b0), .LCU_WIDTH(LCU_WIDTH), .BUDGET(BUDGET-COST), .CI(CI)) + _TECHMAP_REPLACE_ (.A(A[AB_WIDTH-2:0]), .B(B[AB_WIDTH-2:0]), .P(P_), .G(G_), .Y(Y)); end end endgenerate diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index ecf4d5dc5..225cff449 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -285,13 +285,32 @@ module _90_alu (A, B, CI, BI, X, Y, CO); input CI, BI; output [Y_WIDTH-1:0] CO; - wire [Y_WIDTH-1:0] A_buf, B_buf; - \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); - \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); - - wire [Y_WIDTH-1:0] AA = A_buf; + wire [Y_WIDTH-1:0] AA, BB; wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; + if (A_WIDTH == 0) begin + wire [Y_WIDTH-1:0] B_buf; + \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + + assign AA = {Y_WIDTH{1'b0}}; + assign BB = BI ? ~B_buf : B_buf; + end + else if (B_WIDTH == 0) begin + wire [Y_WIDTH-1:0] A_buf; + \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); + + assign AA = A_buf; + assign BB = {Y_WIDTH{BI ? 1'b0 : 1'b1}}; + end + else begin + wire [Y_WIDTH-1:0] A_buf, B_buf; + \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + + assign AA = A_buf; + assign BB = BI ? ~B_buf : B_buf; + end + \$lcu #(.WIDTH(Y_WIDTH)) lcu (.P(X), .G(AA & BB), .CI(CI), .CO(CO)); assign X = AA ^ BB; diff --git a/tests/opt/opt_clean_init.ys b/tests/opt/opt_clean_init.ys new file mode 100644 index 000000000..0d567608d --- /dev/null +++ b/tests/opt/opt_clean_init.ys @@ -0,0 +1,13 @@ +logger -expect warning "Initial value conflict for \\y resolving to 1'0 but with init 1'1" 1 +logger -expect-no-warnings +read_verilog <<EOT +module top; +(* init=1'b0 *) wire w = 1'b0; +(* init=1'bx *) wire x = 1'b0; +(* init=1'b1 *) wire y = 1'b0; +(* init=1'b0 *) wire z = 1'bx; +endmodule +EOT +clean +select -assert-count 1 a:init +select -assert-count 1 w:y a:init %i diff --git a/tests/verilog/upto.ys b/tests/verilog/upto.ys new file mode 100644 index 000000000..2f3394761 --- /dev/null +++ b/tests/verilog/upto.ys @@ -0,0 +1,4 @@ +read_verilog <<EOT +module top(input [-128:-65] a); +endmodule +EOT |