mirror of https://github.com/YosysHQ/yosys.git
ID(\\.*) -> ID(.*)
This commit is contained in:
parent
467c34eff0
commit
02dead2e60
|
@ -170,7 +170,7 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
|
||||||
{
|
{
|
||||||
if (clk_polarity != (cell->type == ID($_DFF_P_)))
|
if (clk_polarity != (cell->type == ID($_DFF_P_)))
|
||||||
return;
|
return;
|
||||||
if (clk_sig != assign_map(cell->getPort(ID(\\C))))
|
if (clk_sig != assign_map(cell->getPort(ID(C))))
|
||||||
return;
|
return;
|
||||||
if (GetSize(en_sig) != 0)
|
if (GetSize(en_sig) != 0)
|
||||||
return;
|
return;
|
||||||
|
@ -183,22 +183,22 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
|
||||||
return;
|
return;
|
||||||
if (en_polarity != cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)))
|
if (en_polarity != cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)))
|
||||||
return;
|
return;
|
||||||
if (clk_sig != assign_map(cell->getPort(ID(\\C))))
|
if (clk_sig != assign_map(cell->getPort(ID(C))))
|
||||||
return;
|
return;
|
||||||
if (en_sig != assign_map(cell->getPort(ID(\\E))))
|
if (en_sig != assign_map(cell->getPort(ID(E))))
|
||||||
return;
|
return;
|
||||||
goto matching_dff;
|
goto matching_dff;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0) {
|
if (0) {
|
||||||
matching_dff:
|
matching_dff:
|
||||||
RTLIL::SigSpec sig_d = cell->getPort(ID(\\D));
|
RTLIL::SigSpec sig_d = cell->getPort(ID(D));
|
||||||
RTLIL::SigSpec sig_q = cell->getPort(ID(\\Q));
|
RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
|
||||||
|
|
||||||
if (keepff)
|
if (keepff)
|
||||||
for (auto &c : sig_q.chunks())
|
for (auto &c : sig_q.chunks())
|
||||||
if (c.wire != NULL)
|
if (c.wire != NULL)
|
||||||
c.wire->attributes[ID(\\keep)] = 1;
|
c.wire->attributes[ID(keep)] = 1;
|
||||||
|
|
||||||
assign_map.apply(sig_d);
|
assign_map.apply(sig_d);
|
||||||
assign_map.apply(sig_q);
|
assign_map.apply(sig_q);
|
||||||
|
@ -211,8 +211,8 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
|
||||||
|
|
||||||
if (cell->type.in(ID($_BUF_), ID($_NOT_)))
|
if (cell->type.in(ID($_BUF_), ID($_NOT_)))
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec sig_a = cell->getPort(ID(\\A));
|
RTLIL::SigSpec sig_a = cell->getPort(ID(A));
|
||||||
RTLIL::SigSpec sig_y = cell->getPort(ID(\\Y));
|
RTLIL::SigSpec sig_y = cell->getPort(ID(Y));
|
||||||
|
|
||||||
assign_map.apply(sig_a);
|
assign_map.apply(sig_a);
|
||||||
assign_map.apply(sig_y);
|
assign_map.apply(sig_y);
|
||||||
|
@ -225,9 +225,9 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
|
||||||
|
|
||||||
if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_)))
|
if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_)))
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec sig_a = cell->getPort(ID(\\A));
|
RTLIL::SigSpec sig_a = cell->getPort(ID(A));
|
||||||
RTLIL::SigSpec sig_b = cell->getPort(ID(\\B));
|
RTLIL::SigSpec sig_b = cell->getPort(ID(B));
|
||||||
RTLIL::SigSpec sig_y = cell->getPort(ID(\\Y));
|
RTLIL::SigSpec sig_y = cell->getPort(ID(Y));
|
||||||
|
|
||||||
assign_map.apply(sig_a);
|
assign_map.apply(sig_a);
|
||||||
assign_map.apply(sig_b);
|
assign_map.apply(sig_b);
|
||||||
|
@ -261,10 +261,10 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
|
||||||
|
|
||||||
if (cell->type.in(ID($_MUX_), ID($_NMUX_)))
|
if (cell->type.in(ID($_MUX_), ID($_NMUX_)))
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec sig_a = cell->getPort(ID(\\A));
|
RTLIL::SigSpec sig_a = cell->getPort(ID(A));
|
||||||
RTLIL::SigSpec sig_b = cell->getPort(ID(\\B));
|
RTLIL::SigSpec sig_b = cell->getPort(ID(B));
|
||||||
RTLIL::SigSpec sig_s = cell->getPort(ID(\\S));
|
RTLIL::SigSpec sig_s = cell->getPort(ID(S));
|
||||||
RTLIL::SigSpec sig_y = cell->getPort(ID(\\Y));
|
RTLIL::SigSpec sig_y = cell->getPort(ID(Y));
|
||||||
|
|
||||||
assign_map.apply(sig_a);
|
assign_map.apply(sig_a);
|
||||||
assign_map.apply(sig_b);
|
assign_map.apply(sig_b);
|
||||||
|
@ -283,10 +283,10 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
|
||||||
|
|
||||||
if (cell->type.in(ID($_AOI3_), ID($_OAI3_)))
|
if (cell->type.in(ID($_AOI3_), ID($_OAI3_)))
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec sig_a = cell->getPort(ID(\\A));
|
RTLIL::SigSpec sig_a = cell->getPort(ID(A));
|
||||||
RTLIL::SigSpec sig_b = cell->getPort(ID(\\B));
|
RTLIL::SigSpec sig_b = cell->getPort(ID(B));
|
||||||
RTLIL::SigSpec sig_c = cell->getPort(ID(\\C));
|
RTLIL::SigSpec sig_c = cell->getPort(ID(C));
|
||||||
RTLIL::SigSpec sig_y = cell->getPort(ID(\\Y));
|
RTLIL::SigSpec sig_y = cell->getPort(ID(Y));
|
||||||
|
|
||||||
assign_map.apply(sig_a);
|
assign_map.apply(sig_a);
|
||||||
assign_map.apply(sig_b);
|
assign_map.apply(sig_b);
|
||||||
|
@ -305,11 +305,11 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
|
||||||
|
|
||||||
if (cell->type.in(ID($_AOI4_), ID($_OAI4_)))
|
if (cell->type.in(ID($_AOI4_), ID($_OAI4_)))
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec sig_a = cell->getPort(ID(\\A));
|
RTLIL::SigSpec sig_a = cell->getPort(ID(A));
|
||||||
RTLIL::SigSpec sig_b = cell->getPort(ID(\\B));
|
RTLIL::SigSpec sig_b = cell->getPort(ID(B));
|
||||||
RTLIL::SigSpec sig_c = cell->getPort(ID(\\C));
|
RTLIL::SigSpec sig_c = cell->getPort(ID(C));
|
||||||
RTLIL::SigSpec sig_d = cell->getPort(ID(\\D));
|
RTLIL::SigSpec sig_d = cell->getPort(ID(D));
|
||||||
RTLIL::SigSpec sig_y = cell->getPort(ID(\\Y));
|
RTLIL::SigSpec sig_y = cell->getPort(ID(Y));
|
||||||
|
|
||||||
assign_map.apply(sig_a);
|
assign_map.apply(sig_a);
|
||||||
assign_map.apply(sig_b);
|
assign_map.apply(sig_b);
|
||||||
|
@ -787,7 +787,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
|
||||||
extract_cell(c, keepff);
|
extract_cell(c, keepff);
|
||||||
|
|
||||||
for (auto &wire_it : module->wires_) {
|
for (auto &wire_it : module->wires_) {
|
||||||
if (wire_it.second->port_id > 0 || wire_it.second->get_bool_attribute(ID(\\keep)))
|
if (wire_it.second->port_id > 0 || wire_it.second->get_bool_attribute(ID(keep)))
|
||||||
mark_port(RTLIL::SigSpec(wire_it.second));
|
mark_port(RTLIL::SigSpec(wire_it.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1016,21 +1016,21 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
|
||||||
|
|
||||||
bool builtin_lib = liberty_file.empty();
|
bool builtin_lib = liberty_file.empty();
|
||||||
RTLIL::Design *mapped_design = new RTLIL::Design;
|
RTLIL::Design *mapped_design = new RTLIL::Design;
|
||||||
parse_blif(mapped_design, ifs, builtin_lib ? ID(\\DFF) : ID(\\_dff_), false, sop_mode);
|
parse_blif(mapped_design, ifs, builtin_lib ? ID(DFF) : ID(_dff_), false, sop_mode);
|
||||||
|
|
||||||
ifs.close();
|
ifs.close();
|
||||||
|
|
||||||
log_header(design, "Re-integrating ABC results.\n");
|
log_header(design, "Re-integrating ABC results.\n");
|
||||||
RTLIL::Module *mapped_mod = mapped_design->modules_[ID(\\netlist)];
|
RTLIL::Module *mapped_mod = mapped_design->modules_[ID(netlist)];
|
||||||
if (mapped_mod == NULL)
|
if (mapped_mod == NULL)
|
||||||
log_error("ABC output file does not contain a module `netlist'.\n");
|
log_error("ABC output file does not contain a module `netlist'.\n");
|
||||||
for (auto &it : mapped_mod->wires_) {
|
for (auto &it : mapped_mod->wires_) {
|
||||||
RTLIL::Wire *w = it.second;
|
RTLIL::Wire *w = it.second;
|
||||||
RTLIL::Wire *orig_wire = nullptr;
|
RTLIL::Wire *orig_wire = nullptr;
|
||||||
RTLIL::Wire *wire = module->addWire(remap_name(w->name, &orig_wire));
|
RTLIL::Wire *wire = module->addWire(remap_name(w->name, &orig_wire));
|
||||||
if (orig_wire != nullptr && orig_wire->attributes.count(ID(\\src)))
|
if (orig_wire != nullptr && orig_wire->attributes.count(ID(src)))
|
||||||
wire->attributes[ID(\\src)] = orig_wire->attributes[ID(\\src)];
|
wire->attributes[ID(src)] = orig_wire->attributes[ID(src)];
|
||||||
if (markgroups) wire->attributes[ID(\\abcgroup)] = map_autoidx;
|
if (markgroups) wire->attributes[ID(abcgroup)] = map_autoidx;
|
||||||
design->select(module, wire);
|
design->select(module, wire);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1040,127 +1040,127 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
|
||||||
if (builtin_lib)
|
if (builtin_lib)
|
||||||
{
|
{
|
||||||
cell_stats[RTLIL::unescape_id(c->type)]++;
|
cell_stats[RTLIL::unescape_id(c->type)]++;
|
||||||
if (c->type.in(ID(\\ZERO), ID(\\ONE))) {
|
if (c->type.in(ID(ZERO), ID(ONE))) {
|
||||||
RTLIL::SigSig conn;
|
RTLIL::SigSig conn;
|
||||||
conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\Y)).as_wire()->name)]);
|
conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)]);
|
||||||
conn.second = RTLIL::SigSpec(c->type == ID(\\ZERO) ? 0 : 1, 1);
|
conn.second = RTLIL::SigSpec(c->type == ID(ZERO) ? 0 : 1, 1);
|
||||||
module->connect(conn);
|
module->connect(conn);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c->type == ID(\\BUF)) {
|
if (c->type == ID(BUF)) {
|
||||||
RTLIL::SigSig conn;
|
RTLIL::SigSig conn;
|
||||||
conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\Y)).as_wire()->name)]);
|
conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)]);
|
||||||
conn.second = RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\A)).as_wire()->name)]);
|
conn.second = RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)]);
|
||||||
module->connect(conn);
|
module->connect(conn);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c->type == ID(\\NOT)) {
|
if (c->type == ID(NOT)) {
|
||||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_NOT_));
|
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_NOT_));
|
||||||
if (markgroups) cell->attributes[ID(\\abcgroup)] = map_autoidx;
|
if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
|
||||||
cell->setPort(ID(\\A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\A)).as_wire()->name)]));
|
cell->setPort(ID(A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\Y)).as_wire()->name)]));
|
cell->setPort(ID(Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)]));
|
||||||
design->select(module, cell);
|
design->select(module, cell);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c->type.in(ID(\\AND), ID(\\OR), ID(\\XOR), ID(\\NAND), ID(\\NOR), ID(\\XNOR), ID(\\ANDNOT), ID(\\ORNOT))) {
|
if (c->type.in(ID(AND), ID(OR), ID(XOR), ID(NAND), ID(NOR), ID(XNOR), ID(ANDNOT), ID(ORNOT))) {
|
||||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
|
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
|
||||||
if (markgroups) cell->attributes[ID(\\abcgroup)] = map_autoidx;
|
if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
|
||||||
cell->setPort(ID(\\A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\A)).as_wire()->name)]));
|
cell->setPort(ID(A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\B)).as_wire()->name)]));
|
cell->setPort(ID(B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(B)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\Y)).as_wire()->name)]));
|
cell->setPort(ID(Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)]));
|
||||||
design->select(module, cell);
|
design->select(module, cell);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c->type.in(ID(\\MUX), ID(\\NMUX))) {
|
if (c->type.in(ID(MUX), ID(NMUX))) {
|
||||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
|
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
|
||||||
if (markgroups) cell->attributes[ID(\\abcgroup)] = map_autoidx;
|
if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
|
||||||
cell->setPort(ID(\\A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\A)).as_wire()->name)]));
|
cell->setPort(ID(A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\B)).as_wire()->name)]));
|
cell->setPort(ID(B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(B)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\S)).as_wire()->name)]));
|
cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\Y)).as_wire()->name)]));
|
cell->setPort(ID(Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)]));
|
||||||
design->select(module, cell);
|
design->select(module, cell);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c->type == ID(\\MUX4)) {
|
if (c->type == ID(MUX4)) {
|
||||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX4_));
|
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX4_));
|
||||||
if (markgroups) cell->attributes[ID(\\abcgroup)] = map_autoidx;
|
if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
|
||||||
cell->setPort(ID(\\A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\A)).as_wire()->name)]));
|
cell->setPort(ID(A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\B)).as_wire()->name)]));
|
cell->setPort(ID(B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(B)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\C)).as_wire()->name)]));
|
cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\D)).as_wire()->name)]));
|
cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\S)).as_wire()->name)]));
|
cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\T)).as_wire()->name)]));
|
cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\Y)).as_wire()->name)]));
|
cell->setPort(ID(Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)]));
|
||||||
design->select(module, cell);
|
design->select(module, cell);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c->type == ID(\\MUX8)) {
|
if (c->type == ID(MUX8)) {
|
||||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX8_));
|
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX8_));
|
||||||
if (markgroups) cell->attributes[ID(\\abcgroup)] = map_autoidx;
|
if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
|
||||||
cell->setPort(ID(\\A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\A)).as_wire()->name)]));
|
cell->setPort(ID(A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\B)).as_wire()->name)]));
|
cell->setPort(ID(B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(B)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\C)).as_wire()->name)]));
|
cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\D)).as_wire()->name)]));
|
cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\E), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\E)).as_wire()->name)]));
|
cell->setPort(ID(E), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(E)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\F), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\F)).as_wire()->name)]));
|
cell->setPort(ID(F), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(F)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\G), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\G)).as_wire()->name)]));
|
cell->setPort(ID(G), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(G)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\H), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\H)).as_wire()->name)]));
|
cell->setPort(ID(H), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(H)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\S)).as_wire()->name)]));
|
cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\T)).as_wire()->name)]));
|
cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\U), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\U)).as_wire()->name)]));
|
cell->setPort(ID(U), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(U)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\Y)).as_wire()->name)]));
|
cell->setPort(ID(Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)]));
|
||||||
design->select(module, cell);
|
design->select(module, cell);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c->type == ID(\\MUX16)) {
|
if (c->type == ID(MUX16)) {
|
||||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX16_));
|
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX16_));
|
||||||
if (markgroups) cell->attributes[ID(\\abcgroup)] = map_autoidx;
|
if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
|
||||||
cell->setPort(ID(\\A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\A)).as_wire()->name)]));
|
cell->setPort(ID(A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\B)).as_wire()->name)]));
|
cell->setPort(ID(B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(B)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\C)).as_wire()->name)]));
|
cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\D)).as_wire()->name)]));
|
cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\E), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\E)).as_wire()->name)]));
|
cell->setPort(ID(E), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(E)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\F), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\F)).as_wire()->name)]));
|
cell->setPort(ID(F), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(F)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\G), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\G)).as_wire()->name)]));
|
cell->setPort(ID(G), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(G)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\H), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\H)).as_wire()->name)]));
|
cell->setPort(ID(H), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(H)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\I), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\I)).as_wire()->name)]));
|
cell->setPort(ID(I), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(I)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\J), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\J)).as_wire()->name)]));
|
cell->setPort(ID(J), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(J)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\K), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\K)).as_wire()->name)]));
|
cell->setPort(ID(K), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(K)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\L), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\L)).as_wire()->name)]));
|
cell->setPort(ID(L), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(L)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\M), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\M)).as_wire()->name)]));
|
cell->setPort(ID(M), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(M)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\N), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\N)).as_wire()->name)]));
|
cell->setPort(ID(N), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(N)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\O), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\O)).as_wire()->name)]));
|
cell->setPort(ID(O), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(O)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\P), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\P)).as_wire()->name)]));
|
cell->setPort(ID(P), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(P)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\S)).as_wire()->name)]));
|
cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\T)).as_wire()->name)]));
|
cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\U), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\U)).as_wire()->name)]));
|
cell->setPort(ID(U), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(U)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\V), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\V)).as_wire()->name)]));
|
cell->setPort(ID(V), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(V)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\Y)).as_wire()->name)]));
|
cell->setPort(ID(Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)]));
|
||||||
design->select(module, cell);
|
design->select(module, cell);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c->type.in(ID(\\AOI3), ID(\\OAI3))) {
|
if (c->type.in(ID(AOI3), ID(OAI3))) {
|
||||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
|
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
|
||||||
if (markgroups) cell->attributes[ID(\\abcgroup)] = map_autoidx;
|
if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
|
||||||
cell->setPort(ID(\\A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\A)).as_wire()->name)]));
|
cell->setPort(ID(A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\B)).as_wire()->name)]));
|
cell->setPort(ID(B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(B)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\C)).as_wire()->name)]));
|
cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\Y)).as_wire()->name)]));
|
cell->setPort(ID(Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)]));
|
||||||
design->select(module, cell);
|
design->select(module, cell);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c->type.in(ID(\\AOI4), ID(\\OAI4))) {
|
if (c->type.in(ID(AOI4), ID(OAI4))) {
|
||||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
|
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
|
||||||
if (markgroups) cell->attributes[ID(\\abcgroup)] = map_autoidx;
|
if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
|
||||||
cell->setPort(ID(\\A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\A)).as_wire()->name)]));
|
cell->setPort(ID(A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\B)).as_wire()->name)]));
|
cell->setPort(ID(B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(B)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\C)).as_wire()->name)]));
|
cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\D)).as_wire()->name)]));
|
cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\Y)).as_wire()->name)]));
|
cell->setPort(ID(Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)]));
|
||||||
design->select(module, cell);
|
design->select(module, cell);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c->type == ID(\\DFF)) {
|
if (c->type == ID(DFF)) {
|
||||||
log_assert(clk_sig.size() == 1);
|
log_assert(clk_sig.size() == 1);
|
||||||
RTLIL::Cell *cell;
|
RTLIL::Cell *cell;
|
||||||
if (en_sig.size() == 0) {
|
if (en_sig.size() == 0) {
|
||||||
|
@ -1168,12 +1168,12 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
|
||||||
} else {
|
} else {
|
||||||
log_assert(en_sig.size() == 1);
|
log_assert(en_sig.size() == 1);
|
||||||
cell = module->addCell(remap_name(c->name), stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N'));
|
cell = module->addCell(remap_name(c->name), stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N'));
|
||||||
cell->setPort(ID(\\E), en_sig);
|
cell->setPort(ID(E), en_sig);
|
||||||
}
|
}
|
||||||
if (markgroups) cell->attributes[ID(\\abcgroup)] = map_autoidx;
|
if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
|
||||||
cell->setPort(ID(\\D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\D)).as_wire()->name)]));
|
cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\Q), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\Q)).as_wire()->name)]));
|
cell->setPort(ID(Q), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Q)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\C), clk_sig);
|
cell->setPort(ID(C), clk_sig);
|
||||||
design->select(module, cell);
|
design->select(module, cell);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1181,15 +1181,15 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
|
||||||
else
|
else
|
||||||
cell_stats[RTLIL::unescape_id(c->type)]++;
|
cell_stats[RTLIL::unescape_id(c->type)]++;
|
||||||
|
|
||||||
if (c->type.in(ID(\\_const0_), ID(\\_const1_))) {
|
if (c->type.in(ID(_const0_), ID(_const1_))) {
|
||||||
RTLIL::SigSig conn;
|
RTLIL::SigSig conn;
|
||||||
conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->connections().begin()->second.as_wire()->name)]);
|
conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->connections().begin()->second.as_wire()->name)]);
|
||||||
conn.second = RTLIL::SigSpec(c->type == ID(\\_const0_) ? 0 : 1, 1);
|
conn.second = RTLIL::SigSpec(c->type == ID(_const0_) ? 0 : 1, 1);
|
||||||
module->connect(conn);
|
module->connect(conn);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->type == ID(\\_dff_)) {
|
if (c->type == ID(_dff_)) {
|
||||||
log_assert(clk_sig.size() == 1);
|
log_assert(clk_sig.size() == 1);
|
||||||
RTLIL::Cell *cell;
|
RTLIL::Cell *cell;
|
||||||
if (en_sig.size() == 0) {
|
if (en_sig.size() == 0) {
|
||||||
|
@ -1197,25 +1197,25 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
|
||||||
} else {
|
} else {
|
||||||
log_assert(en_sig.size() == 1);
|
log_assert(en_sig.size() == 1);
|
||||||
cell = module->addCell(remap_name(c->name), stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N'));
|
cell = module->addCell(remap_name(c->name), stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N'));
|
||||||
cell->setPort(ID(\\E), en_sig);
|
cell->setPort(ID(E), en_sig);
|
||||||
}
|
}
|
||||||
if (markgroups) cell->attributes[ID(\\abcgroup)] = map_autoidx;
|
if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
|
||||||
cell->setPort(ID(\\D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\D)).as_wire()->name)]));
|
cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\Q), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(\\Q)).as_wire()->name)]));
|
cell->setPort(ID(Q), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Q)).as_wire()->name)]));
|
||||||
cell->setPort(ID(\\C), clk_sig);
|
cell->setPort(ID(C), clk_sig);
|
||||||
design->select(module, cell);
|
design->select(module, cell);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->type == ID($lut) && GetSize(c->getPort(ID(\\A))) == 1 && c->getParam(ID(\\LUT)).as_int() == 2) {
|
if (c->type == ID($lut) && GetSize(c->getPort(ID(A))) == 1 && c->getParam(ID(LUT)).as_int() == 2) {
|
||||||
SigSpec my_a = module->wires_[remap_name(c->getPort(ID(\\A)).as_wire()->name)];
|
SigSpec my_a = module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)];
|
||||||
SigSpec my_y = module->wires_[remap_name(c->getPort(ID(\\Y)).as_wire()->name)];
|
SigSpec my_y = module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)];
|
||||||
module->connect(my_y, my_a);
|
module->connect(my_y, my_a);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), c->type);
|
RTLIL::Cell *cell = module->addCell(remap_name(c->name), c->type);
|
||||||
if (markgroups) cell->attributes[ID(\\abcgroup)] = map_autoidx;
|
if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
|
||||||
cell->parameters = c->parameters;
|
cell->parameters = c->parameters;
|
||||||
for (auto &conn : c->connections()) {
|
for (auto &conn : c->connections()) {
|
||||||
RTLIL::SigSpec newsig;
|
RTLIL::SigSpec newsig;
|
||||||
|
@ -1240,10 +1240,10 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
|
||||||
|
|
||||||
if (recover_init)
|
if (recover_init)
|
||||||
for (auto wire : mapped_mod->wires()) {
|
for (auto wire : mapped_mod->wires()) {
|
||||||
if (wire->attributes.count(ID(\\init))) {
|
if (wire->attributes.count(ID(init))) {
|
||||||
Wire *w = module->wires_[remap_name(wire->name)];
|
Wire *w = module->wires_[remap_name(wire->name)];
|
||||||
log_assert(w->attributes.count(ID(\\init)) == 0);
|
log_assert(w->attributes.count(ID(init)) == 0);
|
||||||
w->attributes[ID(\\init)] = wire->attributes.at(ID(\\init));
|
w->attributes[ID(init)] = wire->attributes.at(ID(init));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1798,9 +1798,9 @@ struct AbcPass : public Pass {
|
||||||
signal_init.clear();
|
signal_init.clear();
|
||||||
|
|
||||||
for (Wire *wire : mod->wires())
|
for (Wire *wire : mod->wires())
|
||||||
if (wire->attributes.count(ID(\\init))) {
|
if (wire->attributes.count(ID(init))) {
|
||||||
SigSpec initsig = assign_map(wire);
|
SigSpec initsig = assign_map(wire);
|
||||||
Const initval = wire->attributes.at(ID(\\init));
|
Const initval = wire->attributes.at(ID(init));
|
||||||
for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++)
|
for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++)
|
||||||
switch (initval[i]) {
|
switch (initval[i]) {
|
||||||
case State::S0:
|
case State::S0:
|
||||||
|
@ -1859,14 +1859,14 @@ struct AbcPass : public Pass {
|
||||||
|
|
||||||
if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_)))
|
if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_)))
|
||||||
{
|
{
|
||||||
key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(\\C))), true, RTLIL::SigSpec());
|
key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
|
if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
|
||||||
{
|
{
|
||||||
bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_));
|
bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_));
|
||||||
bool this_en_pol = cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_));
|
bool this_en_pol = cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_));
|
||||||
key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(\\C))), this_en_pol, assign_map(cell->getPort(ID(\\E))));
|
key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, assign_map(cell->getPort(ID(E))));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -87,7 +87,7 @@ void handle_loops(RTLIL::Design *design)
|
||||||
// wires
|
// wires
|
||||||
pool<RTLIL::Const> ids_seen;
|
pool<RTLIL::Const> ids_seen;
|
||||||
for (auto cell : module->cells()) {
|
for (auto cell : module->cells()) {
|
||||||
auto it = cell->attributes.find(ID(\\abc_scc_id));
|
auto it = cell->attributes.find(ID(abc_scc_id));
|
||||||
if (it != cell->attributes.end()) {
|
if (it != cell->attributes.end()) {
|
||||||
auto r = ids_seen.insert(it->second);
|
auto r = ids_seen.insert(it->second);
|
||||||
if (r.second) {
|
if (r.second) {
|
||||||
|
@ -107,7 +107,7 @@ void handle_loops(RTLIL::Design *design)
|
||||||
log_assert(w->port_input);
|
log_assert(w->port_input);
|
||||||
log_assert(b.offset < GetSize(w));
|
log_assert(b.offset < GetSize(w));
|
||||||
}
|
}
|
||||||
w->set_bool_attribute(ID(\\abc_scc_break));
|
w->set_bool_attribute(ID(abc_scc_break));
|
||||||
module->swap_names(b.wire, w);
|
module->swap_names(b.wire, w);
|
||||||
c.second = RTLIL::SigBit(w, b.offset);
|
c.second = RTLIL::SigBit(w, b.offset);
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ void handle_loops(RTLIL::Design *design)
|
||||||
std::vector<IdString> ports;
|
std::vector<IdString> ports;
|
||||||
RTLIL::Module* box_module = design->module(cell->type);
|
RTLIL::Module* box_module = design->module(cell->type);
|
||||||
if (box_module) {
|
if (box_module) {
|
||||||
auto ports_csv = box_module->attributes.at(ID(\\abc_scc_break), RTLIL::Const::from_string("")).decode_string();
|
auto ports_csv = box_module->attributes.at(ID(abc_scc_break), RTLIL::Const::from_string("")).decode_string();
|
||||||
for (const auto &port_name : split_tokens(ports_csv, ",")) {
|
for (const auto &port_name : split_tokens(ports_csv, ",")) {
|
||||||
auto port_id = RTLIL::escape_id(port_name);
|
auto port_id = RTLIL::escape_id(port_name);
|
||||||
auto kt = cell->connections_.find(port_id);
|
auto kt = cell->connections_.find(port_id);
|
||||||
|
@ -140,7 +140,7 @@ void handle_loops(RTLIL::Design *design)
|
||||||
Wire *w = b.wire;
|
Wire *w = b.wire;
|
||||||
if (!w) continue;
|
if (!w) continue;
|
||||||
w->port_output = true;
|
w->port_output = true;
|
||||||
w->set_bool_attribute(ID(\\abc_scc_break));
|
w->set_bool_attribute(ID(abc_scc_break));
|
||||||
w = module->wire(stringf("%s.abci", w->name.c_str()));
|
w = module->wire(stringf("%s.abci", w->name.c_str()));
|
||||||
if (!w) {
|
if (!w) {
|
||||||
w = module->addWire(stringf("%s.abci", b.wire->name.c_str()), GetSize(b.wire));
|
w = module->addWire(stringf("%s.abci", b.wire->name.c_str()), GetSize(b.wire));
|
||||||
|
@ -460,7 +460,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
|
||||||
// the expose operation -- remove them from PO/PI
|
// the expose operation -- remove them from PO/PI
|
||||||
// and re-connecting them back together
|
// and re-connecting them back together
|
||||||
for (auto wire : module->wires()) {
|
for (auto wire : module->wires()) {
|
||||||
auto it = wire->attributes.find(ID(\\abc_scc_break));
|
auto it = wire->attributes.find(ID(abc_scc_break));
|
||||||
if (it != wire->attributes.end()) {
|
if (it != wire->attributes.end()) {
|
||||||
wire->attributes.erase(it);
|
wire->attributes.erase(it);
|
||||||
log_assert(wire->port_output);
|
log_assert(wire->port_output);
|
||||||
|
@ -535,7 +535,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
|
||||||
for (auto &it : mapped_mod->wires_) {
|
for (auto &it : mapped_mod->wires_) {
|
||||||
RTLIL::Wire *w = it.second;
|
RTLIL::Wire *w = it.second;
|
||||||
RTLIL::Wire *remap_wire = module->addWire(remap_name(w->name), GetSize(w));
|
RTLIL::Wire *remap_wire = module->addWire(remap_name(w->name), GetSize(w));
|
||||||
if (markgroups) remap_wire->attributes[ID(\\abcgroup)] = map_autoidx;
|
if (markgroups) remap_wire->attributes[ID(abcgroup)] = map_autoidx;
|
||||||
if (w->port_output) {
|
if (w->port_output) {
|
||||||
RTLIL::Wire *wire = module->wire(w->name);
|
RTLIL::Wire *wire = module->wire(w->name);
|
||||||
log_assert(wire);
|
log_assert(wire);
|
||||||
|
@ -564,7 +564,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
|
||||||
auto jt = abc_box.find(cell->type);
|
auto jt = abc_box.find(cell->type);
|
||||||
if (jt == abc_box.end()) {
|
if (jt == abc_box.end()) {
|
||||||
RTLIL::Module* box_module = design->module(cell->type);
|
RTLIL::Module* box_module = design->module(cell->type);
|
||||||
jt = abc_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count(ID(\\abc_box_id)))).first;
|
jt = abc_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count(ID(abc_box_id)))).first;
|
||||||
}
|
}
|
||||||
if (jt->second)
|
if (jt->second)
|
||||||
boxes.emplace_back(cell);
|
boxes.emplace_back(cell);
|
||||||
|
@ -582,13 +582,13 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
|
||||||
|
|
||||||
RTLIL::Cell *cell = nullptr;
|
RTLIL::Cell *cell = nullptr;
|
||||||
if (c->type == ID($_NOT_)) {
|
if (c->type == ID($_NOT_)) {
|
||||||
RTLIL::SigBit a_bit = c->getPort(ID(\\A));
|
RTLIL::SigBit a_bit = c->getPort(ID(A));
|
||||||
RTLIL::SigBit y_bit = c->getPort(ID(\\Y));
|
RTLIL::SigBit y_bit = c->getPort(ID(Y));
|
||||||
bit_users[a_bit].insert(c->name);
|
bit_users[a_bit].insert(c->name);
|
||||||
bit_drivers[y_bit].insert(c->name);
|
bit_drivers[y_bit].insert(c->name);
|
||||||
|
|
||||||
if (!a_bit.wire) {
|
if (!a_bit.wire) {
|
||||||
c->setPort(ID(\\Y), module->addWire(NEW_ID));
|
c->setPort(ID(Y), module->addWire(NEW_ID));
|
||||||
RTLIL::Wire *wire = module->wire(remap_name(y_bit.wire->name));
|
RTLIL::Wire *wire = module->wire(remap_name(y_bit.wire->name));
|
||||||
log_assert(wire);
|
log_assert(wire);
|
||||||
module->connect(RTLIL::SigBit(wire, y_bit.offset), State::S1);
|
module->connect(RTLIL::SigBit(wire, y_bit.offset), State::S1);
|
||||||
|
@ -616,7 +616,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
|
||||||
RTLIL::SigBit(module->wires_.at(remap_name(a_bit.wire->name)), a_bit.offset),
|
RTLIL::SigBit(module->wires_.at(remap_name(a_bit.wire->name)), a_bit.offset),
|
||||||
RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset),
|
RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset),
|
||||||
RTLIL::Const::from_string("01"));
|
RTLIL::Const::from_string("01"));
|
||||||
bit2sinks[cell->getPort(ID(\\A))].push_back(cell);
|
bit2sinks[cell->getPort(ID(A))].push_back(cell);
|
||||||
cell_stats[ID($lut)]++;
|
cell_stats[ID($lut)]++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -625,18 +625,18 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
log_abort();
|
log_abort();
|
||||||
if (cell && markgroups) cell->attributes[ID(\\abcgroup)] = map_autoidx;
|
if (cell && markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
cell_stats[RTLIL::unescape_id(c->type)]++;
|
cell_stats[RTLIL::unescape_id(c->type)]++;
|
||||||
|
|
||||||
RTLIL::Cell *existing_cell = nullptr;
|
RTLIL::Cell *existing_cell = nullptr;
|
||||||
if (c->type == ID($lut)) {
|
if (c->type == ID($lut)) {
|
||||||
if (GetSize(c->getPort(ID(\\A))) == 1 && c->getParam(ID(\\LUT)) == RTLIL::Const::from_string("01")) {
|
if (GetSize(c->getPort(ID(A))) == 1 && c->getParam(ID(LUT)) == RTLIL::Const::from_string("01")) {
|
||||||
SigSpec my_a = module->wires_.at(remap_name(c->getPort(ID(\\A)).as_wire()->name));
|
SigSpec my_a = module->wires_.at(remap_name(c->getPort(ID(A)).as_wire()->name));
|
||||||
SigSpec my_y = module->wires_.at(remap_name(c->getPort(ID(\\Y)).as_wire()->name));
|
SigSpec my_y = module->wires_.at(remap_name(c->getPort(ID(Y)).as_wire()->name));
|
||||||
module->connect(my_y, my_a);
|
module->connect(my_y, my_a);
|
||||||
if (markgroups) c->attributes[ID(\\abcgroup)] = map_autoidx;
|
if (markgroups) c->attributes[ID(abcgroup)] = map_autoidx;
|
||||||
log_abort();
|
log_abort();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -649,7 +649,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
|
||||||
module->swap_names(cell, existing_cell);
|
module->swap_names(cell, existing_cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (markgroups) cell->attributes[ID(\\abcgroup)] = map_autoidx;
|
if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
|
||||||
if (existing_cell) {
|
if (existing_cell) {
|
||||||
cell->parameters = existing_cell->parameters;
|
cell->parameters = existing_cell->parameters;
|
||||||
cell->attributes = existing_cell->attributes;
|
cell->attributes = existing_cell->attributes;
|
||||||
|
@ -751,8 +751,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
|
||||||
if (it == not2drivers.end())
|
if (it == not2drivers.end())
|
||||||
continue;
|
continue;
|
||||||
RTLIL::Cell *driver_lut = it->second;
|
RTLIL::Cell *driver_lut = it->second;
|
||||||
RTLIL::SigBit a_bit = not_cell->getPort(ID(\\A));
|
RTLIL::SigBit a_bit = not_cell->getPort(ID(A));
|
||||||
RTLIL::SigBit y_bit = not_cell->getPort(ID(\\Y));
|
RTLIL::SigBit y_bit = not_cell->getPort(ID(Y));
|
||||||
RTLIL::Const driver_mask;
|
RTLIL::Const driver_mask;
|
||||||
|
|
||||||
a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name));
|
a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name));
|
||||||
|
@ -768,8 +768,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
|
||||||
|
|
||||||
// Push downstream LUTs past inverter
|
// Push downstream LUTs past inverter
|
||||||
for (auto sink_cell : jt->second) {
|
for (auto sink_cell : jt->second) {
|
||||||
SigSpec A = sink_cell->getPort(ID(\\A));
|
SigSpec A = sink_cell->getPort(ID(A));
|
||||||
RTLIL::Const mask = sink_cell->getParam(ID(\\LUT));
|
RTLIL::Const mask = sink_cell->getParam(ID(LUT));
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (; index < GetSize(A); index++)
|
for (; index < GetSize(A); index++)
|
||||||
if (A[index] == a_bit)
|
if (A[index] == a_bit)
|
||||||
|
@ -782,8 +782,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
|
||||||
i += 1 << (index+1);
|
i += 1 << (index+1);
|
||||||
}
|
}
|
||||||
A[index] = y_bit;
|
A[index] = y_bit;
|
||||||
sink_cell->setPort(ID(\\A), A);
|
sink_cell->setPort(ID(A), A);
|
||||||
sink_cell->setParam(ID(\\LUT), mask);
|
sink_cell->setParam(ID(LUT), mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Since we have rewritten all sinks (which we know
|
// Since we have rewritten all sinks (which we know
|
||||||
|
@ -792,16 +792,16 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
|
||||||
// that the original driving LUT will become dangling
|
// that the original driving LUT will become dangling
|
||||||
// and get cleaned away
|
// and get cleaned away
|
||||||
clone_lut:
|
clone_lut:
|
||||||
driver_mask = driver_lut->getParam(ID(\\LUT));
|
driver_mask = driver_lut->getParam(ID(LUT));
|
||||||
for (auto &b : driver_mask.bits) {
|
for (auto &b : driver_mask.bits) {
|
||||||
if (b == RTLIL::State::S0) b = RTLIL::State::S1;
|
if (b == RTLIL::State::S0) b = RTLIL::State::S1;
|
||||||
else if (b == RTLIL::State::S1) b = RTLIL::State::S0;
|
else if (b == RTLIL::State::S1) b = RTLIL::State::S0;
|
||||||
}
|
}
|
||||||
auto cell = module->addLut(NEW_ID,
|
auto cell = module->addLut(NEW_ID,
|
||||||
driver_lut->getPort(ID(\\A)),
|
driver_lut->getPort(ID(A)),
|
||||||
y_bit,
|
y_bit,
|
||||||
driver_mask);
|
driver_mask);
|
||||||
for (auto &bit : cell->connections_.at(ID(\\A))) {
|
for (auto &bit : cell->connections_.at(ID(A))) {
|
||||||
bit.wire = module->wires_.at(remap_name(bit.wire->name));
|
bit.wire = module->wires_.at(remap_name(bit.wire->name));
|
||||||
bit2sinks[bit].push_back(cell);
|
bit2sinks[bit].push_back(cell);
|
||||||
}
|
}
|
||||||
|
@ -1082,7 +1082,7 @@ struct Abc9Pass : public Pass {
|
||||||
|
|
||||||
dict<int,IdString> box_lookup;
|
dict<int,IdString> box_lookup;
|
||||||
for (auto m : design->modules()) {
|
for (auto m : design->modules()) {
|
||||||
auto it = m->attributes.find(ID(\\abc_box_id));
|
auto it = m->attributes.find(ID(abc_box_id));
|
||||||
if (it == m->attributes.end())
|
if (it == m->attributes.end())
|
||||||
continue;
|
continue;
|
||||||
if (m->name.begins_with("$paramod"))
|
if (m->name.begins_with("$paramod"))
|
||||||
|
@ -1097,7 +1097,7 @@ struct Abc9Pass : public Pass {
|
||||||
|
|
||||||
for (auto mod : design->selected_modules())
|
for (auto mod : design->selected_modules())
|
||||||
{
|
{
|
||||||
if (mod->attributes.count(ID(\\abc_box_id)))
|
if (mod->attributes.count(ID(abc_box_id)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mod->processes.size() > 0) {
|
if (mod->processes.size() > 0) {
|
||||||
|
@ -1153,14 +1153,14 @@ struct Abc9Pass : public Pass {
|
||||||
|
|
||||||
if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_)))
|
if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_)))
|
||||||
{
|
{
|
||||||
key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(\\C))), true, RTLIL::SigSpec());
|
key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
|
if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
|
||||||
{
|
{
|
||||||
bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_));
|
bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_));
|
||||||
bool this_en_pol = cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_));
|
bool this_en_pol = cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_));
|
||||||
key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(\\C))), this_en_pol, assign_map(cell->getPort(ID(\\E))));
|
key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, assign_map(cell->getPort(ID(E))));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -61,7 +61,7 @@ struct AlumaccWorker
|
||||||
|
|
||||||
RTLIL::SigSpec get_eq() {
|
RTLIL::SigSpec get_eq() {
|
||||||
if (GetSize(cached_eq) == 0)
|
if (GetSize(cached_eq) == 0)
|
||||||
cached_eq = alu_cell->module->ReduceAnd(NEW_ID, alu_cell->getPort(ID(\\X)), false, alu_cell->get_src_attribute());
|
cached_eq = alu_cell->module->ReduceAnd(NEW_ID, alu_cell->getPort(ID(X)), false, alu_cell->get_src_attribute());
|
||||||
return cached_eq;
|
return cached_eq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ struct AlumaccWorker
|
||||||
|
|
||||||
RTLIL::SigSpec get_cf() {
|
RTLIL::SigSpec get_cf() {
|
||||||
if (GetSize(cached_cf) == 0) {
|
if (GetSize(cached_cf) == 0) {
|
||||||
cached_cf = alu_cell->getPort(ID(\\CO));
|
cached_cf = alu_cell->getPort(ID(CO));
|
||||||
log_assert(GetSize(cached_cf) >= 1);
|
log_assert(GetSize(cached_cf) >= 1);
|
||||||
cached_cf = alu_cell->module->Not(NEW_ID, cached_cf[GetSize(cached_cf)-1], false, alu_cell->get_src_attribute());
|
cached_cf = alu_cell->module->Not(NEW_ID, cached_cf[GetSize(cached_cf)-1], false, alu_cell->get_src_attribute());
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ struct AlumaccWorker
|
||||||
|
|
||||||
RTLIL::SigSpec get_of() {
|
RTLIL::SigSpec get_of() {
|
||||||
if (GetSize(cached_of) == 0) {
|
if (GetSize(cached_of) == 0) {
|
||||||
cached_of = {alu_cell->getPort(ID(\\CO)), alu_cell->getPort(ID(\\CI))};
|
cached_of = {alu_cell->getPort(ID(CO)), alu_cell->getPort(ID(CI))};
|
||||||
log_assert(GetSize(cached_of) >= 2);
|
log_assert(GetSize(cached_of) >= 2);
|
||||||
cached_of = alu_cell->module->Xor(NEW_ID, cached_of[GetSize(cached_of)-1], cached_of[GetSize(cached_of)-2]);
|
cached_of = alu_cell->module->Xor(NEW_ID, cached_of[GetSize(cached_of)-1], cached_of[GetSize(cached_of)-2]);
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ struct AlumaccWorker
|
||||||
|
|
||||||
RTLIL::SigSpec get_sf() {
|
RTLIL::SigSpec get_sf() {
|
||||||
if (GetSize(cached_sf) == 0) {
|
if (GetSize(cached_sf) == 0) {
|
||||||
cached_sf = alu_cell->getPort(ID(\\Y));
|
cached_sf = alu_cell->getPort(ID(Y));
|
||||||
cached_sf = cached_sf[GetSize(cached_sf)-1];
|
cached_sf = cached_sf[GetSize(cached_sf)-1];
|
||||||
}
|
}
|
||||||
return cached_sf;
|
return cached_sf;
|
||||||
|
@ -134,7 +134,7 @@ struct AlumaccWorker
|
||||||
Macc::port_t new_port;
|
Macc::port_t new_port;
|
||||||
|
|
||||||
n->cell = cell;
|
n->cell = cell;
|
||||||
n->y = sigmap(cell->getPort(ID(\\Y)));
|
n->y = sigmap(cell->getPort(ID(Y)));
|
||||||
n->users = 0;
|
n->users = 0;
|
||||||
|
|
||||||
for (auto bit : n->y)
|
for (auto bit : n->y)
|
||||||
|
@ -142,30 +142,30 @@ struct AlumaccWorker
|
||||||
|
|
||||||
if (cell->type.in(ID($pos), ID($neg)))
|
if (cell->type.in(ID($pos), ID($neg)))
|
||||||
{
|
{
|
||||||
new_port.in_a = sigmap(cell->getPort(ID(\\A)));
|
new_port.in_a = sigmap(cell->getPort(ID(A)));
|
||||||
new_port.is_signed = cell->getParam(ID(\\A_SIGNED)).as_bool();
|
new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
|
||||||
new_port.do_subtract = cell->type == ID($neg);
|
new_port.do_subtract = cell->type == ID($neg);
|
||||||
n->macc.ports.push_back(new_port);
|
n->macc.ports.push_back(new_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cell->type.in(ID($add), ID($sub)))
|
if (cell->type.in(ID($add), ID($sub)))
|
||||||
{
|
{
|
||||||
new_port.in_a = sigmap(cell->getPort(ID(\\A)));
|
new_port.in_a = sigmap(cell->getPort(ID(A)));
|
||||||
new_port.is_signed = cell->getParam(ID(\\A_SIGNED)).as_bool();
|
new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
|
||||||
new_port.do_subtract = false;
|
new_port.do_subtract = false;
|
||||||
n->macc.ports.push_back(new_port);
|
n->macc.ports.push_back(new_port);
|
||||||
|
|
||||||
new_port.in_a = sigmap(cell->getPort(ID(\\B)));
|
new_port.in_a = sigmap(cell->getPort(ID(B)));
|
||||||
new_port.is_signed = cell->getParam(ID(\\B_SIGNED)).as_bool();
|
new_port.is_signed = cell->getParam(ID(B_SIGNED)).as_bool();
|
||||||
new_port.do_subtract = cell->type == ID($sub);
|
new_port.do_subtract = cell->type == ID($sub);
|
||||||
n->macc.ports.push_back(new_port);
|
n->macc.ports.push_back(new_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cell->type.in(ID($mul)))
|
if (cell->type.in(ID($mul)))
|
||||||
{
|
{
|
||||||
new_port.in_a = sigmap(cell->getPort(ID(\\A)));
|
new_port.in_a = sigmap(cell->getPort(ID(A)));
|
||||||
new_port.in_b = sigmap(cell->getPort(ID(\\B)));
|
new_port.in_b = sigmap(cell->getPort(ID(B)));
|
||||||
new_port.is_signed = cell->getParam(ID(\\A_SIGNED)).as_bool();
|
new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
|
||||||
new_port.do_subtract = false;
|
new_port.do_subtract = false;
|
||||||
n->macc.ports.push_back(new_port);
|
n->macc.ports.push_back(new_port);
|
||||||
}
|
}
|
||||||
|
@ -361,7 +361,7 @@ struct AlumaccWorker
|
||||||
|
|
||||||
n->macc.optimize(GetSize(n->y));
|
n->macc.optimize(GetSize(n->y));
|
||||||
n->macc.to_cell(cell);
|
n->macc.to_cell(cell);
|
||||||
cell->setPort(ID(\\Y), n->y);
|
cell->setPort(ID(Y), n->y);
|
||||||
cell->fixup_parameters();
|
cell->fixup_parameters();
|
||||||
module->remove(n->cell);
|
module->remove(n->cell);
|
||||||
delete n;
|
delete n;
|
||||||
|
@ -388,11 +388,11 @@ struct AlumaccWorker
|
||||||
|
|
||||||
bool cmp_less = cell->type.in(ID($lt), ID($le));
|
bool cmp_less = cell->type.in(ID($lt), ID($le));
|
||||||
bool cmp_equal = cell->type.in(ID($le), ID($ge));
|
bool cmp_equal = cell->type.in(ID($le), ID($ge));
|
||||||
bool is_signed = cell->getParam(ID(\\A_SIGNED)).as_bool();
|
bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
|
||||||
|
|
||||||
RTLIL::SigSpec A = sigmap(cell->getPort(ID(\\A)));
|
RTLIL::SigSpec A = sigmap(cell->getPort(ID(A)));
|
||||||
RTLIL::SigSpec B = sigmap(cell->getPort(ID(\\B)));
|
RTLIL::SigSpec B = sigmap(cell->getPort(ID(B)));
|
||||||
RTLIL::SigSpec Y = sigmap(cell->getPort(ID(\\Y)));
|
RTLIL::SigSpec Y = sigmap(cell->getPort(ID(Y)));
|
||||||
|
|
||||||
if (B < A && GetSize(B)) {
|
if (B < A && GetSize(B)) {
|
||||||
cmp_less = !cmp_less;
|
cmp_less = !cmp_less;
|
||||||
|
@ -428,11 +428,11 @@ struct AlumaccWorker
|
||||||
for (auto cell : eq_cells)
|
for (auto cell : eq_cells)
|
||||||
{
|
{
|
||||||
bool cmp_equal = cell->type.in(ID($eq), ID($eqx));
|
bool cmp_equal = cell->type.in(ID($eq), ID($eqx));
|
||||||
bool is_signed = cell->getParam(ID(\\A_SIGNED)).as_bool();
|
bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
|
||||||
|
|
||||||
RTLIL::SigSpec A = sigmap(cell->getPort(ID(\\A)));
|
RTLIL::SigSpec A = sigmap(cell->getPort(ID(A)));
|
||||||
RTLIL::SigSpec B = sigmap(cell->getPort(ID(\\B)));
|
RTLIL::SigSpec B = sigmap(cell->getPort(ID(B)));
|
||||||
RTLIL::SigSpec Y = sigmap(cell->getPort(ID(\\Y)));
|
RTLIL::SigSpec Y = sigmap(cell->getPort(ID(Y)));
|
||||||
|
|
||||||
if (B < A && GetSize(B))
|
if (B < A && GetSize(B))
|
||||||
std::swap(A, B);
|
std::swap(A, B);
|
||||||
|
@ -482,13 +482,13 @@ struct AlumaccWorker
|
||||||
if (n->cells.size() > 0)
|
if (n->cells.size() > 0)
|
||||||
n->alu_cell->set_src_attribute(n->cells[0]->get_src_attribute());
|
n->alu_cell->set_src_attribute(n->cells[0]->get_src_attribute());
|
||||||
|
|
||||||
n->alu_cell->setPort(ID(\\A), n->a);
|
n->alu_cell->setPort(ID(A), n->a);
|
||||||
n->alu_cell->setPort(ID(\\B), n->b);
|
n->alu_cell->setPort(ID(B), n->b);
|
||||||
n->alu_cell->setPort(ID(\\CI), GetSize(n->c) ? n->c : State::S0);
|
n->alu_cell->setPort(ID(CI), GetSize(n->c) ? n->c : State::S0);
|
||||||
n->alu_cell->setPort(ID(\\BI), n->invert_b ? State::S1 : State::S0);
|
n->alu_cell->setPort(ID(BI), n->invert_b ? State::S1 : State::S0);
|
||||||
n->alu_cell->setPort(ID(\\Y), n->y);
|
n->alu_cell->setPort(ID(Y), n->y);
|
||||||
n->alu_cell->setPort(ID(\\X), module->addWire(NEW_ID, GetSize(n->y)));
|
n->alu_cell->setPort(ID(X), module->addWire(NEW_ID, GetSize(n->y)));
|
||||||
n->alu_cell->setPort(ID(\\CO), module->addWire(NEW_ID, GetSize(n->y)));
|
n->alu_cell->setPort(ID(CO), module->addWire(NEW_ID, GetSize(n->y)));
|
||||||
n->alu_cell->fixup_parameters(n->is_signed, n->is_signed);
|
n->alu_cell->fixup_parameters(n->is_signed, n->is_signed);
|
||||||
|
|
||||||
for (auto &it : n->cmp)
|
for (auto &it : n->cmp)
|
||||||
|
|
|
@ -83,13 +83,13 @@ struct DeminoutPass : public Pass {
|
||||||
for (auto bit : sigmap(conn.second))
|
for (auto bit : sigmap(conn.second))
|
||||||
bits_used.insert(bit);
|
bits_used.insert(bit);
|
||||||
|
|
||||||
if (conn.first == ID(\\Y) && cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_TBUF_), ID($tribuf)))
|
if (conn.first == ID(Y) && cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_TBUF_), ID($tribuf)))
|
||||||
{
|
{
|
||||||
bool tribuf = cell->type.in(ID($_TBUF_), ID($tribuf));
|
bool tribuf = cell->type.in(ID($_TBUF_), ID($tribuf));
|
||||||
|
|
||||||
if (!tribuf) {
|
if (!tribuf) {
|
||||||
for (auto &c : cell->connections()) {
|
for (auto &c : cell->connections()) {
|
||||||
if (!c.first.in(ID(\\A), ID(\\B)))
|
if (!c.first.in(ID(A), ID(B)))
|
||||||
continue;
|
continue;
|
||||||
for (auto b : sigmap(c.second))
|
for (auto b : sigmap(c.second))
|
||||||
if (b == State::Sz)
|
if (b == State::Sz)
|
||||||
|
|
|
@ -53,7 +53,7 @@ struct Dff2dffeWorker
|
||||||
|
|
||||||
for (auto cell : module->cells()) {
|
for (auto cell : module->cells()) {
|
||||||
if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_))) {
|
if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_))) {
|
||||||
RTLIL::SigSpec sig_y = sigmap(cell->getPort(ID(\\Y)));
|
RTLIL::SigSpec sig_y = sigmap(cell->getPort(ID(Y)));
|
||||||
for (int i = 0; i < GetSize(sig_y); i++)
|
for (int i = 0; i < GetSize(sig_y); i++)
|
||||||
bit2mux[sig_y[i]] = cell_int_t(cell, i);
|
bit2mux[sig_y[i]] = cell_int_t(cell, i);
|
||||||
}
|
}
|
||||||
|
@ -86,9 +86,9 @@ struct Dff2dffeWorker
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
cell_int_t mux_cell_int = bit2mux.at(d);
|
cell_int_t mux_cell_int = bit2mux.at(d);
|
||||||
RTLIL::SigSpec sig_a = sigmap(mux_cell_int.first->getPort(ID(\\A)));
|
RTLIL::SigSpec sig_a = sigmap(mux_cell_int.first->getPort(ID(A)));
|
||||||
RTLIL::SigSpec sig_b = sigmap(mux_cell_int.first->getPort(ID(\\B)));
|
RTLIL::SigSpec sig_b = sigmap(mux_cell_int.first->getPort(ID(B)));
|
||||||
RTLIL::SigSpec sig_s = sigmap(mux_cell_int.first->getPort(ID(\\S)));
|
RTLIL::SigSpec sig_s = sigmap(mux_cell_int.first->getPort(ID(S)));
|
||||||
int width = GetSize(sig_a), index = mux_cell_int.second;
|
int width = GetSize(sig_a), index = mux_cell_int.second;
|
||||||
|
|
||||||
for (int i = 0; i < GetSize(sig_s); i++)
|
for (int i = 0; i < GetSize(sig_s); i++)
|
||||||
|
@ -97,9 +97,9 @@ struct Dff2dffeWorker
|
||||||
ret = find_muxtree_feedback_patterns(sig_b[i*width + index], q, path);
|
ret = find_muxtree_feedback_patterns(sig_b[i*width + index], q, path);
|
||||||
|
|
||||||
if (sig_b[i*width + index] == q) {
|
if (sig_b[i*width + index] == q) {
|
||||||
RTLIL::SigSpec s = mux_cell_int.first->getPort(ID(\\B));
|
RTLIL::SigSpec s = mux_cell_int.first->getPort(ID(B));
|
||||||
s[i*width + index] = RTLIL::Sx;
|
s[i*width + index] = RTLIL::Sx;
|
||||||
mux_cell_int.first->setPort(ID(\\B), s);
|
mux_cell_int.first->setPort(ID(B), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -120,9 +120,9 @@ struct Dff2dffeWorker
|
||||||
ret.insert(pat);
|
ret.insert(pat);
|
||||||
|
|
||||||
if (sig_b[i*width + index] == q) {
|
if (sig_b[i*width + index] == q) {
|
||||||
RTLIL::SigSpec s = mux_cell_int.first->getPort(ID(\\B));
|
RTLIL::SigSpec s = mux_cell_int.first->getPort(ID(B));
|
||||||
s[i*width + index] = RTLIL::Sx;
|
s[i*width + index] = RTLIL::Sx;
|
||||||
mux_cell_int.first->setPort(ID(\\B), s);
|
mux_cell_int.first->setPort(ID(B), s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,9 +130,9 @@ struct Dff2dffeWorker
|
||||||
ret.insert(pat);
|
ret.insert(pat);
|
||||||
|
|
||||||
if (sig_a[index] == q) {
|
if (sig_a[index] == q) {
|
||||||
RTLIL::SigSpec s = mux_cell_int.first->getPort(ID(\\A));
|
RTLIL::SigSpec s = mux_cell_int.first->getPort(ID(A));
|
||||||
s[index] = RTLIL::Sx;
|
s[index] = RTLIL::Sx;
|
||||||
mux_cell_int.first->setPort(ID(\\A), s);
|
mux_cell_int.first->setPort(ID(A), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -185,8 +185,8 @@ struct Dff2dffeWorker
|
||||||
|
|
||||||
void handle_dff_cell(RTLIL::Cell *dff_cell)
|
void handle_dff_cell(RTLIL::Cell *dff_cell)
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec sig_d = sigmap(dff_cell->getPort(ID(\\D)));
|
RTLIL::SigSpec sig_d = sigmap(dff_cell->getPort(ID(D)));
|
||||||
RTLIL::SigSpec sig_q = sigmap(dff_cell->getPort(ID(\\Q)));
|
RTLIL::SigSpec sig_q = sigmap(dff_cell->getPort(ID(Q)));
|
||||||
|
|
||||||
std::map<patterns_t, std::set<int>> grouped_patterns;
|
std::map<patterns_t, std::set<int>> grouped_patterns;
|
||||||
std::set<int> remaining_indices;
|
std::set<int> remaining_indices;
|
||||||
|
@ -208,15 +208,15 @@ struct Dff2dffeWorker
|
||||||
}
|
}
|
||||||
if (!direct_dict.empty()) {
|
if (!direct_dict.empty()) {
|
||||||
log(" converting %s cell %s to %s for %s -> %s.\n", log_id(dff_cell->type), log_id(dff_cell), log_id(direct_dict.at(dff_cell->type)), log_signal(new_sig_d), log_signal(new_sig_q));
|
log(" converting %s cell %s to %s for %s -> %s.\n", log_id(dff_cell->type), log_id(dff_cell), log_id(direct_dict.at(dff_cell->type)), log_signal(new_sig_d), log_signal(new_sig_q));
|
||||||
dff_cell->setPort(ID(\\E), make_patterns_logic(it.first, true));
|
dff_cell->setPort(ID(E), make_patterns_logic(it.first, true));
|
||||||
dff_cell->type = direct_dict.at(dff_cell->type);
|
dff_cell->type = direct_dict.at(dff_cell->type);
|
||||||
} else
|
} else
|
||||||
if (dff_cell->type == ID($dff)) {
|
if (dff_cell->type == ID($dff)) {
|
||||||
RTLIL::Cell *new_cell = module->addDffe(NEW_ID, dff_cell->getPort(ID(\\CLK)), make_patterns_logic(it.first, false),
|
RTLIL::Cell *new_cell = module->addDffe(NEW_ID, dff_cell->getPort(ID(CLK)), make_patterns_logic(it.first, false),
|
||||||
new_sig_d, new_sig_q, dff_cell->getParam(ID(\\CLK_POLARITY)).as_bool(), true);
|
new_sig_d, new_sig_q, dff_cell->getParam(ID(CLK_POLARITY)).as_bool(), true);
|
||||||
log(" created $dffe cell %s for %s -> %s.\n", log_id(new_cell), log_signal(new_sig_d), log_signal(new_sig_q));
|
log(" created $dffe cell %s for %s -> %s.\n", log_id(new_cell), log_signal(new_sig_d), log_signal(new_sig_q));
|
||||||
} else {
|
} else {
|
||||||
RTLIL::Cell *new_cell = module->addDffeGate(NEW_ID, dff_cell->getPort(ID(\\C)), make_patterns_logic(it.first, true),
|
RTLIL::Cell *new_cell = module->addDffeGate(NEW_ID, dff_cell->getPort(ID(C)), make_patterns_logic(it.first, true),
|
||||||
new_sig_d, new_sig_q, dff_cell->type == ID($_DFF_P_), true);
|
new_sig_d, new_sig_q, dff_cell->type == ID($_DFF_P_), true);
|
||||||
log(" created %s cell %s for %s -> %s.\n", log_id(new_cell->type), log_id(new_cell), log_signal(new_sig_d), log_signal(new_sig_q));
|
log(" created %s cell %s for %s -> %s.\n", log_id(new_cell->type), log_id(new_cell), log_signal(new_sig_d), log_signal(new_sig_q));
|
||||||
}
|
}
|
||||||
|
@ -235,9 +235,9 @@ struct Dff2dffeWorker
|
||||||
new_sig_d.append(sig_d[i]);
|
new_sig_d.append(sig_d[i]);
|
||||||
new_sig_q.append(sig_q[i]);
|
new_sig_q.append(sig_q[i]);
|
||||||
}
|
}
|
||||||
dff_cell->setPort(ID(\\D), new_sig_d);
|
dff_cell->setPort(ID(D), new_sig_d);
|
||||||
dff_cell->setPort(ID(\\Q), new_sig_q);
|
dff_cell->setPort(ID(Q), new_sig_q);
|
||||||
dff_cell->setParam(ID(\\WIDTH), GetSize(remaining_indices));
|
dff_cell->setParam(ID(WIDTH), GetSize(remaining_indices));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,19 +361,19 @@ struct Dff2dffePass : public Pass {
|
||||||
for (auto cell_other : mod->selected_cells()) {
|
for (auto cell_other : mod->selected_cells()) {
|
||||||
if (cell_other->type != cell->type)
|
if (cell_other->type != cell->type)
|
||||||
continue;
|
continue;
|
||||||
if (sigmap(cell->getPort(ID(\\EN))) == sigmap(cell_other->getPort(ID(\\EN))))
|
if (sigmap(cell->getPort(ID(EN))) == sigmap(cell_other->getPort(ID(EN))))
|
||||||
ce_use++;
|
ce_use++;
|
||||||
}
|
}
|
||||||
if (ce_use >= min_ce_use)
|
if (ce_use >= min_ce_use)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
RTLIL::SigSpec tmp = mod->addWire(NEW_ID, GetSize(cell->getPort(ID(\\D))));
|
RTLIL::SigSpec tmp = mod->addWire(NEW_ID, GetSize(cell->getPort(ID(D))));
|
||||||
mod->addDff(NEW_ID, cell->getPort(ID(\\CLK)), tmp, cell->getPort(ID(\\Q)), cell->getParam(ID(\\CLK_POLARITY)).as_bool());
|
mod->addDff(NEW_ID, cell->getPort(ID(CLK)), tmp, cell->getPort(ID(Q)), cell->getParam(ID(CLK_POLARITY)).as_bool());
|
||||||
if (cell->getParam(ID(\\EN_POLARITY)).as_bool())
|
if (cell->getParam(ID(EN_POLARITY)).as_bool())
|
||||||
mod->addMux(NEW_ID, cell->getPort(ID(\\Q)), cell->getPort(ID(\\D)), cell->getPort(ID(\\EN)), tmp);
|
mod->addMux(NEW_ID, cell->getPort(ID(Q)), cell->getPort(ID(D)), cell->getPort(ID(EN)), tmp);
|
||||||
else
|
else
|
||||||
mod->addMux(NEW_ID, cell->getPort(ID(\\D)), cell->getPort(ID(\\Q)), cell->getPort(ID(\\EN)), tmp);
|
mod->addMux(NEW_ID, cell->getPort(ID(D)), cell->getPort(ID(Q)), cell->getPort(ID(EN)), tmp);
|
||||||
mod->remove(cell);
|
mod->remove(cell);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -383,7 +383,7 @@ struct Dff2dffePass : public Pass {
|
||||||
for (auto cell_other : mod->selected_cells()) {
|
for (auto cell_other : mod->selected_cells()) {
|
||||||
if (cell_other->type != cell->type)
|
if (cell_other->type != cell->type)
|
||||||
continue;
|
continue;
|
||||||
if (sigmap(cell->getPort(ID(\\E))) == sigmap(cell_other->getPort(ID(\\E))))
|
if (sigmap(cell->getPort(ID(E))) == sigmap(cell_other->getPort(ID(E))))
|
||||||
ce_use++;
|
ce_use++;
|
||||||
}
|
}
|
||||||
if (ce_use >= min_ce_use)
|
if (ce_use >= min_ce_use)
|
||||||
|
@ -393,11 +393,11 @@ struct Dff2dffePass : public Pass {
|
||||||
bool clk_pol = cell->type.compare(7, 1, "P") == 0;
|
bool clk_pol = cell->type.compare(7, 1, "P") == 0;
|
||||||
bool en_pol = cell->type.compare(8, 1, "P") == 0;
|
bool en_pol = cell->type.compare(8, 1, "P") == 0;
|
||||||
RTLIL::SigSpec tmp = mod->addWire(NEW_ID);
|
RTLIL::SigSpec tmp = mod->addWire(NEW_ID);
|
||||||
mod->addDff(NEW_ID, cell->getPort(ID(\\C)), tmp, cell->getPort(ID(\\Q)), clk_pol);
|
mod->addDff(NEW_ID, cell->getPort(ID(C)), tmp, cell->getPort(ID(Q)), clk_pol);
|
||||||
if (en_pol)
|
if (en_pol)
|
||||||
mod->addMux(NEW_ID, cell->getPort(ID(\\Q)), cell->getPort(ID(\\D)), cell->getPort(ID(\\E)), tmp);
|
mod->addMux(NEW_ID, cell->getPort(ID(Q)), cell->getPort(ID(D)), cell->getPort(ID(E)), tmp);
|
||||||
else
|
else
|
||||||
mod->addMux(NEW_ID, cell->getPort(ID(\\D)), cell->getPort(ID(\\Q)), cell->getPort(ID(\\E)), tmp);
|
mod->addMux(NEW_ID, cell->getPort(ID(D)), cell->getPort(ID(Q)), cell->getPort(ID(E)), tmp);
|
||||||
mod->remove(cell);
|
mod->remove(cell);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,16 +72,16 @@ struct Dff2dffsPass : public Pass {
|
||||||
if (cell->type != ID($_MUX_))
|
if (cell->type != ID($_MUX_))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SigBit bit_a = sigmap(cell->getPort(ID(\\A)));
|
SigBit bit_a = sigmap(cell->getPort(ID(A)));
|
||||||
SigBit bit_b = sigmap(cell->getPort(ID(\\B)));
|
SigBit bit_b = sigmap(cell->getPort(ID(B)));
|
||||||
|
|
||||||
if (bit_a.wire == nullptr || bit_b.wire == nullptr)
|
if (bit_a.wire == nullptr || bit_b.wire == nullptr)
|
||||||
sr_muxes[sigmap(cell->getPort(ID(\\Y)))] = cell;
|
sr_muxes[sigmap(cell->getPort(ID(Y)))] = cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto cell : ff_cells)
|
for (auto cell : ff_cells)
|
||||||
{
|
{
|
||||||
SigSpec sig_d = cell->getPort(ID(\\D));
|
SigSpec sig_d = cell->getPort(ID(D));
|
||||||
|
|
||||||
if (GetSize(sig_d) < 1)
|
if (GetSize(sig_d) < 1)
|
||||||
continue;
|
continue;
|
||||||
|
@ -92,9 +92,9 @@ struct Dff2dffsPass : public Pass {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Cell *mux_cell = sr_muxes.at(bit_d);
|
Cell *mux_cell = sr_muxes.at(bit_d);
|
||||||
SigBit bit_a = sigmap(mux_cell->getPort(ID(\\A)));
|
SigBit bit_a = sigmap(mux_cell->getPort(ID(A)));
|
||||||
SigBit bit_b = sigmap(mux_cell->getPort(ID(\\B)));
|
SigBit bit_b = sigmap(mux_cell->getPort(ID(B)));
|
||||||
SigBit bit_s = sigmap(mux_cell->getPort(ID(\\S)));
|
SigBit bit_s = sigmap(mux_cell->getPort(ID(S)));
|
||||||
|
|
||||||
log(" Merging %s (A=%s, B=%s, S=%s) into %s (%s).\n", log_id(mux_cell),
|
log(" Merging %s (A=%s, B=%s, S=%s) into %s (%s).\n", log_id(mux_cell),
|
||||||
log_signal(bit_a), log_signal(bit_b), log_signal(bit_s), log_id(cell), log_id(cell->type));
|
log_signal(bit_a), log_signal(bit_b), log_signal(bit_s), log_id(cell), log_id(cell->type));
|
||||||
|
@ -132,8 +132,8 @@ struct Dff2dffsPass : public Pass {
|
||||||
else cell->type = ID($__DFFS_PP0_);
|
else cell->type = ID($__DFFS_PP0_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cell->setPort(ID(\\R), sr_sig);
|
cell->setPort(ID(R), sr_sig);
|
||||||
cell->setPort(ID(\\D), bit_d);
|
cell->setPort(ID(D), bit_d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,8 +99,8 @@ struct DffinitPass : public Pass {
|
||||||
pool<SigBit> used_bits;
|
pool<SigBit> used_bits;
|
||||||
|
|
||||||
for (auto wire : module->selected_wires()) {
|
for (auto wire : module->selected_wires()) {
|
||||||
if (wire->attributes.count(ID(\\init))) {
|
if (wire->attributes.count(ID(init))) {
|
||||||
Const value = wire->attributes.at(ID(\\init));
|
Const value = wire->attributes.at(ID(init));
|
||||||
for (int i = 0; i < min(GetSize(value), GetSize(wire)); i++)
|
for (int i = 0; i < min(GetSize(value), GetSize(wire)); i++)
|
||||||
if (value[i] != State::Sx)
|
if (value[i] != State::Sx)
|
||||||
init_bits[sigmap(SigBit(wire, i))] = value[i];
|
init_bits[sigmap(SigBit(wire, i))] = value[i];
|
||||||
|
@ -161,8 +161,8 @@ struct DffinitPass : public Pass {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto wire : module->selected_wires())
|
for (auto wire : module->selected_wires())
|
||||||
if (wire->attributes.count(ID(\\init))) {
|
if (wire->attributes.count(ID(init))) {
|
||||||
Const &value = wire->attributes.at(ID(\\init));
|
Const &value = wire->attributes.at(ID(init));
|
||||||
bool do_cleanup = true;
|
bool do_cleanup = true;
|
||||||
for (int i = 0; i < min(GetSize(value), GetSize(wire)); i++) {
|
for (int i = 0; i < min(GetSize(value), GetSize(wire)); i++) {
|
||||||
SigBit bit = sigmap(SigBit(wire, i));
|
SigBit bit = sigmap(SigBit(wire, i));
|
||||||
|
@ -173,7 +173,7 @@ struct DffinitPass : public Pass {
|
||||||
}
|
}
|
||||||
if (do_cleanup) {
|
if (do_cleanup) {
|
||||||
log("Removing init attribute from wire %s.%s.\n", log_id(module), log_id(wire));
|
log("Removing init attribute from wire %s.%s.\n", log_id(module), log_id(wire));
|
||||||
wire->attributes.erase(ID(\\init));
|
wire->attributes.erase(ID(init));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -485,7 +485,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module, bool prepare
|
||||||
if (design->selected(module, it.second) && cell_mappings.count(it.second->type) > 0)
|
if (design->selected(module, it.second) && cell_mappings.count(it.second->type) > 0)
|
||||||
cell_list.push_back(it.second);
|
cell_list.push_back(it.second);
|
||||||
if (it.second->type == ID($_NOT_))
|
if (it.second->type == ID($_NOT_))
|
||||||
notmap[sigmap(it.second->getPort(ID(\\A)))].insert(it.second);
|
notmap[sigmap(it.second->getPort(ID(A)))].insert(it.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, int> stats;
|
std::map<std::string, int> stats;
|
||||||
|
@ -519,8 +519,8 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module, bool prepare
|
||||||
sig = module->addWire(NEW_ID, GetSize(old_sig));
|
sig = module->addWire(NEW_ID, GetSize(old_sig));
|
||||||
if (has_q && has_qn) {
|
if (has_q && has_qn) {
|
||||||
for (auto &it : notmap[sigmap(old_sig)]) {
|
for (auto &it : notmap[sigmap(old_sig)]) {
|
||||||
module->connect(it->getPort(ID(\\Y)), sig);
|
module->connect(it->getPort(ID(Y)), sig);
|
||||||
it->setPort(ID(\\Y), module->addWire(NEW_ID, GetSize(old_sig)));
|
it->setPort(ID(Y), module->addWire(NEW_ID, GetSize(old_sig)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
module->addNotGate(NEW_ID, sig, old_sig);
|
module->addNotGate(NEW_ID, sig, old_sig);
|
||||||
|
|
|
@ -27,15 +27,15 @@ void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell)
|
||||||
{
|
{
|
||||||
if (cell->type == ID($dffsr))
|
if (cell->type == ID($dffsr))
|
||||||
{
|
{
|
||||||
int width = cell->getParam(ID(\\WIDTH)).as_int();
|
int width = cell->getParam(ID(WIDTH)).as_int();
|
||||||
bool setpol = cell->getParam(ID(\\SET_POLARITY)).as_bool();
|
bool setpol = cell->getParam(ID(SET_POLARITY)).as_bool();
|
||||||
bool clrpol = cell->getParam(ID(\\CLR_POLARITY)).as_bool();
|
bool clrpol = cell->getParam(ID(CLR_POLARITY)).as_bool();
|
||||||
|
|
||||||
SigBit setunused = setpol ? State::S0 : State::S1;
|
SigBit setunused = setpol ? State::S0 : State::S1;
|
||||||
SigBit clrunused = clrpol ? State::S0 : State::S1;
|
SigBit clrunused = clrpol ? State::S0 : State::S1;
|
||||||
|
|
||||||
SigSpec setsig = sigmap(cell->getPort(ID(\\SET)));
|
SigSpec setsig = sigmap(cell->getPort(ID(SET)));
|
||||||
SigSpec clrsig = sigmap(cell->getPort(ID(\\CLR)));
|
SigSpec clrsig = sigmap(cell->getPort(ID(CLR)));
|
||||||
|
|
||||||
Const reset_val;
|
Const reset_val;
|
||||||
SigSpec setctrl, clrctrl;
|
SigSpec setctrl, clrctrl;
|
||||||
|
@ -78,19 +78,19 @@ void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell)
|
||||||
log("Converting %s cell %s.%s to $adff.\n", log_id(cell->type), log_id(module), log_id(cell));
|
log("Converting %s cell %s.%s to $adff.\n", log_id(cell->type), log_id(module), log_id(cell));
|
||||||
|
|
||||||
if (GetSize(setctrl) == 1) {
|
if (GetSize(setctrl) == 1) {
|
||||||
cell->setPort(ID(\\ARST), setctrl);
|
cell->setPort(ID(ARST), setctrl);
|
||||||
cell->setParam(ID(\\ARST_POLARITY), setpol);
|
cell->setParam(ID(ARST_POLARITY), setpol);
|
||||||
} else {
|
} else {
|
||||||
cell->setPort(ID(\\ARST), clrctrl);
|
cell->setPort(ID(ARST), clrctrl);
|
||||||
cell->setParam(ID(\\ARST_POLARITY), clrpol);
|
cell->setParam(ID(ARST_POLARITY), clrpol);
|
||||||
}
|
}
|
||||||
|
|
||||||
cell->type = ID($adff);
|
cell->type = ID($adff);
|
||||||
cell->unsetPort(ID(\\SET));
|
cell->unsetPort(ID(SET));
|
||||||
cell->unsetPort(ID(\\CLR));
|
cell->unsetPort(ID(CLR));
|
||||||
cell->setParam(ID(\\ARST_VALUE), reset_val);
|
cell->setParam(ID(ARST_VALUE), reset_val);
|
||||||
cell->unsetParam(ID(\\SET_POLARITY));
|
cell->unsetParam(ID(SET_POLARITY));
|
||||||
cell->unsetParam(ID(\\CLR_POLARITY));
|
cell->unsetParam(ID(CLR_POLARITY));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -102,8 +102,8 @@ void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell)
|
||||||
char setpol = cell->type.c_str()[9];
|
char setpol = cell->type.c_str()[9];
|
||||||
char clrpol = cell->type.c_str()[10];
|
char clrpol = cell->type.c_str()[10];
|
||||||
|
|
||||||
SigBit setbit = sigmap(cell->getPort(ID(\\S)));
|
SigBit setbit = sigmap(cell->getPort(ID(S)));
|
||||||
SigBit clrbit = sigmap(cell->getPort(ID(\\R)));
|
SigBit clrbit = sigmap(cell->getPort(ID(R)));
|
||||||
|
|
||||||
SigBit setunused = setpol == 'P' ? State::S0 : State::S1;
|
SigBit setunused = setpol == 'P' ? State::S0 : State::S1;
|
||||||
SigBit clrunused = clrpol == 'P' ? State::S0 : State::S1;
|
SigBit clrunused = clrpol == 'P' ? State::S0 : State::S1;
|
||||||
|
@ -112,14 +112,14 @@ void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell)
|
||||||
|
|
||||||
if (setbit == setunused) {
|
if (setbit == setunused) {
|
||||||
cell->type = stringf("$_DFF_%c%c0_", clkpol, clrpol);
|
cell->type = stringf("$_DFF_%c%c0_", clkpol, clrpol);
|
||||||
cell->unsetPort(ID(\\S));
|
cell->unsetPort(ID(S));
|
||||||
goto converted_gate;
|
goto converted_gate;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clrbit == clrunused) {
|
if (clrbit == clrunused) {
|
||||||
cell->type = stringf("$_DFF_%c%c1_", clkpol, setpol);
|
cell->type = stringf("$_DFF_%c%c1_", clkpol, setpol);
|
||||||
cell->setPort(ID(\\R), cell->getPort(ID(\\S)));
|
cell->setPort(ID(R), cell->getPort(ID(S)));
|
||||||
cell->unsetPort(ID(\\S));
|
cell->unsetPort(ID(S));
|
||||||
goto converted_gate;
|
goto converted_gate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,9 +135,9 @@ void adff_worker(SigMap &sigmap, Module *module, Cell *cell)
|
||||||
{
|
{
|
||||||
if (cell->type == ID($adff))
|
if (cell->type == ID($adff))
|
||||||
{
|
{
|
||||||
bool rstpol = cell->getParam(ID(\\ARST_POLARITY)).as_bool();
|
bool rstpol = cell->getParam(ID(ARST_POLARITY)).as_bool();
|
||||||
SigBit rstunused = rstpol ? State::S0 : State::S1;
|
SigBit rstunused = rstpol ? State::S0 : State::S1;
|
||||||
SigSpec rstsig = sigmap(cell->getPort(ID(\\ARST)));
|
SigSpec rstsig = sigmap(cell->getPort(ID(ARST)));
|
||||||
|
|
||||||
if (rstsig != rstunused)
|
if (rstsig != rstunused)
|
||||||
return;
|
return;
|
||||||
|
@ -145,9 +145,9 @@ void adff_worker(SigMap &sigmap, Module *module, Cell *cell)
|
||||||
log("Converting %s cell %s.%s to $dff.\n", log_id(cell->type), log_id(module), log_id(cell));
|
log("Converting %s cell %s.%s to $dff.\n", log_id(cell->type), log_id(module), log_id(cell));
|
||||||
|
|
||||||
cell->type = ID($dff);
|
cell->type = ID($dff);
|
||||||
cell->unsetPort(ID(\\ARST));
|
cell->unsetPort(ID(ARST));
|
||||||
cell->unsetParam(ID(\\ARST_VALUE));
|
cell->unsetParam(ID(ARST_VALUE));
|
||||||
cell->unsetParam(ID(\\ARST_POLARITY));
|
cell->unsetParam(ID(ARST_POLARITY));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,7 @@ void adff_worker(SigMap &sigmap, Module *module, Cell *cell)
|
||||||
char clkpol = cell->type.c_str()[6];
|
char clkpol = cell->type.c_str()[6];
|
||||||
char rstpol = cell->type.c_str()[7];
|
char rstpol = cell->type.c_str()[7];
|
||||||
|
|
||||||
SigBit rstbit = sigmap(cell->getPort(ID(\\R)));
|
SigBit rstbit = sigmap(cell->getPort(ID(R)));
|
||||||
SigBit rstunused = rstpol == 'P' ? State::S0 : State::S1;
|
SigBit rstunused = rstpol == 'P' ? State::S0 : State::S1;
|
||||||
|
|
||||||
if (rstbit != rstunused)
|
if (rstbit != rstunused)
|
||||||
|
@ -168,7 +168,7 @@ void adff_worker(SigMap &sigmap, Module *module, Cell *cell)
|
||||||
log("Converting %s cell %s.%s to %s.\n", log_id(cell->type), log_id(module), log_id(cell), log_id(newtype));
|
log("Converting %s cell %s.%s to %s.\n", log_id(cell->type), log_id(module), log_id(cell), log_id(newtype));
|
||||||
|
|
||||||
cell->type = newtype;
|
cell->type = newtype;
|
||||||
cell->unsetPort(ID(\\R));
|
cell->unsetPort(ID(R));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,36 +58,36 @@ public:
|
||||||
return value;
|
return value;
|
||||||
|
|
||||||
#define param_bool(_n) if (param == _n) return value.as_bool();
|
#define param_bool(_n) if (param == _n) return value.as_bool();
|
||||||
param_bool(ID(\\ARST_POLARITY));
|
param_bool(ID(ARST_POLARITY));
|
||||||
param_bool(ID(\\A_SIGNED));
|
param_bool(ID(A_SIGNED));
|
||||||
param_bool(ID(\\B_SIGNED));
|
param_bool(ID(B_SIGNED));
|
||||||
param_bool(ID(\\CLK_ENABLE));
|
param_bool(ID(CLK_ENABLE));
|
||||||
param_bool(ID(\\CLK_POLARITY));
|
param_bool(ID(CLK_POLARITY));
|
||||||
param_bool(ID(\\CLR_POLARITY));
|
param_bool(ID(CLR_POLARITY));
|
||||||
param_bool(ID(\\EN_POLARITY));
|
param_bool(ID(EN_POLARITY));
|
||||||
param_bool(ID(\\SET_POLARITY));
|
param_bool(ID(SET_POLARITY));
|
||||||
param_bool(ID(\\TRANSPARENT));
|
param_bool(ID(TRANSPARENT));
|
||||||
#undef param_bool
|
#undef param_bool
|
||||||
|
|
||||||
#define param_int(_n) if (param == _n) return value.as_int();
|
#define param_int(_n) if (param == _n) return value.as_int();
|
||||||
param_int(ID(\\ABITS))
|
param_int(ID(ABITS))
|
||||||
param_int(ID(\\A_WIDTH))
|
param_int(ID(A_WIDTH))
|
||||||
param_int(ID(\\B_WIDTH))
|
param_int(ID(B_WIDTH))
|
||||||
param_int(ID(\\CTRL_IN_WIDTH))
|
param_int(ID(CTRL_IN_WIDTH))
|
||||||
param_int(ID(\\CTRL_OUT_WIDTH))
|
param_int(ID(CTRL_OUT_WIDTH))
|
||||||
param_int(ID(\\OFFSET))
|
param_int(ID(OFFSET))
|
||||||
param_int(ID(\\PRIORITY))
|
param_int(ID(PRIORITY))
|
||||||
param_int(ID(\\RD_PORTS))
|
param_int(ID(RD_PORTS))
|
||||||
param_int(ID(\\SIZE))
|
param_int(ID(SIZE))
|
||||||
param_int(ID(\\STATE_BITS))
|
param_int(ID(STATE_BITS))
|
||||||
param_int(ID(\\STATE_NUM))
|
param_int(ID(STATE_NUM))
|
||||||
param_int(ID(\\STATE_NUM_LOG2))
|
param_int(ID(STATE_NUM_LOG2))
|
||||||
param_int(ID(\\STATE_RST))
|
param_int(ID(STATE_RST))
|
||||||
param_int(ID(\\S_WIDTH))
|
param_int(ID(S_WIDTH))
|
||||||
param_int(ID(\\TRANS_NUM))
|
param_int(ID(TRANS_NUM))
|
||||||
param_int(ID(\\WIDTH))
|
param_int(ID(WIDTH))
|
||||||
param_int(ID(\\WR_PORTS))
|
param_int(ID(WR_PORTS))
|
||||||
param_int(ID(\\Y_WIDTH))
|
param_int(ID(Y_WIDTH))
|
||||||
#undef param_int
|
#undef param_int
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
|
@ -341,10 +341,10 @@ RTLIL::Cell *replace(RTLIL::Module *needle, RTLIL::Module *haystack, SubCircuit:
|
||||||
bool compareSortNeedleList(RTLIL::Module *left, RTLIL::Module *right)
|
bool compareSortNeedleList(RTLIL::Module *left, RTLIL::Module *right)
|
||||||
{
|
{
|
||||||
int left_idx = 0, right_idx = 0;
|
int left_idx = 0, right_idx = 0;
|
||||||
if (left->attributes.count(ID(\\extract_order)) > 0)
|
if (left->attributes.count(ID(extract_order)) > 0)
|
||||||
left_idx = left->attributes.at(ID(\\extract_order)).as_int();
|
left_idx = left->attributes.at(ID(extract_order)).as_int();
|
||||||
if (right->attributes.count(ID(\\extract_order)) > 0)
|
if (right->attributes.count(ID(extract_order)) > 0)
|
||||||
right_idx = right->attributes.at(ID(\\extract_order)).as_int();
|
right_idx = right->attributes.at(ID(extract_order)).as_int();
|
||||||
if (left_idx != right_idx)
|
if (left_idx != right_idx)
|
||||||
return left_idx < right_idx;
|
return left_idx < right_idx;
|
||||||
return left->name < right->name;
|
return left->name < right->name;
|
||||||
|
|
|
@ -120,45 +120,45 @@ int counter_tryextract(
|
||||||
|
|
||||||
//A counter with less than 2 bits makes no sense
|
//A counter with less than 2 bits makes no sense
|
||||||
//TODO: configurable min threshold
|
//TODO: configurable min threshold
|
||||||
int a_width = cell->getParam(ID(\\A_WIDTH)).as_int();
|
int a_width = cell->getParam(ID(A_WIDTH)).as_int();
|
||||||
extract.width = a_width;
|
extract.width = a_width;
|
||||||
if( (a_width < 2) || (a_width > maxwidth) )
|
if( (a_width < 2) || (a_width > maxwidth) )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
//Second input must be a single bit
|
//Second input must be a single bit
|
||||||
int b_width = cell->getParam(ID(\\B_WIDTH)).as_int();
|
int b_width = cell->getParam(ID(B_WIDTH)).as_int();
|
||||||
if(b_width != 1)
|
if(b_width != 1)
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
//Both inputs must be unsigned, so don't extract anything with a signed input
|
//Both inputs must be unsigned, so don't extract anything with a signed input
|
||||||
bool a_sign = cell->getParam(ID(\\A_SIGNED)).as_bool();
|
bool a_sign = cell->getParam(ID(A_SIGNED)).as_bool();
|
||||||
bool b_sign = cell->getParam(ID(\\B_SIGNED)).as_bool();
|
bool b_sign = cell->getParam(ID(B_SIGNED)).as_bool();
|
||||||
if(a_sign || b_sign)
|
if(a_sign || b_sign)
|
||||||
return 3;
|
return 3;
|
||||||
|
|
||||||
//To be a counter, one input of the ALU must be a constant 1
|
//To be a counter, one input of the ALU must be a constant 1
|
||||||
//TODO: can A or B be swapped in synthesized RTL or is B always the 1?
|
//TODO: can A or B be swapped in synthesized RTL or is B always the 1?
|
||||||
const RTLIL::SigSpec b_port = sigmap(cell->getPort(ID(\\B)));
|
const RTLIL::SigSpec b_port = sigmap(cell->getPort(ID(B)));
|
||||||
if(!b_port.is_fully_const() || (b_port.as_int() != 1) )
|
if(!b_port.is_fully_const() || (b_port.as_int() != 1) )
|
||||||
return 4;
|
return 4;
|
||||||
|
|
||||||
//BI and CI must be constant 1 as well
|
//BI and CI must be constant 1 as well
|
||||||
const RTLIL::SigSpec bi_port = sigmap(cell->getPort(ID(\\BI)));
|
const RTLIL::SigSpec bi_port = sigmap(cell->getPort(ID(BI)));
|
||||||
if(!bi_port.is_fully_const() || (bi_port.as_int() != 1) )
|
if(!bi_port.is_fully_const() || (bi_port.as_int() != 1) )
|
||||||
return 5;
|
return 5;
|
||||||
const RTLIL::SigSpec ci_port = sigmap(cell->getPort(ID(\\CI)));
|
const RTLIL::SigSpec ci_port = sigmap(cell->getPort(ID(CI)));
|
||||||
if(!ci_port.is_fully_const() || (ci_port.as_int() != 1) )
|
if(!ci_port.is_fully_const() || (ci_port.as_int() != 1) )
|
||||||
return 6;
|
return 6;
|
||||||
|
|
||||||
//CO and X must be unconnected (exactly one connection to each port)
|
//CO and X must be unconnected (exactly one connection to each port)
|
||||||
if(!is_unconnected(sigmap(cell->getPort(ID(\\CO))), index))
|
if(!is_unconnected(sigmap(cell->getPort(ID(CO))), index))
|
||||||
return 7;
|
return 7;
|
||||||
if(!is_unconnected(sigmap(cell->getPort(ID(\\X))), index))
|
if(!is_unconnected(sigmap(cell->getPort(ID(X))), index))
|
||||||
return 8;
|
return 8;
|
||||||
|
|
||||||
//Y must have exactly one connection, and it has to be a $mux cell.
|
//Y must have exactly one connection, and it has to be a $mux cell.
|
||||||
//We must have a direct bus connection from our Y to their A.
|
//We must have a direct bus connection from our Y to their A.
|
||||||
const RTLIL::SigSpec aluy = sigmap(cell->getPort(ID(\\Y)));
|
const RTLIL::SigSpec aluy = sigmap(cell->getPort(ID(Y)));
|
||||||
pool<Cell*> y_loads = get_other_cells(aluy, index, cell);
|
pool<Cell*> y_loads = get_other_cells(aluy, index, cell);
|
||||||
if(y_loads.size() != 1)
|
if(y_loads.size() != 1)
|
||||||
return 9;
|
return 9;
|
||||||
|
@ -166,17 +166,17 @@ int counter_tryextract(
|
||||||
extract.count_mux = count_mux;
|
extract.count_mux = count_mux;
|
||||||
if(count_mux->type != ID($mux))
|
if(count_mux->type != ID($mux))
|
||||||
return 10;
|
return 10;
|
||||||
if(!is_full_bus(aluy, index, cell, ID(\\Y), count_mux, ID(\\A)))
|
if(!is_full_bus(aluy, index, cell, ID(Y), count_mux, ID(A)))
|
||||||
return 11;
|
return 11;
|
||||||
|
|
||||||
//B connection of the mux is our underflow value
|
//B connection of the mux is our underflow value
|
||||||
const RTLIL::SigSpec underflow = sigmap(count_mux->getPort(ID(\\B)));
|
const RTLIL::SigSpec underflow = sigmap(count_mux->getPort(ID(B)));
|
||||||
if(!underflow.is_fully_const())
|
if(!underflow.is_fully_const())
|
||||||
return 12;
|
return 12;
|
||||||
extract.count_value = underflow.as_int();
|
extract.count_value = underflow.as_int();
|
||||||
|
|
||||||
//S connection of the mux must come from an inverter (need not be the only load)
|
//S connection of the mux must come from an inverter (need not be the only load)
|
||||||
const RTLIL::SigSpec muxsel = sigmap(count_mux->getPort(ID(\\S)));
|
const RTLIL::SigSpec muxsel = sigmap(count_mux->getPort(ID(S)));
|
||||||
extract.outsig = muxsel;
|
extract.outsig = muxsel;
|
||||||
pool<Cell*> muxsel_conns = get_other_cells(muxsel, index, count_mux);
|
pool<Cell*> muxsel_conns = get_other_cells(muxsel, index, count_mux);
|
||||||
Cell* underflow_inv = NULL;
|
Cell* underflow_inv = NULL;
|
||||||
|
@ -184,7 +184,7 @@ int counter_tryextract(
|
||||||
{
|
{
|
||||||
if(c->type != ID($logic_not))
|
if(c->type != ID($logic_not))
|
||||||
continue;
|
continue;
|
||||||
if(!is_full_bus(muxsel, index, c, ID(\\Y), count_mux, ID(\\S), true))
|
if(!is_full_bus(muxsel, index, c, ID(Y), count_mux, ID(S), true))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
underflow_inv = c;
|
underflow_inv = c;
|
||||||
|
@ -196,7 +196,7 @@ int counter_tryextract(
|
||||||
|
|
||||||
//Y connection of the mux must have exactly one load, the counter's internal register, if there's no clock enable
|
//Y connection of the mux must have exactly one load, the counter's internal register, if there's no clock enable
|
||||||
//If we have a clock enable, Y drives the B input of a mux. A of that mux must come from our register
|
//If we have a clock enable, Y drives the B input of a mux. A of that mux must come from our register
|
||||||
const RTLIL::SigSpec muxy = sigmap(count_mux->getPort(ID(\\Y)));
|
const RTLIL::SigSpec muxy = sigmap(count_mux->getPort(ID(Y)));
|
||||||
pool<Cell*> muxy_loads = get_other_cells(muxy, index, count_mux);
|
pool<Cell*> muxy_loads = get_other_cells(muxy, index, count_mux);
|
||||||
if(muxy_loads.size() != 1)
|
if(muxy_loads.size() != 1)
|
||||||
return 14;
|
return 14;
|
||||||
|
@ -209,7 +209,7 @@ int counter_tryextract(
|
||||||
//This mux is probably a clock enable mux.
|
//This mux is probably a clock enable mux.
|
||||||
//Find our count register (should be our only load)
|
//Find our count register (should be our only load)
|
||||||
cemux = muxload;
|
cemux = muxload;
|
||||||
cey = sigmap(cemux->getPort(ID(\\Y)));
|
cey = sigmap(cemux->getPort(ID(Y)));
|
||||||
pool<Cell*> cey_loads = get_other_cells(cey, index, cemux);
|
pool<Cell*> cey_loads = get_other_cells(cey, index, cemux);
|
||||||
if(cey_loads.size() != 1)
|
if(cey_loads.size() != 1)
|
||||||
return 24;
|
return 24;
|
||||||
|
@ -217,16 +217,16 @@ int counter_tryextract(
|
||||||
|
|
||||||
//Mux should have A driven by count Q, and B by muxy
|
//Mux should have A driven by count Q, and B by muxy
|
||||||
//TODO: if A and B are swapped, CE polarity is inverted
|
//TODO: if A and B are swapped, CE polarity is inverted
|
||||||
if(sigmap(cemux->getPort(ID(\\B))) != muxy)
|
if(sigmap(cemux->getPort(ID(B))) != muxy)
|
||||||
return 24;
|
return 24;
|
||||||
if(sigmap(cemux->getPort(ID(\\A))) != sigmap(count_reg->getPort(ID(\\Q))))
|
if(sigmap(cemux->getPort(ID(A))) != sigmap(count_reg->getPort(ID(Q))))
|
||||||
return 24;
|
return 24;
|
||||||
if(sigmap(cemux->getPort(ID(\\Y))) != sigmap(count_reg->getPort(ID(\\D))))
|
if(sigmap(cemux->getPort(ID(Y))) != sigmap(count_reg->getPort(ID(D))))
|
||||||
return 24;
|
return 24;
|
||||||
|
|
||||||
//Select of the mux is our clock enable
|
//Select of the mux is our clock enable
|
||||||
extract.has_ce = true;
|
extract.has_ce = true;
|
||||||
extract.ce = sigmap(cemux->getPort(ID(\\S)));
|
extract.ce = sigmap(cemux->getPort(ID(S)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
extract.has_ce = false;
|
extract.has_ce = false;
|
||||||
|
@ -239,10 +239,10 @@ int counter_tryextract(
|
||||||
extract.has_reset = true;
|
extract.has_reset = true;
|
||||||
|
|
||||||
//Check polarity of reset - we may have to add an inverter later on!
|
//Check polarity of reset - we may have to add an inverter later on!
|
||||||
extract.rst_inverted = (count_reg->getParam(ID(\\ARST_POLARITY)).as_int() != 1);
|
extract.rst_inverted = (count_reg->getParam(ID(ARST_POLARITY)).as_int() != 1);
|
||||||
|
|
||||||
//Verify ARST_VALUE is zero or full scale
|
//Verify ARST_VALUE is zero or full scale
|
||||||
int rst_value = count_reg->getParam(ID(\\ARST_VALUE)).as_int();
|
int rst_value = count_reg->getParam(ID(ARST_VALUE)).as_int();
|
||||||
if(rst_value == 0)
|
if(rst_value == 0)
|
||||||
extract.rst_to_max = false;
|
extract.rst_to_max = false;
|
||||||
else if(rst_value == extract.count_value)
|
else if(rst_value == extract.count_value)
|
||||||
|
@ -251,7 +251,7 @@ int counter_tryextract(
|
||||||
return 23;
|
return 23;
|
||||||
|
|
||||||
//Save the reset
|
//Save the reset
|
||||||
extract.rst = sigmap(count_reg->getPort(ID(\\ARST)));
|
extract.rst = sigmap(count_reg->getPort(ID(ARST)));
|
||||||
}
|
}
|
||||||
//TODO: support synchronous reset
|
//TODO: support synchronous reset
|
||||||
else
|
else
|
||||||
|
@ -260,12 +260,12 @@ int counter_tryextract(
|
||||||
//Sanity check that we use the ALU output properly
|
//Sanity check that we use the ALU output properly
|
||||||
if(extract.has_ce)
|
if(extract.has_ce)
|
||||||
{
|
{
|
||||||
if(!is_full_bus(muxy, index, count_mux, ID(\\Y), cemux, ID(\\B)))
|
if(!is_full_bus(muxy, index, count_mux, ID(Y), cemux, ID(B)))
|
||||||
return 16;
|
return 16;
|
||||||
if(!is_full_bus(cey, index, cemux, ID(\\Y), count_reg, ID(\\D)))
|
if(!is_full_bus(cey, index, cemux, ID(Y), count_reg, ID(D)))
|
||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
else if(!is_full_bus(muxy, index, count_mux, ID(\\Y), count_reg, ID(\\D)))
|
else if(!is_full_bus(muxy, index, count_mux, ID(Y), count_reg, ID(D)))
|
||||||
return 16;
|
return 16;
|
||||||
|
|
||||||
//TODO: Verify count_reg CLK_POLARITY is 1
|
//TODO: Verify count_reg CLK_POLARITY is 1
|
||||||
|
@ -273,7 +273,7 @@ int counter_tryextract(
|
||||||
//Register output must have exactly two loads, the inverter and ALU
|
//Register output must have exactly two loads, the inverter and ALU
|
||||||
//(unless we have a parallel output!)
|
//(unless we have a parallel output!)
|
||||||
//If we have a clock enable, 3 is OK
|
//If we have a clock enable, 3 is OK
|
||||||
const RTLIL::SigSpec qport = count_reg->getPort(ID(\\Q));
|
const RTLIL::SigSpec qport = count_reg->getPort(ID(Q));
|
||||||
const RTLIL::SigSpec cnout = sigmap(qport);
|
const RTLIL::SigSpec cnout = sigmap(qport);
|
||||||
pool<Cell*> cnout_loads = get_other_cells(cnout, index, count_reg);
|
pool<Cell*> cnout_loads = get_other_cells(cnout, index, count_reg);
|
||||||
unsigned int max_loads = 2;
|
unsigned int max_loads = 2;
|
||||||
|
@ -312,19 +312,19 @@ int counter_tryextract(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!is_full_bus(cnout, index, count_reg, ID(\\Q), underflow_inv, ID(\\A), true))
|
if(!is_full_bus(cnout, index, count_reg, ID(Q), underflow_inv, ID(A), true))
|
||||||
return 18;
|
return 18;
|
||||||
if(!is_full_bus(cnout, index, count_reg, ID(\\Q), cell, ID(\\A), true))
|
if(!is_full_bus(cnout, index, count_reg, ID(Q), cell, ID(A), true))
|
||||||
return 19;
|
return 19;
|
||||||
|
|
||||||
//Look up the clock from the register
|
//Look up the clock from the register
|
||||||
extract.clk = sigmap(count_reg->getPort(ID(\\CLK)));
|
extract.clk = sigmap(count_reg->getPort(ID(CLK)));
|
||||||
|
|
||||||
//Register output net must have an INIT attribute equal to the count value
|
//Register output net must have an INIT attribute equal to the count value
|
||||||
extract.rwire = cnout.as_wire();
|
extract.rwire = cnout.as_wire();
|
||||||
if(extract.rwire->attributes.find(ID(\\init)) == extract.rwire->attributes.end())
|
if(extract.rwire->attributes.find(ID(init)) == extract.rwire->attributes.end())
|
||||||
return 20;
|
return 20;
|
||||||
int rinit = extract.rwire->attributes[ID(\\init)].as_int();
|
int rinit = extract.rwire->attributes[ID(init)].as_int();
|
||||||
if(rinit != extract.count_value)
|
if(rinit != extract.count_value)
|
||||||
return 21;
|
return 21;
|
||||||
|
|
||||||
|
@ -348,16 +348,16 @@ void counter_worker(
|
||||||
|
|
||||||
//A input is the count value. Check if it has COUNT_EXTRACT set.
|
//A input is the count value. Check if it has COUNT_EXTRACT set.
|
||||||
//If it's not a wire, don't even try
|
//If it's not a wire, don't even try
|
||||||
auto port = sigmap(cell->getPort(ID(\\A)));
|
auto port = sigmap(cell->getPort(ID(A)));
|
||||||
if(!port.is_wire())
|
if(!port.is_wire())
|
||||||
return;
|
return;
|
||||||
RTLIL::Wire* a_wire = port.as_wire();
|
RTLIL::Wire* a_wire = port.as_wire();
|
||||||
bool force_extract = false;
|
bool force_extract = false;
|
||||||
bool never_extract = false;
|
bool never_extract = false;
|
||||||
string count_reg_src = a_wire->attributes[ID(\\src)].decode_string().c_str();
|
string count_reg_src = a_wire->attributes[ID(src)].decode_string().c_str();
|
||||||
if(a_wire->attributes.find(ID(\\COUNT_EXTRACT)) != a_wire->attributes.end())
|
if(a_wire->attributes.find(ID(COUNT_EXTRACT)) != a_wire->attributes.end())
|
||||||
{
|
{
|
||||||
pool<string> sa = a_wire->get_strpool_attribute(ID(\\COUNT_EXTRACT));
|
pool<string> sa = a_wire->get_strpool_attribute(ID(COUNT_EXTRACT));
|
||||||
string extract_value;
|
string extract_value;
|
||||||
if(sa.size() >= 1)
|
if(sa.size() >= 1)
|
||||||
{
|
{
|
||||||
|
@ -434,18 +434,18 @@ void counter_worker(
|
||||||
string countname = string("$COUNTx$") + log_id(extract.rwire->name.str());
|
string countname = string("$COUNTx$") + log_id(extract.rwire->name.str());
|
||||||
|
|
||||||
//Wipe all of the old connections to the ALU
|
//Wipe all of the old connections to the ALU
|
||||||
cell->unsetPort(ID(\\A));
|
cell->unsetPort(ID(A));
|
||||||
cell->unsetPort(ID(\\B));
|
cell->unsetPort(ID(B));
|
||||||
cell->unsetPort(ID(\\BI));
|
cell->unsetPort(ID(BI));
|
||||||
cell->unsetPort(ID(\\CI));
|
cell->unsetPort(ID(CI));
|
||||||
cell->unsetPort(ID(\\CO));
|
cell->unsetPort(ID(CO));
|
||||||
cell->unsetPort(ID(\\X));
|
cell->unsetPort(ID(X));
|
||||||
cell->unsetPort(ID(\\Y));
|
cell->unsetPort(ID(Y));
|
||||||
cell->unsetParam(ID(\\A_SIGNED));
|
cell->unsetParam(ID(A_SIGNED));
|
||||||
cell->unsetParam(ID(\\A_WIDTH));
|
cell->unsetParam(ID(A_WIDTH));
|
||||||
cell->unsetParam(ID(\\B_SIGNED));
|
cell->unsetParam(ID(B_SIGNED));
|
||||||
cell->unsetParam(ID(\\B_WIDTH));
|
cell->unsetParam(ID(B_WIDTH));
|
||||||
cell->unsetParam(ID(\\Y_WIDTH));
|
cell->unsetParam(ID(Y_WIDTH));
|
||||||
|
|
||||||
//Change the cell type
|
//Change the cell type
|
||||||
cell->type = ID($__COUNT_);
|
cell->type = ID($__COUNT_);
|
||||||
|
@ -454,46 +454,46 @@ void counter_worker(
|
||||||
if(extract.has_reset)
|
if(extract.has_reset)
|
||||||
{
|
{
|
||||||
//TODO: support other kinds of reset
|
//TODO: support other kinds of reset
|
||||||
cell->setParam(ID(\\RESET_MODE), RTLIL::Const("LEVEL"));
|
cell->setParam(ID(RESET_MODE), RTLIL::Const("LEVEL"));
|
||||||
|
|
||||||
//If the reset is active low, infer an inverter ($__COUNT_ cells always have active high reset)
|
//If the reset is active low, infer an inverter ($__COUNT_ cells always have active high reset)
|
||||||
if(extract.rst_inverted)
|
if(extract.rst_inverted)
|
||||||
{
|
{
|
||||||
auto realreset = cell->module->addWire(NEW_ID);
|
auto realreset = cell->module->addWire(NEW_ID);
|
||||||
cell->module->addNot(NEW_ID, extract.rst, RTLIL::SigSpec(realreset));
|
cell->module->addNot(NEW_ID, extract.rst, RTLIL::SigSpec(realreset));
|
||||||
cell->setPort(ID(\\RST), realreset);
|
cell->setPort(ID(RST), realreset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cell->setPort(ID(\\RST), extract.rst);
|
cell->setPort(ID(RST), extract.rst);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cell->setParam(ID(\\RESET_MODE), RTLIL::Const("RISING"));
|
cell->setParam(ID(RESET_MODE), RTLIL::Const("RISING"));
|
||||||
cell->setPort(ID(\\RST), RTLIL::SigSpec(false));
|
cell->setPort(ID(RST), RTLIL::SigSpec(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Hook up other stuff
|
//Hook up other stuff
|
||||||
//cell->setParam(ID(\\CLKIN_DIVIDE), RTLIL::Const(1));
|
//cell->setParam(ID(CLKIN_DIVIDE), RTLIL::Const(1));
|
||||||
cell->setParam(ID(\\COUNT_TO), RTLIL::Const(extract.count_value));
|
cell->setParam(ID(COUNT_TO), RTLIL::Const(extract.count_value));
|
||||||
cell->setParam(ID(\\WIDTH), RTLIL::Const(extract.width));
|
cell->setParam(ID(WIDTH), RTLIL::Const(extract.width));
|
||||||
cell->setPort(ID(\\CLK), extract.clk);
|
cell->setPort(ID(CLK), extract.clk);
|
||||||
cell->setPort(ID(\\OUT), extract.outsig);
|
cell->setPort(ID(OUT), extract.outsig);
|
||||||
|
|
||||||
//Hook up clock enable
|
//Hook up clock enable
|
||||||
if(extract.has_ce)
|
if(extract.has_ce)
|
||||||
{
|
{
|
||||||
cell->setParam(ID(\\HAS_CE), RTLIL::Const(1));
|
cell->setParam(ID(HAS_CE), RTLIL::Const(1));
|
||||||
cell->setPort(ID(\\CE), extract.ce);
|
cell->setPort(ID(CE), extract.ce);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cell->setParam(ID(\\HAS_CE), RTLIL::Const(0));
|
cell->setParam(ID(HAS_CE), RTLIL::Const(0));
|
||||||
|
|
||||||
//Hook up hard-wired ports (for now up/down are not supported), default to no parallel output
|
//Hook up hard-wired ports (for now up/down are not supported), default to no parallel output
|
||||||
cell->setParam(ID(\\HAS_POUT), RTLIL::Const(0));
|
cell->setParam(ID(HAS_POUT), RTLIL::Const(0));
|
||||||
cell->setParam(ID(\\RESET_TO_MAX), RTLIL::Const(0));
|
cell->setParam(ID(RESET_TO_MAX), RTLIL::Const(0));
|
||||||
cell->setParam(ID(\\DIRECTION), RTLIL::Const("DOWN"));
|
cell->setParam(ID(DIRECTION), RTLIL::Const("DOWN"));
|
||||||
cell->setPort(ID(\\CE), RTLIL::Const(1));
|
cell->setPort(ID(CE), RTLIL::Const(1));
|
||||||
cell->setPort(ID(\\UP), RTLIL::Const(0));
|
cell->setPort(ID(UP), RTLIL::Const(0));
|
||||||
|
|
||||||
//Hook up any parallel outputs
|
//Hook up any parallel outputs
|
||||||
for(auto load : extract.pouts)
|
for(auto load : extract.pouts)
|
||||||
|
@ -505,8 +505,8 @@ void counter_worker(
|
||||||
|
|
||||||
//Connect it to our parallel output
|
//Connect it to our parallel output
|
||||||
//(this is OK to do more than once b/c they all go to the same place)
|
//(this is OK to do more than once b/c they all go to the same place)
|
||||||
cell->setPort(ID(\\POUT), sig);
|
cell->setPort(ID(POUT), sig);
|
||||||
cell->setParam(ID(\\HAS_POUT), RTLIL::Const(1));
|
cell->setParam(ID(HAS_POUT), RTLIL::Const(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Delete the cells we've replaced (let opt_clean handle deleting the now-redundant wires)
|
//Delete the cells we've replaced (let opt_clean handle deleting the now-redundant wires)
|
||||||
|
@ -546,7 +546,7 @@ void counter_worker(
|
||||||
int newbits = ceil(log2(extract.count_value));
|
int newbits = ceil(log2(extract.count_value));
|
||||||
if(extract.width != newbits)
|
if(extract.width != newbits)
|
||||||
{
|
{
|
||||||
cell->setParam(ID(\\WIDTH), RTLIL::Const(newbits));
|
cell->setParam(ID(WIDTH), RTLIL::Const(newbits));
|
||||||
log(" Optimizing out %d unused high-order bits (new width is %d)\n",
|
log(" Optimizing out %d unused high-order bits (new width is %d)\n",
|
||||||
extract.width - newbits,
|
extract.width - newbits,
|
||||||
newbits);
|
newbits);
|
||||||
|
|
|
@ -89,7 +89,7 @@ struct ExtractFaWorker
|
||||||
ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), ID($_MUX_), ID($_NMUX_),
|
ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), ID($_MUX_), ID($_NMUX_),
|
||||||
ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_)))
|
ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_)))
|
||||||
{
|
{
|
||||||
SigBit y = sigmap(SigBit(cell->getPort(ID(\\Y))));
|
SigBit y = sigmap(SigBit(cell->getPort(ID(Y))));
|
||||||
log_assert(driver.count(y) == 0);
|
log_assert(driver.count(y) == 0);
|
||||||
driver[y] = cell;
|
driver[y] = cell;
|
||||||
}
|
}
|
||||||
|
@ -262,10 +262,10 @@ struct ExtractFaWorker
|
||||||
pool<SigBit> new_leaves = leaves;
|
pool<SigBit> new_leaves = leaves;
|
||||||
|
|
||||||
new_leaves.erase(bit);
|
new_leaves.erase(bit);
|
||||||
if (cell->hasPort(ID(\\A))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(\\A)))));
|
if (cell->hasPort(ID(A))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(A)))));
|
||||||
if (cell->hasPort(ID(\\B))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(\\B)))));
|
if (cell->hasPort(ID(B))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(B)))));
|
||||||
if (cell->hasPort(ID(\\C))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(\\C)))));
|
if (cell->hasPort(ID(C))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(C)))));
|
||||||
if (cell->hasPort(ID(\\D))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(\\D)))));
|
if (cell->hasPort(ID(D))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(D)))));
|
||||||
|
|
||||||
if (GetSize(new_leaves) > maxbreadth)
|
if (GetSize(new_leaves) > maxbreadth)
|
||||||
continue;
|
continue;
|
||||||
|
@ -277,8 +277,8 @@ struct ExtractFaWorker
|
||||||
void assign_new_driver(SigBit bit, SigBit new_driver)
|
void assign_new_driver(SigBit bit, SigBit new_driver)
|
||||||
{
|
{
|
||||||
Cell *cell = driver.at(bit);
|
Cell *cell = driver.at(bit);
|
||||||
if (sigmap(cell->getPort(ID(\\Y))) == bit) {
|
if (sigmap(cell->getPort(ID(Y))) == bit) {
|
||||||
cell->setPort(ID(\\Y), module->addWire(NEW_ID));
|
cell->setPort(ID(Y), module->addWire(NEW_ID));
|
||||||
module->connect(bit, new_driver);
|
module->connect(bit, new_driver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -391,19 +391,19 @@ struct ExtractFaWorker
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Cell *cell = module->addCell(NEW_ID, ID($fa));
|
Cell *cell = module->addCell(NEW_ID, ID($fa));
|
||||||
cell->setParam(ID(\\WIDTH), 1);
|
cell->setParam(ID(WIDTH), 1);
|
||||||
|
|
||||||
log(" Created $fa cell %s.\n", log_id(cell));
|
log(" Created $fa cell %s.\n", log_id(cell));
|
||||||
|
|
||||||
cell->setPort(ID(\\A), f3i.inv_a ? module->NotGate(NEW_ID, A) : A);
|
cell->setPort(ID(A), f3i.inv_a ? module->NotGate(NEW_ID, A) : A);
|
||||||
cell->setPort(ID(\\B), f3i.inv_b ? module->NotGate(NEW_ID, B) : B);
|
cell->setPort(ID(B), f3i.inv_b ? module->NotGate(NEW_ID, B) : B);
|
||||||
cell->setPort(ID(\\C), f3i.inv_c ? module->NotGate(NEW_ID, C) : C);
|
cell->setPort(ID(C), f3i.inv_c ? module->NotGate(NEW_ID, C) : C);
|
||||||
|
|
||||||
X = module->addWire(NEW_ID);
|
X = module->addWire(NEW_ID);
|
||||||
Y = module->addWire(NEW_ID);
|
Y = module->addWire(NEW_ID);
|
||||||
|
|
||||||
cell->setPort(ID(\\X), X);
|
cell->setPort(ID(X), X);
|
||||||
cell->setPort(ID(\\Y), Y);
|
cell->setPort(ID(Y), Y);
|
||||||
|
|
||||||
facache[fakey] = make_tuple(X, Y, cell);
|
facache[fakey] = make_tuple(X, Y, cell);
|
||||||
}
|
}
|
||||||
|
@ -497,19 +497,19 @@ struct ExtractFaWorker
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Cell *cell = module->addCell(NEW_ID, ID($fa));
|
Cell *cell = module->addCell(NEW_ID, ID($fa));
|
||||||
cell->setParam(ID(\\WIDTH), 1);
|
cell->setParam(ID(WIDTH), 1);
|
||||||
|
|
||||||
log(" Created $fa cell %s.\n", log_id(cell));
|
log(" Created $fa cell %s.\n", log_id(cell));
|
||||||
|
|
||||||
cell->setPort(ID(\\A), f2i.inv_a ? module->NotGate(NEW_ID, A) : A);
|
cell->setPort(ID(A), f2i.inv_a ? module->NotGate(NEW_ID, A) : A);
|
||||||
cell->setPort(ID(\\B), f2i.inv_b ? module->NotGate(NEW_ID, B) : B);
|
cell->setPort(ID(B), f2i.inv_b ? module->NotGate(NEW_ID, B) : B);
|
||||||
cell->setPort(ID(\\C), State::S0);
|
cell->setPort(ID(C), State::S0);
|
||||||
|
|
||||||
X = module->addWire(NEW_ID);
|
X = module->addWire(NEW_ID);
|
||||||
Y = module->addWire(NEW_ID);
|
Y = module->addWire(NEW_ID);
|
||||||
|
|
||||||
cell->setPort(ID(\\X), X);
|
cell->setPort(ID(X), X);
|
||||||
cell->setPort(ID(\\Y), Y);
|
cell->setPort(ID(Y), Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (func2.at(key).count(xor2_func)) {
|
if (func2.at(key).count(xor2_func)) {
|
||||||
|
|
|
@ -148,7 +148,7 @@ struct ExtractReducePass : public Pass
|
||||||
|
|
||||||
head_cell = x;
|
head_cell = x;
|
||||||
|
|
||||||
auto y = sigmap(x->getPort(ID(\\Y)));
|
auto y = sigmap(x->getPort(ID(Y)));
|
||||||
log_assert(y.size() == 1);
|
log_assert(y.size() == 1);
|
||||||
|
|
||||||
// Should only continue if there is one fanout back into a cell (not to a port)
|
// Should only continue if there is one fanout back into a cell (not to a port)
|
||||||
|
@ -166,7 +166,7 @@ struct ExtractReducePass : public Pass
|
||||||
{
|
{
|
||||||
//BFS, following all chains until they hit a cell of a different type
|
//BFS, following all chains until they hit a cell of a different type
|
||||||
//Pick the longest one
|
//Pick the longest one
|
||||||
auto y = sigmap(cell->getPort(ID(\\Y)));
|
auto y = sigmap(cell->getPort(ID(Y)));
|
||||||
pool<Cell*> current_loads = sig_to_sink[y];
|
pool<Cell*> current_loads = sig_to_sink[y];
|
||||||
pool<Cell*> next_loads;
|
pool<Cell*> next_loads;
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ struct ExtractReducePass : public Pass
|
||||||
|
|
||||||
cur_supercell.insert(x);
|
cur_supercell.insert(x);
|
||||||
|
|
||||||
auto a = sigmap(x->getPort(ID(\\A)));
|
auto a = sigmap(x->getPort(ID(A)));
|
||||||
log_assert(a.size() == 1);
|
log_assert(a.size() == 1);
|
||||||
|
|
||||||
// Must have only one sink unless we're going off chain
|
// Must have only one sink unless we're going off chain
|
||||||
|
@ -249,7 +249,7 @@ struct ExtractReducePass : public Pass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto b = sigmap(x->getPort(ID(\\B)));
|
auto b = sigmap(x->getPort(ID(B)));
|
||||||
log_assert(b.size() == 1);
|
log_assert(b.size() == 1);
|
||||||
|
|
||||||
// Must have only one sink
|
// Must have only one sink
|
||||||
|
@ -279,26 +279,26 @@ struct ExtractReducePass : public Pass
|
||||||
pool<SigBit> input_pool_intermed;
|
pool<SigBit> input_pool_intermed;
|
||||||
for (auto x : cur_supercell)
|
for (auto x : cur_supercell)
|
||||||
{
|
{
|
||||||
input_pool.insert(sigmap(x->getPort(ID(\\A)))[0]);
|
input_pool.insert(sigmap(x->getPort(ID(A)))[0]);
|
||||||
input_pool.insert(sigmap(x->getPort(ID(\\B)))[0]);
|
input_pool.insert(sigmap(x->getPort(ID(B)))[0]);
|
||||||
input_pool_intermed.insert(sigmap(x->getPort(ID(\\Y)))[0]);
|
input_pool_intermed.insert(sigmap(x->getPort(ID(Y)))[0]);
|
||||||
}
|
}
|
||||||
SigSpec input;
|
SigSpec input;
|
||||||
for (auto b : input_pool)
|
for (auto b : input_pool)
|
||||||
if (input_pool_intermed.count(b) == 0)
|
if (input_pool_intermed.count(b) == 0)
|
||||||
input.append_bit(b);
|
input.append_bit(b);
|
||||||
|
|
||||||
SigBit output = sigmap(head_cell->getPort(ID(\\Y))[0]);
|
SigBit output = sigmap(head_cell->getPort(ID(Y))[0]);
|
||||||
|
|
||||||
auto new_reduce_cell = module->addCell(NEW_ID,
|
auto new_reduce_cell = module->addCell(NEW_ID,
|
||||||
gt == GateType::And ? ID($reduce_and) :
|
gt == GateType::And ? ID($reduce_and) :
|
||||||
gt == GateType::Or ? ID($reduce_or) :
|
gt == GateType::Or ? ID($reduce_or) :
|
||||||
gt == GateType::Xor ? ID($reduce_xor) : "");
|
gt == GateType::Xor ? ID($reduce_xor) : "");
|
||||||
new_reduce_cell->setParam(ID(\\A_SIGNED), 0);
|
new_reduce_cell->setParam(ID(A_SIGNED), 0);
|
||||||
new_reduce_cell->setParam(ID(\\A_WIDTH), input.size());
|
new_reduce_cell->setParam(ID(A_WIDTH), input.size());
|
||||||
new_reduce_cell->setParam(ID(\\Y_WIDTH), 1);
|
new_reduce_cell->setParam(ID(Y_WIDTH), 1);
|
||||||
new_reduce_cell->setPort(ID(\\A), input);
|
new_reduce_cell->setPort(ID(A), input);
|
||||||
new_reduce_cell->setPort(ID(\\Y), output);
|
new_reduce_cell->setPort(ID(Y), output);
|
||||||
|
|
||||||
if(allow_off_chain)
|
if(allow_off_chain)
|
||||||
consumed_cells.insert(head_cell);
|
consumed_cells.insert(head_cell);
|
||||||
|
|
|
@ -671,8 +671,8 @@ struct FlowmapWorker
|
||||||
labels[node] = -1;
|
labels[node] = -1;
|
||||||
for (auto input : inputs)
|
for (auto input : inputs)
|
||||||
{
|
{
|
||||||
if (input.wire->attributes.count(ID(\\$flowmap_level)))
|
if (input.wire->attributes.count(ID($flowmap_level)))
|
||||||
labels[input] = input.wire->attributes[ID(\\$flowmap_level)].as_int();
|
labels[input] = input.wire->attributes[ID($flowmap_level)].as_int();
|
||||||
else
|
else
|
||||||
labels[input] = 0;
|
labels[input] = 0;
|
||||||
}
|
}
|
||||||
|
@ -1412,7 +1412,7 @@ struct FlowmapWorker
|
||||||
for (auto gate_node : lut_gates[node])
|
for (auto gate_node : lut_gates[node])
|
||||||
{
|
{
|
||||||
auto gate_origin = node_origins[gate_node];
|
auto gate_origin = node_origins[gate_node];
|
||||||
lut->add_strpool_attribute(ID(\\src), gate_origin.cell->get_strpool_attribute(ID(\\src)));
|
lut->add_strpool_attribute(ID(src), gate_origin.cell->get_strpool_attribute(ID(src)));
|
||||||
packed_count++;
|
packed_count++;
|
||||||
}
|
}
|
||||||
lut_count++;
|
lut_count++;
|
||||||
|
|
|
@ -180,7 +180,7 @@ struct IopadmapPass : public Pass {
|
||||||
|
|
||||||
for (auto cell : module->cells())
|
for (auto cell : module->cells())
|
||||||
if (cell->type == ID($_TBUF_)) {
|
if (cell->type == ID($_TBUF_)) {
|
||||||
SigBit bit = sigmap(cell->getPort(ID(\\Y)).as_bit());
|
SigBit bit = sigmap(cell->getPort(ID(Y)).as_bit());
|
||||||
tbuf_bits[bit].first = cell->name;
|
tbuf_bits[bit].first = cell->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,8 +212,8 @@ struct IopadmapPass : public Pass {
|
||||||
if (tbuf_cell == nullptr)
|
if (tbuf_cell == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SigBit en_sig = tbuf_cell->getPort(ID(\\E)).as_bit();
|
SigBit en_sig = tbuf_cell->getPort(ID(E)).as_bit();
|
||||||
SigBit data_sig = tbuf_cell->getPort(ID(\\A)).as_bit();
|
SigBit data_sig = tbuf_cell->getPort(ID(A)).as_bit();
|
||||||
|
|
||||||
if (wire->port_input && !tinoutpad_celltype.empty())
|
if (wire->port_input && !tinoutpad_celltype.empty())
|
||||||
{
|
{
|
||||||
|
@ -226,7 +226,7 @@ struct IopadmapPass : public Pass {
|
||||||
cell->setPort(RTLIL::escape_id(tinoutpad_portname2), owire);
|
cell->setPort(RTLIL::escape_id(tinoutpad_portname2), owire);
|
||||||
cell->setPort(RTLIL::escape_id(tinoutpad_portname3), data_sig);
|
cell->setPort(RTLIL::escape_id(tinoutpad_portname3), data_sig);
|
||||||
cell->setPort(RTLIL::escape_id(tinoutpad_portname4), wire_bit);
|
cell->setPort(RTLIL::escape_id(tinoutpad_portname4), wire_bit);
|
||||||
cell->attributes[ID(\\keep)] = RTLIL::Const(1);
|
cell->attributes[ID(keep)] = RTLIL::Const(1);
|
||||||
|
|
||||||
for (auto cn : tbuf_cache.second) {
|
for (auto cn : tbuf_cache.second) {
|
||||||
auto c = module->cell(cn);
|
auto c = module->cell(cn);
|
||||||
|
@ -263,7 +263,7 @@ struct IopadmapPass : public Pass {
|
||||||
cell->setPort(RTLIL::escape_id(toutpad_portname), en_sig);
|
cell->setPort(RTLIL::escape_id(toutpad_portname), en_sig);
|
||||||
cell->setPort(RTLIL::escape_id(toutpad_portname2), data_sig);
|
cell->setPort(RTLIL::escape_id(toutpad_portname2), data_sig);
|
||||||
cell->setPort(RTLIL::escape_id(toutpad_portname3), wire_bit);
|
cell->setPort(RTLIL::escape_id(toutpad_portname3), wire_bit);
|
||||||
cell->attributes[ID(\\keep)] = RTLIL::Const(1);
|
cell->attributes[ID(keep)] = RTLIL::Const(1);
|
||||||
|
|
||||||
for (auto cn : tbuf_cache.second) {
|
for (auto cn : tbuf_cache.second) {
|
||||||
auto c = module->cell(cn);
|
auto c = module->cell(cn);
|
||||||
|
@ -390,7 +390,7 @@ struct IopadmapPass : public Pass {
|
||||||
cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(1);
|
cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(1);
|
||||||
if (!nameparam.empty())
|
if (!nameparam.empty())
|
||||||
cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(stringf("%s[%d]", RTLIL::id2cstr(wire->name), i));
|
cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(stringf("%s[%d]", RTLIL::id2cstr(wire->name), i));
|
||||||
cell->attributes[ID(\\keep)] = RTLIL::Const(1);
|
cell->attributes[ID(keep)] = RTLIL::Const(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -403,7 +403,7 @@ struct IopadmapPass : public Pass {
|
||||||
cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(wire->width);
|
cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(wire->width);
|
||||||
if (!nameparam.empty())
|
if (!nameparam.empty())
|
||||||
cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(RTLIL::id2cstr(wire->name));
|
cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(RTLIL::id2cstr(wire->name));
|
||||||
cell->attributes[ID(\\keep)] = RTLIL::Const(1);
|
cell->attributes[ID(keep)] = RTLIL::Const(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
wire->port_id = 0;
|
wire->port_id = 0;
|
||||||
|
|
|
@ -25,9 +25,9 @@ PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
int lut2mux(Cell *cell)
|
int lut2mux(Cell *cell)
|
||||||
{
|
{
|
||||||
SigSpec sig_a = cell->getPort(ID(\\A));
|
SigSpec sig_a = cell->getPort(ID(A));
|
||||||
SigSpec sig_y = cell->getPort(ID(\\Y));
|
SigSpec sig_y = cell->getPort(ID(Y));
|
||||||
Const lut = cell->getParam(ID(\\LUT));
|
Const lut = cell->getParam(ID(LUT));
|
||||||
int count = 1;
|
int count = 1;
|
||||||
|
|
||||||
if (GetSize(sig_a) == 1)
|
if (GetSize(sig_a) == 1)
|
||||||
|
|
|
@ -112,12 +112,12 @@ struct MaccmapWorker
|
||||||
RTLIL::Wire *w2 = module->addWire(NEW_ID, width);
|
RTLIL::Wire *w2 = module->addWire(NEW_ID, width);
|
||||||
|
|
||||||
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($fa));
|
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($fa));
|
||||||
cell->setParam(ID(\\WIDTH), width);
|
cell->setParam(ID(WIDTH), width);
|
||||||
cell->setPort(ID(\\A), in1);
|
cell->setPort(ID(A), in1);
|
||||||
cell->setPort(ID(\\B), in2);
|
cell->setPort(ID(B), in2);
|
||||||
cell->setPort(ID(\\C), in3);
|
cell->setPort(ID(C), in3);
|
||||||
cell->setPort(ID(\\Y), w1);
|
cell->setPort(ID(Y), w1);
|
||||||
cell->setPort(ID(\\X), w2);
|
cell->setPort(ID(X), w2);
|
||||||
|
|
||||||
out1 = {out_zeros_msb, w1, out_zeros_lsb};
|
out1 = {out_zeros_msb, w1, out_zeros_lsb};
|
||||||
out2 = {out_zeros_msb, w2, out_zeros_lsb};
|
out2 = {out_zeros_msb, w2, out_zeros_lsb};
|
||||||
|
@ -238,22 +238,22 @@ struct MaccmapWorker
|
||||||
|
|
||||||
|
|
||||||
RTLIL::Cell *c = module->addCell(NEW_ID, ID($alu));
|
RTLIL::Cell *c = module->addCell(NEW_ID, ID($alu));
|
||||||
c->setPort(ID(\\A), summands.front());
|
c->setPort(ID(A), summands.front());
|
||||||
c->setPort(ID(\\B), summands.back());
|
c->setPort(ID(B), summands.back());
|
||||||
c->setPort(ID(\\CI), State::S0);
|
c->setPort(ID(CI), State::S0);
|
||||||
c->setPort(ID(\\BI), State::S0);
|
c->setPort(ID(BI), State::S0);
|
||||||
c->setPort(ID(\\Y), module->addWire(NEW_ID, width));
|
c->setPort(ID(Y), module->addWire(NEW_ID, width));
|
||||||
c->setPort(ID(\\X), module->addWire(NEW_ID, width));
|
c->setPort(ID(X), module->addWire(NEW_ID, width));
|
||||||
c->setPort(ID(\\CO), module->addWire(NEW_ID, width));
|
c->setPort(ID(CO), module->addWire(NEW_ID, width));
|
||||||
c->fixup_parameters();
|
c->fixup_parameters();
|
||||||
|
|
||||||
if (!tree_sum_bits.empty()) {
|
if (!tree_sum_bits.empty()) {
|
||||||
c->setPort(ID(\\CI), tree_sum_bits.back());
|
c->setPort(ID(CI), tree_sum_bits.back());
|
||||||
tree_sum_bits.pop_back();
|
tree_sum_bits.pop_back();
|
||||||
}
|
}
|
||||||
log_assert(tree_sum_bits.empty());
|
log_assert(tree_sum_bits.empty());
|
||||||
|
|
||||||
return c->getPort(ID(\\Y));
|
return c->getPort(ID(Y));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -264,17 +264,17 @@ extern void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap = false
|
||||||
|
|
||||||
void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap)
|
void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap)
|
||||||
{
|
{
|
||||||
int width = GetSize(cell->getPort(ID(\\Y)));
|
int width = GetSize(cell->getPort(ID(Y)));
|
||||||
|
|
||||||
Macc macc;
|
Macc macc;
|
||||||
macc.from_cell(cell);
|
macc.from_cell(cell);
|
||||||
|
|
||||||
RTLIL::SigSpec all_input_bits;
|
RTLIL::SigSpec all_input_bits;
|
||||||
all_input_bits.append(cell->getPort(ID(\\A)));
|
all_input_bits.append(cell->getPort(ID(A)));
|
||||||
all_input_bits.append(cell->getPort(ID(\\B)));
|
all_input_bits.append(cell->getPort(ID(B)));
|
||||||
|
|
||||||
if (all_input_bits.to_sigbit_set().count(RTLIL::Sx)) {
|
if (all_input_bits.to_sigbit_set().count(RTLIL::Sx)) {
|
||||||
module->connect(cell->getPort(ID(\\Y)), RTLIL::SigSpec(RTLIL::Sx, width));
|
module->connect(cell->getPort(ID(Y)), RTLIL::SigSpec(RTLIL::Sx, width));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,9 +339,9 @@ void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (summands.front().second)
|
if (summands.front().second)
|
||||||
module->addNeg(NEW_ID, summands.front().first, cell->getPort(ID(\\Y)));
|
module->addNeg(NEW_ID, summands.front().first, cell->getPort(ID(Y)));
|
||||||
else
|
else
|
||||||
module->connect(cell->getPort(ID(\\Y)), summands.front().first);
|
module->connect(cell->getPort(ID(Y)), summands.front().first);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -356,7 +356,7 @@ void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap)
|
||||||
for (auto &bit : macc.bit_ports)
|
for (auto &bit : macc.bit_ports)
|
||||||
worker.add(bit, 0);
|
worker.add(bit, 0);
|
||||||
|
|
||||||
module->connect(cell->getPort(ID(\\Y)), worker.synth());
|
module->connect(cell->getPort(ID(Y)), worker.synth());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,13 +116,13 @@ struct MuxcoverWorker
|
||||||
if (!cell->input(conn.first))
|
if (!cell->input(conn.first))
|
||||||
continue;
|
continue;
|
||||||
for (auto bit : sigmap(conn.second)) {
|
for (auto bit : sigmap(conn.second)) {
|
||||||
if (used_once.count(bit) || cell->type != ID($_MUX_) || conn.first == ID(\\S))
|
if (used_once.count(bit) || cell->type != ID($_MUX_) || conn.first == ID(S))
|
||||||
roots.insert(bit);
|
roots.insert(bit);
|
||||||
used_once.insert(bit);
|
used_once.insert(bit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cell->type == ID($_MUX_))
|
if (cell->type == ID($_MUX_))
|
||||||
sig_to_mux[sigmap(cell->getPort(ID(\\Y)))] = cell;
|
sig_to_mux[sigmap(cell->getPort(ID(Y)))] = cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
log(" Treeifying %d MUXes:\n", GetSize(sig_to_mux));
|
log(" Treeifying %d MUXes:\n", GetSize(sig_to_mux));
|
||||||
|
@ -141,8 +141,8 @@ struct MuxcoverWorker
|
||||||
if (sig_to_mux.count(bit) && (bit == rootsig || !roots.count(bit))) {
|
if (sig_to_mux.count(bit) && (bit == rootsig || !roots.count(bit))) {
|
||||||
Cell *c = sig_to_mux.at(bit);
|
Cell *c = sig_to_mux.at(bit);
|
||||||
tree.muxes[bit] = c;
|
tree.muxes[bit] = c;
|
||||||
wavefront.insert(sigmap(c->getPort(ID(\\A))));
|
wavefront.insert(sigmap(c->getPort(ID(A))));
|
||||||
wavefront.insert(sigmap(c->getPort(ID(\\B))));
|
wavefront.insert(sigmap(c->getPort(ID(B))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,68 +517,68 @@ struct MuxcoverWorker
|
||||||
if (GetSize(mux.inputs) == 2) {
|
if (GetSize(mux.inputs) == 2) {
|
||||||
count_muxes_by_type[0]++;
|
count_muxes_by_type[0]++;
|
||||||
Cell *cell = module->addCell(NEW_ID, ID($_MUX_));
|
Cell *cell = module->addCell(NEW_ID, ID($_MUX_));
|
||||||
cell->setPort(ID(\\A), mux.inputs[0]);
|
cell->setPort(ID(A), mux.inputs[0]);
|
||||||
cell->setPort(ID(\\B), mux.inputs[1]);
|
cell->setPort(ID(B), mux.inputs[1]);
|
||||||
cell->setPort(ID(\\S), mux.selects[0]);
|
cell->setPort(ID(S), mux.selects[0]);
|
||||||
cell->setPort(ID(\\Y), bit);
|
cell->setPort(ID(Y), bit);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetSize(mux.inputs) == 4) {
|
if (GetSize(mux.inputs) == 4) {
|
||||||
count_muxes_by_type[1]++;
|
count_muxes_by_type[1]++;
|
||||||
Cell *cell = module->addCell(NEW_ID, ID($_MUX4_));
|
Cell *cell = module->addCell(NEW_ID, ID($_MUX4_));
|
||||||
cell->setPort(ID(\\A), mux.inputs[0]);
|
cell->setPort(ID(A), mux.inputs[0]);
|
||||||
cell->setPort(ID(\\B), mux.inputs[1]);
|
cell->setPort(ID(B), mux.inputs[1]);
|
||||||
cell->setPort(ID(\\C), mux.inputs[2]);
|
cell->setPort(ID(C), mux.inputs[2]);
|
||||||
cell->setPort(ID(\\D), mux.inputs[3]);
|
cell->setPort(ID(D), mux.inputs[3]);
|
||||||
cell->setPort(ID(\\S), mux.selects[0]);
|
cell->setPort(ID(S), mux.selects[0]);
|
||||||
cell->setPort(ID(\\T), mux.selects[1]);
|
cell->setPort(ID(T), mux.selects[1]);
|
||||||
cell->setPort(ID(\\Y), bit);
|
cell->setPort(ID(Y), bit);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetSize(mux.inputs) == 8) {
|
if (GetSize(mux.inputs) == 8) {
|
||||||
count_muxes_by_type[2]++;
|
count_muxes_by_type[2]++;
|
||||||
Cell *cell = module->addCell(NEW_ID, ID($_MUX8_));
|
Cell *cell = module->addCell(NEW_ID, ID($_MUX8_));
|
||||||
cell->setPort(ID(\\A), mux.inputs[0]);
|
cell->setPort(ID(A), mux.inputs[0]);
|
||||||
cell->setPort(ID(\\B), mux.inputs[1]);
|
cell->setPort(ID(B), mux.inputs[1]);
|
||||||
cell->setPort(ID(\\C), mux.inputs[2]);
|
cell->setPort(ID(C), mux.inputs[2]);
|
||||||
cell->setPort(ID(\\D), mux.inputs[3]);
|
cell->setPort(ID(D), mux.inputs[3]);
|
||||||
cell->setPort(ID(\\E), mux.inputs[4]);
|
cell->setPort(ID(E), mux.inputs[4]);
|
||||||
cell->setPort(ID(\\F), mux.inputs[5]);
|
cell->setPort(ID(F), mux.inputs[5]);
|
||||||
cell->setPort(ID(\\G), mux.inputs[6]);
|
cell->setPort(ID(G), mux.inputs[6]);
|
||||||
cell->setPort(ID(\\H), mux.inputs[7]);
|
cell->setPort(ID(H), mux.inputs[7]);
|
||||||
cell->setPort(ID(\\S), mux.selects[0]);
|
cell->setPort(ID(S), mux.selects[0]);
|
||||||
cell->setPort(ID(\\T), mux.selects[1]);
|
cell->setPort(ID(T), mux.selects[1]);
|
||||||
cell->setPort(ID(\\U), mux.selects[2]);
|
cell->setPort(ID(U), mux.selects[2]);
|
||||||
cell->setPort(ID(\\Y), bit);
|
cell->setPort(ID(Y), bit);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetSize(mux.inputs) == 16) {
|
if (GetSize(mux.inputs) == 16) {
|
||||||
count_muxes_by_type[3]++;
|
count_muxes_by_type[3]++;
|
||||||
Cell *cell = module->addCell(NEW_ID, ID($_MUX16_));
|
Cell *cell = module->addCell(NEW_ID, ID($_MUX16_));
|
||||||
cell->setPort(ID(\\A), mux.inputs[0]);
|
cell->setPort(ID(A), mux.inputs[0]);
|
||||||
cell->setPort(ID(\\B), mux.inputs[1]);
|
cell->setPort(ID(B), mux.inputs[1]);
|
||||||
cell->setPort(ID(\\C), mux.inputs[2]);
|
cell->setPort(ID(C), mux.inputs[2]);
|
||||||
cell->setPort(ID(\\D), mux.inputs[3]);
|
cell->setPort(ID(D), mux.inputs[3]);
|
||||||
cell->setPort(ID(\\E), mux.inputs[4]);
|
cell->setPort(ID(E), mux.inputs[4]);
|
||||||
cell->setPort(ID(\\F), mux.inputs[5]);
|
cell->setPort(ID(F), mux.inputs[5]);
|
||||||
cell->setPort(ID(\\G), mux.inputs[6]);
|
cell->setPort(ID(G), mux.inputs[6]);
|
||||||
cell->setPort(ID(\\H), mux.inputs[7]);
|
cell->setPort(ID(H), mux.inputs[7]);
|
||||||
cell->setPort(ID(\\I), mux.inputs[8]);
|
cell->setPort(ID(I), mux.inputs[8]);
|
||||||
cell->setPort(ID(\\J), mux.inputs[9]);
|
cell->setPort(ID(J), mux.inputs[9]);
|
||||||
cell->setPort(ID(\\K), mux.inputs[10]);
|
cell->setPort(ID(K), mux.inputs[10]);
|
||||||
cell->setPort(ID(\\L), mux.inputs[11]);
|
cell->setPort(ID(L), mux.inputs[11]);
|
||||||
cell->setPort(ID(\\M), mux.inputs[12]);
|
cell->setPort(ID(M), mux.inputs[12]);
|
||||||
cell->setPort(ID(\\N), mux.inputs[13]);
|
cell->setPort(ID(N), mux.inputs[13]);
|
||||||
cell->setPort(ID(\\O), mux.inputs[14]);
|
cell->setPort(ID(O), mux.inputs[14]);
|
||||||
cell->setPort(ID(\\P), mux.inputs[15]);
|
cell->setPort(ID(P), mux.inputs[15]);
|
||||||
cell->setPort(ID(\\S), mux.selects[0]);
|
cell->setPort(ID(S), mux.selects[0]);
|
||||||
cell->setPort(ID(\\T), mux.selects[1]);
|
cell->setPort(ID(T), mux.selects[1]);
|
||||||
cell->setPort(ID(\\U), mux.selects[2]);
|
cell->setPort(ID(U), mux.selects[2]);
|
||||||
cell->setPort(ID(\\V), mux.selects[3]);
|
cell->setPort(ID(V), mux.selects[3]);
|
||||||
cell->setPort(ID(\\Y), bit);
|
cell->setPort(ID(Y), bit);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ struct NlutmapWorker
|
||||||
if (cell->type != ID($lut) || mapped_cells.count(cell))
|
if (cell->type != ID($lut) || mapped_cells.count(cell))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (GetSize(cell->getPort(ID(\\A))) == lut_size || lut_size == 2)
|
if (GetSize(cell->getPort(ID(A))) == lut_size || lut_size == 2)
|
||||||
candidate_ratings[cell] = 0;
|
candidate_ratings[cell] = 0;
|
||||||
|
|
||||||
for (auto &conn : cell->connections())
|
for (auto &conn : cell->connections())
|
||||||
|
|
|
@ -92,18 +92,18 @@ struct PmuxtreePass : public Pass {
|
||||||
if (cell->type != ID($pmux))
|
if (cell->type != ID($pmux))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SigSpec sig_data = cell->getPort(ID(\\B));
|
SigSpec sig_data = cell->getPort(ID(B));
|
||||||
SigSpec sig_sel = cell->getPort(ID(\\S));
|
SigSpec sig_sel = cell->getPort(ID(S));
|
||||||
|
|
||||||
if (!cell->getPort(ID(\\A)).is_fully_undef()) {
|
if (!cell->getPort(ID(A)).is_fully_undef()) {
|
||||||
sig_data.append(cell->getPort(ID(\\A)));
|
sig_data.append(cell->getPort(ID(A)));
|
||||||
SigSpec sig_sel_or = module->ReduceOr(NEW_ID, sig_sel);
|
SigSpec sig_sel_or = module->ReduceOr(NEW_ID, sig_sel);
|
||||||
sig_sel.append(module->Not(NEW_ID, sig_sel_or));
|
sig_sel.append(module->Not(NEW_ID, sig_sel_or));
|
||||||
}
|
}
|
||||||
|
|
||||||
SigSpec result, result_or;
|
SigSpec result, result_or;
|
||||||
result = recursive_mux_generator(module, sig_data, sig_sel, result_or);
|
result = recursive_mux_generator(module, sig_data, sig_sel, result_or);
|
||||||
module->connect(cell->getPort(ID(\\Y)), result);
|
module->connect(cell->getPort(ID(Y)), result);
|
||||||
module->remove(cell);
|
module->remove(cell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,22 +73,22 @@ struct ShregmapTechGreenpak4 : ShregmapTech
|
||||||
|
|
||||||
bool fixup(Cell *cell, dict<int, SigBit> &taps)
|
bool fixup(Cell *cell, dict<int, SigBit> &taps)
|
||||||
{
|
{
|
||||||
auto D = cell->getPort(ID(\\D));
|
auto D = cell->getPort(ID(D));
|
||||||
auto C = cell->getPort(ID(\\C));
|
auto C = cell->getPort(ID(C));
|
||||||
|
|
||||||
auto newcell = cell->module->addCell(NEW_ID, ID(\\GP_SHREG));
|
auto newcell = cell->module->addCell(NEW_ID, ID(GP_SHREG));
|
||||||
newcell->setPort(ID(\\nRST), State::S1);
|
newcell->setPort(ID(nRST), State::S1);
|
||||||
newcell->setPort(ID(\\CLK), C);
|
newcell->setPort(ID(CLK), C);
|
||||||
newcell->setPort(ID(\\IN), D);
|
newcell->setPort(ID(IN), D);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (auto tap : taps) {
|
for (auto tap : taps) {
|
||||||
newcell->setPort(i ? ID(\\OUTB) : ID(\\OUTA), tap.second);
|
newcell->setPort(i ? ID(OUTB) : ID(OUTA), tap.second);
|
||||||
newcell->setParam(i ? ID(\\OUTB_TAP) : ID(\\OUTA_TAP), tap.first + 1);
|
newcell->setParam(i ? ID(OUTB_TAP) : ID(OUTA_TAP), tap.first + 1);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
cell->setParam(ID(\\OUTA_INVERT), 0);
|
cell->setParam(ID(OUTA_INVERT), 0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -105,18 +105,18 @@ struct ShregmapTechXilinx7 : ShregmapTech
|
||||||
for (const auto &i : module->cells_) {
|
for (const auto &i : module->cells_) {
|
||||||
auto cell = i.second;
|
auto cell = i.second;
|
||||||
if (cell->type == ID($shiftx)) {
|
if (cell->type == ID($shiftx)) {
|
||||||
if (cell->getParam(ID(\\Y_WIDTH)) != 1) continue;
|
if (cell->getParam(ID(Y_WIDTH)) != 1) continue;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
for (auto bit : sigmap(cell->getPort(ID(\\A))))
|
for (auto bit : sigmap(cell->getPort(ID(A))))
|
||||||
sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, j++, 0);
|
sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, j++, 0);
|
||||||
log_assert(j == cell->getParam(ID(\\A_WIDTH)).as_int());
|
log_assert(j == cell->getParam(ID(A_WIDTH)).as_int());
|
||||||
}
|
}
|
||||||
else if (cell->type == ID($mux)) {
|
else if (cell->type == ID($mux)) {
|
||||||
int j = 0;
|
int j = 0;
|
||||||
for (auto bit : sigmap(cell->getPort(ID(\\A))))
|
for (auto bit : sigmap(cell->getPort(ID(A))))
|
||||||
sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, 0, j++);
|
sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, 0, j++);
|
||||||
j = 0;
|
j = 0;
|
||||||
for (auto bit : sigmap(cell->getPort(ID(\\B))))
|
for (auto bit : sigmap(cell->getPort(ID(B))))
|
||||||
sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, 1, j++);
|
sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, 1, j++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,9 +128,9 @@ struct ShregmapTechXilinx7 : ShregmapTech
|
||||||
if (it == sigbit_to_shiftx_offset.end())
|
if (it == sigbit_to_shiftx_offset.end())
|
||||||
return;
|
return;
|
||||||
if (cell) {
|
if (cell) {
|
||||||
if (cell->type == ID($shiftx) && port == ID(\\A))
|
if (cell->type == ID($shiftx) && port == ID(A))
|
||||||
return;
|
return;
|
||||||
if (cell->type == ID($mux) && port.in(ID(\\A), ID(\\B)))
|
if (cell->type == ID($mux) && port.in(ID(A), ID(B)))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sigbit_to_shiftx_offset.erase(it);
|
sigbit_to_shiftx_offset.erase(it);
|
||||||
|
@ -178,17 +178,17 @@ struct ShregmapTechXilinx7 : ShregmapTech
|
||||||
|
|
||||||
// Only map if $shiftx exclusively covers the shift register
|
// Only map if $shiftx exclusively covers the shift register
|
||||||
if (shiftx->type == ID($shiftx)) {
|
if (shiftx->type == ID($shiftx)) {
|
||||||
if (GetSize(taps) > shiftx->getParam(ID(\\A_WIDTH)).as_int())
|
if (GetSize(taps) > shiftx->getParam(ID(A_WIDTH)).as_int())
|
||||||
return false;
|
return false;
|
||||||
// Due to padding the most significant bits of A may be 1'bx,
|
// Due to padding the most significant bits of A may be 1'bx,
|
||||||
// and if so, discount them
|
// and if so, discount them
|
||||||
if (GetSize(taps) < shiftx->getParam(ID(\\A_WIDTH)).as_int()) {
|
if (GetSize(taps) < shiftx->getParam(ID(A_WIDTH)).as_int()) {
|
||||||
const SigSpec A = shiftx->getPort(ID(\\A));
|
const SigSpec A = shiftx->getPort(ID(A));
|
||||||
const int A_width = shiftx->getParam(ID(\\A_WIDTH)).as_int();
|
const int A_width = shiftx->getParam(ID(A_WIDTH)).as_int();
|
||||||
for (int i = GetSize(taps); i < A_width; ++i)
|
for (int i = GetSize(taps); i < A_width; ++i)
|
||||||
if (A[i] != RTLIL::Sx) return false;
|
if (A[i] != RTLIL::Sx) return false;
|
||||||
}
|
}
|
||||||
else if (GetSize(taps) != shiftx->getParam(ID(\\A_WIDTH)).as_int())
|
else if (GetSize(taps) != shiftx->getParam(ID(A_WIDTH)).as_int())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (shiftx->type == ID($mux)) {
|
else if (shiftx->type == ID($mux)) {
|
||||||
|
@ -210,32 +210,32 @@ struct ShregmapTechXilinx7 : ShregmapTech
|
||||||
|
|
||||||
auto newcell = cell->module->addCell(NEW_ID, ID($__XILINX_SHREG_));
|
auto newcell = cell->module->addCell(NEW_ID, ID($__XILINX_SHREG_));
|
||||||
newcell->set_src_attribute(cell->get_src_attribute());
|
newcell->set_src_attribute(cell->get_src_attribute());
|
||||||
newcell->setParam(ID(\\DEPTH), cell->getParam(ID(\\DEPTH)));
|
newcell->setParam(ID(DEPTH), cell->getParam(ID(DEPTH)));
|
||||||
newcell->setParam(ID(\\INIT), cell->getParam(ID(\\INIT)));
|
newcell->setParam(ID(INIT), cell->getParam(ID(INIT)));
|
||||||
newcell->setParam(ID(\\CLKPOL), cell->getParam(ID(\\CLKPOL)));
|
newcell->setParam(ID(CLKPOL), cell->getParam(ID(CLKPOL)));
|
||||||
newcell->setParam(ID(\\ENPOL), cell->getParam(ID(\\ENPOL)));
|
newcell->setParam(ID(ENPOL), cell->getParam(ID(ENPOL)));
|
||||||
|
|
||||||
newcell->setPort(ID(\\C), cell->getPort(ID(\\C)));
|
newcell->setPort(ID(C), cell->getPort(ID(C)));
|
||||||
newcell->setPort(ID(\\D), cell->getPort(ID(\\D)));
|
newcell->setPort(ID(D), cell->getPort(ID(D)));
|
||||||
if (cell->hasPort(ID(\\E)))
|
if (cell->hasPort(ID(E)))
|
||||||
newcell->setPort(ID(\\E), cell->getPort(ID(\\E)));
|
newcell->setPort(ID(E), cell->getPort(ID(E)));
|
||||||
|
|
||||||
Cell* shiftx = std::get<0>(it->second);
|
Cell* shiftx = std::get<0>(it->second);
|
||||||
RTLIL::SigSpec l_wire, q_wire;
|
RTLIL::SigSpec l_wire, q_wire;
|
||||||
if (shiftx->type == ID($shiftx)) {
|
if (shiftx->type == ID($shiftx)) {
|
||||||
l_wire = shiftx->getPort(ID(\\B));
|
l_wire = shiftx->getPort(ID(B));
|
||||||
q_wire = shiftx->getPort(ID(\\Y));
|
q_wire = shiftx->getPort(ID(Y));
|
||||||
shiftx->setPort(ID(\\Y), cell->module->addWire(NEW_ID));
|
shiftx->setPort(ID(Y), cell->module->addWire(NEW_ID));
|
||||||
}
|
}
|
||||||
else if (shiftx->type == ID($mux)) {
|
else if (shiftx->type == ID($mux)) {
|
||||||
l_wire = shiftx->getPort(ID(\\S));
|
l_wire = shiftx->getPort(ID(S));
|
||||||
q_wire = shiftx->getPort(ID(\\Y));
|
q_wire = shiftx->getPort(ID(Y));
|
||||||
shiftx->setPort(ID(\\Y), cell->module->addWire(NEW_ID));
|
shiftx->setPort(ID(Y), cell->module->addWire(NEW_ID));
|
||||||
}
|
}
|
||||||
else log_abort();
|
else log_abort();
|
||||||
|
|
||||||
newcell->setPort(ID(\\Q), q_wire);
|
newcell->setPort(ID(Q), q_wire);
|
||||||
newcell->setPort(ID(\\L), l_wire);
|
newcell->setPort(ID(L), l_wire);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -263,16 +263,16 @@ struct ShregmapWorker
|
||||||
{
|
{
|
||||||
for (auto wire : module->wires())
|
for (auto wire : module->wires())
|
||||||
{
|
{
|
||||||
if (wire->port_output || wire->get_bool_attribute(ID(\\keep))) {
|
if (wire->port_output || wire->get_bool_attribute(ID(keep))) {
|
||||||
for (auto bit : sigmap(wire)) {
|
for (auto bit : sigmap(wire)) {
|
||||||
sigbit_with_non_chain_users.insert(bit);
|
sigbit_with_non_chain_users.insert(bit);
|
||||||
if (opts.tech) opts.tech->non_chain_user(bit, nullptr, {});
|
if (opts.tech) opts.tech->non_chain_user(bit, nullptr, {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wire->attributes.count(ID(\\init))) {
|
if (wire->attributes.count(ID(init))) {
|
||||||
SigSpec initsig = sigmap(wire);
|
SigSpec initsig = sigmap(wire);
|
||||||
Const initval = wire->attributes.at(ID(\\init));
|
Const initval = wire->attributes.at(ID(init));
|
||||||
for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++)
|
for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++)
|
||||||
if (initval[i] == State::S0 && !opts.zinit)
|
if (initval[i] == State::S0 && !opts.zinit)
|
||||||
sigbit_init[initsig[i]] = false;
|
sigbit_init[initsig[i]] = false;
|
||||||
|
@ -283,7 +283,7 @@ struct ShregmapWorker
|
||||||
|
|
||||||
for (auto cell : module->cells())
|
for (auto cell : module->cells())
|
||||||
{
|
{
|
||||||
if (opts.ffcells.count(cell->type) && !cell->get_bool_attribute(ID(\\keep)))
|
if (opts.ffcells.count(cell->type) && !cell->get_bool_attribute(ID(keep)))
|
||||||
{
|
{
|
||||||
IdString d_port = opts.ffcells.at(cell->type).first;
|
IdString d_port = opts.ffcells.at(cell->type).first;
|
||||||
IdString q_port = opts.ffcells.at(cell->type).second;
|
IdString q_port = opts.ffcells.at(cell->type).second;
|
||||||
|
@ -474,7 +474,7 @@ struct ShregmapWorker
|
||||||
initval.push_back(State::S0);
|
initval.push_back(State::S0);
|
||||||
remove_init.insert(bit);
|
remove_init.insert(bit);
|
||||||
}
|
}
|
||||||
first_cell->setParam(ID(\\INIT), initval);
|
first_cell->setParam(ID(INIT), initval);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.zinit)
|
if (opts.zinit)
|
||||||
|
@ -497,13 +497,13 @@ struct ShregmapWorker
|
||||||
if (first_cell->type == ID($_DFFE_PP_)) param_clkpol = 1, param_enpol = 1;
|
if (first_cell->type == ID($_DFFE_PP_)) param_clkpol = 1, param_enpol = 1;
|
||||||
|
|
||||||
log_assert(param_clkpol >= 0);
|
log_assert(param_clkpol >= 0);
|
||||||
first_cell->setParam(ID(\\CLKPOL), param_clkpol);
|
first_cell->setParam(ID(CLKPOL), param_clkpol);
|
||||||
if (opts.ffe) first_cell->setParam(ID(\\ENPOL), param_enpol);
|
if (opts.ffe) first_cell->setParam(ID(ENPOL), param_enpol);
|
||||||
}
|
}
|
||||||
|
|
||||||
first_cell->type = shreg_cell_type_str;
|
first_cell->type = shreg_cell_type_str;
|
||||||
first_cell->setPort(q_port, last_cell->getPort(q_port));
|
first_cell->setPort(q_port, last_cell->getPort(q_port));
|
||||||
first_cell->setParam(ID(\\DEPTH), depth);
|
first_cell->setParam(ID(DEPTH), depth);
|
||||||
|
|
||||||
if (opts.tech != nullptr && !opts.tech->fixup(first_cell, taps_dict))
|
if (opts.tech != nullptr && !opts.tech->fixup(first_cell, taps_dict))
|
||||||
remove_cells.insert(first_cell);
|
remove_cells.insert(first_cell);
|
||||||
|
@ -521,18 +521,18 @@ struct ShregmapWorker
|
||||||
|
|
||||||
for (auto wire : module->wires())
|
for (auto wire : module->wires())
|
||||||
{
|
{
|
||||||
if (wire->attributes.count(ID(\\init)) == 0)
|
if (wire->attributes.count(ID(init)) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SigSpec initsig = sigmap(wire);
|
SigSpec initsig = sigmap(wire);
|
||||||
Const &initval = wire->attributes.at(ID(\\init));
|
Const &initval = wire->attributes.at(ID(init));
|
||||||
|
|
||||||
for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++)
|
for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++)
|
||||||
if (remove_init.count(initsig[i]))
|
if (remove_init.count(initsig[i]))
|
||||||
initval[i] = State::Sx;
|
initval[i] = State::Sx;
|
||||||
|
|
||||||
if (SigSpec(initval).is_fully_undef())
|
if (SigSpec(initval).is_fully_undef())
|
||||||
wire->attributes.erase(ID(\\init));
|
wire->attributes.erase(ID(init));
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_cells.clear();
|
remove_cells.clear();
|
||||||
|
@ -717,19 +717,19 @@ struct ShregmapPass : public Pass {
|
||||||
bool en_neg = enpol == "neg" || enpol == "any" || enpol == "any_or_none";
|
bool en_neg = enpol == "neg" || enpol == "any" || enpol == "any_or_none";
|
||||||
|
|
||||||
if (clk_pos && en_none)
|
if (clk_pos && en_none)
|
||||||
opts.ffcells[ID($_DFF_P_)] = make_pair(IdString(ID(\\D)), IdString(ID(\\Q)));
|
opts.ffcells[ID($_DFF_P_)] = make_pair(IdString(ID(D)), IdString(ID(Q)));
|
||||||
if (clk_neg && en_none)
|
if (clk_neg && en_none)
|
||||||
opts.ffcells[ID($_DFF_N_)] = make_pair(IdString(ID(\\D)), IdString(ID(\\Q)));
|
opts.ffcells[ID($_DFF_N_)] = make_pair(IdString(ID(D)), IdString(ID(Q)));
|
||||||
|
|
||||||
if (clk_pos && en_pos)
|
if (clk_pos && en_pos)
|
||||||
opts.ffcells[ID($_DFFE_PP_)] = make_pair(IdString(ID(\\D)), IdString(ID(\\Q)));
|
opts.ffcells[ID($_DFFE_PP_)] = make_pair(IdString(ID(D)), IdString(ID(Q)));
|
||||||
if (clk_pos && en_neg)
|
if (clk_pos && en_neg)
|
||||||
opts.ffcells[ID($_DFFE_PN_)] = make_pair(IdString(ID(\\D)), IdString(ID(\\Q)));
|
opts.ffcells[ID($_DFFE_PN_)] = make_pair(IdString(ID(D)), IdString(ID(Q)));
|
||||||
|
|
||||||
if (clk_neg && en_pos)
|
if (clk_neg && en_pos)
|
||||||
opts.ffcells[ID($_DFFE_NP_)] = make_pair(IdString(ID(\\D)), IdString(ID(\\Q)));
|
opts.ffcells[ID($_DFFE_NP_)] = make_pair(IdString(ID(D)), IdString(ID(Q)));
|
||||||
if (clk_neg && en_neg)
|
if (clk_neg && en_neg)
|
||||||
opts.ffcells[ID($_DFFE_NN_)] = make_pair(IdString(ID(\\D)), IdString(ID(\\Q)));
|
opts.ffcells[ID($_DFFE_NN_)] = make_pair(IdString(ID(D)), IdString(ID(Q)));
|
||||||
|
|
||||||
if (en_pos || en_neg)
|
if (en_pos || en_neg)
|
||||||
opts.ffe = true;
|
opts.ffe = true;
|
||||||
|
|
|
@ -28,37 +28,37 @@ YOSYS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec sig_a = cell->getPort(ID(\\A));
|
RTLIL::SigSpec sig_a = cell->getPort(ID(A));
|
||||||
RTLIL::SigSpec sig_y = cell->getPort(ID(\\Y));
|
RTLIL::SigSpec sig_y = cell->getPort(ID(Y));
|
||||||
|
|
||||||
sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID(\\A_SIGNED)).as_bool());
|
sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID(A_SIGNED)).as_bool());
|
||||||
|
|
||||||
for (int i = 0; i < GetSize(sig_y); i++) {
|
for (int i = 0; i < GetSize(sig_y); i++) {
|
||||||
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
|
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
|
||||||
gate->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
gate->setPort(ID(\\A), sig_a[i]);
|
gate->setPort(ID(A), sig_a[i]);
|
||||||
gate->setPort(ID(\\Y), sig_y[i]);
|
gate->setPort(ID(Y), sig_y[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplemap_pos(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_pos(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec sig_a = cell->getPort(ID(\\A));
|
RTLIL::SigSpec sig_a = cell->getPort(ID(A));
|
||||||
RTLIL::SigSpec sig_y = cell->getPort(ID(\\Y));
|
RTLIL::SigSpec sig_y = cell->getPort(ID(Y));
|
||||||
|
|
||||||
sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID(\\A_SIGNED)).as_bool());
|
sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID(A_SIGNED)).as_bool());
|
||||||
|
|
||||||
module->connect(RTLIL::SigSig(sig_y, sig_a));
|
module->connect(RTLIL::SigSig(sig_y, sig_a));
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec sig_a = cell->getPort(ID(\\A));
|
RTLIL::SigSpec sig_a = cell->getPort(ID(A));
|
||||||
RTLIL::SigSpec sig_b = cell->getPort(ID(\\B));
|
RTLIL::SigSpec sig_b = cell->getPort(ID(B));
|
||||||
RTLIL::SigSpec sig_y = cell->getPort(ID(\\Y));
|
RTLIL::SigSpec sig_y = cell->getPort(ID(Y));
|
||||||
|
|
||||||
sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID(\\A_SIGNED)).as_bool());
|
sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID(A_SIGNED)).as_bool());
|
||||||
sig_b.extend_u0(GetSize(sig_y), cell->parameters.at(ID(\\B_SIGNED)).as_bool());
|
sig_b.extend_u0(GetSize(sig_y), cell->parameters.at(ID(B_SIGNED)).as_bool());
|
||||||
|
|
||||||
if (cell->type == ID($xnor))
|
if (cell->type == ID($xnor))
|
||||||
{
|
{
|
||||||
|
@ -66,9 +66,9 @@ void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
|
|
||||||
for (int i = 0; i < GetSize(sig_y); i++) {
|
for (int i = 0; i < GetSize(sig_y); i++) {
|
||||||
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
|
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
|
||||||
gate->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
gate->setPort(ID(\\A), sig_t[i]);
|
gate->setPort(ID(A), sig_t[i]);
|
||||||
gate->setPort(ID(\\Y), sig_y[i]);
|
gate->setPort(ID(Y), sig_y[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
sig_y = sig_t;
|
sig_y = sig_t;
|
||||||
|
@ -83,17 +83,17 @@ void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
|
|
||||||
for (int i = 0; i < GetSize(sig_y); i++) {
|
for (int i = 0; i < GetSize(sig_y); i++) {
|
||||||
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
||||||
gate->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
gate->setPort(ID(\\A), sig_a[i]);
|
gate->setPort(ID(A), sig_a[i]);
|
||||||
gate->setPort(ID(\\B), sig_b[i]);
|
gate->setPort(ID(B), sig_b[i]);
|
||||||
gate->setPort(ID(\\Y), sig_y[i]);
|
gate->setPort(ID(Y), sig_y[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec sig_a = cell->getPort(ID(\\A));
|
RTLIL::SigSpec sig_a = cell->getPort(ID(A));
|
||||||
RTLIL::SigSpec sig_y = cell->getPort(ID(\\Y));
|
RTLIL::SigSpec sig_y = cell->getPort(ID(Y));
|
||||||
|
|
||||||
if (sig_y.size() == 0)
|
if (sig_y.size() == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -134,10 +134,10 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
||||||
gate->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
gate->setPort(ID(\\A), sig_a[i]);
|
gate->setPort(ID(A), sig_a[i]);
|
||||||
gate->setPort(ID(\\B), sig_a[i+1]);
|
gate->setPort(ID(B), sig_a[i+1]);
|
||||||
gate->setPort(ID(\\Y), sig_t[i/2]);
|
gate->setPort(ID(Y), sig_t[i/2]);
|
||||||
last_output_cell = gate;
|
last_output_cell = gate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,9 +147,9 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
if (cell->type == ID($reduce_xnor)) {
|
if (cell->type == ID($reduce_xnor)) {
|
||||||
RTLIL::SigSpec sig_t = module->addWire(NEW_ID);
|
RTLIL::SigSpec sig_t = module->addWire(NEW_ID);
|
||||||
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
|
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
|
||||||
gate->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
gate->setPort(ID(\\A), sig_a);
|
gate->setPort(ID(A), sig_a);
|
||||||
gate->setPort(ID(\\Y), sig_t);
|
gate->setPort(ID(Y), sig_t);
|
||||||
last_output_cell = gate;
|
last_output_cell = gate;
|
||||||
sig_a = sig_t;
|
sig_a = sig_t;
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,7 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
if (last_output_cell == NULL) {
|
if (last_output_cell == NULL) {
|
||||||
module->connect(RTLIL::SigSig(sig_y, sig_a));
|
module->connect(RTLIL::SigSig(sig_y, sig_a));
|
||||||
} else {
|
} else {
|
||||||
last_output_cell->setPort(ID(\\Y), sig_y);
|
last_output_cell->setPort(ID(Y), sig_y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,10 +175,10 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLIL::Cell
|
||||||
}
|
}
|
||||||
|
|
||||||
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_OR_));
|
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_OR_));
|
||||||
gate->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
gate->setPort(ID(\\A), sig[i]);
|
gate->setPort(ID(A), sig[i]);
|
||||||
gate->setPort(ID(\\B), sig[i+1]);
|
gate->setPort(ID(B), sig[i+1]);
|
||||||
gate->setPort(ID(\\Y), sig_t[i/2]);
|
gate->setPort(ID(Y), sig_t[i/2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
sig = sig_t;
|
sig = sig_t;
|
||||||
|
@ -190,10 +190,10 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLIL::Cell
|
||||||
|
|
||||||
void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec sig_a = cell->getPort(ID(\\A));
|
RTLIL::SigSpec sig_a = cell->getPort(ID(A));
|
||||||
logic_reduce(module, sig_a, cell);
|
logic_reduce(module, sig_a, cell);
|
||||||
|
|
||||||
RTLIL::SigSpec sig_y = cell->getPort(ID(\\Y));
|
RTLIL::SigSpec sig_y = cell->getPort(ID(Y));
|
||||||
|
|
||||||
if (sig_y.size() == 0)
|
if (sig_y.size() == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -204,20 +204,20 @@ void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
|
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
|
||||||
gate->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
gate->setPort(ID(\\A), sig_a);
|
gate->setPort(ID(A), sig_a);
|
||||||
gate->setPort(ID(\\Y), sig_y);
|
gate->setPort(ID(Y), sig_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec sig_a = cell->getPort(ID(\\A));
|
RTLIL::SigSpec sig_a = cell->getPort(ID(A));
|
||||||
logic_reduce(module, sig_a, cell);
|
logic_reduce(module, sig_a, cell);
|
||||||
|
|
||||||
RTLIL::SigSpec sig_b = cell->getPort(ID(\\B));
|
RTLIL::SigSpec sig_b = cell->getPort(ID(B));
|
||||||
logic_reduce(module, sig_b, cell);
|
logic_reduce(module, sig_b, cell);
|
||||||
|
|
||||||
RTLIL::SigSpec sig_y = cell->getPort(ID(\\Y));
|
RTLIL::SigSpec sig_y = cell->getPort(ID(Y));
|
||||||
|
|
||||||
if (sig_y.size() == 0)
|
if (sig_y.size() == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -233,35 +233,35 @@ void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
log_assert(!gate_type.empty());
|
log_assert(!gate_type.empty());
|
||||||
|
|
||||||
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
||||||
gate->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
gate->setPort(ID(\\A), sig_a);
|
gate->setPort(ID(A), sig_a);
|
||||||
gate->setPort(ID(\\B), sig_b);
|
gate->setPort(ID(B), sig_b);
|
||||||
gate->setPort(ID(\\Y), sig_y);
|
gate->setPort(ID(Y), sig_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplemap_eqne(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_eqne(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec sig_a = cell->getPort(ID(\\A));
|
RTLIL::SigSpec sig_a = cell->getPort(ID(A));
|
||||||
RTLIL::SigSpec sig_b = cell->getPort(ID(\\B));
|
RTLIL::SigSpec sig_b = cell->getPort(ID(B));
|
||||||
RTLIL::SigSpec sig_y = cell->getPort(ID(\\Y));
|
RTLIL::SigSpec sig_y = cell->getPort(ID(Y));
|
||||||
bool is_signed = cell->parameters.at(ID(\\A_SIGNED)).as_bool();
|
bool is_signed = cell->parameters.at(ID(A_SIGNED)).as_bool();
|
||||||
bool is_ne = cell->type.in(ID($ne), ID($nex));
|
bool is_ne = cell->type.in(ID($ne), ID($nex));
|
||||||
|
|
||||||
RTLIL::SigSpec xor_out = module->addWire(NEW_ID, max(GetSize(sig_a), GetSize(sig_b)));
|
RTLIL::SigSpec xor_out = module->addWire(NEW_ID, max(GetSize(sig_a), GetSize(sig_b)));
|
||||||
RTLIL::Cell *xor_cell = module->addXor(NEW_ID, sig_a, sig_b, xor_out, is_signed);
|
RTLIL::Cell *xor_cell = module->addXor(NEW_ID, sig_a, sig_b, xor_out, is_signed);
|
||||||
xor_cell->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
xor_cell->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
simplemap_bitop(module, xor_cell);
|
simplemap_bitop(module, xor_cell);
|
||||||
module->remove(xor_cell);
|
module->remove(xor_cell);
|
||||||
|
|
||||||
RTLIL::SigSpec reduce_out = is_ne ? sig_y : module->addWire(NEW_ID);
|
RTLIL::SigSpec reduce_out = is_ne ? sig_y : module->addWire(NEW_ID);
|
||||||
RTLIL::Cell *reduce_cell = module->addReduceOr(NEW_ID, xor_out, reduce_out);
|
RTLIL::Cell *reduce_cell = module->addReduceOr(NEW_ID, xor_out, reduce_out);
|
||||||
reduce_cell->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
reduce_cell->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
simplemap_reduce(module, reduce_cell);
|
simplemap_reduce(module, reduce_cell);
|
||||||
module->remove(reduce_cell);
|
module->remove(reduce_cell);
|
||||||
|
|
||||||
if (!is_ne) {
|
if (!is_ne) {
|
||||||
RTLIL::Cell *not_cell = module->addLogicNot(NEW_ID, reduce_out, sig_y);
|
RTLIL::Cell *not_cell = module->addLogicNot(NEW_ID, reduce_out, sig_y);
|
||||||
not_cell->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
not_cell->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
simplemap_lognot(module, not_cell);
|
simplemap_lognot(module, not_cell);
|
||||||
module->remove(not_cell);
|
module->remove(not_cell);
|
||||||
}
|
}
|
||||||
|
@ -269,65 +269,65 @@ void simplemap_eqne(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
|
|
||||||
void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec sig_a = cell->getPort(ID(\\A));
|
RTLIL::SigSpec sig_a = cell->getPort(ID(A));
|
||||||
RTLIL::SigSpec sig_b = cell->getPort(ID(\\B));
|
RTLIL::SigSpec sig_b = cell->getPort(ID(B));
|
||||||
RTLIL::SigSpec sig_y = cell->getPort(ID(\\Y));
|
RTLIL::SigSpec sig_y = cell->getPort(ID(Y));
|
||||||
|
|
||||||
for (int i = 0; i < GetSize(sig_y); i++) {
|
for (int i = 0; i < GetSize(sig_y); i++) {
|
||||||
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_));
|
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_));
|
||||||
gate->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
gate->setPort(ID(\\A), sig_a[i]);
|
gate->setPort(ID(A), sig_a[i]);
|
||||||
gate->setPort(ID(\\B), sig_b[i]);
|
gate->setPort(ID(B), sig_b[i]);
|
||||||
gate->setPort(ID(\\S), cell->getPort(ID(\\S)));
|
gate->setPort(ID(S), cell->getPort(ID(S)));
|
||||||
gate->setPort(ID(\\Y), sig_y[i]);
|
gate->setPort(ID(Y), sig_y[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplemap_tribuf(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_tribuf(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec sig_a = cell->getPort(ID(\\A));
|
RTLIL::SigSpec sig_a = cell->getPort(ID(A));
|
||||||
RTLIL::SigSpec sig_e = cell->getPort(ID(\\EN));
|
RTLIL::SigSpec sig_e = cell->getPort(ID(EN));
|
||||||
RTLIL::SigSpec sig_y = cell->getPort(ID(\\Y));
|
RTLIL::SigSpec sig_y = cell->getPort(ID(Y));
|
||||||
|
|
||||||
for (int i = 0; i < GetSize(sig_y); i++) {
|
for (int i = 0; i < GetSize(sig_y); i++) {
|
||||||
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_TBUF_));
|
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_TBUF_));
|
||||||
gate->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
gate->setPort(ID(\\A), sig_a[i]);
|
gate->setPort(ID(A), sig_a[i]);
|
||||||
gate->setPort(ID(\\E), sig_e);
|
gate->setPort(ID(E), sig_e);
|
||||||
gate->setPort(ID(\\Y), sig_y[i]);
|
gate->setPort(ID(Y), sig_y[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
SigSpec lut_ctrl = cell->getPort(ID(\\A));
|
SigSpec lut_ctrl = cell->getPort(ID(A));
|
||||||
SigSpec lut_data = cell->getParam(ID(\\LUT));
|
SigSpec lut_data = cell->getParam(ID(LUT));
|
||||||
lut_data.extend_u0(1 << cell->getParam(ID(\\WIDTH)).as_int());
|
lut_data.extend_u0(1 << cell->getParam(ID(WIDTH)).as_int());
|
||||||
|
|
||||||
for (int idx = 0; GetSize(lut_data) > 1; idx++) {
|
for (int idx = 0; GetSize(lut_data) > 1; idx++) {
|
||||||
SigSpec sig_s = lut_ctrl[idx];
|
SigSpec sig_s = lut_ctrl[idx];
|
||||||
SigSpec new_lut_data = module->addWire(NEW_ID, GetSize(lut_data)/2);
|
SigSpec new_lut_data = module->addWire(NEW_ID, GetSize(lut_data)/2);
|
||||||
for (int i = 0; i < GetSize(lut_data); i += 2) {
|
for (int i = 0; i < GetSize(lut_data); i += 2) {
|
||||||
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_));
|
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_));
|
||||||
gate->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
gate->setPort(ID(\\A), lut_data[i]);
|
gate->setPort(ID(A), lut_data[i]);
|
||||||
gate->setPort(ID(\\B), lut_data[i+1]);
|
gate->setPort(ID(B), lut_data[i+1]);
|
||||||
gate->setPort(ID(\\S), lut_ctrl[idx]);
|
gate->setPort(ID(S), lut_ctrl[idx]);
|
||||||
gate->setPort(ID(\\Y), new_lut_data[i/2]);
|
gate->setPort(ID(Y), new_lut_data[i/2]);
|
||||||
}
|
}
|
||||||
lut_data = new_lut_data;
|
lut_data = new_lut_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
module->connect(cell->getPort(ID(\\Y)), lut_data);
|
module->connect(cell->getPort(ID(Y)), lut_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplemap_sop(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_sop(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
SigSpec ctrl = cell->getPort(ID(\\A));
|
SigSpec ctrl = cell->getPort(ID(A));
|
||||||
SigSpec table = cell->getParam(ID(\\TABLE));
|
SigSpec table = cell->getParam(ID(TABLE));
|
||||||
|
|
||||||
int width = cell->getParam(ID(\\WIDTH)).as_int();
|
int width = cell->getParam(ID(WIDTH)).as_int();
|
||||||
int depth = cell->getParam(ID(\\DEPTH)).as_int();
|
int depth = cell->getParam(ID(DEPTH)).as_int();
|
||||||
table.extend_u0(2 * width * depth);
|
table.extend_u0(2 * width * depth);
|
||||||
|
|
||||||
SigSpec products;
|
SigSpec products;
|
||||||
|
@ -348,177 +348,177 @@ void simplemap_sop(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
products.append(GetSize(in) > 0 ? module->Eq(NEW_ID, in, pat) : State::S1);
|
products.append(GetSize(in) > 0 ? module->Eq(NEW_ID, in, pat) : State::S1);
|
||||||
}
|
}
|
||||||
|
|
||||||
module->connect(cell->getPort(ID(\\Y)), module->ReduceOr(NEW_ID, products));
|
module->connect(cell->getPort(ID(Y)), module->ReduceOr(NEW_ID, products));
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
int offset = cell->parameters.at(ID(\\OFFSET)).as_int();
|
int offset = cell->parameters.at(ID(OFFSET)).as_int();
|
||||||
RTLIL::SigSpec sig_a = cell->getPort(ID(\\A));
|
RTLIL::SigSpec sig_a = cell->getPort(ID(A));
|
||||||
RTLIL::SigSpec sig_y = cell->getPort(ID(\\Y));
|
RTLIL::SigSpec sig_y = cell->getPort(ID(Y));
|
||||||
module->connect(RTLIL::SigSig(sig_y, sig_a.extract(offset, sig_y.size())));
|
module->connect(RTLIL::SigSig(sig_y, sig_a.extract(offset, sig_y.size())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec sig_ab = cell->getPort(ID(\\A));
|
RTLIL::SigSpec sig_ab = cell->getPort(ID(A));
|
||||||
sig_ab.append(cell->getPort(ID(\\B)));
|
sig_ab.append(cell->getPort(ID(B)));
|
||||||
RTLIL::SigSpec sig_y = cell->getPort(ID(\\Y));
|
RTLIL::SigSpec sig_y = cell->getPort(ID(Y));
|
||||||
module->connect(RTLIL::SigSig(sig_y, sig_ab));
|
module->connect(RTLIL::SigSig(sig_y, sig_ab));
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
int width = cell->parameters.at(ID(\\WIDTH)).as_int();
|
int width = cell->parameters.at(ID(WIDTH)).as_int();
|
||||||
char set_pol = cell->parameters.at(ID(\\SET_POLARITY)).as_bool() ? 'P' : 'N';
|
char set_pol = cell->parameters.at(ID(SET_POLARITY)).as_bool() ? 'P' : 'N';
|
||||||
char clr_pol = cell->parameters.at(ID(\\CLR_POLARITY)).as_bool() ? 'P' : 'N';
|
char clr_pol = cell->parameters.at(ID(CLR_POLARITY)).as_bool() ? 'P' : 'N';
|
||||||
|
|
||||||
RTLIL::SigSpec sig_s = cell->getPort(ID(\\SET));
|
RTLIL::SigSpec sig_s = cell->getPort(ID(SET));
|
||||||
RTLIL::SigSpec sig_r = cell->getPort(ID(\\CLR));
|
RTLIL::SigSpec sig_r = cell->getPort(ID(CLR));
|
||||||
RTLIL::SigSpec sig_q = cell->getPort(ID(\\Q));
|
RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
|
||||||
|
|
||||||
std::string gate_type = stringf("$_SR_%c%c_", set_pol, clr_pol);
|
std::string gate_type = stringf("$_SR_%c%c_", set_pol, clr_pol);
|
||||||
|
|
||||||
for (int i = 0; i < width; i++) {
|
for (int i = 0; i < width; i++) {
|
||||||
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
||||||
gate->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
gate->setPort(ID(\\S), sig_s[i]);
|
gate->setPort(ID(S), sig_s[i]);
|
||||||
gate->setPort(ID(\\R), sig_r[i]);
|
gate->setPort(ID(R), sig_r[i]);
|
||||||
gate->setPort(ID(\\Q), sig_q[i]);
|
gate->setPort(ID(Q), sig_q[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplemap_ff(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_ff(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
int width = cell->parameters.at(ID(\\WIDTH)).as_int();
|
int width = cell->parameters.at(ID(WIDTH)).as_int();
|
||||||
|
|
||||||
RTLIL::SigSpec sig_d = cell->getPort(ID(\\D));
|
RTLIL::SigSpec sig_d = cell->getPort(ID(D));
|
||||||
RTLIL::SigSpec sig_q = cell->getPort(ID(\\Q));
|
RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
|
||||||
|
|
||||||
IdString gate_type = ID($_FF_);
|
IdString gate_type = ID($_FF_);
|
||||||
|
|
||||||
for (int i = 0; i < width; i++) {
|
for (int i = 0; i < width; i++) {
|
||||||
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
||||||
gate->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
gate->setPort(ID(\\D), sig_d[i]);
|
gate->setPort(ID(D), sig_d[i]);
|
||||||
gate->setPort(ID(\\Q), sig_q[i]);
|
gate->setPort(ID(Q), sig_q[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
int width = cell->parameters.at(ID(\\WIDTH)).as_int();
|
int width = cell->parameters.at(ID(WIDTH)).as_int();
|
||||||
char clk_pol = cell->parameters.at(ID(\\CLK_POLARITY)).as_bool() ? 'P' : 'N';
|
char clk_pol = cell->parameters.at(ID(CLK_POLARITY)).as_bool() ? 'P' : 'N';
|
||||||
|
|
||||||
RTLIL::SigSpec sig_clk = cell->getPort(ID(\\CLK));
|
RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK));
|
||||||
RTLIL::SigSpec sig_d = cell->getPort(ID(\\D));
|
RTLIL::SigSpec sig_d = cell->getPort(ID(D));
|
||||||
RTLIL::SigSpec sig_q = cell->getPort(ID(\\Q));
|
RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
|
||||||
|
|
||||||
IdString gate_type = stringf("$_DFF_%c_", clk_pol);
|
IdString gate_type = stringf("$_DFF_%c_", clk_pol);
|
||||||
|
|
||||||
for (int i = 0; i < width; i++) {
|
for (int i = 0; i < width; i++) {
|
||||||
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
||||||
gate->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
gate->setPort(ID(\\C), sig_clk);
|
gate->setPort(ID(C), sig_clk);
|
||||||
gate->setPort(ID(\\D), sig_d[i]);
|
gate->setPort(ID(D), sig_d[i]);
|
||||||
gate->setPort(ID(\\Q), sig_q[i]);
|
gate->setPort(ID(Q), sig_q[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplemap_dffe(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_dffe(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
int width = cell->parameters.at(ID(\\WIDTH)).as_int();
|
int width = cell->parameters.at(ID(WIDTH)).as_int();
|
||||||
char clk_pol = cell->parameters.at(ID(\\CLK_POLARITY)).as_bool() ? 'P' : 'N';
|
char clk_pol = cell->parameters.at(ID(CLK_POLARITY)).as_bool() ? 'P' : 'N';
|
||||||
char en_pol = cell->parameters.at(ID(\\EN_POLARITY)).as_bool() ? 'P' : 'N';
|
char en_pol = cell->parameters.at(ID(EN_POLARITY)).as_bool() ? 'P' : 'N';
|
||||||
|
|
||||||
RTLIL::SigSpec sig_clk = cell->getPort(ID(\\CLK));
|
RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK));
|
||||||
RTLIL::SigSpec sig_en = cell->getPort(ID(\\EN));
|
RTLIL::SigSpec sig_en = cell->getPort(ID(EN));
|
||||||
RTLIL::SigSpec sig_d = cell->getPort(ID(\\D));
|
RTLIL::SigSpec sig_d = cell->getPort(ID(D));
|
||||||
RTLIL::SigSpec sig_q = cell->getPort(ID(\\Q));
|
RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
|
||||||
|
|
||||||
IdString gate_type = stringf("$_DFFE_%c%c_", clk_pol, en_pol);
|
IdString gate_type = stringf("$_DFFE_%c%c_", clk_pol, en_pol);
|
||||||
|
|
||||||
for (int i = 0; i < width; i++) {
|
for (int i = 0; i < width; i++) {
|
||||||
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
||||||
gate->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
gate->setPort(ID(\\C), sig_clk);
|
gate->setPort(ID(C), sig_clk);
|
||||||
gate->setPort(ID(\\E), sig_en);
|
gate->setPort(ID(E), sig_en);
|
||||||
gate->setPort(ID(\\D), sig_d[i]);
|
gate->setPort(ID(D), sig_d[i]);
|
||||||
gate->setPort(ID(\\Q), sig_q[i]);
|
gate->setPort(ID(Q), sig_q[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
int width = cell->parameters.at(ID(\\WIDTH)).as_int();
|
int width = cell->parameters.at(ID(WIDTH)).as_int();
|
||||||
char clk_pol = cell->parameters.at(ID(\\CLK_POLARITY)).as_bool() ? 'P' : 'N';
|
char clk_pol = cell->parameters.at(ID(CLK_POLARITY)).as_bool() ? 'P' : 'N';
|
||||||
char set_pol = cell->parameters.at(ID(\\SET_POLARITY)).as_bool() ? 'P' : 'N';
|
char set_pol = cell->parameters.at(ID(SET_POLARITY)).as_bool() ? 'P' : 'N';
|
||||||
char clr_pol = cell->parameters.at(ID(\\CLR_POLARITY)).as_bool() ? 'P' : 'N';
|
char clr_pol = cell->parameters.at(ID(CLR_POLARITY)).as_bool() ? 'P' : 'N';
|
||||||
|
|
||||||
RTLIL::SigSpec sig_clk = cell->getPort(ID(\\CLK));
|
RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK));
|
||||||
RTLIL::SigSpec sig_s = cell->getPort(ID(\\SET));
|
RTLIL::SigSpec sig_s = cell->getPort(ID(SET));
|
||||||
RTLIL::SigSpec sig_r = cell->getPort(ID(\\CLR));
|
RTLIL::SigSpec sig_r = cell->getPort(ID(CLR));
|
||||||
RTLIL::SigSpec sig_d = cell->getPort(ID(\\D));
|
RTLIL::SigSpec sig_d = cell->getPort(ID(D));
|
||||||
RTLIL::SigSpec sig_q = cell->getPort(ID(\\Q));
|
RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
|
||||||
|
|
||||||
IdString gate_type = stringf("$_DFFSR_%c%c%c_", clk_pol, set_pol, clr_pol);
|
IdString gate_type = stringf("$_DFFSR_%c%c%c_", clk_pol, set_pol, clr_pol);
|
||||||
|
|
||||||
for (int i = 0; i < width; i++) {
|
for (int i = 0; i < width; i++) {
|
||||||
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
||||||
gate->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
gate->setPort(ID(\\C), sig_clk);
|
gate->setPort(ID(C), sig_clk);
|
||||||
gate->setPort(ID(\\S), sig_s[i]);
|
gate->setPort(ID(S), sig_s[i]);
|
||||||
gate->setPort(ID(\\R), sig_r[i]);
|
gate->setPort(ID(R), sig_r[i]);
|
||||||
gate->setPort(ID(\\D), sig_d[i]);
|
gate->setPort(ID(D), sig_d[i]);
|
||||||
gate->setPort(ID(\\Q), sig_q[i]);
|
gate->setPort(ID(Q), sig_q[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
int width = cell->parameters.at(ID(\\WIDTH)).as_int();
|
int width = cell->parameters.at(ID(WIDTH)).as_int();
|
||||||
char clk_pol = cell->parameters.at(ID(\\CLK_POLARITY)).as_bool() ? 'P' : 'N';
|
char clk_pol = cell->parameters.at(ID(CLK_POLARITY)).as_bool() ? 'P' : 'N';
|
||||||
char rst_pol = cell->parameters.at(ID(\\ARST_POLARITY)).as_bool() ? 'P' : 'N';
|
char rst_pol = cell->parameters.at(ID(ARST_POLARITY)).as_bool() ? 'P' : 'N';
|
||||||
|
|
||||||
std::vector<RTLIL::State> rst_val = cell->parameters.at(ID(\\ARST_VALUE)).bits;
|
std::vector<RTLIL::State> rst_val = cell->parameters.at(ID(ARST_VALUE)).bits;
|
||||||
while (int(rst_val.size()) < width)
|
while (int(rst_val.size()) < width)
|
||||||
rst_val.push_back(RTLIL::State::S0);
|
rst_val.push_back(RTLIL::State::S0);
|
||||||
|
|
||||||
RTLIL::SigSpec sig_clk = cell->getPort(ID(\\CLK));
|
RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK));
|
||||||
RTLIL::SigSpec sig_rst = cell->getPort(ID(\\ARST));
|
RTLIL::SigSpec sig_rst = cell->getPort(ID(ARST));
|
||||||
RTLIL::SigSpec sig_d = cell->getPort(ID(\\D));
|
RTLIL::SigSpec sig_d = cell->getPort(ID(D));
|
||||||
RTLIL::SigSpec sig_q = cell->getPort(ID(\\Q));
|
RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
|
||||||
|
|
||||||
IdString gate_type_0 = stringf("$_DFF_%c%c0_", clk_pol, rst_pol);
|
IdString gate_type_0 = stringf("$_DFF_%c%c0_", clk_pol, rst_pol);
|
||||||
IdString gate_type_1 = stringf("$_DFF_%c%c1_", clk_pol, rst_pol);
|
IdString gate_type_1 = stringf("$_DFF_%c%c1_", clk_pol, rst_pol);
|
||||||
|
|
||||||
for (int i = 0; i < width; i++) {
|
for (int i = 0; i < width; i++) {
|
||||||
RTLIL::Cell *gate = module->addCell(NEW_ID, rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0);
|
RTLIL::Cell *gate = module->addCell(NEW_ID, rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0);
|
||||||
gate->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
gate->setPort(ID(\\C), sig_clk);
|
gate->setPort(ID(C), sig_clk);
|
||||||
gate->setPort(ID(\\R), sig_rst);
|
gate->setPort(ID(R), sig_rst);
|
||||||
gate->setPort(ID(\\D), sig_d[i]);
|
gate->setPort(ID(D), sig_d[i]);
|
||||||
gate->setPort(ID(\\Q), sig_q[i]);
|
gate->setPort(ID(Q), sig_q[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
int width = cell->parameters.at(ID(\\WIDTH)).as_int();
|
int width = cell->parameters.at(ID(WIDTH)).as_int();
|
||||||
char en_pol = cell->parameters.at(ID(\\EN_POLARITY)).as_bool() ? 'P' : 'N';
|
char en_pol = cell->parameters.at(ID(EN_POLARITY)).as_bool() ? 'P' : 'N';
|
||||||
|
|
||||||
RTLIL::SigSpec sig_en = cell->getPort(ID(\\EN));
|
RTLIL::SigSpec sig_en = cell->getPort(ID(EN));
|
||||||
RTLIL::SigSpec sig_d = cell->getPort(ID(\\D));
|
RTLIL::SigSpec sig_d = cell->getPort(ID(D));
|
||||||
RTLIL::SigSpec sig_q = cell->getPort(ID(\\Q));
|
RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
|
||||||
|
|
||||||
IdString gate_type = stringf("$_DLATCH_%c_", en_pol);
|
IdString gate_type = stringf("$_DLATCH_%c_", en_pol);
|
||||||
|
|
||||||
for (int i = 0; i < width; i++) {
|
for (int i = 0; i < width; i++) {
|
||||||
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
||||||
gate->add_strpool_attribute(ID(\\src), cell->get_strpool_attribute(ID(\\src)));
|
gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
|
||||||
gate->setPort(ID(\\E), sig_en);
|
gate->setPort(ID(E), sig_en);
|
||||||
gate->setPort(ID(\\D), sig_d[i]);
|
gate->setPort(ID(D), sig_d[i]);
|
||||||
gate->setPort(ID(\\Q), sig_q[i]);
|
gate->setPort(ID(Q), sig_q[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,8 +145,8 @@ struct TechmapWorker
|
||||||
record.wire = it.second;
|
record.wire = it.second;
|
||||||
record.value = it.second;
|
record.value = it.second;
|
||||||
result[p].push_back(record);
|
result[p].push_back(record);
|
||||||
it.second->attributes[ID(\\keep)] = RTLIL::Const(1);
|
it.second->attributes[ID(keep)] = RTLIL::Const(1);
|
||||||
it.second->attributes[ID(\\_techmap_special_)] = RTLIL::Const(1);
|
it.second->attributes[ID(_techmap_special_)] = RTLIL::Const(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,11 +175,11 @@ struct TechmapWorker
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string orig_cell_name;
|
std::string orig_cell_name;
|
||||||
pool<string> extra_src_attrs = cell->get_strpool_attribute(ID(\\src));
|
pool<string> extra_src_attrs = cell->get_strpool_attribute(ID(src));
|
||||||
|
|
||||||
if (!flatten_mode) {
|
if (!flatten_mode) {
|
||||||
for (auto &it : tpl->cells_)
|
for (auto &it : tpl->cells_)
|
||||||
if (it.first == ID(\\_TECHMAP_REPLACE_)) {
|
if (it.first == ID(_TECHMAP_REPLACE_)) {
|
||||||
orig_cell_name = cell->name.str();
|
orig_cell_name = cell->name.str();
|
||||||
module->rename(cell, stringf("$techmap%d", autoidx++) + cell->name.str());
|
module->rename(cell, stringf("$techmap%d", autoidx++) + cell->name.str());
|
||||||
break;
|
break;
|
||||||
|
@ -197,8 +197,8 @@ struct TechmapWorker
|
||||||
m->start_offset = it.second->start_offset;
|
m->start_offset = it.second->start_offset;
|
||||||
m->size = it.second->size;
|
m->size = it.second->size;
|
||||||
m->attributes = it.second->attributes;
|
m->attributes = it.second->attributes;
|
||||||
if (m->attributes.count(ID(\\src)))
|
if (m->attributes.count(ID(src)))
|
||||||
m->add_strpool_attribute(ID(\\src), extra_src_attrs);
|
m->add_strpool_attribute(ID(src), extra_src_attrs);
|
||||||
module->memories[m->name] = m;
|
module->memories[m->name] = m;
|
||||||
memory_renames[it.first] = m->name;
|
memory_renames[it.first] = m->name;
|
||||||
design->select(module, m);
|
design->select(module, m);
|
||||||
|
@ -215,10 +215,10 @@ struct TechmapWorker
|
||||||
w->port_input = false;
|
w->port_input = false;
|
||||||
w->port_output = false;
|
w->port_output = false;
|
||||||
w->port_id = 0;
|
w->port_id = 0;
|
||||||
if (it.second->get_bool_attribute(ID(\\_techmap_special_)))
|
if (it.second->get_bool_attribute(ID(_techmap_special_)))
|
||||||
w->attributes.clear();
|
w->attributes.clear();
|
||||||
if (w->attributes.count(ID(\\src)))
|
if (w->attributes.count(ID(src)))
|
||||||
w->add_strpool_attribute(ID(\\src), extra_src_attrs);
|
w->add_strpool_attribute(ID(src), extra_src_attrs);
|
||||||
design->select(module, w);
|
design->select(module, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +320,7 @@ struct TechmapWorker
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &attr : w->attributes) {
|
for (auto &attr : w->attributes) {
|
||||||
if (attr.first == ID(\\src))
|
if (attr.first == ID(src))
|
||||||
continue;
|
continue;
|
||||||
module->connect(extra_connect);
|
module->connect(extra_connect);
|
||||||
break;
|
break;
|
||||||
|
@ -331,7 +331,7 @@ struct TechmapWorker
|
||||||
for (auto &it : tpl->cells_)
|
for (auto &it : tpl->cells_)
|
||||||
{
|
{
|
||||||
IdString c_name = it.second->name.str();
|
IdString c_name = it.second->name.str();
|
||||||
bool techmap_replace_cell = (!flatten_mode) && (c_name == ID(\\_TECHMAP_REPLACE_));
|
bool techmap_replace_cell = (!flatten_mode) && (c_name == ID(_TECHMAP_REPLACE_));
|
||||||
|
|
||||||
if (techmap_replace_cell)
|
if (techmap_replace_cell)
|
||||||
c_name = orig_cell_name;
|
c_name = orig_cell_name;
|
||||||
|
@ -350,19 +350,19 @@ struct TechmapWorker
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->type.in(ID($memrd), ID($memwr), ID($meminit))) {
|
if (c->type.in(ID($memrd), ID($memwr), ID($meminit))) {
|
||||||
IdString memid = c->getParam(ID(\\MEMID)).decode_string();
|
IdString memid = c->getParam(ID(MEMID)).decode_string();
|
||||||
log_assert(memory_renames.count(memid) != 0);
|
log_assert(memory_renames.count(memid) != 0);
|
||||||
c->setParam(ID(\\MEMID), Const(memory_renames[memid].str()));
|
c->setParam(ID(MEMID), Const(memory_renames[memid].str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->type == ID($mem)) {
|
if (c->type == ID($mem)) {
|
||||||
IdString memid = c->getParam(ID(\\MEMID)).decode_string();
|
IdString memid = c->getParam(ID(MEMID)).decode_string();
|
||||||
apply_prefix(cell->name, memid);
|
apply_prefix(cell->name, memid);
|
||||||
c->setParam(ID(\\MEMID), Const(memid.c_str()));
|
c->setParam(ID(MEMID), Const(memid.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->attributes.count(ID(\\src)))
|
if (c->attributes.count(ID(src)))
|
||||||
c->add_strpool_attribute(ID(\\src), extra_src_attrs);
|
c->add_strpool_attribute(ID(src), extra_src_attrs);
|
||||||
|
|
||||||
if (techmap_replace_cell)
|
if (techmap_replace_cell)
|
||||||
for (auto attr : cell->attributes)
|
for (auto attr : cell->attributes)
|
||||||
|
@ -416,9 +416,9 @@ struct TechmapWorker
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flatten_mode) {
|
if (flatten_mode) {
|
||||||
bool keepit = cell->get_bool_attribute(ID(\\keep_hierarchy));
|
bool keepit = cell->get_bool_attribute(ID(keep_hierarchy));
|
||||||
for (auto &tpl_name : celltypeMap.at(cell_type))
|
for (auto &tpl_name : celltypeMap.at(cell_type))
|
||||||
if (map->modules_[tpl_name]->get_bool_attribute(ID(\\keep_hierarchy)))
|
if (map->modules_[tpl_name]->get_bool_attribute(ID(keep_hierarchy)))
|
||||||
keepit = true;
|
keepit = true;
|
||||||
if (keepit) {
|
if (keepit) {
|
||||||
if (!flatten_keep_list[cell]) {
|
if (!flatten_keep_list[cell]) {
|
||||||
|
@ -484,13 +484,13 @@ struct TechmapWorker
|
||||||
{
|
{
|
||||||
std::string extmapper_name;
|
std::string extmapper_name;
|
||||||
|
|
||||||
if (tpl->get_bool_attribute(ID(\\techmap_simplemap)))
|
if (tpl->get_bool_attribute(ID(techmap_simplemap)))
|
||||||
extmapper_name = "simplemap";
|
extmapper_name = "simplemap";
|
||||||
|
|
||||||
if (tpl->get_bool_attribute(ID(\\techmap_maccmap)))
|
if (tpl->get_bool_attribute(ID(techmap_maccmap)))
|
||||||
extmapper_name = "maccmap";
|
extmapper_name = "maccmap";
|
||||||
|
|
||||||
if (tpl->attributes.count(ID(\\techmap_wrap)))
|
if (tpl->attributes.count(ID(techmap_wrap)))
|
||||||
extmapper_name = "wrap";
|
extmapper_name = "wrap";
|
||||||
|
|
||||||
if (!extmapper_name.empty())
|
if (!extmapper_name.empty())
|
||||||
|
@ -505,7 +505,7 @@ struct TechmapWorker
|
||||||
m_name += stringf(":%s=%s", log_id(c.first), log_signal(c.second));
|
m_name += stringf(":%s=%s", log_id(c.first), log_signal(c.second));
|
||||||
|
|
||||||
if (extmapper_name == "wrap")
|
if (extmapper_name == "wrap")
|
||||||
m_name += ":" + sha1(tpl->attributes.at(ID(\\techmap_wrap)).decode_string());
|
m_name += ":" + sha1(tpl->attributes.at(ID(techmap_wrap)).decode_string());
|
||||||
|
|
||||||
RTLIL::Design *extmapper_design = extern_mode && !in_recursion ? design : tpl->design;
|
RTLIL::Design *extmapper_design = extern_mode && !in_recursion ? design : tpl->design;
|
||||||
RTLIL::Module *extmapper_module = extmapper_design->module(m_name);
|
RTLIL::Module *extmapper_module = extmapper_design->module(m_name);
|
||||||
|
@ -520,7 +520,7 @@ struct TechmapWorker
|
||||||
int port_counter = 1;
|
int port_counter = 1;
|
||||||
for (auto &c : extmapper_cell->connections_) {
|
for (auto &c : extmapper_cell->connections_) {
|
||||||
RTLIL::Wire *w = extmapper_module->addWire(c.first, GetSize(c.second));
|
RTLIL::Wire *w = extmapper_module->addWire(c.first, GetSize(c.second));
|
||||||
if (w->name.in(ID(\\Y), ID(\\Q)))
|
if (w->name.in(ID(Y), ID(Q)))
|
||||||
w->port_output = true;
|
w->port_output = true;
|
||||||
else
|
else
|
||||||
w->port_input = true;
|
w->port_input = true;
|
||||||
|
@ -548,7 +548,7 @@ struct TechmapWorker
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extmapper_name == "wrap") {
|
if (extmapper_name == "wrap") {
|
||||||
std::string cmd_string = tpl->attributes.at(ID(\\techmap_wrap)).decode_string();
|
std::string cmd_string = tpl->attributes.at(ID(techmap_wrap)).decode_string();
|
||||||
log("Running \"%s\" on wrapper %s.\n", cmd_string.c_str(), log_id(extmapper_module));
|
log("Running \"%s\" on wrapper %s.\n", cmd_string.c_str(), log_id(extmapper_module));
|
||||||
mkdebug.on();
|
mkdebug.on();
|
||||||
Pass::call_on_module(extmapper_design, extmapper_module, cmd_string);
|
Pass::call_on_module(extmapper_design, extmapper_module, cmd_string);
|
||||||
|
@ -616,8 +616,8 @@ struct TechmapWorker
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tpl->avail_parameters.count(ID(\\_TECHMAP_CELLTYPE_)) != 0)
|
if (tpl->avail_parameters.count(ID(_TECHMAP_CELLTYPE_)) != 0)
|
||||||
parameters[ID(\\_TECHMAP_CELLTYPE_)] = RTLIL::unescape_id(cell->type);
|
parameters[ID(_TECHMAP_CELLTYPE_)] = RTLIL::unescape_id(cell->type);
|
||||||
|
|
||||||
for (auto conn : cell->connections()) {
|
for (auto conn : cell->connections()) {
|
||||||
if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTMSK_%s_", RTLIL::id2cstr(conn.first))) != 0) {
|
if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTMSK_%s_", RTLIL::id2cstr(conn.first))) != 0) {
|
||||||
|
@ -656,8 +656,8 @@ struct TechmapWorker
|
||||||
bits = i;
|
bits = i;
|
||||||
// Increment index by one to get number of bits
|
// Increment index by one to get number of bits
|
||||||
bits++;
|
bits++;
|
||||||
if (tpl->avail_parameters.count(ID(\\_TECHMAP_BITS_CONNMAP_)))
|
if (tpl->avail_parameters.count(ID(_TECHMAP_BITS_CONNMAP_)))
|
||||||
parameters[ID(\\_TECHMAP_BITS_CONNMAP_)] = bits;
|
parameters[ID(_TECHMAP_BITS_CONNMAP_)] = bits;
|
||||||
|
|
||||||
for (auto conn : cell->connections())
|
for (auto conn : cell->connections())
|
||||||
if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", RTLIL::id2cstr(conn.first))) != 0) {
|
if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", RTLIL::id2cstr(conn.first))) != 0) {
|
||||||
|
@ -1136,8 +1136,8 @@ struct TechmapPass : public Pass {
|
||||||
|
|
||||||
std::map<RTLIL::IdString, std::set<RTLIL::IdString, RTLIL::sort_by_id_str>> celltypeMap;
|
std::map<RTLIL::IdString, std::set<RTLIL::IdString, RTLIL::sort_by_id_str>> celltypeMap;
|
||||||
for (auto &it : map->modules_) {
|
for (auto &it : map->modules_) {
|
||||||
if (it.second->attributes.count(ID(\\techmap_celltype)) && !it.second->attributes.at(ID(\\techmap_celltype)).bits.empty()) {
|
if (it.second->attributes.count(ID(techmap_celltype)) && !it.second->attributes.at(ID(techmap_celltype)).bits.empty()) {
|
||||||
char *p = strdup(it.second->attributes.at(ID(\\techmap_celltype)).decode_string().c_str());
|
char *p = strdup(it.second->attributes.at(ID(techmap_celltype)).decode_string().c_str());
|
||||||
for (char *q = strtok(p, " \t\r\n"); q; q = strtok(NULL, " \t\r\n"))
|
for (char *q = strtok(p, " \t\r\n"); q; q = strtok(NULL, " \t\r\n"))
|
||||||
celltypeMap[RTLIL::escape_id(q)].insert(it.first);
|
celltypeMap[RTLIL::escape_id(q)].insert(it.first);
|
||||||
free(p);
|
free(p);
|
||||||
|
@ -1222,7 +1222,7 @@ struct FlattenPass : public Pass {
|
||||||
RTLIL::Module *top_mod = NULL;
|
RTLIL::Module *top_mod = NULL;
|
||||||
if (design->full_selection())
|
if (design->full_selection())
|
||||||
for (auto mod : design->modules())
|
for (auto mod : design->modules())
|
||||||
if (mod->get_bool_attribute(ID(\\top)))
|
if (mod->get_bool_attribute(ID(top)))
|
||||||
top_mod = mod;
|
top_mod = mod;
|
||||||
|
|
||||||
std::set<RTLIL::Cell*> handled_cells;
|
std::set<RTLIL::Cell*> handled_cells;
|
||||||
|
|
|
@ -64,37 +64,37 @@ struct TribufWorker {
|
||||||
for (auto cell : module->selected_cells())
|
for (auto cell : module->selected_cells())
|
||||||
{
|
{
|
||||||
if (cell->type == ID($tribuf))
|
if (cell->type == ID($tribuf))
|
||||||
tribuf_cells[sigmap(cell->getPort(ID(\\Y)))].push_back(cell);
|
tribuf_cells[sigmap(cell->getPort(ID(Y)))].push_back(cell);
|
||||||
|
|
||||||
if (cell->type == ID($_TBUF_))
|
if (cell->type == ID($_TBUF_))
|
||||||
tribuf_cells[sigmap(cell->getPort(ID(\\Y)))].push_back(cell);
|
tribuf_cells[sigmap(cell->getPort(ID(Y)))].push_back(cell);
|
||||||
|
|
||||||
if (cell->type.in(ID($mux), ID($_MUX_)))
|
if (cell->type.in(ID($mux), ID($_MUX_)))
|
||||||
{
|
{
|
||||||
IdString en_port = cell->type == ID($mux) ? ID(\\EN) : ID(\\E);
|
IdString en_port = cell->type == ID($mux) ? ID(EN) : ID(E);
|
||||||
IdString tri_type = cell->type == ID($mux) ? ID($tribuf) : ID($_TBUF_);
|
IdString tri_type = cell->type == ID($mux) ? ID($tribuf) : ID($_TBUF_);
|
||||||
|
|
||||||
if (is_all_z(cell->getPort(ID(\\A))) && is_all_z(cell->getPort(ID(\\B)))) {
|
if (is_all_z(cell->getPort(ID(A))) && is_all_z(cell->getPort(ID(B)))) {
|
||||||
module->remove(cell);
|
module->remove(cell);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_all_z(cell->getPort(ID(\\A)))) {
|
if (is_all_z(cell->getPort(ID(A)))) {
|
||||||
cell->setPort(ID(\\A), cell->getPort(ID(\\B)));
|
cell->setPort(ID(A), cell->getPort(ID(B)));
|
||||||
cell->setPort(en_port, cell->getPort(ID(\\S)));
|
cell->setPort(en_port, cell->getPort(ID(S)));
|
||||||
cell->unsetPort(ID(\\B));
|
cell->unsetPort(ID(B));
|
||||||
cell->unsetPort(ID(\\S));
|
cell->unsetPort(ID(S));
|
||||||
cell->type = tri_type;
|
cell->type = tri_type;
|
||||||
tribuf_cells[sigmap(cell->getPort(ID(\\Y)))].push_back(cell);
|
tribuf_cells[sigmap(cell->getPort(ID(Y)))].push_back(cell);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_all_z(cell->getPort(ID(\\B)))) {
|
if (is_all_z(cell->getPort(ID(B)))) {
|
||||||
cell->setPort(en_port, module->Not(NEW_ID, cell->getPort(ID(\\S))));
|
cell->setPort(en_port, module->Not(NEW_ID, cell->getPort(ID(S))));
|
||||||
cell->unsetPort(ID(\\B));
|
cell->unsetPort(ID(B));
|
||||||
cell->unsetPort(ID(\\S));
|
cell->unsetPort(ID(S));
|
||||||
cell->type = tri_type;
|
cell->type = tri_type;
|
||||||
tribuf_cells[sigmap(cell->getPort(ID(\\Y)))].push_back(cell);
|
tribuf_cells[sigmap(cell->getPort(ID(Y)))].push_back(cell);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,10 +119,10 @@ struct TribufWorker {
|
||||||
SigSpec pmux_b, pmux_s;
|
SigSpec pmux_b, pmux_s;
|
||||||
for (auto cell : it.second) {
|
for (auto cell : it.second) {
|
||||||
if (cell->type == ID($tribuf))
|
if (cell->type == ID($tribuf))
|
||||||
pmux_s.append(cell->getPort(ID(\\EN)));
|
pmux_s.append(cell->getPort(ID(EN)));
|
||||||
else
|
else
|
||||||
pmux_s.append(cell->getPort(ID(\\E)));
|
pmux_s.append(cell->getPort(ID(E)));
|
||||||
pmux_b.append(cell->getPort(ID(\\A)));
|
pmux_b.append(cell->getPort(ID(A)));
|
||||||
module->remove(cell);
|
module->remove(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,12 +62,12 @@ struct ZinitPass : public Pass {
|
||||||
|
|
||||||
for (auto wire : module->selected_wires())
|
for (auto wire : module->selected_wires())
|
||||||
{
|
{
|
||||||
if (wire->attributes.count(ID(\\init)) == 0)
|
if (wire->attributes.count(ID(init)) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SigSpec wirebits = sigmap(wire);
|
SigSpec wirebits = sigmap(wire);
|
||||||
Const initval = wire->attributes.at(ID(\\init));
|
Const initval = wire->attributes.at(ID(init));
|
||||||
wire->attributes.erase(ID(\\init));
|
wire->attributes.erase(ID(init));
|
||||||
|
|
||||||
for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++)
|
for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++)
|
||||||
{
|
{
|
||||||
|
@ -103,8 +103,8 @@ struct ZinitPass : public Pass {
|
||||||
if (!dff_types.count(cell->type))
|
if (!dff_types.count(cell->type))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SigSpec sig_d = sigmap(cell->getPort(ID(\\D)));
|
SigSpec sig_d = sigmap(cell->getPort(ID(D)));
|
||||||
SigSpec sig_q = sigmap(cell->getPort(ID(\\Q)));
|
SigSpec sig_q = sigmap(cell->getPort(ID(Q)));
|
||||||
|
|
||||||
if (GetSize(sig_d) < 1 || GetSize(sig_q) < 1)
|
if (GetSize(sig_d) < 1 || GetSize(sig_q) < 1)
|
||||||
continue;
|
continue;
|
||||||
|
@ -120,14 +120,14 @@ struct ZinitPass : public Pass {
|
||||||
}
|
}
|
||||||
|
|
||||||
Wire *initwire = module->addWire(NEW_ID, GetSize(initval));
|
Wire *initwire = module->addWire(NEW_ID, GetSize(initval));
|
||||||
initwire->attributes[ID(\\init)] = initval;
|
initwire->attributes[ID(init)] = initval;
|
||||||
|
|
||||||
for (int i = 0; i < GetSize(initwire); i++)
|
for (int i = 0; i < GetSize(initwire); i++)
|
||||||
if (initval.bits.at(i) == State::S1)
|
if (initval.bits.at(i) == State::S1)
|
||||||
{
|
{
|
||||||
sig_d[i] = module->NotGate(NEW_ID, sig_d[i]);
|
sig_d[i] = module->NotGate(NEW_ID, sig_d[i]);
|
||||||
module->addNotGate(NEW_ID, SigSpec(initwire, i), sig_q[i]);
|
module->addNotGate(NEW_ID, SigSpec(initwire, i), sig_q[i]);
|
||||||
initwire->attributes[ID(\\init)].bits.at(i) = State::S0;
|
initwire->attributes[ID(init)].bits.at(i) = State::S0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -137,8 +137,8 @@ struct ZinitPass : public Pass {
|
||||||
log("FF init value for cell %s (%s): %s = %s\n", log_id(cell), log_id(cell->type),
|
log("FF init value for cell %s (%s): %s = %s\n", log_id(cell), log_id(cell->type),
|
||||||
log_signal(sig_q), log_signal(initval));
|
log_signal(sig_q), log_signal(initval));
|
||||||
|
|
||||||
cell->setPort(ID(\\D), sig_d);
|
cell->setPort(ID(D), sig_d);
|
||||||
cell->setPort(ID(\\Q), initwire);
|
cell->setPort(ID(Q), initwire);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &it : initbits)
|
for (auto &it : initbits)
|
||||||
|
|
Loading…
Reference in New Issue