Add utility module for dealing with init attributes.
authorMarcelina Kościelnicka <mwk@0x04.net>
Sat, 18 Jul 2020 23:59:47 +0000 (01:59 +0200)
committerMarcelina Kościelnicka <mwk@0x04.net>
Thu, 23 Jul 2020 18:49:48 +0000 (20:49 +0200)
Makefile
kernel/ffinit.h [new file with mode: 0644]

index dfa4fb6a11eb5aedf4131f4ca22c1e1c676981d6..90f8fee05d1dc1637397485e23f72a2d433ffb33 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -585,6 +585,7 @@ $(eval $(call add_include_file,kernel/modtools.h))
 $(eval $(call add_include_file,kernel/macc.h))
 $(eval $(call add_include_file,kernel/utils.h))
 $(eval $(call add_include_file,kernel/satgen.h))
+$(eval $(call add_include_file,kernel/ffinit.h))
 $(eval $(call add_include_file,libs/ezsat/ezsat.h))
 $(eval $(call add_include_file,libs/ezsat/ezminisat.h))
 $(eval $(call add_include_file,libs/sha1/sha1.h))
diff --git a/kernel/ffinit.h b/kernel/ffinit.h
new file mode 100644 (file)
index 0000000..4974769
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ *  yosys -- Yosys Open SYnthesis Suite
+ *
+ *  Copyright (C) 2020  Marcelina Kościelnicka <mwk@0x04.net>
+ *
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifndef FFINIT_H
+#define FFINIT_H
+
+#include "kernel/yosys.h"
+#include "kernel/sigtools.h"
+
+YOSYS_NAMESPACE_BEGIN
+
+struct FfInitVals
+{
+       const SigMap *sigmap;
+       RTLIL::Module *module;
+       dict<SigBit, std::pair<State,SigBit>> initbits;
+
+       void set(const SigMap *sigmap_, RTLIL::Module *module)
+       {
+               sigmap = sigmap_;
+               initbits.clear();
+               for (auto wire : module->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));
+                       }
+               }
+       }
+
+       RTLIL::State operator()(RTLIL::SigBit bit) const
+       {
+               auto it = initbits.find((*sigmap)(bit));
+               if (it != initbits.end())
+                       return it->second.first;
+               else
+                       return State::Sx;
+       }
+
+       RTLIL::Const operator()(const RTLIL::SigSpec &sig) const
+       {
+               RTLIL::Const res;
+               for (auto bit : sig)
+                       res.bits.push_back((*this)(bit));
+               return res;
+       }
+
+       void set_init(RTLIL::SigBit bit, RTLIL::State val)
+       {
+               bit = (*sigmap)(bit);
+               auto it = initbits.find(bit);
+               if (it != initbits.end()) {
+                       auto it2 = it->second.second.wire->attributes.find(ID::init);
+                       it2->second[it->second.second.offset] = val;
+               } else {
+                       log_assert(bit.wire);
+                       initbits[bit] = std::make_pair(val,bit);
+                       auto it2 = bit.wire->attributes.find(ID::init);
+                       if (it2 != bit.wire->attributes.end()) {
+                               it2->second[bit.offset] = val;
+                       } else {
+                               Const cval(State::Sx, GetSize(bit.wire));
+                               cval[bit.offset] = val;
+                               bit.wire->attributes[ID::init] = cval;
+                       }
+               }
+       }
+
+       void set_init(const RTLIL::SigSpec &sig, RTLIL::Const val)
+       {
+               log_assert(GetSize(sig) == GetSize(val));
+               for (int i = 0; i < GetSize(sig); i++)
+                       set_init(sig[i], val[i]);
+       }
+
+       void remove_init(RTLIL::SigBit bit)
+       {
+               auto it = initbits.find((*sigmap)(bit));
+               if (it != initbits.end()) {
+                       auto it2 = it->second.second.wire->attributes.find(ID::init);
+                       it2->second[it->second.second.offset] = State::Sx;
+                       if (it2->second.is_fully_undef())
+                               it->second.second.wire->attributes.erase(it2);
+                       initbits.erase(it);
+               }
+       }
+
+       void remove_init(const RTLIL::SigSpec &sig)
+       {
+               for (auto bit : sig)
+                       remove_init(bit);
+       }
+
+       void clear()
+       {
+               initbits.clear();
+       }
+
+       FfInitVals (const SigMap *sigmap, RTLIL::Module *module)
+       {
+               set(sigmap, module);
+       }
+
+       FfInitVals () {}
+};
+
+
+YOSYS_NAMESPACE_END
+
+#endif