Improve simplec back-end
authorClifford Wolf <clifford@clifford.at>
Sun, 14 May 2017 11:14:49 +0000 (13:14 +0200)
committerClifford Wolf <clifford@clifford.at>
Sun, 14 May 2017 11:14:49 +0000 (13:14 +0200)
backends/simplec/simplec.cc
backends/simplec/test00_tb.c
backends/simplec/test00_uut.v

index 49d8b8537ca2b927454b91d80b3519c50492d428..1308947ffc31f906a4a6645e0f13e09edcb5d021 100644 (file)
@@ -34,6 +34,7 @@ struct HierDirtyFlags
        HierDirtyFlags *parent;
        pool<SigBit> dirty_bits;
        pool<Cell*> dirty_cells;
+       pool<SigBit> sticky_dirty_bits;
        dict<IdString, HierDirtyFlags*> children;
 
        HierDirtyFlags(Module *module, IdString hiername, HierDirtyFlags *parent) : dirty(0), module(module), hiername(hiername), parent(parent)
@@ -56,6 +57,7 @@ struct HierDirtyFlags
                        return;
 
                dirty_bits.insert(bit);
+               sticky_dirty_bits.insert(bit);
 
                HierDirtyFlags *p = this;
                while (p != nullptr) {
@@ -573,6 +575,40 @@ struct SimplecWorker
                }
        }
 
+       void eval_sticky_dirty(HierDirtyFlags *work, const string &prefix, const string &log_prefix)
+       {
+               Module *mod = work->module;
+
+               for (Wire *w : mod->wires())
+               for (SigBit bit : SigSpec(w))
+               {
+                       SigBit canonical_bit = sigmaps.at(mod)(bit);
+
+                       if (canonical_bit == bit)
+                               continue;
+
+                       if (work->sticky_dirty_bits.count(canonical_bit) == 0)
+                               continue;
+
+                       log_assert(bit.wire && canonical_bit.wire);
+                       funct_declarations.push_back(stringf("  %s(&%s, %s(&%s));",
+                                       util_set_bit(bit.wire->width, bit.offset).c_str(),
+                                       (prefix + cid(bit.wire->name)).c_str(),
+                                       util_get_bit(canonical_bit.wire->width, canonical_bit.offset).c_str(),
+                                       (prefix + cid(canonical_bit.wire->name)).c_str()));
+
+                       if (verbose)
+                               log("  Propagating alias %s.%s[%d] -> %s.%s[%d].\n",
+                                               log_prefix.c_str(), log_id(canonical_bit.wire), canonical_bit.offset,
+                                               log_prefix.c_str(), log_id(bit.wire), bit.offset);
+               }
+
+               work->sticky_dirty_bits.clear();
+
+               for (auto &child : work->children)
+                       eval_sticky_dirty(child.second, prefix + cid(child.first) + ".", log_prefix + "." + cid(child.first));
+       }
+
        void make_func(HierDirtyFlags *work, const string &func_name)
        {
                log("Generating function %s():\n", func_name.c_str());
@@ -584,6 +620,7 @@ struct SimplecWorker
                funct_declarations.push_back(stringf("static void %s(struct %s_state_t *state)", func_name.c_str(), cid(work->module->name).c_str()));
                funct_declarations.push_back("{");
                eval_dirty(work, "state->", log_id(work->module->name), "", "");
+               eval_sticky_dirty(work, "state->", log_id(work->module->name));
                funct_declarations.push_back("}");
 
                log("  Activated %d cells (%d activated more than once).\n", GetSize(activated_cells), GetSize(reactivated_cells));
index 9b3ae00e0a1180ffa750f7bb367c6e3cf0dbbdab..7d86d0d914468f5dbf75e3aed792f9f3eec822f7 100644 (file)
@@ -14,7 +14,7 @@ uint32_t xorshift32()
 int main()
 {
        struct test_state_t state;
-       uint32_t a, b, c, x, y, z;
+       uint32_t a, b, c, x, y, z, w;
 
        for (int i = 0; i < 10; i++)
        {
@@ -25,6 +25,7 @@ int main()
                x = (a & b) | c;
                y = a & (b | c);
                z = a ^ b ^ c;
+               w = z;
 
                state.a.value_7_0   = a;
                state.a.value_15_8  = a >> 8;
@@ -61,6 +62,12 @@ int main()
                uut_z |= (uint32_t)state.z.value_23_16 << 16;
                uut_z |= (uint32_t)state.z.value_31_24 << 24;
 
+               uint32_t uut_w = 0;
+               uut_w |= (uint32_t)state.w.value_7_0;
+               uut_w |= (uint32_t)state.w.value_15_8  << 8;
+               uut_w |= (uint32_t)state.w.value_23_16 << 16;
+               uut_w |= (uint32_t)state.w.value_31_24 << 24;
+
                printf("---\n");
                printf("A: 0x%08x\n", a);
                printf("B: 0x%08x\n", b);
@@ -68,10 +75,12 @@ int main()
                printf("X: 0x%08x 0x%08x\n", x, uut_x);
                printf("Y: 0x%08x 0x%08x\n", y, uut_y);
                printf("Z: 0x%08x 0x%08x\n", z, uut_z);
+               printf("W: 0x%08x 0x%08x\n", w, uut_w);
 
                assert(x == uut_x);
                assert(y == uut_y);
                assert(z == uut_z);
+               assert(w == uut_w);
        }
 
        return 0;
index fd634cf82703692c5e931df0cd0e55a776ed2795..744dbe9e39ff36f5cca64b6516ef433cc6c5bab9 100644 (file)
@@ -1,7 +1,7 @@
-module test(input [31:0] a, b, c, output [31:0] x, y, z);
+module test(input [31:0] a, b, c, output [31:0] x, y, z, w);
   unit_x unit_x_inst (.a(a), .b(b), .c(c), .x(x));
   unit_y unit_y_inst (.a(a), .b(b), .c(c), .y(y));
-  assign z = a ^ b ^ c;
+  assign z = a ^ b ^ c, w = z;
 endmodule
   
 module unit_x(input [31:0] a, b, c, output [31:0] x);