Merge remote-tracking branch 'origin/pmux2shiftx' into xc7mux

This commit is contained in:
Eddie Hung 2019-04-11 16:18:45 -07:00
commit 35181a7866
6 changed files with 93 additions and 8 deletions

View File

@ -83,8 +83,8 @@ They are declared like state variables, just using the `udata` statement:
udata <int> min_data_width max_data_width
udata <IdString> data_port_name
They are atomatically initialzed to the default constructed value of their type
when ther pattern matcher object is constructed.
They are automatically initialized to the default constructed value of their type
when the pattern matcher object is constructed.
Embedded C++ code
-----------------
@ -158,7 +158,7 @@ Finally, `filter <expression>` narrows down the remaining list of cells. For
performance reasons `filter` statements should only be used for things that
can't be done using `select` and `index`.
The `optional` statement marks optional matches. I.e. the matcher will also
The `optional` statement marks optional matches. That is, the matcher will also
explore the case where `mul` is set to `nullptr`. Without the `optional`
statement a match may only be assigned nullptr when one of the `if` expressions
evaluates to `false`.

View File

@ -34,7 +34,7 @@ void proc_rmdead(RTLIL::SwitchRule *sw, int &counter)
for (size_t i = 0; i < sw->cases.size(); i++)
{
bool is_default = GetSize(sw->cases[i]->compare) == 0 && (!pool.empty() || GetSize(sw->signal) == 0);
bool is_default = GetSize(sw->cases[i]->compare) == 0 || GetSize(sw->signal) == 0;
for (size_t j = 0; j < sw->cases[i]->compare.size(); j++) {
RTLIL::SigSpec sig = sw->cases[i]->compare[j];

View File

@ -38,6 +38,7 @@ OBJS += passes/techmap/attrmap.o
OBJS += passes/techmap/zinit.o
OBJS += passes/techmap/dff2dffs.o
OBJS += passes/techmap/flowmap.o
OBJS += passes/techmap/pmux2shiftx.o
endif
GENFILES += passes/techmap/techmap.inc

View File

@ -0,0 +1,83 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
*
* 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"
#include "kernel/sigtools.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
struct Pmux2ShiftxPass : public Pass {
Pmux2ShiftxPass() : Pass("pmux2shiftx", "transform $pmux cells to $shiftx cells") { }
void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" pmux2shiftx [selection]\n");
log("\n");
log("This pass transforms $pmux cells to $shiftx cells.\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing PMUX2SHIFTX pass.\n");
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) {
break;
}
extra_args(args, argidx, design);
for (auto module : design->selected_modules())
for (auto cell : module->selected_cells())
{
if (cell->type != "$pmux")
continue;
// Create a new encoder, out of a $pmux, that takes
// the existing pmux's 'S' input and transforms it
// back into a binary value
RTLIL::SigSpec shiftx_a;
RTLIL::SigSpec pmux_s;
int s_width = cell->getParam("\\S_WIDTH").as_int();
if (!cell->getPort("\\A").is_fully_undef()) {
++s_width;
shiftx_a.append(cell->getPort("\\A"));
pmux_s.append(module->Not(NEW_ID, module->ReduceOr(NEW_ID, cell->getPort("\\S"))));
}
const int width = cell->getParam("\\WIDTH").as_int();
const int clog2width = ceil(log2(s_width));
RTLIL::SigSpec pmux_b;
pmux_b.append(RTLIL::Const(0, clog2width));
for (int i = s_width-1; i > 0; i--)
pmux_b.append(RTLIL::Const(i, clog2width));
shiftx_a.append(cell->getPort("\\B"));
pmux_s.append(cell->getPort("\\S"));
RTLIL::SigSpec pmux_y = module->addWire(NEW_ID, clog2width);
module->addPmux(NEW_ID, RTLIL::Const(RTLIL::Sx, clog2width), pmux_b, pmux_s, pmux_y);
module->addShiftx(NEW_ID, shiftx_a, pmux_y, cell->getPort("\\Y"));
module->remove(cell);
}
}
} Pmux2ShiftxPass;
PRIVATE_NAMESPACE_END

View File

@ -71,9 +71,9 @@ struct PmuxtreePass : public Pass {
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" pmuxtree [options] [selection]\n");
log(" pmuxtree [selection]\n");
log("\n");
log("This pass transforms $pmux cells to a trees of $mux cells.\n");
log("This pass transforms $pmux cells to trees of $mux cells.\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE

View File

@ -8,12 +8,13 @@ read_verilog -formal <<EOT
3'b?1?: Y = B;
3'b1??: Y = C;
3'b000: Y = D;
default: Y = 'bx;
endcase
endmodule
EOT
## Examle usage for "pmuxtree" and "muxcover"
## Example usage for "pmuxtree" and "muxcover"
proc
pmuxtree
@ -35,7 +36,7 @@ read_verilog -formal <<EOT
3'b010: Y = B;
3'b100: Y = C;
3'b000: Y = D;
default: Y = 'bx;
default: Y = 'bx;
endcase
endmodule
EOT