aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--frontends/ast/simplify.cc2
-rw-r--r--frontends/verific/verific.cc14
-rw-r--r--passes/opt/opt_clean.cc31
-rw-r--r--techlibs/common/cmp2lcu.v8
-rw-r--r--techlibs/common/techmap.v29
-rw-r--r--techlibs/ecp5/cells_bb.v4
-rw-r--r--techlibs/ice40/cells_sim.v2
-rw-r--r--techlibs/ice40/synth_ice40.cc29
-rw-r--r--tests/opt/opt_clean_init.ys13
-rw-r--r--tests/verilog/upto.ys4
10 files changed, 98 insertions, 38 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/frontends/verific/verific.cc b/frontends/verific/verific.cc
index fe4bda68e..5f8a78e48 100644
--- a/frontends/verific/verific.cc
+++ b/frontends/verific/verific.cc
@@ -1265,7 +1265,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
int numchunks = int(inst->OutputSize()) / memory->width;
int chunksbits = ceil_log2(numchunks);
- if ((numchunks * memory->width) != int(inst->OutputSize()) || (numchunks & (numchunks - 1)) != 0)
+ if ((numchunks * memory->width) != int(inst->OutputSize()))
log_error("Import of asymmetric memories of this type is not supported yet: %s %s\n", inst->Name(), inst->GetInput()->Name());
for (int i = 0; i < numchunks; i++)
@@ -1273,6 +1273,11 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
RTLIL::SigSpec addr = {operatorInput1(inst), RTLIL::Const(i, chunksbits)};
RTLIL::SigSpec data = operatorOutput(inst).extract(i * memory->width, memory->width);
+ if ((numchunks & (numchunks - 1)) != 0) {
+ addr = module->Mul(NEW_ID, operatorInput1(inst), RTLIL::Const(numchunks));
+ addr = module->Add(NEW_ID, addr, RTLIL::Const(i));
+ }
+
RTLIL::Cell *cell = module->addCell(numchunks == 1 ? inst_name :
RTLIL::IdString(stringf("%s_%d", inst_name.c_str(), i)), ID($memrd));
cell->parameters[ID::MEMID] = memory->name.str();
@@ -1295,7 +1300,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
int numchunks = int(inst->Input2Size()) / memory->width;
int chunksbits = ceil_log2(numchunks);
- if ((numchunks * memory->width) != int(inst->Input2Size()) || (numchunks & (numchunks - 1)) != 0)
+ if ((numchunks * memory->width) != int(inst->Input2Size()))
log_error("Import of asymmetric memories of this type is not supported yet: %s %s\n", inst->Name(), inst->GetOutput()->Name());
for (int i = 0; i < numchunks; i++)
@@ -1303,6 +1308,11 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
RTLIL::SigSpec addr = {operatorInput1(inst), RTLIL::Const(i, chunksbits)};
RTLIL::SigSpec data = operatorInput2(inst).extract(i * memory->width, memory->width);
+ if ((numchunks & (numchunks - 1)) != 0) {
+ addr = module->Mul(NEW_ID, operatorInput1(inst), RTLIL::Const(numchunks));
+ addr = module->Add(NEW_ID, addr, RTLIL::Const(i));
+ }
+
RTLIL::Cell *cell = module->addCell(numchunks == 1 ? inst_name :
RTLIL::IdString(stringf("%s_%d", inst_name.c_str(), i)), ID($memwr));
cell->parameters[ID::MEMID] = memory->name.str();
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/techlibs/ecp5/cells_bb.v b/techlibs/ecp5/cells_bb.v
index ae124e7a3..756f05366 100644
--- a/techlibs/ecp5/cells_bb.v
+++ b/techlibs/ecp5/cells_bb.v
@@ -652,6 +652,10 @@ module DCUA(
parameter CH1_PROTOCOL = "8B10B";
parameter CH0_CDR_MAX_RATE = "2.5";
parameter CH1_CDR_MAX_RATE = "2.5";
+ parameter CH0_TXDEPRE = "DISABLED";
+ parameter CH1_TXDEPRE = "DISABLED";
+ parameter CH0_TXDEPOST = "DISABLED";
+ parameter CH1_TXDEPOST = "DISABLED";
endmodule
(* blackbox *)
diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v
index 6a0e3031e..5d107989d 100644
--- a/techlibs/ice40/cells_sim.v
+++ b/techlibs/ice40/cells_sim.v
@@ -1908,7 +1908,7 @@ module ICESTORM_LC (
o_reg <= SR_pd ? SET_NORESET : lut_o;
reg o_reg_async = 1'b0;
- always @(posedge polarized_clk, posedge SR)
+ always @(posedge polarized_clk, posedge SR_pd)
if (SR_pd)
o_reg_async <= SET_NORESET;
else if (CEN_pu)
diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc
index 2b211572d..6e05ab0b2 100644
--- a/techlibs/ice40/synth_ice40.cc
+++ b/techlibs/ice40/synth_ice40.cc
@@ -225,10 +225,10 @@ struct SynthIce40Pass : public ScriptPass
device_opt = args[++argidx];
continue;
}
- if (args[argidx] == "-flowmap") {
- flowmap = true;
- continue;
- }
+ if (args[argidx] == "-flowmap") {
+ flowmap = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -240,13 +240,12 @@ struct SynthIce40Pass : public ScriptPass
if (abc9 && retime)
log_cmd_error("-retime option not currently compatible with -abc9!\n");
-
- if (abc9 && noabc)
- log_cmd_error("-abc9 is incompatible with -noabc!\n");
- if (abc9 && flowmap)
- log_cmd_error("-abc9 is incompatible with -flowmap!\n");
- if (flowmap && noabc)
- log_cmd_error("-flowmap is incompatible with -noabc!\n");
+ if (abc9 && noabc)
+ log_cmd_error("-abc9 is incompatible with -noabc!\n");
+ if (abc9 && flowmap)
+ log_cmd_error("-abc9 is incompatible with -flowmap!\n");
+ if (flowmap && noabc)
+ log_cmd_error("-flowmap is incompatible with -noabc!\n");
log_header(design, "Executing SYNTH_ICE40 pass.\n");
log_push();
@@ -372,10 +371,10 @@ struct SynthIce40Pass : public ScriptPass
run("techmap -map +/ice40/latches_map.v");
if (noabc || flowmap || help_mode) {
run("simplemap", " (if -noabc or -flowmap)");
- if (noabc || help_mode)
- run("techmap -map +/gate2lut.v -D LUT_WIDTH=4", "(only if -noabc)");
- if (flowmap || help_mode)
- run("flowmap -maxlut 4", "(only if -flowmap)");
+ if (noabc || help_mode)
+ run("techmap -map +/gate2lut.v -D LUT_WIDTH=4", "(only if -noabc)");
+ if (flowmap || help_mode)
+ run("flowmap -maxlut 4", "(only if -flowmap)");
}
if (!noabc) {
if (abc9) {
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