memory_dff: Fix needlessly duplicating enable bits.
authorMarcelina Kościelnicka <mwk@0x04.net>
Thu, 22 Oct 2020 08:37:44 +0000 (10:37 +0200)
committerMarcelina Kościelnicka <mwk@0x04.net>
Thu, 22 Oct 2020 11:03:42 +0000 (13:03 +0200)
When the register being merged into the EN signal happens to be a $sdff,
the current code creates a new $mux for every bit, even if they happen
to be identical (as is usually the case), preventing proper grouping
further down the flow.  Fix this by adding a simple cache.

Fixes #2409.

passes/memory/memory_dff.cc
tests/arch/ecp5/bug2409.ys [new file with mode: 0644]

index 68023fd11398a71af83a8c9506c605303dd52423..4adcb462edf523fe9d7cb9b3d63664c4be26a545 100644 (file)
@@ -46,8 +46,15 @@ struct MemoryDffWorker
        {
                sigmap.apply(sig);
 
+               dict<SigBit, SigBit> cache;
+
                for (auto &bit : sig)
                {
+                       if (cache.count(bit)) {
+                               bit = cache[bit];
+                               continue;
+                       }
+
                        if (bit.wire == NULL)
                                continue;
 
@@ -103,6 +110,7 @@ struct MemoryDffWorker
                                                d = module->Mux(NEW_ID, rbit, d, cell->getPort(ID::SRST));
                                }
 
+                               cache[bit] = d;
                                bit = d;
                                clk = this_clk;
                                clk_polarity = this_clk_polarity;
diff --git a/tests/arch/ecp5/bug2409.ys b/tests/arch/ecp5/bug2409.ys
new file mode 100644 (file)
index 0000000..5ba9cec
--- /dev/null
@@ -0,0 +1,24 @@
+read_verilog <<EOT
+module t (...);
+
+input CLK;
+input [10:0] A;
+input WE;
+input C;
+input [7:0] DI;
+output reg [7:0] DO;
+
+reg [7:0] mem[2047:0];
+
+always @(posedge CLK) begin
+       if (C)
+               if (WE)
+                       mem[A] <= DI;
+       DO <= mem[A];
+end
+
+endmodule
+EOT
+
+synth_ecp5
+select -assert-count 1 t:DP16KD