From: Clifford Wolf Date: Tue, 6 Sep 2016 22:28:01 +0000 (+0200) Subject: Added assertpmux X-Git-Tag: yosys-0.7~75 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ab18e9df7c55581a9713a332af425011793106a7;p=yosys.git Added assertpmux --- diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 03596411f..d00738ecd 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -458,6 +458,7 @@ struct AST_INTERNAL::ProcessGenerator case AST_CASE: { RTLIL::SwitchRule *sw = new RTLIL::SwitchRule; + sw->attributes["\\src"] = stringf("%s:%d", ast->filename.c_str(), ast->linenum); sw->signal = ast->children[0]->genWidthRTLIL(-1, &subst_rvalue_map.stdmap()); current_case->switches.push_back(sw); diff --git a/passes/sat/Makefile.inc b/passes/sat/Makefile.inc index 4fa6bf0d4..0c5f6fc60 100644 --- a/passes/sat/Makefile.inc +++ b/passes/sat/Makefile.inc @@ -4,4 +4,5 @@ OBJS += passes/sat/freduce.o OBJS += passes/sat/eval.o OBJS += passes/sat/miter.o OBJS += passes/sat/expose.o +OBJS += passes/sat/assertpmux.o diff --git a/passes/sat/assertpmux.cc b/passes/sat/assertpmux.cc new file mode 100644 index 000000000..3c8928db5 --- /dev/null +++ b/passes/sat/assertpmux.cc @@ -0,0 +1,103 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * 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. + * + */ + +#include "kernel/yosys.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +void assertpmux_worker(Cell *pmux, bool flag_noinit) +{ + Module *module = pmux->module; + + log("Adding assert for $pmux cell %s.%s.\n", log_id(module), log_id(pmux)); + + int swidth = pmux->getParam("\\S_WIDTH").as_int(); + int cntbits = ceil_log2(swidth+1); + + SigSpec sel = pmux->getPort("\\S"); + SigSpec cnt(State::S0, cntbits); + + for (int i = 0; i < swidth; i++) + cnt = module->Add(NEW_ID, cnt, sel[i]); + + SigSpec assert_a = module->Le(NEW_ID, cnt, SigSpec(1, cntbits)); + SigSpec assert_en = State::S1; + + if (flag_noinit) { + Cell *initstate_cell = module->addCell(NEW_ID, "$initstate"); + SigSpec initstate_sig = module->addWire(NEW_ID); + initstate_cell->setPort("\\Y", initstate_sig); + assert_en = module->LogicNot(NEW_ID, initstate_sig); + } + + Cell *assert_cell = module->addAssert(NEW_ID, assert_a, assert_en); + + if (pmux->attributes.count("\\src") != 0) + assert_cell->attributes["\\src"] = pmux->attributes.at("\\src"); +} + +struct AssertpmuxPass : public Pass { + AssertpmuxPass() : Pass("assertpmux", "convert internal signals to module ports") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" assertpmux [options] [selection]\n"); + log("\n"); + log("This command adds asserts to the design that assert that all parallel muxes\n"); + log("($pmux cells) have a maximum of one of their inputs enable at any time.\n"); + log("\n"); + log(" -noinit\n"); + log(" do not enforce the pmux condition during the init state\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) + { + bool flag_noinit = false; + + log_header(design, "Executing ASSERTPMUX pass (add asserts for $pmux cells).\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-noinit") { + flag_noinit = true; + continue; + } + break; + } + extra_args(args, argidx, design); + + for (auto module : design->selected_modules()) + { + vector pmux_cells; + + for (auto cell : module->selected_cells()) + if (cell->type == "$pmux") + pmux_cells.push_back(cell); + + for (auto cell : pmux_cells) + assertpmux_worker(cell, flag_noinit); + } + + } +} AssertpmuxPass; + +PRIVATE_NAMESPACE_END