From 022af4f0ca0c5ccf91eec1bd470ce3948b5e344a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sun, 19 Jul 2020 01:59:47 +0200 Subject: [PATCH] Add utility module for dealing with init attributes. --- Makefile | 1 + kernel/ffinit.h | 146 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 kernel/ffinit.h diff --git a/Makefile b/Makefile index dfa4fb6a1..90f8fee05 100644 --- 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 index 000000000..49747692f --- /dev/null +++ b/kernel/ffinit.h @@ -0,0 +1,146 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 Marcelina Kościelnicka + * + * 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> 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 -- 2.30.2