Bugfix in memory_dff
authorClifford Wolf <clifford@clifford.at>
Sat, 31 Oct 2015 21:01:41 +0000 (22:01 +0100)
committerClifford Wolf <clifford@clifford.at>
Sat, 31 Oct 2015 21:01:41 +0000 (22:01 +0100)
passes/memory/memory_dff.cc
tests/simple/memory.v

index 3373369f6ef141c47981b1350ca7bb70de8015fd..2eec0207b9315f99ea53120940e98f5a8d44a234 100644 (file)
@@ -32,6 +32,7 @@ struct MemoryDffWorker
        dict<SigBit, SigBit> invbits;
        dict<SigBit, int> sigbit_users_count;
        dict<SigSpec, Cell*> mux_cells_a, mux_cells_b;
+       pool<Cell*> forward_merged_dffs, candidate_dffs;
 
        MemoryDffWorker(Module *module) : module(module), sigmap(module) { }
 
@@ -46,6 +47,9 @@ struct MemoryDffWorker
 
                        for (auto cell : dff_cells)
                        {
+                               if (after && forward_merged_dffs.count(cell))
+                                       continue;
+
                                SigSpec this_clk = cell->getPort("\\CLK");
                                bool this_clk_polarity = cell->parameters["\\CLK_POLARITY"].as_bool();
 
@@ -71,6 +75,7 @@ struct MemoryDffWorker
                                bit = d;
                                clk = this_clk;
                                clk_polarity = this_clk_polarity;
+                               candidate_dffs.insert(cell);
                                goto replaced_this_bit;
                        }
 
@@ -87,6 +92,7 @@ struct MemoryDffWorker
 
                RTLIL::SigSpec clk = RTLIL::SigSpec(RTLIL::State::Sx);
                bool clk_polarity = 0;
+               candidate_dffs.clear();
 
                RTLIL::SigSpec sig_addr = cell->getPort("\\ADDR");
                if (!find_sig_before_dff(sig_addr, clk, clk_polarity)) {
@@ -106,13 +112,18 @@ struct MemoryDffWorker
                        return;
                }
 
-               if (clk != RTLIL::SigSpec(RTLIL::State::Sx)) {
+               if (clk != RTLIL::SigSpec(RTLIL::State::Sx))
+               {
+                       for (auto cell : candidate_dffs)
+                               forward_merged_dffs.insert(cell);
+
                        cell->setPort("\\CLK", clk);
                        cell->setPort("\\ADDR", sig_addr);
                        cell->setPort("\\DATA", sig_data);
                        cell->setPort("\\EN", sig_en);
                        cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
                        cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
+
                        log("merged $dff to cell.\n");
                        return;
                }
index 67f89cd75639f8f852f54ebb5379aa5052df9c89..d58ed9d1aabc5c9edabd4990dedba93cfcf8b824 100644 (file)
@@ -228,3 +228,18 @@ module memtest09 (
     end
 endmodule
 
+// ----------------------------------------------------------
+
+module memtest10(input clk, input [5:0] din, output [5:0] dout);
+        reg [5:0] queue [0:3];
+        integer i;
+
+        always @(posedge clk) begin
+                queue[0] <= din;
+                for (i = 1; i < 4; i=i+1) begin
+                        queue[i] <= queue[i-1];
+                end
+        end
+
+       assign dout = queue[3];
+endmodule