aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--passes/opt/wreduce.cc13
-rw-r--r--tests/opt/opt_ff.v21
-rw-r--r--tests/opt/opt_ff.ys3
3 files changed, 37 insertions, 0 deletions
diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc
index 3aa916ec2..c550b402e 100644
--- a/passes/opt/wreduce.cc
+++ b/passes/opt/wreduce.cc
@@ -195,6 +195,19 @@ struct WreduceWorker
for (auto bit : sig_q)
work_queue_bits.insert(bit);
+ // Narrow ARST_VALUE parameter to new size.
+ //
+ // Note: This works because earlier loop only removes signals from
+ // the upper bits of the DFF.
+ if(cell->parameters.count("\\ARST_VALUE") > 0) {
+ RTLIL::Const old_arst_value = cell->parameters.at("\\ARST_VALUE");
+ std::vector<RTLIL::State> new_arst_value(GetSize(sig_q));
+ for(int i = 0; i < GetSize(sig_q); ++i) {
+ new_arst_value[i] = old_arst_value[i];
+ }
+ cell->parameters["\\ARST_VALUE"] = RTLIL::Const(new_arst_value);
+ }
+
cell->setPort("\\D", sig_d);
cell->setPort("\\Q", sig_q);
cell->fixup_parameters();
diff --git a/tests/opt/opt_ff.v b/tests/opt/opt_ff.v
new file mode 100644
index 000000000..a01b64b61
--- /dev/null
+++ b/tests/opt/opt_ff.v
@@ -0,0 +1,21 @@
+module top(
+ input clk,
+ input rst,
+ input [2:0] a,
+ output [1:0] b
+);
+ reg [2:0] b_reg;
+ initial begin
+ b_reg <= 3'b0;
+ end
+
+ assign b = b_reg[1:0];
+ always @(posedge clk or posedge rst) begin
+ if(rst) begin
+ b_reg <= 3'b0;
+ end else begin
+ b_reg <= a;
+ end
+ end
+endmodule
+
diff --git a/tests/opt/opt_ff.ys b/tests/opt/opt_ff.ys
new file mode 100644
index 000000000..704c7acf3
--- /dev/null
+++ b/tests/opt/opt_ff.ys
@@ -0,0 +1,3 @@
+read_verilog opt_ff.v
+synth_ice40
+ice40_unlut