mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-23 17:15:33 +00:00
Add $bmux and $demux cells.
This commit is contained in:
parent
db33b1e535
commit
93508d58da
25 changed files with 694 additions and 49 deletions
|
@ -80,7 +80,7 @@ struct CleanZeroWidthPass : public Pass {
|
|||
if (GetSize(cell->getPort(ID::Q)) == 0) {
|
||||
module->remove(cell);
|
||||
}
|
||||
} else if (cell->type == ID($pmux)) {
|
||||
} else if (cell->type.in(ID($pmux), ID($bmux), ID($demux))) {
|
||||
// Remove altogether if WIDTH is 0, replace with
|
||||
// a connection if S_WIDTH is 0.
|
||||
if (cell->getParam(ID::WIDTH).as_int() == 0) {
|
||||
|
|
|
@ -117,6 +117,10 @@ struct statdata_t
|
|||
}
|
||||
else if (cell_type.in(ID($mux), ID($pmux)))
|
||||
cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(cell->getPort(ID::Y)));
|
||||
else if (cell_type == ID($bmux))
|
||||
cell_type = stringf("%s_%d_%d", cell_type.c_str(), GetSize(cell->getPort(ID::Y)), GetSize(cell->getPort(ID::S)));
|
||||
else if (cell_type == ID($demux))
|
||||
cell_type = stringf("%s_%d_%d", cell_type.c_str(), GetSize(cell->getPort(ID::A)), GetSize(cell->getPort(ID::S)));
|
||||
else if (cell_type.in(
|
||||
ID($sr), ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($dffsre),
|
||||
ID($adff), ID($adffe), ID($sdff), ID($sdffe), ID($sdffce),
|
||||
|
|
|
@ -313,6 +313,12 @@ struct SimInstance
|
|||
return;
|
||||
}
|
||||
|
||||
// (A,S -> Y) cells
|
||||
if (has_a && !has_b && !has_c && !has_d && has_s && has_y) {
|
||||
set_state(sig_y, CellTypes::eval(cell, get_state(sig_a), get_state(sig_s)));
|
||||
return;
|
||||
}
|
||||
|
||||
// (A,B,S -> Y) cells
|
||||
if (has_a && has_b && !has_c && !has_d && has_s && has_y) {
|
||||
set_state(sig_y, CellTypes::eval(cell, get_state(sig_a), get_state(sig_b), get_state(sig_s)));
|
||||
|
|
|
@ -29,6 +29,8 @@ OBJS += passes/techmap/extract_reduce.o
|
|||
OBJS += passes/techmap/alumacc.o
|
||||
OBJS += passes/techmap/dffinit.o
|
||||
OBJS += passes/techmap/pmuxtree.o
|
||||
OBJS += passes/techmap/bmuxmap.o
|
||||
OBJS += passes/techmap/demuxmap.o
|
||||
OBJS += passes/techmap/muxcover.o
|
||||
OBJS += passes/techmap/aigmap.o
|
||||
OBJS += passes/techmap/tribuf.o
|
||||
|
|
76
passes/techmap/bmuxmap.cc
Normal file
76
passes/techmap/bmuxmap.cc
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2022 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "kernel/yosys.h"
|
||||
#include "kernel/sigtools.h"
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
struct BmuxmapPass : public Pass {
|
||||
BmuxmapPass() : Pass("bmuxmap", "transform $bmux cells to trees of $mux cells") { }
|
||||
void help() override
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" bmuxmap [selection]\n");
|
||||
log("\n");
|
||||
log("This pass transforms $bmux cells to trees of $mux cells.\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
log_header(design, "Executing BMUXMAP 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 != ID($bmux))
|
||||
continue;
|
||||
|
||||
SigSpec sel = cell->getPort(ID::S);
|
||||
SigSpec data = cell->getPort(ID::A);
|
||||
int width = GetSize(cell->getPort(ID::Y));
|
||||
|
||||
for (int idx = 0; idx < GetSize(sel); idx++) {
|
||||
SigSpec new_data = module->addWire(NEW_ID, GetSize(data)/2);
|
||||
for (int i = 0; i < GetSize(new_data); i += width) {
|
||||
RTLIL::Cell *mux = module->addMux(NEW_ID,
|
||||
data.extract(i*2, width),
|
||||
data.extract(i*2+width, width),
|
||||
sel[idx],
|
||||
new_data.extract(i, width));
|
||||
mux->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
|
||||
}
|
||||
data = new_data;
|
||||
}
|
||||
|
||||
module->connect(cell->getPort(ID::Y), data);
|
||||
module->remove(cell);
|
||||
}
|
||||
}
|
||||
} BmuxmapPass;
|
||||
|
||||
PRIVATE_NAMESPACE_END
|
80
passes/techmap/demuxmap.cc
Normal file
80
passes/techmap/demuxmap.cc
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2022 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "kernel/yosys.h"
|
||||
#include "kernel/sigtools.h"
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
struct DemuxmapPass : public Pass {
|
||||
DemuxmapPass() : Pass("demuxmap", "transform $demux cells to $eq + $mux cells") { }
|
||||
void help() override
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" demuxmap [selection]\n");
|
||||
log("\n");
|
||||
log("This pass transforms $demux cells to a bunch of equality comparisons.\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
log_header(design, "Executing DEMUXMAP 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 != ID($demux))
|
||||
continue;
|
||||
|
||||
SigSpec sel = cell->getPort(ID::S);
|
||||
SigSpec data = cell->getPort(ID::A);
|
||||
SigSpec out = cell->getPort(ID::Y);
|
||||
int width = GetSize(cell->getPort(ID::A));
|
||||
|
||||
for (int i = 0; i < 1 << GetSize(sel); i++) {
|
||||
if (width == 1 && data == State::S1) {
|
||||
RTLIL::Cell *eq_cell = module->addEq(NEW_ID, sel, Const(i, GetSize(sel)), out[i]);
|
||||
eq_cell->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
|
||||
} else {
|
||||
Wire *eq = module->addWire(NEW_ID);
|
||||
RTLIL::Cell *eq_cell = module->addEq(NEW_ID, sel, Const(i, GetSize(sel)), eq);
|
||||
eq_cell->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
|
||||
RTLIL::Cell *mux = module->addMux(NEW_ID,
|
||||
Const(State::S0, width),
|
||||
data,
|
||||
eq,
|
||||
out.extract(i*width, width));
|
||||
mux->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
|
||||
}
|
||||
}
|
||||
|
||||
module->remove(cell);
|
||||
}
|
||||
}
|
||||
} DemuxmapPass;
|
||||
|
||||
PRIVATE_NAMESPACE_END
|
|
@ -299,6 +299,30 @@ void simplemap_tribuf(RTLIL::Module *module, RTLIL::Cell *cell)
|
|||
}
|
||||
}
|
||||
|
||||
void simplemap_bmux(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||
{
|
||||
SigSpec sel = cell->getPort(ID::S);
|
||||
SigSpec data = cell->getPort(ID::A);
|
||||
int width = GetSize(cell->getPort(ID::Y));
|
||||
|
||||
for (int idx = 0; idx < GetSize(sel); idx++) {
|
||||
SigSpec new_data = module->addWire(NEW_ID, GetSize(data)/2);
|
||||
for (int i = 0; i < GetSize(new_data); i += width) {
|
||||
for (int k = 0; k < width; k++) {
|
||||
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_));
|
||||
gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
|
||||
gate->setPort(ID::A, data[i*2+k]);
|
||||
gate->setPort(ID::B, data[i*2+width+k]);
|
||||
gate->setPort(ID::S, sel[idx]);
|
||||
gate->setPort(ID::Y, new_data[i+k]);
|
||||
}
|
||||
}
|
||||
data = new_data;
|
||||
}
|
||||
|
||||
module->connect(cell->getPort(ID::Y), data);
|
||||
}
|
||||
|
||||
void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||
{
|
||||
SigSpec lut_ctrl = cell->getPort(ID::A);
|
||||
|
@ -306,7 +330,6 @@ void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell)
|
|||
lut_data.extend_u0(1 << cell->getParam(ID::WIDTH).as_int());
|
||||
|
||||
for (int idx = 0; GetSize(lut_data) > 1; idx++) {
|
||||
SigSpec sig_s = lut_ctrl[idx];
|
||||
SigSpec new_lut_data = module->addWire(NEW_ID, GetSize(lut_data)/2);
|
||||
for (int i = 0; i < GetSize(lut_data); i += 2) {
|
||||
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_));
|
||||
|
@ -400,6 +423,7 @@ void simplemap_get_mappers(dict<IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)>
|
|||
mappers[ID($nex)] = simplemap_eqne;
|
||||
mappers[ID($mux)] = simplemap_mux;
|
||||
mappers[ID($tribuf)] = simplemap_tribuf;
|
||||
mappers[ID($bmux)] = simplemap_bmux;
|
||||
mappers[ID($lut)] = simplemap_lut;
|
||||
mappers[ID($sop)] = simplemap_sop;
|
||||
mappers[ID($slice)] = simplemap_slice;
|
||||
|
|
|
@ -69,6 +69,48 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type,
|
|||
cell->setPort(ID::Y, wire);
|
||||
}
|
||||
|
||||
if (cell_type == ID($bmux))
|
||||
{
|
||||
int width = 1 + xorshift32(8);
|
||||
int swidth = 1 + xorshift32(4);
|
||||
|
||||
wire = module->addWire(ID::A);
|
||||
wire->width = width << swidth;
|
||||
wire->port_input = true;
|
||||
cell->setPort(ID::A, wire);
|
||||
|
||||
wire = module->addWire(ID::S);
|
||||
wire->width = swidth;
|
||||
wire->port_input = true;
|
||||
cell->setPort(ID::S, wire);
|
||||
|
||||
wire = module->addWire(ID::Y);
|
||||
wire->width = width;
|
||||
wire->port_output = true;
|
||||
cell->setPort(ID::Y, wire);
|
||||
}
|
||||
|
||||
if (cell_type == ID($demux))
|
||||
{
|
||||
int width = 1 + xorshift32(8);
|
||||
int swidth = 1 + xorshift32(6);
|
||||
|
||||
wire = module->addWire(ID::A);
|
||||
wire->width = width;
|
||||
wire->port_input = true;
|
||||
cell->setPort(ID::A, wire);
|
||||
|
||||
wire = module->addWire(ID::S);
|
||||
wire->width = swidth;
|
||||
wire->port_input = true;
|
||||
cell->setPort(ID::S, wire);
|
||||
|
||||
wire = module->addWire(ID::Y);
|
||||
wire->width = width << swidth;
|
||||
wire->port_output = true;
|
||||
cell->setPort(ID::Y, wire);
|
||||
}
|
||||
|
||||
if (cell_type == ID($fa))
|
||||
{
|
||||
int width = 1 + xorshift32(8);
|
||||
|
@ -855,8 +897,10 @@ struct TestCellPass : public Pass {
|
|||
cell_types[ID($logic_and)] = "ABSY";
|
||||
cell_types[ID($logic_or)] = "ABSY";
|
||||
|
||||
cell_types[ID($mux)] = "*";
|
||||
cell_types[ID($bmux)] = "*";
|
||||
cell_types[ID($demux)] = "*";
|
||||
if (edges) {
|
||||
cell_types[ID($mux)] = "*";
|
||||
cell_types[ID($pmux)] = "*";
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue