zinit: Refactor to use FfInitVals.
authorMarcelina Kościelnicka <mwk@0x04.net>
Sun, 19 Jul 2020 00:05:32 +0000 (02:05 +0200)
committerMarcelina Kościelnicka <mwk@0x04.net>
Fri, 24 Jul 2020 09:22:31 +0000 (11:22 +0200)
passes/techmap/zinit.cc
tests/techmap/zinit.ys

index cc0b26bcc5288a2fe009a3e79167c52a889e70d4..e3b4ae57309745aa6be1094918a99ecb17eca13f 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "kernel/yosys.h"
 #include "kernel/sigtools.h"
+#include "kernel/ffinit.h"
 
 USING_YOSYS_NAMESPACE
 PRIVATE_NAMESPACE_BEGIN
@@ -57,35 +58,7 @@ struct ZinitPass : public Pass {
                for (auto module : design->selected_modules())
                {
                        SigMap sigmap(module);
-                       dict<SigBit, std::pair<State,SigBit>> initbits;
-
-                       for (auto wire : module->selected_wires())
-                       {
-                               if (wire->attributes.count(ID::init) == 0)
-                                       continue;
-
-                               SigSpec wirebits = sigmap(wire);
-                               Const initval = wire->attributes.at(ID::init);
-
-                               for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++)
-                               {
-                                       SigBit bit = wirebits[i];
-                                       State val = initval[i];
-
-                                       if (val != State::S0 && val != State::S1 && bit.wire != nullptr)
-                                               continue;
-
-                                       if (initbits.count(bit)) {
-                                               if (initbits.at(bit).first != val)
-                                                       log_error("Conflicting init values for signal %s (%s = %s != %s).\n",
-                                                                       log_signal(bit), log_signal(SigBit(wire, i)),
-                                                                       log_signal(val), log_signal(initbits.at(bit).first));
-                                               continue;
-                                       }
-
-                                       initbits[bit] = std::make_pair(val,SigBit(wire,i));
-                               }
-                       }
+                       FfInitVals initvals(&sigmap, module);
 
                        pool<IdString> dff_types = {
                                                                // FIXME: It would appear that supporting
@@ -127,33 +100,28 @@ struct ZinitPass : public Pass {
                                if (GetSize(sig_d) < 1 || GetSize(sig_q) < 1)
                                        continue;
 
-                               Const initval;
+                               Const initval = initvals(sig_q);
+                               Const newval = initval;
+                               initvals.remove_init(sig_q);
 
-                               for (int i = 0; i < GetSize(sig_q); i++) {
-                                       if (initbits.count(sig_q[i])) {
-                                               const auto &d = initbits.at(sig_q[i]);
-                                               initval.bits.push_back(d.first);
-                                               const auto &b = d.second;
-                                               b.wire->attributes.at(ID::init)[b.offset] = State::Sx;
-                                       } else
-                                               initval.bits.push_back(all_mode ? State::S0 : State::Sx);
-                               }
-
-                               Wire *initwire = module->addWire(NEW_ID, GetSize(initval));
-                               initwire->attributes[ID::init] = initval;
+                               Wire *initwire = module->addWire(NEW_ID, GetSize(sig_q));
 
                                for (int i = 0; i < GetSize(initwire); i++)
                                        if (initval[i] == State::S1)
                                        {
                                                sig_d[i] = module->NotGate(NEW_ID, sig_d[i]);
                                                module->addNotGate(NEW_ID, SigSpec(initwire, i), sig_q[i]);
-                                               initwire->attributes[ID::init][i] = State::S0;
+                                               newval[i] = State::S0;
                                        }
                                        else
                                        {
                                                module->connect(sig_q[i], SigSpec(initwire, i));
+                                               if (all_mode)
+                                                       newval[i] = State::S0;
                                        }
 
+                               initvals.set_init(initwire, newval);
+
                                log("FF init value for cell %s (%s): %s = %s\n", log_id(cell), log_id(cell->type),
                                                log_signal(sig_q), log_signal(initval));
 
index 3527840b918d90177b0788efc2aff4feeba522e4..1670573dd50387248b638092c1dc9771fd5ce1a5 100644 (file)
@@ -95,7 +95,7 @@ EOT
 zinit
 
 select -assert-count 48 t:$_NOT_
-select -assert-count 1 w:Q a:init=24'bx %i
+select -assert-count 0 w:Q a:init %i
 select -assert-count 4 c:dff0 c:dff2 c:dff4 c:dff6 %% t:$_DFFE_??1P_ %i
 select -assert-count 4 c:dff1 c:dff3 c:dff5 c:dff7 %% t:$_DFFE_??0P_ %i
 select -assert-count 4 c:dff8 c:dff10 c:dff12 c:dff14 %% t:$_SDFF_??1_ %i
@@ -142,7 +142,7 @@ EOT
 zinit
 
 select -assert-count 0 t:$_NOT_
-select -assert-count 1 w:Q a:init=24'bx %i
+select -assert-count 0 w:Q a:init %i
 select -assert-count 4 c:dff0 c:dff2 c:dff4 c:dff6 %% t:$_DFFE_??0P_ %i
 select -assert-count 4 c:dff1 c:dff3 c:dff5 c:dff7 %% t:$_DFFE_??1P_ %i
 select -assert-count 4 c:dff8 c:dff10 c:dff12 c:dff14 %% t:$_SDFF_??0_ %i