mirror of https://github.com/YosysHQ/yosys.git
Merge remote-tracking branch 'origin/pmux2shiftx' into xc7mux
This commit is contained in:
commit
35181a7866
|
@ -83,8 +83,8 @@ They are declared like state variables, just using the `udata` statement:
|
||||||
udata <int> min_data_width max_data_width
|
udata <int> min_data_width max_data_width
|
||||||
udata <IdString> data_port_name
|
udata <IdString> data_port_name
|
||||||
|
|
||||||
They are atomatically initialzed to the default constructed value of their type
|
They are automatically initialized to the default constructed value of their type
|
||||||
when ther pattern matcher object is constructed.
|
when the pattern matcher object is constructed.
|
||||||
|
|
||||||
Embedded C++ code
|
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
|
performance reasons `filter` statements should only be used for things that
|
||||||
can't be done using `select` and `index`.
|
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`
|
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
|
statement a match may only be assigned nullptr when one of the `if` expressions
|
||||||
evaluates to `false`.
|
evaluates to `false`.
|
||||||
|
|
|
@ -34,7 +34,7 @@ void proc_rmdead(RTLIL::SwitchRule *sw, int &counter)
|
||||||
|
|
||||||
for (size_t i = 0; i < sw->cases.size(); i++)
|
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++) {
|
for (size_t j = 0; j < sw->cases[i]->compare.size(); j++) {
|
||||||
RTLIL::SigSpec sig = sw->cases[i]->compare[j];
|
RTLIL::SigSpec sig = sw->cases[i]->compare[j];
|
||||||
|
|
|
@ -38,6 +38,7 @@ OBJS += passes/techmap/attrmap.o
|
||||||
OBJS += passes/techmap/zinit.o
|
OBJS += passes/techmap/zinit.o
|
||||||
OBJS += passes/techmap/dff2dffs.o
|
OBJS += passes/techmap/dff2dffs.o
|
||||||
OBJS += passes/techmap/flowmap.o
|
OBJS += passes/techmap/flowmap.o
|
||||||
|
OBJS += passes/techmap/pmux2shiftx.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
GENFILES += passes/techmap/techmap.inc
|
GENFILES += passes/techmap/techmap.inc
|
||||||
|
|
|
@ -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
|
|
@ -71,9 +71,9 @@ struct PmuxtreePass : public Pass {
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" pmuxtree [options] [selection]\n");
|
log(" pmuxtree [selection]\n");
|
||||||
log("\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");
|
log("\n");
|
||||||
}
|
}
|
||||||
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||||
|
|
|
@ -8,12 +8,13 @@ read_verilog -formal <<EOT
|
||||||
3'b?1?: Y = B;
|
3'b?1?: Y = B;
|
||||||
3'b1??: Y = C;
|
3'b1??: Y = C;
|
||||||
3'b000: Y = D;
|
3'b000: Y = D;
|
||||||
|
default: Y = 'bx;
|
||||||
endcase
|
endcase
|
||||||
endmodule
|
endmodule
|
||||||
EOT
|
EOT
|
||||||
|
|
||||||
|
|
||||||
## Examle usage for "pmuxtree" and "muxcover"
|
## Example usage for "pmuxtree" and "muxcover"
|
||||||
|
|
||||||
proc
|
proc
|
||||||
pmuxtree
|
pmuxtree
|
||||||
|
@ -35,7 +36,7 @@ read_verilog -formal <<EOT
|
||||||
3'b010: Y = B;
|
3'b010: Y = B;
|
||||||
3'b100: Y = C;
|
3'b100: Y = C;
|
||||||
3'b000: Y = D;
|
3'b000: Y = D;
|
||||||
default: Y = 'bx;
|
default: Y = 'bx;
|
||||||
endcase
|
endcase
|
||||||
endmodule
|
endmodule
|
||||||
EOT
|
EOT
|
||||||
|
|
Loading…
Reference in New Issue