3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-06-14 18:06:16 +00:00

Merge remote-tracking branch 'origin/master' into xc7dsp

This commit is contained in:
Eddie Hung 2019-08-20 20:18:17 -07:00
commit b7a48e3e0f
133 changed files with 4172 additions and 2286 deletions

View file

@ -14,11 +14,19 @@ Yosys 0.9 .. Yosys 0.9-dev
- Added "synth -abc9" (experimental) - Added "synth -abc9" (experimental)
- Added "script -scriptwire - Added "script -scriptwire
- "synth_xilinx" to now infer wide multiplexers (-widemux <min> to enable) - "synth_xilinx" to now infer wide multiplexers (-widemux <min> to enable)
- Renamed labels/options in synth_ice40 (e.g. dram -> map_lutram; -nodram -> -nolutram)
- Renamed labels/options in synth_ecp5 (e.g. dram -> map_lutram; -nodram -> -nolutram)
- Renamed labels in synth_intel (e.g. bram -> map_bram)
- Renamed labels/options in synth_xilinx (e.g. dram -> map_lutram; -nodram -> -nolutram)
- Added automatic gzip decompression for frontends - Added automatic gzip decompression for frontends
- Added $_NMUX_ cell type - Added $_NMUX_ cell type
- Added automatic gzip compression (based on filename extension) for backends - Added automatic gzip compression (based on filename extension) for backends
- Improve attribute and parameter encoding in JSON to avoid ambiguities between - Improve attribute and parameter encoding in JSON to avoid ambiguities between
bit vectors and strings containing [01xz]* bit vectors and strings containing [01xz]*
- Improvements in pmgen: subpattern and recursive matches
- Added "opt_share" pass, run as part of "opt -full"
- Added "ice40_wrapcarry" to encapsulate SB_LUT+SB_CARRY pairs for techmapping
- Removed "ice40_unlut"
Yosys 0.8 .. Yosys 0.8-dev Yosys 0.8 .. Yosys 0.8-dev
-------------------------- --------------------------

View file

@ -487,6 +487,11 @@ define add_include_file
$(eval $(call add_share_file,$(dir share/include/$(1)),$(1))) $(eval $(call add_share_file,$(dir share/include/$(1)),$(1)))
endef endef
define add_extra_objs
EXTRA_OBJS += $(1)
.SECONDARY: $(1)
endef
ifeq ($(PRETTY), 1) ifeq ($(PRETTY), 1)
P_STATUS = 0 P_STATUS = 0
P_OFFSET = 0 P_OFFSET = 0
@ -682,10 +687,12 @@ endif
test: $(TARGETS) $(EXTRA_TARGETS) test: $(TARGETS) $(EXTRA_TARGETS)
+cd tests/simple && bash run-test.sh $(SEEDOPT) +cd tests/simple && bash run-test.sh $(SEEDOPT)
+cd tests/simple_abc9 && bash run-test.sh $(SEEDOPT)
+cd tests/hana && bash run-test.sh $(SEEDOPT) +cd tests/hana && bash run-test.sh $(SEEDOPT)
+cd tests/asicworld && bash run-test.sh $(SEEDOPT) +cd tests/asicworld && bash run-test.sh $(SEEDOPT)
# +cd tests/realmath && bash run-test.sh $(SEEDOPT) # +cd tests/realmath && bash run-test.sh $(SEEDOPT)
+cd tests/share && bash run-test.sh $(SEEDOPT) +cd tests/share && bash run-test.sh $(SEEDOPT)
+cd tests/opt_share && bash run-test.sh $(SEEDOPT)
+cd tests/fsm && bash run-test.sh $(SEEDOPT) +cd tests/fsm && bash run-test.sh $(SEEDOPT)
+cd tests/techmap && bash run-test.sh +cd tests/techmap && bash run-test.sh
+cd tests/memories && bash run-test.sh $(ABCOPT) $(SEEDOPT) +cd tests/memories && bash run-test.sh $(ABCOPT) $(SEEDOPT)
@ -693,10 +700,10 @@ test: $(TARGETS) $(EXTRA_TARGETS)
+cd tests/various && bash run-test.sh +cd tests/various && bash run-test.sh
+cd tests/sat && bash run-test.sh +cd tests/sat && bash run-test.sh
+cd tests/svinterfaces && bash run-test.sh $(SEEDOPT) +cd tests/svinterfaces && bash run-test.sh $(SEEDOPT)
+cd tests/proc && bash run-test.sh
+cd tests/opt && bash run-test.sh +cd tests/opt && bash run-test.sh
+cd tests/aiger && bash run-test.sh $(ABCOPT) +cd tests/aiger && bash run-test.sh $(ABCOPT)
+cd tests/arch && bash run-test.sh +cd tests/arch && bash run-test.sh
+cd tests/simple_abc9 && bash run-test.sh $(SEEDOPT)
@echo "" @echo ""
@echo " Passed \"make test\"." @echo " Passed \"make test\"."
@echo "" @echo ""

View file

@ -405,6 +405,23 @@ Verilog Attributes and non-standard features
blackboxes and whiteboxes. Use ``read_verilog -specify`` to enable this blackboxes and whiteboxes. Use ``read_verilog -specify`` to enable this
functionality. (By default specify .. endspecify blocks are ignored.) functionality. (By default specify .. endspecify blocks are ignored.)
- The module attribute ``abc_box_id`` specifies a positive integer linking a
blackbox or whitebox definition to a corresponding entry in a `abc9`
box-file.
- The port attribute ``abc_scc_break`` indicates a module input port that will
be treated as a primary output during `abc9` techmapping. Doing so eliminates
the possibility of a strongly-connected component (i.e. a combinatorial loop)
existing. Typically, this is specified for sequential inputs on otherwise
combinatorial boxes -- for example, applying ``abc_scc_break`` onto the `D`
port of a LUTRAM cell prevents `abc9` from interpreting any `Q` -> `D` paths
as a combinatorial loop.
- The port attribute ``abc_carry`` marks the carry-in (if an input port) and
carry-out (if output port) ports of a box. This information is necessary for
`abc9` to preserve the integrity of carry-chains. Specifying this attribute
onto a bus port will affect only its most significant bit.
Non-standard or SystemVerilog features for formal verification Non-standard or SystemVerilog features for formal verification
============================================================== ==============================================================

View file

@ -312,7 +312,7 @@ struct XAigerWriter
#if 0 #if 0
toposort.analyze_loops = true; toposort.analyze_loops = true;
#endif #endif
bool no_loops = toposort.sort(); bool no_loops YS_ATTRIBUTE(unused) = toposort.sort();
#if 0 #if 0
unsigned i = 0; unsigned i = 0;
for (auto &it : toposort.loops) { for (auto &it : toposort.loops) {
@ -326,7 +326,6 @@ struct XAigerWriter
#endif #endif
log_assert(no_loops); log_assert(no_loops);
pool<IdString> seen_boxes;
for (auto cell_name : toposort.sorted) { for (auto cell_name : toposort.sorted) {
RTLIL::Cell *cell = module->cell(cell_name); RTLIL::Cell *cell = module->cell(cell_name);
log_assert(cell); log_assert(cell);
@ -335,47 +334,6 @@ struct XAigerWriter
if (!box_module || !box_module->attributes.count("\\abc_box_id")) if (!box_module || !box_module->attributes.count("\\abc_box_id"))
continue; continue;
if (seen_boxes.insert(cell->type).second) {
auto it = box_module->attributes.find("\\abc_carry");
if (it != box_module->attributes.end()) {
RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr;
auto carry_in_out = it->second.decode_string();
auto pos = carry_in_out.find(',');
if (pos == std::string::npos)
log_error("'abc_carry' attribute on module '%s' does not contain ','.\n", log_id(cell->type));
auto carry_in_name = RTLIL::escape_id(carry_in_out.substr(0, pos));
carry_in = box_module->wire(carry_in_name);
if (!carry_in || !carry_in->port_input)
log_error("'abc_carry' on module '%s' contains '%s' which does not exist or is not an input port.\n", log_id(cell->type), carry_in_name.c_str());
auto carry_out_name = RTLIL::escape_id(carry_in_out.substr(pos+1));
carry_out = box_module->wire(carry_out_name);
if (!carry_out || !carry_out->port_output)
log_error("'abc_carry' on module '%s' contains '%s' which does not exist or is not an output port.\n", log_id(cell->type), carry_out_name.c_str());
auto &ports = box_module->ports;
for (auto jt = ports.begin(); jt != ports.end(); ) {
RTLIL::Wire* w = box_module->wire(*jt);
log_assert(w);
if (w == carry_in || w == carry_out) {
jt = ports.erase(jt);
continue;
}
if (w->port_id > carry_in->port_id)
--w->port_id;
if (w->port_id > carry_out->port_id)
--w->port_id;
log_assert(w->port_input || w->port_output);
log_assert(ports[w->port_id-1] == w->name);
++jt;
}
ports.push_back(carry_in->name);
carry_in->port_id = ports.size();
ports.push_back(carry_out->name);
carry_out->port_id = ports.size();
}
}
// Fully pad all unused input connections of this box cell with S0 // Fully pad all unused input connections of this box cell with S0
// Fully pad all undriven output connections of this box cell with anonymous wires // Fully pad all undriven output connections of this box cell with anonymous wires
// NB: Assume box_module->ports are sorted alphabetically // NB: Assume box_module->ports are sorted alphabetically

View file

@ -67,7 +67,7 @@ struct ConstEvalAig
continue; continue;
for (auto &it2 : it.second->connections()) for (auto &it2 : it.second->connections())
if (yosys_celltypes.cell_output(it.second->type, it2.first)) { if (yosys_celltypes.cell_output(it.second->type, it2.first)) {
auto r = sig2driver.insert(std::make_pair(it2.second, it.second)); auto r YS_ATTRIBUTE(unused) = sig2driver.insert(std::make_pair(it2.second, it.second));
log_assert(r.second); log_assert(r.second);
} }
} }
@ -389,9 +389,9 @@ void AigerReader::parse_xaiger(const dict<int,IdString> &box_lookup)
f.ignore(1); f.ignore(1);
// XAIGER extensions // XAIGER extensions
if (c == 'm') { if (c == 'm') {
uint32_t dataSize = parse_xaiger_literal(f); uint32_t dataSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
uint32_t lutNum = parse_xaiger_literal(f); uint32_t lutNum = parse_xaiger_literal(f);
uint32_t lutSize = parse_xaiger_literal(f); uint32_t lutSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
log_debug("m: dataSize=%u lutNum=%u lutSize=%u\n", dataSize, lutNum, lutSize); log_debug("m: dataSize=%u lutNum=%u lutSize=%u\n", dataSize, lutNum, lutSize);
ConstEvalAig ce(module); ConstEvalAig ce(module);
for (unsigned i = 0; i < lutNum; ++i) { for (unsigned i = 0; i < lutNum; ++i) {
@ -416,7 +416,7 @@ void AigerReader::parse_xaiger(const dict<int,IdString> &box_lookup)
int gray = j ^ (j >> 1); int gray = j ^ (j >> 1);
ce.set_incremental(input_sig, RTLIL::Const{gray, static_cast<int>(cutLeavesM)}); ce.set_incremental(input_sig, RTLIL::Const{gray, static_cast<int>(cutLeavesM)});
RTLIL::SigBit o(output_sig); RTLIL::SigBit o(output_sig);
bool success = ce.eval(o); bool success YS_ATTRIBUTE(unused) = ce.eval(o);
log_assert(success); log_assert(success);
log_assert(o.wire == nullptr); log_assert(o.wire == nullptr);
lut_mask[gray] = o.data; lut_mask[gray] = o.data;
@ -428,7 +428,7 @@ void AigerReader::parse_xaiger(const dict<int,IdString> &box_lookup)
} }
} }
else if (c == 'r') { else if (c == 'r') {
uint32_t dataSize = parse_xaiger_literal(f); uint32_t dataSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
flopNum = parse_xaiger_literal(f); flopNum = parse_xaiger_literal(f);
log_assert(dataSize == (flopNum+1) * sizeof(uint32_t)); log_assert(dataSize == (flopNum+1) * sizeof(uint32_t));
f.ignore(flopNum * sizeof(uint32_t)); f.ignore(flopNum * sizeof(uint32_t));
@ -440,18 +440,18 @@ void AigerReader::parse_xaiger(const dict<int,IdString> &box_lookup)
} }
else if (c == 'h') { else if (c == 'h') {
f.ignore(sizeof(uint32_t)); f.ignore(sizeof(uint32_t));
uint32_t version = parse_xaiger_literal(f); uint32_t version YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
log_assert(version == 1); log_assert(version == 1);
uint32_t ciNum = parse_xaiger_literal(f); uint32_t ciNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
log_debug("ciNum = %u\n", ciNum); log_debug("ciNum = %u\n", ciNum);
uint32_t coNum = parse_xaiger_literal(f); uint32_t coNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
log_debug("coNum = %u\n", coNum); log_debug("coNum = %u\n", coNum);
piNum = parse_xaiger_literal(f); piNum = parse_xaiger_literal(f);
log_debug("piNum = %u\n", piNum); log_debug("piNum = %u\n", piNum);
uint32_t poNum = parse_xaiger_literal(f); uint32_t poNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
log_debug("poNum = %u\n", poNum); log_debug("poNum = %u\n", poNum);
uint32_t boxNum = parse_xaiger_literal(f); uint32_t boxNum = parse_xaiger_literal(f);
log_debug("boxNum = %u\n", poNum); log_debug("boxNum = %u\n", boxNum);
for (unsigned i = 0; i < boxNum; i++) { for (unsigned i = 0; i < boxNum; i++) {
f.ignore(2*sizeof(uint32_t)); f.ignore(2*sizeof(uint32_t));
uint32_t boxUniqueId = parse_xaiger_literal(f); uint32_t boxUniqueId = parse_xaiger_literal(f);
@ -901,9 +901,6 @@ void AigerReader::post_process()
RTLIL::Cell* cell = module->cell(stringf("$__box%d__", variable)); RTLIL::Cell* cell = module->cell(stringf("$__box%d__", variable));
if (cell) { // ABC could have optimised this box away if (cell) { // ABC could have optimised this box away
module->rename(cell, escaped_s); module->rename(cell, escaped_s);
RTLIL::Module* box_module = design->module(cell->type);
log_assert(box_module);
for (const auto &i : cell->connections()) { for (const auto &i : cell->connections()) {
RTLIL::IdString port_name = i.first; RTLIL::IdString port_name = i.first;
RTLIL::SigSpec rhs = i.second; RTLIL::SigSpec rhs = i.second;

View file

@ -1172,7 +1172,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump
if (design->has((*it)->str)) { if (design->has((*it)->str)) {
RTLIL::Module *existing_mod = design->module((*it)->str); RTLIL::Module *existing_mod = design->module((*it)->str);
if (!nooverwrite && !overwrite && !existing_mod->get_bool_attribute("\\blackbox")) { if (!nooverwrite && !overwrite && !existing_mod->get_blackbox_attribute()) {
log_file_error((*it)->filename, (*it)->linenum, "Re-definition of module `%s'!\n", (*it)->str.c_str()); log_file_error((*it)->filename, (*it)->linenum, "Re-definition of module `%s'!\n", (*it)->str.c_str());
} else if (nooverwrite) { } else if (nooverwrite) {
log("Ignoring re-definition of module `%s' at %s:%d.\n", log("Ignoring re-definition of module `%s' at %s:%d.\n",
@ -1502,7 +1502,10 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString
rewrite_parameter: rewrite_parameter:
para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
delete child->children.at(0); delete child->children.at(0);
if ((parameters[para_id].flags & RTLIL::CONST_FLAG_STRING) != 0) if ((parameters[para_id].flags & RTLIL::CONST_FLAG_REAL) != 0) {
child->children[0] = new AstNode(AST_REALVALUE);
child->children[0]->realvalue = std::stod(parameters[para_id].decode_string());
} else if ((parameters[para_id].flags & RTLIL::CONST_FLAG_STRING) != 0)
child->children[0] = AstNode::mkconst_str(parameters[para_id].decode_string()); child->children[0] = AstNode::mkconst_str(parameters[para_id].decode_string());
else else
child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, (parameters[para_id].flags & RTLIL::CONST_FLAG_SIGNED) != 0); child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, (parameters[para_id].flags & RTLIL::CONST_FLAG_SIGNED) != 0);

View file

@ -78,7 +78,7 @@ failed:
return std::pair<RTLIL::IdString, int>("\\" + name, 0); return std::pair<RTLIL::IdString, int>("\\" + name, 0);
} }
void parse_blif(RTLIL::Design *design, std::istream &f, std::string dff_name, bool run_clean, bool sop_mode, bool wideports) void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool run_clean, bool sop_mode, bool wideports)
{ {
RTLIL::Module *module = nullptr; RTLIL::Module *module = nullptr;
RTLIL::Const *lutptr = NULL; RTLIL::Const *lutptr = NULL;

View file

@ -24,7 +24,7 @@
YOSYS_NAMESPACE_BEGIN YOSYS_NAMESPACE_BEGIN
extern void parse_blif(RTLIL::Design *design, std::istream &f, std::string dff_name, extern void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name,
bool run_clean = false, bool sop_mode = false, bool wideports = false); bool run_clean = false, bool sop_mode = false, bool wideports = false);
YOSYS_NAMESPACE_END YOSYS_NAMESPACE_END

View file

@ -1789,7 +1789,7 @@ struct VerificExtNets
new_net = new Net(name.c_str()); new_net = new Net(name.c_str());
nl->Add(new_net); nl->Add(new_net);
Net *n = route_up(new_net, port->IsOutput(), ca_nl, ca_net); Net *n YS_ATTRIBUTE(unused) = route_up(new_net, port->IsOutput(), ca_nl, ca_net);
log_assert(n == ca_net); log_assert(n == ca_net);
} }

View file

@ -292,19 +292,19 @@ Aig::Aig(Cell *cell)
if (cell->type.in(ID($not), ID($_NOT_), ID($pos), ID($_BUF_))) if (cell->type.in(ID($not), ID($_NOT_), ID($pos), ID($_BUF_)))
{ {
for (int i = 0; i < GetSize(cell->getPort(ID(Y))); i++) { for (int i = 0; i < GetSize(cell->getPort(ID::Y)); i++) {
int A = mk.inport(ID(A), i); int A = mk.inport(ID::A, i);
int Y = cell->type.in(ID($not), ID($_NOT_)) ? mk.not_gate(A) : A; int Y = cell->type.in(ID($not), ID($_NOT_)) ? mk.not_gate(A) : A;
mk.outport(Y, ID(Y), i); mk.outport(Y, ID::Y, i);
} }
goto optimize; goto optimize;
} }
if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_), ID($or), ID($_OR_), ID($_NOR_), ID($xor), ID($xnor), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_))) if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_), ID($or), ID($_OR_), ID($_NOR_), ID($xor), ID($xnor), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_)))
{ {
for (int i = 0; i < GetSize(cell->getPort(ID(Y))); i++) { for (int i = 0; i < GetSize(cell->getPort(ID::Y)); i++) {
int A = mk.inport(ID(A), i); int A = mk.inport(ID::A, i);
int B = mk.inport(ID(B), i); int B = mk.inport(ID::B, i);
int Y = cell->type.in(ID($and), ID($_AND_)) ? mk.and_gate(A, B) : int Y = cell->type.in(ID($and), ID($_AND_)) ? mk.and_gate(A, B) :
cell->type.in(ID($_NAND_)) ? mk.nand_gate(A, B) : cell->type.in(ID($_NAND_)) ? mk.nand_gate(A, B) :
cell->type.in(ID($or), ID($_OR_)) ? mk.or_gate(A, B) : cell->type.in(ID($or), ID($_OR_)) ? mk.or_gate(A, B) :
@ -313,7 +313,7 @@ Aig::Aig(Cell *cell)
cell->type.in(ID($xnor), ID($_XNOR_)) ? mk.xnor_gate(A, B) : cell->type.in(ID($xnor), ID($_XNOR_)) ? mk.xnor_gate(A, B) :
cell->type.in(ID($_ANDNOT_)) ? mk.andnot_gate(A, B) : cell->type.in(ID($_ANDNOT_)) ? mk.andnot_gate(A, B) :
cell->type.in(ID($_ORNOT_)) ? mk.ornot_gate(A, B) : -1; cell->type.in(ID($_ORNOT_)) ? mk.ornot_gate(A, B) : -1;
mk.outport(Y, ID(Y), i); mk.outport(Y, ID::Y, i);
} }
goto optimize; goto optimize;
} }
@ -321,22 +321,22 @@ Aig::Aig(Cell *cell)
if (cell->type.in(ID($mux), ID($_MUX_))) if (cell->type.in(ID($mux), ID($_MUX_)))
{ {
int S = mk.inport(ID(S)); int S = mk.inport(ID(S));
for (int i = 0; i < GetSize(cell->getPort(ID(Y))); i++) { for (int i = 0; i < GetSize(cell->getPort(ID::Y)); i++) {
int A = mk.inport(ID(A), i); int A = mk.inport(ID::A, i);
int B = mk.inport(ID(B), i); int B = mk.inport(ID::B, i);
int Y = mk.mux_gate(A, B, S); int Y = mk.mux_gate(A, B, S);
if (cell->type == ID($_NMUX_)) if (cell->type == ID($_NMUX_))
Y = mk.not_gate(Y); Y = mk.not_gate(Y);
mk.outport(Y, ID(Y), i); mk.outport(Y, ID::Y, i);
} }
goto optimize; goto optimize;
} }
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool))) if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool)))
{ {
int Y = mk.inport(ID(A), 0); int Y = mk.inport(ID::A, 0);
for (int i = 1; i < GetSize(cell->getPort(ID(A))); i++) { for (int i = 1; i < GetSize(cell->getPort(ID::A)); i++) {
int A = mk.inport(ID(A), i); int A = mk.inport(ID::A, i);
if (cell->type == ID($reduce_and)) Y = mk.and_gate(A, Y); if (cell->type == ID($reduce_and)) Y = mk.and_gate(A, Y);
if (cell->type == ID($reduce_or)) Y = mk.or_gate(A, Y); if (cell->type == ID($reduce_or)) Y = mk.or_gate(A, Y);
if (cell->type == ID($reduce_bool)) Y = mk.or_gate(A, Y); if (cell->type == ID($reduce_bool)) Y = mk.or_gate(A, Y);
@ -345,35 +345,35 @@ Aig::Aig(Cell *cell)
} }
if (cell->type == ID($reduce_xnor)) if (cell->type == ID($reduce_xnor))
Y = mk.not_gate(Y); Y = mk.not_gate(Y);
mk.outport(Y, ID(Y), 0); mk.outport(Y, ID::Y, 0);
for (int i = 1; i < GetSize(cell->getPort(ID(Y))); i++) for (int i = 1; i < GetSize(cell->getPort(ID::Y)); i++)
mk.outport(mk.bool_node(false), ID(Y), i); mk.outport(mk.bool_node(false), ID::Y, i);
goto optimize; goto optimize;
} }
if (cell->type.in(ID($logic_not), ID($logic_and), ID($logic_or))) if (cell->type.in(ID($logic_not), ID($logic_and), ID($logic_or)))
{ {
int A = mk.inport(ID(A), 0), Y = -1; int A = mk.inport(ID::A, 0), Y = -1;
for (int i = 1; i < GetSize(cell->getPort(ID(A))); i++) for (int i = 1; i < GetSize(cell->getPort(ID::A)); i++)
A = mk.or_gate(mk.inport(ID(A), i), A); A = mk.or_gate(mk.inport(ID::A, i), A);
if (cell->type.in(ID($logic_and), ID($logic_or))) { if (cell->type.in(ID($logic_and), ID($logic_or))) {
int B = mk.inport(ID(B), 0); int B = mk.inport(ID::B, 0);
for (int i = 1; i < GetSize(cell->getPort(ID(B))); i++) for (int i = 1; i < GetSize(cell->getPort(ID::B)); i++)
B = mk.or_gate(mk.inport(ID(B), i), B); B = mk.or_gate(mk.inport(ID::B, i), B);
if (cell->type == ID($logic_and)) Y = mk.and_gate(A, B); if (cell->type == ID($logic_and)) Y = mk.and_gate(A, B);
if (cell->type == ID($logic_or)) Y = mk.or_gate(A, B); if (cell->type == ID($logic_or)) Y = mk.or_gate(A, B);
} else { } else {
if (cell->type == ID($logic_not)) Y = mk.not_gate(A); if (cell->type == ID($logic_not)) Y = mk.not_gate(A);
} }
mk.outport_bool(Y, ID(Y)); mk.outport_bool(Y, ID::Y);
goto optimize; goto optimize;
} }
if (cell->type.in(ID($add), ID($sub))) if (cell->type.in(ID($add), ID($sub)))
{ {
int width = GetSize(cell->getPort(ID(Y))); int width = GetSize(cell->getPort(ID::Y));
vector<int> A = mk.inport_vec(ID(A), width); vector<int> A = mk.inport_vec(ID::A, width);
vector<int> B = mk.inport_vec(ID(B), width); vector<int> B = mk.inport_vec(ID::B, width);
int carry = mk.bool_node(false); int carry = mk.bool_node(false);
if (cell->type == ID($sub)) { if (cell->type == ID($sub)) {
for (auto &n : B) for (auto &n : B)
@ -381,15 +381,15 @@ Aig::Aig(Cell *cell)
carry = mk.not_gate(carry); carry = mk.not_gate(carry);
} }
vector<int> Y = mk.adder(A, B, carry); vector<int> Y = mk.adder(A, B, carry);
mk.outport_vec(Y, ID(Y)); mk.outport_vec(Y, ID::Y);
goto optimize; goto optimize;
} }
if (cell->type == ID($alu)) if (cell->type == ID($alu))
{ {
int width = GetSize(cell->getPort(ID(Y))); int width = GetSize(cell->getPort(ID::Y));
vector<int> A = mk.inport_vec(ID(A), width); vector<int> A = mk.inport_vec(ID::A, width);
vector<int> B = mk.inport_vec(ID(B), width); vector<int> B = mk.inport_vec(ID::B, width);
int carry = mk.inport(ID(CI)); int carry = mk.inport(ID(CI));
int binv = mk.inport(ID(BI)); int binv = mk.inport(ID(BI));
for (auto &n : B) for (auto &n : B)
@ -398,7 +398,7 @@ Aig::Aig(Cell *cell)
vector<int> Y = mk.adder(A, B, carry, &X, &CO); vector<int> Y = mk.adder(A, B, carry, &X, &CO);
for (int i = 0; i < width; i++) for (int i = 0; i < width; i++)
X[i] = mk.xor_gate(A[i], B[i]); X[i] = mk.xor_gate(A[i], B[i]);
mk.outport_vec(Y, ID(Y)); mk.outport_vec(Y, ID::Y);
mk.outport_vec(X, ID(X)); mk.outport_vec(X, ID(X));
mk.outport_vec(CO, ID(CO)); mk.outport_vec(CO, ID(CO));
goto optimize; goto optimize;
@ -406,57 +406,57 @@ Aig::Aig(Cell *cell)
if (cell->type.in(ID($eq), ID($ne))) if (cell->type.in(ID($eq), ID($ne)))
{ {
int width = max(GetSize(cell->getPort(ID(A))), GetSize(cell->getPort(ID(B)))); int width = max(GetSize(cell->getPort(ID::A)), GetSize(cell->getPort(ID::B)));
vector<int> A = mk.inport_vec(ID(A), width); vector<int> A = mk.inport_vec(ID::A, width);
vector<int> B = mk.inport_vec(ID(B), width); vector<int> B = mk.inport_vec(ID::B, width);
int Y = mk.bool_node(false); int Y = mk.bool_node(false);
for (int i = 0; i < width; i++) for (int i = 0; i < width; i++)
Y = mk.or_gate(Y, mk.xor_gate(A[i], B[i])); Y = mk.or_gate(Y, mk.xor_gate(A[i], B[i]));
if (cell->type == ID($eq)) if (cell->type == ID($eq))
Y = mk.not_gate(Y); Y = mk.not_gate(Y);
mk.outport_bool(Y, ID(Y)); mk.outport_bool(Y, ID::Y);
goto optimize; goto optimize;
} }
if (cell->type == ID($_AOI3_)) if (cell->type == ID($_AOI3_))
{ {
int A = mk.inport(ID(A)); int A = mk.inport(ID::A);
int B = mk.inport(ID(B)); int B = mk.inport(ID::B);
int C = mk.inport(ID(C)); int C = mk.inport(ID(C));
int Y = mk.nor_gate(mk.and_gate(A, B), C); int Y = mk.nor_gate(mk.and_gate(A, B), C);
mk.outport(Y, ID(Y)); mk.outport(Y, ID::Y);
goto optimize; goto optimize;
} }
if (cell->type == ID($_OAI3_)) if (cell->type == ID($_OAI3_))
{ {
int A = mk.inport(ID(A)); int A = mk.inport(ID::A);
int B = mk.inport(ID(B)); int B = mk.inport(ID::B);
int C = mk.inport(ID(C)); int C = mk.inport(ID(C));
int Y = mk.nand_gate(mk.or_gate(A, B), C); int Y = mk.nand_gate(mk.or_gate(A, B), C);
mk.outport(Y, ID(Y)); mk.outport(Y, ID::Y);
goto optimize; goto optimize;
} }
if (cell->type == ID($_AOI4_)) if (cell->type == ID($_AOI4_))
{ {
int A = mk.inport(ID(A)); int A = mk.inport(ID::A);
int B = mk.inport(ID(B)); int B = mk.inport(ID::B);
int C = mk.inport(ID(C)); int C = mk.inport(ID(C));
int D = mk.inport(ID(D)); int D = mk.inport(ID(D));
int Y = mk.nor_gate(mk.and_gate(A, B), mk.and_gate(C, D)); int Y = mk.nor_gate(mk.and_gate(A, B), mk.and_gate(C, D));
mk.outport(Y, ID(Y)); mk.outport(Y, ID::Y);
goto optimize; goto optimize;
} }
if (cell->type == ID($_OAI4_)) if (cell->type == ID($_OAI4_))
{ {
int A = mk.inport(ID(A)); int A = mk.inport(ID::A);
int B = mk.inport(ID(B)); int B = mk.inport(ID::B);
int C = mk.inport(ID(C)); int C = mk.inport(ID(C));
int D = mk.inport(ID(D)); int D = mk.inport(ID(D));
int Y = mk.nand_gate(mk.or_gate(A, B), mk.or_gate(C, D)); int Y = mk.nand_gate(mk.or_gate(A, B), mk.or_gate(C, D));
mk.outport(Y, ID(Y)); mk.outport(Y, ID::Y);
goto optimize; goto optimize;
} }

View file

@ -24,7 +24,7 @@ PRIVATE_NAMESPACE_BEGIN
void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{ {
IdString A = ID(A), Y = ID(Y); IdString A = ID::A, Y = ID::Y;
bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
int a_width = GetSize(cell->getPort(A)); int a_width = GetSize(cell->getPort(A));
@ -41,7 +41,7 @@ void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{ {
IdString A = ID(A), B = ID(B), Y = ID(Y); IdString A = ID::A, B = ID::B, Y = ID::Y;
bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
int a_width = GetSize(cell->getPort(A)); int a_width = GetSize(cell->getPort(A));
@ -71,7 +71,7 @@ void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{ {
IdString A = ID(A), Y = ID(Y); IdString A = ID::A, Y = ID::Y;
bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
int a_width = GetSize(cell->getPort(A)); int a_width = GetSize(cell->getPort(A));
@ -87,7 +87,7 @@ void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{ {
IdString A = ID(A), B = ID(B), Y = ID(Y); IdString A = ID::A, B = ID::B, Y = ID::Y;
bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
int a_width = GetSize(cell->getPort(A)); int a_width = GetSize(cell->getPort(A));
@ -114,7 +114,7 @@ void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{ {
IdString A = ID(A), Y = ID(Y); IdString A = ID::A, Y = ID::Y;
int a_width = GetSize(cell->getPort(A)); int a_width = GetSize(cell->getPort(A));
@ -124,7 +124,7 @@ void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{ {
IdString A = ID(A), B = ID(B), Y = ID(Y); IdString A = ID::A, B = ID::B, Y = ID::Y;
int a_width = GetSize(cell->getPort(A)); int a_width = GetSize(cell->getPort(A));
int b_width = GetSize(cell->getPort(B)); int b_width = GetSize(cell->getPort(B));
@ -138,7 +138,7 @@ void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
void mux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void mux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{ {
IdString A = ID(A), B = ID(B), S = ID(S), Y = ID(Y); IdString A = ID::A, B = ID::B, S = ID(S), Y = ID::Y;
int a_width = GetSize(cell->getPort(A)); int a_width = GetSize(cell->getPort(A));
int b_width = GetSize(cell->getPort(B)); int b_width = GetSize(cell->getPort(B));

View file

@ -84,7 +84,7 @@ struct CellTypes
{ {
setup_internals_eval(); setup_internals_eval();
IdString A = ID(A), B = ID(B), EN = ID(EN), Y = ID(Y); IdString A = ID::A, B = ID::B, EN = ID(EN), Y = ID::Y;
IdString SRC = ID(SRC), DST = ID(DST), DAT = ID(DAT); IdString SRC = ID(SRC), DST = ID(DST), DAT = ID(DAT);
IdString EN_SRC = ID(EN_SRC), EN_DST = ID(EN_DST); IdString EN_SRC = ID(EN_SRC), EN_DST = ID(EN_DST);
@ -121,7 +121,7 @@ struct CellTypes
ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow), ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow),
ID($logic_and), ID($logic_or), ID($concat), ID($macc) ID($logic_and), ID($logic_or), ID($concat), ID($macc)
}; };
IdString A = ID(A), B = ID(B), S = ID(S), Y = ID(Y); IdString A = ID::A, B = ID::B, S = ID(S), Y = ID::Y;
IdString P = ID(P), G = ID(G), C = ID(C), X = ID(X); IdString P = ID(P), G = ID(G), C = ID(C), X = ID(X);
IdString BI = ID(BI), CI = ID(CI), CO = ID(CO), EN = ID(EN); IdString BI = ID(BI), CI = ID(CI), CO = ID(CO), EN = ID(EN);
@ -177,19 +177,19 @@ struct CellTypes
{ {
setup_stdcells_eval(); setup_stdcells_eval();
IdString A = ID(A), E = ID(E), Y = ID(Y); IdString A = ID::A, E = ID(E), Y = ID::Y;
setup_type(ID($_TBUF_), {A, E}, {Y}, true); setup_type(ID($_TBUF_), {A, E}, {Y}, true);
} }
void setup_stdcells_eval() void setup_stdcells_eval()
{ {
IdString A = ID(A), B = ID(B), C = ID(C), D = ID(D); IdString A = ID::A, B = ID::B, C = ID(C), D = ID(D);
IdString E = ID(E), F = ID(F), G = ID(G), H = ID(H); IdString E = ID(E), F = ID(F), G = ID(G), H = ID(H);
IdString I = ID(I), J = ID(J), K = ID(K), L = ID(L); IdString I = ID(I), J = ID(J), K = ID(K), L = ID(L);
IdString M = ID(M), N = ID(N), O = ID(O), P = ID(P); IdString M = ID(M), N = ID(N), O = ID(O), P = ID(P);
IdString S = ID(S), T = ID(T), U = ID(U), V = ID(V); IdString S = ID(S), T = ID(T), U = ID(U), V = ID(V);
IdString Y = ID(Y); IdString Y = ID::Y;
setup_type(ID($_BUF_), {A}, {Y}, true); setup_type(ID($_BUF_), {A}, {Y}, true);
setup_type(ID($_NOT_), {A}, {Y}, true); setup_type(ID($_NOT_), {A}, {Y}, true);

View file

@ -128,8 +128,8 @@ struct ConstEval
RTLIL::SigSpec sig_a, sig_b, sig_s, sig_y; RTLIL::SigSpec sig_a, sig_b, sig_s, sig_y;
log_assert(cell->hasPort(ID(Y))); log_assert(cell->hasPort(ID::Y));
sig_y = values_map(assign_map(cell->getPort(ID(Y)))); sig_y = values_map(assign_map(cell->getPort(ID::Y)));
if (sig_y.is_fully_const()) if (sig_y.is_fully_const())
return true; return true;
@ -139,11 +139,11 @@ struct ConstEval
return false; return false;
} }
if (cell->hasPort(ID(A))) if (cell->hasPort(ID::A))
sig_a = cell->getPort(ID(A)); sig_a = cell->getPort(ID::A);
if (cell->hasPort(ID(B))) if (cell->hasPort(ID::B))
sig_b = cell->getPort(ID(B)); sig_b = cell->getPort(ID::B);
if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_NMUX_))) if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_NMUX_)))
{ {
@ -298,11 +298,11 @@ struct ConstEval
return false; return false;
} }
RTLIL::Const result(0, GetSize(cell->getPort(ID(Y)))); RTLIL::Const result(0, GetSize(cell->getPort(ID::Y)));
if (!macc.eval(result)) if (!macc.eval(result))
log_abort(); log_abort();
set(cell->getPort(ID(Y)), result); set(cell->getPort(ID::Y), result);
} }
else else
{ {

View file

@ -91,7 +91,7 @@ YS_NORETURN void log_cmd_error(const char *format, ...) YS_ATTRIBUTE(format(prin
static inline bool ys_debug(int n = 0) { if (log_force_debug) return true; log_debug_suppressed += n; return false; } static inline bool ys_debug(int n = 0) { if (log_force_debug) return true; log_debug_suppressed += n; return false; }
# define log_debug(...) do { if (ys_debug(1)) log(__VA_ARGS__); } while (0) # define log_debug(...) do { if (ys_debug(1)) log(__VA_ARGS__); } while (0)
#else #else
static inline bool ys_debug(int n = 0) { return false; } static inline bool ys_debug(int = 0) { return false; }
# define log_debug(_fmt, ...) do { } while (0) # define log_debug(_fmt, ...) do { } while (0)
#endif #endif

View file

@ -99,10 +99,10 @@ struct Macc
void from_cell(RTLIL::Cell *cell) void from_cell(RTLIL::Cell *cell)
{ {
RTLIL::SigSpec port_a = cell->getPort(ID(A)); RTLIL::SigSpec port_a = cell->getPort(ID::A);
ports.clear(); ports.clear();
bit_ports = cell->getPort(ID(B)); bit_ports = cell->getPort(ID::B);
std::vector<RTLIL::State> config_bits = cell->getParam(ID(CONFIG)).bits; std::vector<RTLIL::State> config_bits = cell->getParam(ID(CONFIG)).bits;
int config_cursor = 0; int config_cursor = 0;
@ -191,8 +191,8 @@ struct Macc
port_a.append(port.in_b); port_a.append(port.in_b);
} }
cell->setPort(ID(A), port_a); cell->setPort(ID::A, port_a);
cell->setPort(ID(B), bit_ports); cell->setPort(ID::B, bit_ports);
cell->setParam(ID(CONFIG), config_bits); cell->setParam(ID(CONFIG), config_bits);
cell->setParam(ID(CONFIG_WIDTH), GetSize(config_bits)); cell->setParam(ID(CONFIG_WIDTH), GetSize(config_bits));
cell->setParam(ID(A_WIDTH), GetSize(port_a)); cell->setParam(ID(A_WIDTH), GetSize(port_a));

View file

@ -717,7 +717,7 @@ void RTLIL::Module::makeblackbox()
processes.clear(); processes.clear();
remove(delwires); remove(delwires);
set_bool_attribute(ID(blackbox)); set_bool_attribute(ID::blackbox);
} }
void RTLIL::Module::reprocess_module(RTLIL::Design *, dict<RTLIL::IdString, RTLIL::Module *>) void RTLIL::Module::reprocess_module(RTLIL::Design *, dict<RTLIL::IdString, RTLIL::Module *>)
@ -845,8 +845,8 @@ namespace {
if (cell->type.in(ID($not), ID($pos), ID($neg))) { if (cell->type.in(ID($not), ID($pos), ID($neg))) {
param_bool(ID(A_SIGNED)); param_bool(ID(A_SIGNED));
port(ID(A), param(ID(A_WIDTH))); port(ID::A, param(ID(A_WIDTH)));
port(ID(Y), param(ID(Y_WIDTH))); port(ID::Y, param(ID(Y_WIDTH)));
check_expected(); check_expected();
return; return;
} }
@ -854,17 +854,17 @@ namespace {
if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor))) { if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor))) {
param_bool(ID(A_SIGNED)); param_bool(ID(A_SIGNED));
param_bool(ID(B_SIGNED)); param_bool(ID(B_SIGNED));
port(ID(A), param(ID(A_WIDTH))); port(ID::A, param(ID(A_WIDTH)));
port(ID(B), param(ID(B_WIDTH))); port(ID::B, param(ID(B_WIDTH)));
port(ID(Y), param(ID(Y_WIDTH))); port(ID::Y, param(ID(Y_WIDTH)));
check_expected(); check_expected();
return; return;
} }
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool))) { if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool))) {
param_bool(ID(A_SIGNED)); param_bool(ID(A_SIGNED));
port(ID(A), param(ID(A_WIDTH))); port(ID::A, param(ID(A_WIDTH)));
port(ID(Y), param(ID(Y_WIDTH))); port(ID::Y, param(ID(Y_WIDTH)));
check_expected(); check_expected();
return; return;
} }
@ -872,9 +872,9 @@ namespace {
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) { if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) {
param_bool(ID(A_SIGNED)); param_bool(ID(A_SIGNED));
param_bool(ID(B_SIGNED)); param_bool(ID(B_SIGNED));
port(ID(A), param(ID(A_WIDTH))); port(ID::A, param(ID(A_WIDTH)));
port(ID(B), param(ID(B_WIDTH))); port(ID::B, param(ID(B_WIDTH)));
port(ID(Y), param(ID(Y_WIDTH))); port(ID::Y, param(ID(Y_WIDTH)));
check_expected(false); check_expected(false);
return; return;
} }
@ -882,9 +882,9 @@ namespace {
if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) { if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) {
param_bool(ID(A_SIGNED)); param_bool(ID(A_SIGNED));
param_bool(ID(B_SIGNED)); param_bool(ID(B_SIGNED));
port(ID(A), param(ID(A_WIDTH))); port(ID::A, param(ID(A_WIDTH)));
port(ID(B), param(ID(B_WIDTH))); port(ID::B, param(ID(B_WIDTH)));
port(ID(Y), param(ID(Y_WIDTH))); port(ID::Y, param(ID(Y_WIDTH)));
check_expected(); check_expected();
return; return;
} }
@ -892,19 +892,19 @@ namespace {
if (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow))) { if (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow))) {
param_bool(ID(A_SIGNED)); param_bool(ID(A_SIGNED));
param_bool(ID(B_SIGNED)); param_bool(ID(B_SIGNED));
port(ID(A), param(ID(A_WIDTH))); port(ID::A, param(ID(A_WIDTH)));
port(ID(B), param(ID(B_WIDTH))); port(ID::B, param(ID(B_WIDTH)));
port(ID(Y), param(ID(Y_WIDTH))); port(ID::Y, param(ID(Y_WIDTH)));
check_expected(cell->type != ID($pow)); check_expected(cell->type != ID($pow));
return; return;
} }
if (cell->type == ID($fa)) { if (cell->type == ID($fa)) {
port(ID(A), param(ID(WIDTH))); port(ID::A, param(ID(WIDTH)));
port(ID(B), param(ID(WIDTH))); port(ID::B, param(ID(WIDTH)));
port(ID(C), param(ID(WIDTH))); port(ID(C), param(ID(WIDTH)));
port(ID(X), param(ID(WIDTH))); port(ID(X), param(ID(WIDTH)));
port(ID(Y), param(ID(WIDTH))); port(ID::Y, param(ID(WIDTH)));
check_expected(); check_expected();
return; return;
} }
@ -921,12 +921,12 @@ namespace {
if (cell->type == ID($alu)) { if (cell->type == ID($alu)) {
param_bool(ID(A_SIGNED)); param_bool(ID(A_SIGNED));
param_bool(ID(B_SIGNED)); param_bool(ID(B_SIGNED));
port(ID(A), param(ID(A_WIDTH))); port(ID::A, param(ID(A_WIDTH)));
port(ID(B), param(ID(B_WIDTH))); port(ID::B, param(ID(B_WIDTH)));
port(ID(CI), 1); port(ID(CI), 1);
port(ID(BI), 1); port(ID(BI), 1);
port(ID(X), param(ID(Y_WIDTH))); port(ID(X), param(ID(Y_WIDTH)));
port(ID(Y), param(ID(Y_WIDTH))); port(ID::Y, param(ID(Y_WIDTH)));
port(ID(CO), param(ID(Y_WIDTH))); port(ID(CO), param(ID(Y_WIDTH)));
check_expected(); check_expected();
return; return;
@ -935,9 +935,9 @@ namespace {
if (cell->type == ID($macc)) { if (cell->type == ID($macc)) {
param(ID(CONFIG)); param(ID(CONFIG));
param(ID(CONFIG_WIDTH)); param(ID(CONFIG_WIDTH));
port(ID(A), param(ID(A_WIDTH))); port(ID::A, param(ID(A_WIDTH)));
port(ID(B), param(ID(B_WIDTH))); port(ID::B, param(ID(B_WIDTH)));
port(ID(Y), param(ID(Y_WIDTH))); port(ID::Y, param(ID(Y_WIDTH)));
check_expected(); check_expected();
Macc().from_cell(cell); Macc().from_cell(cell);
return; return;
@ -945,8 +945,8 @@ namespace {
if (cell->type == ID($logic_not)) { if (cell->type == ID($logic_not)) {
param_bool(ID(A_SIGNED)); param_bool(ID(A_SIGNED));
port(ID(A), param(ID(A_WIDTH))); port(ID::A, param(ID(A_WIDTH)));
port(ID(Y), param(ID(Y_WIDTH))); port(ID::Y, param(ID(Y_WIDTH)));
check_expected(); check_expected();
return; return;
} }
@ -954,17 +954,17 @@ namespace {
if (cell->type.in(ID($logic_and), ID($logic_or))) { if (cell->type.in(ID($logic_and), ID($logic_or))) {
param_bool(ID(A_SIGNED)); param_bool(ID(A_SIGNED));
param_bool(ID(B_SIGNED)); param_bool(ID(B_SIGNED));
port(ID(A), param(ID(A_WIDTH))); port(ID::A, param(ID(A_WIDTH)));
port(ID(B), param(ID(B_WIDTH))); port(ID::B, param(ID(B_WIDTH)));
port(ID(Y), param(ID(Y_WIDTH))); port(ID::Y, param(ID(Y_WIDTH)));
check_expected(false); check_expected(false);
return; return;
} }
if (cell->type == ID($slice)) { if (cell->type == ID($slice)) {
param(ID(OFFSET)); param(ID(OFFSET));
port(ID(A), param(ID(A_WIDTH))); port(ID::A, param(ID(A_WIDTH)));
port(ID(Y), param(ID(Y_WIDTH))); port(ID::Y, param(ID(Y_WIDTH)));
if (param(ID(OFFSET)) + param(ID(Y_WIDTH)) > param(ID(A_WIDTH))) if (param(ID(OFFSET)) + param(ID(Y_WIDTH)) > param(ID(A_WIDTH)))
error(__LINE__); error(__LINE__);
check_expected(); check_expected();
@ -972,35 +972,35 @@ namespace {
} }
if (cell->type == ID($concat)) { if (cell->type == ID($concat)) {
port(ID(A), param(ID(A_WIDTH))); port(ID::A, param(ID(A_WIDTH)));
port(ID(B), param(ID(B_WIDTH))); port(ID::B, param(ID(B_WIDTH)));
port(ID(Y), param(ID(A_WIDTH)) + param(ID(B_WIDTH))); port(ID::Y, param(ID(A_WIDTH)) + param(ID(B_WIDTH)));
check_expected(); check_expected();
return; return;
} }
if (cell->type == ID($mux)) { if (cell->type == ID($mux)) {
port(ID(A), param(ID(WIDTH))); port(ID::A, param(ID(WIDTH)));
port(ID(B), param(ID(WIDTH))); port(ID::B, param(ID(WIDTH)));
port(ID(S), 1); port(ID(S), 1);
port(ID(Y), param(ID(WIDTH))); port(ID::Y, param(ID(WIDTH)));
check_expected(); check_expected();
return; return;
} }
if (cell->type == ID($pmux)) { if (cell->type == ID($pmux)) {
port(ID(A), param(ID(WIDTH))); port(ID::A, param(ID(WIDTH)));
port(ID(B), param(ID(WIDTH)) * param(ID(S_WIDTH))); port(ID::B, param(ID(WIDTH)) * param(ID(S_WIDTH)));
port(ID(S), param(ID(S_WIDTH))); port(ID(S), param(ID(S_WIDTH)));
port(ID(Y), param(ID(WIDTH))); port(ID::Y, param(ID(WIDTH)));
check_expected(); check_expected();
return; return;
} }
if (cell->type == ID($lut)) { if (cell->type == ID($lut)) {
param(ID(LUT)); param(ID(LUT));
port(ID(A), param(ID(WIDTH))); port(ID::A, param(ID(WIDTH)));
port(ID(Y), 1); port(ID::Y, 1);
check_expected(); check_expected();
return; return;
} }
@ -1008,8 +1008,8 @@ namespace {
if (cell->type == ID($sop)) { if (cell->type == ID($sop)) {
param(ID(DEPTH)); param(ID(DEPTH));
param(ID(TABLE)); param(ID(TABLE));
port(ID(A), param(ID(WIDTH))); port(ID::A, param(ID(WIDTH)));
port(ID(Y), 1); port(ID::Y, 1);
check_expected(); check_expected();
return; return;
} }
@ -1175,36 +1175,36 @@ namespace {
} }
if (cell->type == ID($tribuf)) { if (cell->type == ID($tribuf)) {
port(ID(A), param(ID(WIDTH))); port(ID::A, param(ID(WIDTH)));
port(ID(Y), param(ID(WIDTH))); port(ID::Y, param(ID(WIDTH)));
port(ID(EN), 1); port(ID(EN), 1);
check_expected(); check_expected();
return; return;
} }
if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) { if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) {
port(ID(A), 1); port(ID::A, 1);
port(ID(EN), 1); port(ID(EN), 1);
check_expected(); check_expected();
return; return;
} }
if (cell->type == ID($initstate)) { if (cell->type == ID($initstate)) {
port(ID(Y), 1); port(ID::Y, 1);
check_expected(); check_expected();
return; return;
} }
if (cell->type.in(ID($anyconst), ID($anyseq), ID($allconst), ID($allseq))) { if (cell->type.in(ID($anyconst), ID($anyseq), ID($allconst), ID($allseq))) {
port(ID(Y), param(ID(WIDTH))); port(ID::Y, param(ID(WIDTH)));
check_expected(); check_expected();
return; return;
} }
if (cell->type == ID($equiv)) { if (cell->type == ID($equiv)) {
port(ID(A), 1); port(ID::A, 1);
port(ID(B), 1); port(ID::B, 1);
port(ID(Y), 1); port(ID::Y, 1);
check_expected(); check_expected();
return; return;
} }
@ -1831,8 +1831,8 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth
cell->parameters[ID(A_SIGNED)] = is_signed; \ cell->parameters[ID(A_SIGNED)] = is_signed; \
cell->parameters[ID(A_WIDTH)] = sig_a.size(); \ cell->parameters[ID(A_WIDTH)] = sig_a.size(); \
cell->parameters[ID(Y_WIDTH)] = sig_y.size(); \ cell->parameters[ID(Y_WIDTH)] = sig_y.size(); \
cell->setPort(ID(A), sig_a); \ cell->setPort(ID::A, sig_a); \
cell->setPort(ID(Y), sig_y); \ cell->setPort(ID::Y, sig_y); \
cell->set_src_attribute(src); \ cell->set_src_attribute(src); \
return cell; \ return cell; \
} \ } \
@ -1860,9 +1860,9 @@ DEF_METHOD(LogicNot, 1, ID($logic_not))
cell->parameters[ID(A_WIDTH)] = sig_a.size(); \ cell->parameters[ID(A_WIDTH)] = sig_a.size(); \
cell->parameters[ID(B_WIDTH)] = sig_b.size(); \ cell->parameters[ID(B_WIDTH)] = sig_b.size(); \
cell->parameters[ID(Y_WIDTH)] = sig_y.size(); \ cell->parameters[ID(Y_WIDTH)] = sig_y.size(); \
cell->setPort(ID(A), sig_a); \ cell->setPort(ID::A, sig_a); \
cell->setPort(ID(B), sig_b); \ cell->setPort(ID::B, sig_b); \
cell->setPort(ID(Y), sig_y); \ cell->setPort(ID::Y, sig_y); \
cell->set_src_attribute(src); \ cell->set_src_attribute(src); \
return cell; \ return cell; \
} \ } \
@ -1903,10 +1903,10 @@ DEF_METHOD(LogicOr, 1, ID($logic_or))
RTLIL::Cell *cell = addCell(name, _type); \ RTLIL::Cell *cell = addCell(name, _type); \
cell->parameters[ID(WIDTH)] = sig_a.size(); \ cell->parameters[ID(WIDTH)] = sig_a.size(); \
if (_pmux) cell->parameters[ID(S_WIDTH)] = sig_s.size(); \ if (_pmux) cell->parameters[ID(S_WIDTH)] = sig_s.size(); \
cell->setPort(ID(A), sig_a); \ cell->setPort(ID::A, sig_a); \
cell->setPort(ID(B), sig_b); \ cell->setPort(ID::B, sig_b); \
cell->setPort(ID(S), sig_s); \ cell->setPort(ID(S), sig_s); \
cell->setPort(ID(Y), sig_y); \ cell->setPort(ID::Y, sig_y); \
cell->set_src_attribute(src); \ cell->set_src_attribute(src); \
return cell; \ return cell; \
} \ } \
@ -2006,9 +2006,9 @@ RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, R
cell->parameters[ID(A_WIDTH)] = sig_a.size(); cell->parameters[ID(A_WIDTH)] = sig_a.size();
cell->parameters[ID(B_WIDTH)] = sig_b.size(); cell->parameters[ID(B_WIDTH)] = sig_b.size();
cell->parameters[ID(Y_WIDTH)] = sig_y.size(); cell->parameters[ID(Y_WIDTH)] = sig_y.size();
cell->setPort(ID(A), sig_a); cell->setPort(ID::A, sig_a);
cell->setPort(ID(B), sig_b); cell->setPort(ID::B, sig_b);
cell->setPort(ID(Y), sig_y); cell->setPort(ID::Y, sig_y);
cell->set_src_attribute(src); cell->set_src_attribute(src);
return cell; return cell;
} }
@ -2019,8 +2019,8 @@ RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, RTLIL::SigSpec sig_a,
cell->parameters[ID(A_WIDTH)] = sig_a.size(); cell->parameters[ID(A_WIDTH)] = sig_a.size();
cell->parameters[ID(Y_WIDTH)] = sig_y.size(); cell->parameters[ID(Y_WIDTH)] = sig_y.size();
cell->parameters[ID(OFFSET)] = offset; cell->parameters[ID(OFFSET)] = offset;
cell->setPort(ID(A), sig_a); cell->setPort(ID::A, sig_a);
cell->setPort(ID(Y), sig_y); cell->setPort(ID::Y, sig_y);
cell->set_src_attribute(src); cell->set_src_attribute(src);
return cell; return cell;
} }
@ -2030,9 +2030,9 @@ RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a
RTLIL::Cell *cell = addCell(name, ID($concat)); RTLIL::Cell *cell = addCell(name, ID($concat));
cell->parameters[ID(A_WIDTH)] = sig_a.size(); cell->parameters[ID(A_WIDTH)] = sig_a.size();
cell->parameters[ID(B_WIDTH)] = sig_b.size(); cell->parameters[ID(B_WIDTH)] = sig_b.size();
cell->setPort(ID(A), sig_a); cell->setPort(ID::A, sig_a);
cell->setPort(ID(B), sig_b); cell->setPort(ID::B, sig_b);
cell->setPort(ID(Y), sig_y); cell->setPort(ID::Y, sig_y);
cell->set_src_attribute(src); cell->set_src_attribute(src);
return cell; return cell;
} }
@ -2042,8 +2042,8 @@ RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_a, R
RTLIL::Cell *cell = addCell(name, ID($lut)); RTLIL::Cell *cell = addCell(name, ID($lut));
cell->parameters[ID(LUT)] = lut; cell->parameters[ID(LUT)] = lut;
cell->parameters[ID(WIDTH)] = sig_a.size(); cell->parameters[ID(WIDTH)] = sig_a.size();
cell->setPort(ID(A), sig_a); cell->setPort(ID::A, sig_a);
cell->setPort(ID(Y), sig_y); cell->setPort(ID::Y, sig_y);
cell->set_src_attribute(src); cell->set_src_attribute(src);
return cell; return cell;
} }
@ -2052,9 +2052,9 @@ RTLIL::Cell* RTLIL::Module::addTribuf(RTLIL::IdString name, RTLIL::SigSpec sig_a
{ {
RTLIL::Cell *cell = addCell(name, ID($tribuf)); RTLIL::Cell *cell = addCell(name, ID($tribuf));
cell->parameters[ID(WIDTH)] = sig_a.size(); cell->parameters[ID(WIDTH)] = sig_a.size();
cell->setPort(ID(A), sig_a); cell->setPort(ID::A, sig_a);
cell->setPort(ID(EN), sig_en); cell->setPort(ID(EN), sig_en);
cell->setPort(ID(Y), sig_y); cell->setPort(ID::Y, sig_y);
cell->set_src_attribute(src); cell->set_src_attribute(src);
return cell; return cell;
} }
@ -2062,7 +2062,7 @@ RTLIL::Cell* RTLIL::Module::addTribuf(RTLIL::IdString name, RTLIL::SigSpec sig_a
RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
{ {
RTLIL::Cell *cell = addCell(name, ID($assert)); RTLIL::Cell *cell = addCell(name, ID($assert));
cell->setPort(ID(A), sig_a); cell->setPort(ID::A, sig_a);
cell->setPort(ID(EN), sig_en); cell->setPort(ID(EN), sig_en);
cell->set_src_attribute(src); cell->set_src_attribute(src);
return cell; return cell;
@ -2071,7 +2071,7 @@ RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a
RTLIL::Cell* RTLIL::Module::addAssume(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) RTLIL::Cell* RTLIL::Module::addAssume(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
{ {
RTLIL::Cell *cell = addCell(name, ID($assume)); RTLIL::Cell *cell = addCell(name, ID($assume));
cell->setPort(ID(A), sig_a); cell->setPort(ID::A, sig_a);
cell->setPort(ID(EN), sig_en); cell->setPort(ID(EN), sig_en);
cell->set_src_attribute(src); cell->set_src_attribute(src);
return cell; return cell;
@ -2080,7 +2080,7 @@ RTLIL::Cell* RTLIL::Module::addAssume(RTLIL::IdString name, RTLIL::SigSpec sig_a
RTLIL::Cell* RTLIL::Module::addLive(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) RTLIL::Cell* RTLIL::Module::addLive(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
{ {
RTLIL::Cell *cell = addCell(name, ID($live)); RTLIL::Cell *cell = addCell(name, ID($live));
cell->setPort(ID(A), sig_a); cell->setPort(ID::A, sig_a);
cell->setPort(ID(EN), sig_en); cell->setPort(ID(EN), sig_en);
cell->set_src_attribute(src); cell->set_src_attribute(src);
return cell; return cell;
@ -2089,7 +2089,7 @@ RTLIL::Cell* RTLIL::Module::addLive(RTLIL::IdString name, RTLIL::SigSpec sig_a,
RTLIL::Cell* RTLIL::Module::addFair(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) RTLIL::Cell* RTLIL::Module::addFair(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
{ {
RTLIL::Cell *cell = addCell(name, ID($fair)); RTLIL::Cell *cell = addCell(name, ID($fair));
cell->setPort(ID(A), sig_a); cell->setPort(ID::A, sig_a);
cell->setPort(ID(EN), sig_en); cell->setPort(ID(EN), sig_en);
cell->set_src_attribute(src); cell->set_src_attribute(src);
return cell; return cell;
@ -2098,7 +2098,7 @@ RTLIL::Cell* RTLIL::Module::addFair(RTLIL::IdString name, RTLIL::SigSpec sig_a,
RTLIL::Cell* RTLIL::Module::addCover(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) RTLIL::Cell* RTLIL::Module::addCover(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
{ {
RTLIL::Cell *cell = addCell(name, ID($cover)); RTLIL::Cell *cell = addCell(name, ID($cover));
cell->setPort(ID(A), sig_a); cell->setPort(ID::A, sig_a);
cell->setPort(ID(EN), sig_en); cell->setPort(ID(EN), sig_en);
cell->set_src_attribute(src); cell->set_src_attribute(src);
return cell; return cell;
@ -2107,9 +2107,9 @@ RTLIL::Cell* RTLIL::Module::addCover(RTLIL::IdString name, RTLIL::SigSpec sig_a,
RTLIL::Cell* RTLIL::Module::addEquiv(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src) RTLIL::Cell* RTLIL::Module::addEquiv(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src)
{ {
RTLIL::Cell *cell = addCell(name, ID($equiv)); RTLIL::Cell *cell = addCell(name, ID($equiv));
cell->setPort(ID(A), sig_a); cell->setPort(ID::A, sig_a);
cell->setPort(ID(B), sig_b); cell->setPort(ID::B, sig_b);
cell->setPort(ID(Y), sig_y); cell->setPort(ID::Y, sig_y);
cell->set_src_attribute(src); cell->set_src_attribute(src);
return cell; return cell;
} }
@ -2308,7 +2308,7 @@ RTLIL::SigSpec RTLIL::Module::Anyconst(RTLIL::IdString name, int width, const st
RTLIL::SigSpec sig = addWire(NEW_ID, width); RTLIL::SigSpec sig = addWire(NEW_ID, width);
Cell *cell = addCell(name, ID($anyconst)); Cell *cell = addCell(name, ID($anyconst));
cell->setParam(ID(WIDTH), width); cell->setParam(ID(WIDTH), width);
cell->setPort(ID(Y), sig); cell->setPort(ID::Y, sig);
cell->set_src_attribute(src); cell->set_src_attribute(src);
return sig; return sig;
} }
@ -2318,7 +2318,7 @@ RTLIL::SigSpec RTLIL::Module::Anyseq(RTLIL::IdString name, int width, const std:
RTLIL::SigSpec sig = addWire(NEW_ID, width); RTLIL::SigSpec sig = addWire(NEW_ID, width);
Cell *cell = addCell(name, ID($anyseq)); Cell *cell = addCell(name, ID($anyseq));
cell->setParam(ID(WIDTH), width); cell->setParam(ID(WIDTH), width);
cell->setPort(ID(Y), sig); cell->setPort(ID::Y, sig);
cell->set_src_attribute(src); cell->set_src_attribute(src);
return sig; return sig;
} }
@ -2328,7 +2328,7 @@ RTLIL::SigSpec RTLIL::Module::Allconst(RTLIL::IdString name, int width, const st
RTLIL::SigSpec sig = addWire(NEW_ID, width); RTLIL::SigSpec sig = addWire(NEW_ID, width);
Cell *cell = addCell(name, ID($allconst)); Cell *cell = addCell(name, ID($allconst));
cell->setParam(ID(WIDTH), width); cell->setParam(ID(WIDTH), width);
cell->setPort(ID(Y), sig); cell->setPort(ID::Y, sig);
cell->set_src_attribute(src); cell->set_src_attribute(src);
return sig; return sig;
} }
@ -2338,7 +2338,7 @@ RTLIL::SigSpec RTLIL::Module::Allseq(RTLIL::IdString name, int width, const std:
RTLIL::SigSpec sig = addWire(NEW_ID, width); RTLIL::SigSpec sig = addWire(NEW_ID, width);
Cell *cell = addCell(name, ID($allseq)); Cell *cell = addCell(name, ID($allseq));
cell->setParam(ID(WIDTH), width); cell->setParam(ID(WIDTH), width);
cell->setPort(ID(Y), sig); cell->setPort(ID::Y, sig);
cell->set_src_attribute(src); cell->set_src_attribute(src);
return sig; return sig;
} }
@ -2347,7 +2347,7 @@ RTLIL::SigSpec RTLIL::Module::Initstate(RTLIL::IdString name, const std::string
{ {
RTLIL::SigSpec sig = addWire(NEW_ID); RTLIL::SigSpec sig = addWire(NEW_ID);
Cell *cell = addCell(name, ID($initstate)); Cell *cell = addCell(name, ID($initstate));
cell->setPort(ID(Y), sig); cell->setPort(ID::Y, sig);
cell->set_src_attribute(src); cell->set_src_attribute(src);
return sig; return sig;
} }
@ -2569,7 +2569,7 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
return; return;
if (type == ID($mux) || type == ID($pmux)) { if (type == ID($mux) || type == ID($pmux)) {
parameters[ID(WIDTH)] = GetSize(connections_[ID(Y)]); parameters[ID(WIDTH)] = GetSize(connections_[ID::Y]);
if (type == ID($pmux)) if (type == ID($pmux))
parameters[ID(S_WIDTH)] = GetSize(connections_[ID(S)]); parameters[ID(S_WIDTH)] = GetSize(connections_[ID(S)]);
check(); check();
@ -2577,12 +2577,12 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
} }
if (type == ID($lut) || type == ID($sop)) { if (type == ID($lut) || type == ID($sop)) {
parameters[ID(WIDTH)] = GetSize(connections_[ID(A)]); parameters[ID(WIDTH)] = GetSize(connections_[ID::A]);
return; return;
} }
if (type == ID($fa)) { if (type == ID($fa)) {
parameters[ID(WIDTH)] = GetSize(connections_[ID(Y)]); parameters[ID(WIDTH)] = GetSize(connections_[ID::Y]);
return; return;
} }
@ -2593,28 +2593,28 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
bool signedness_ab = !type.in(ID($slice), ID($concat), ID($macc)); bool signedness_ab = !type.in(ID($slice), ID($concat), ID($macc));
if (connections_.count(ID(A))) { if (connections_.count(ID::A)) {
if (signedness_ab) { if (signedness_ab) {
if (set_a_signed) if (set_a_signed)
parameters[ID(A_SIGNED)] = true; parameters[ID(A_SIGNED)] = true;
else if (parameters.count(ID(A_SIGNED)) == 0) else if (parameters.count(ID(A_SIGNED)) == 0)
parameters[ID(A_SIGNED)] = false; parameters[ID(A_SIGNED)] = false;
} }
parameters[ID(A_WIDTH)] = GetSize(connections_[ID(A)]); parameters[ID(A_WIDTH)] = GetSize(connections_[ID::A]);
} }
if (connections_.count(ID(B))) { if (connections_.count(ID::B)) {
if (signedness_ab) { if (signedness_ab) {
if (set_b_signed) if (set_b_signed)
parameters[ID(B_SIGNED)] = true; parameters[ID(B_SIGNED)] = true;
else if (parameters.count(ID(B_SIGNED)) == 0) else if (parameters.count(ID(B_SIGNED)) == 0)
parameters[ID(B_SIGNED)] = false; parameters[ID(B_SIGNED)] = false;
} }
parameters[ID(B_WIDTH)] = GetSize(connections_[ID(B)]); parameters[ID(B_WIDTH)] = GetSize(connections_[ID::B]);
} }
if (connections_.count(ID(Y))) if (connections_.count(ID::Y))
parameters[ID(Y_WIDTH)] = GetSize(connections_[ID(Y)]); parameters[ID(Y_WIDTH)] = GetSize(connections_[ID::Y]);
if (connections_.count(ID(Q))) if (connections_.count(ID(Q)))
parameters[ID(WIDTH)] = GetSize(connections_[ID(Q)]); parameters[ID(WIDTH)] = GetSize(connections_[ID(Q)]);

View file

@ -281,9 +281,9 @@ struct SatGen
if (model_undef && (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod)) || is_arith_compare)) if (model_undef && (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod)) || is_arith_compare))
{ {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
if (is_arith_compare) if (is_arith_compare)
extendSignalWidth(undef_a, undef_b, cell, true); extendSignalWidth(undef_a, undef_b, cell, true);
else else
@ -293,8 +293,8 @@ struct SatGen
int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); int undef_any_b = ez->expression(ezSAT::OpOr, undef_b);
int undef_y_bit = ez->OR(undef_any_a, undef_any_b); int undef_y_bit = ez->OR(undef_any_a, undef_any_b);
if (cell->type == ID($div) || cell->type == ID($mod)) { if (cell->type.in(ID($div), ID($mod))) {
std::vector<int> b = importSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> b = importSigSpec(cell->getPort(ID::B), timestep);
undef_y_bit = ez->OR(undef_y_bit, ez->NOT(ez->expression(ezSAT::OpOr, b))); undef_y_bit = ez->OR(undef_y_bit, ez->NOT(ez->expression(ezSAT::OpOr, b)));
} }
@ -313,24 +313,24 @@ struct SatGen
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_),
ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($sub))) ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($sub)))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidth(a, b, y, cell); extendSignalWidth(a, b, y, cell);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
if (cell->type == ID($and) || cell->type == ID($_AND_)) if (cell->type.in(ID($and), ID($_AND_)))
ez->assume(ez->vec_eq(ez->vec_and(a, b), yy)); ez->assume(ez->vec_eq(ez->vec_and(a, b), yy));
if (cell->type == ID($_NAND_)) if (cell->type == ID($_NAND_))
ez->assume(ez->vec_eq(ez->vec_not(ez->vec_and(a, b)), yy)); ez->assume(ez->vec_eq(ez->vec_not(ez->vec_and(a, b)), yy));
if (cell->type == ID($or) || cell->type == ID($_OR_)) if (cell->type.in(ID($or), ID($_OR_)))
ez->assume(ez->vec_eq(ez->vec_or(a, b), yy)); ez->assume(ez->vec_eq(ez->vec_or(a, b), yy));
if (cell->type == ID($_NOR_)) if (cell->type == ID($_NOR_))
ez->assume(ez->vec_eq(ez->vec_not(ez->vec_or(a, b)), yy)); ez->assume(ez->vec_eq(ez->vec_not(ez->vec_or(a, b)), yy));
if (cell->type == ID($xor) || cell->type == ID($_XOR_)) if (cell->type.in(ID($xor), ID($_XOR_)))
ez->assume(ez->vec_eq(ez->vec_xor(a, b), yy)); ez->assume(ez->vec_eq(ez->vec_xor(a, b), yy));
if (cell->type == ID($xnor) || cell->type == ID($_XNOR_)) if (cell->type.in(ID($xnor), ID($_XNOR_)))
ez->assume(ez->vec_eq(ez->vec_not(ez->vec_xor(a, b)), yy)); ez->assume(ez->vec_eq(ez->vec_not(ez->vec_xor(a, b)), yy));
if (cell->type == ID($_ANDNOT_)) if (cell->type == ID($_ANDNOT_))
ez->assume(ez->vec_eq(ez->vec_and(a, ez->vec_not(b)), yy)); ez->assume(ez->vec_eq(ez->vec_and(a, ez->vec_not(b)), yy));
@ -343,9 +343,9 @@ struct SatGen
if (model_undef && !arith_undef_handled) if (model_undef && !arith_undef_handled)
{ {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidth(undef_a, undef_b, undef_y, cell, false); extendSignalWidth(undef_a, undef_b, undef_y, cell, false);
if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_))) { if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_))) {
@ -384,7 +384,7 @@ struct SatGen
} }
else if (model_undef) else if (model_undef)
{ {
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
undefGating(y, yy, undef_y); undefGating(y, yy, undef_y);
} }
return true; return true;
@ -395,11 +395,11 @@ struct SatGen
bool aoi_mode = cell->type.in(ID($_AOI3_), ID($_AOI4_)); bool aoi_mode = cell->type.in(ID($_AOI3_), ID($_AOI4_));
bool three_mode = cell->type.in(ID($_AOI3_), ID($_OAI3_)); bool three_mode = cell->type.in(ID($_AOI3_), ID($_OAI3_));
int a = importDefSigSpec(cell->getPort(ID(A)), timestep).at(0); int a = importDefSigSpec(cell->getPort(ID::A), timestep).at(0);
int b = importDefSigSpec(cell->getPort(ID(B)), timestep).at(0); int b = importDefSigSpec(cell->getPort(ID::B), timestep).at(0);
int c = importDefSigSpec(cell->getPort(ID(C)), timestep).at(0); int c = importDefSigSpec(cell->getPort(ID(C)), timestep).at(0);
int d = three_mode ? (aoi_mode ? ez->CONST_TRUE : ez->CONST_FALSE) : importDefSigSpec(cell->getPort(ID(D)), timestep).at(0); int d = three_mode ? (aoi_mode ? ez->CONST_TRUE : ez->CONST_FALSE) : importDefSigSpec(cell->getPort(ID(D)), timestep).at(0);
int y = importDefSigSpec(cell->getPort(ID(Y)), timestep).at(0); int y = importDefSigSpec(cell->getPort(ID::Y), timestep).at(0);
int yy = model_undef ? ez->literal() : y; int yy = model_undef ? ez->literal() : y;
if (cell->type.in(ID($_AOI3_), ID($_AOI4_))) if (cell->type.in(ID($_AOI3_), ID($_AOI4_)))
@ -409,11 +409,11 @@ struct SatGen
if (model_undef) if (model_undef)
{ {
int undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep).at(0); int undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep).at(0);
int undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep).at(0); int undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep).at(0);
int undef_c = importUndefSigSpec(cell->getPort(ID(C)), timestep).at(0); int undef_c = importUndefSigSpec(cell->getPort(ID(C)), timestep).at(0);
int undef_d = three_mode ? ez->CONST_FALSE : importUndefSigSpec(cell->getPort(ID(D)), timestep).at(0); int undef_d = three_mode ? ez->CONST_FALSE : importUndefSigSpec(cell->getPort(ID(D)), timestep).at(0);
int undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep).at(0); int undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep).at(0);
if (aoi_mode) if (aoi_mode)
{ {
@ -456,18 +456,18 @@ struct SatGen
return true; return true;
} }
if (cell->type == ID($_NOT_) || cell->type == ID($not)) if (cell->type.in(ID($_NOT_), ID($not)))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidthUnary(a, y, cell); extendSignalWidthUnary(a, y, cell);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
ez->assume(ez->vec_eq(ez->vec_not(a), yy)); ez->assume(ez->vec_eq(ez->vec_not(a), yy));
if (model_undef) { if (model_undef) {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidthUnary(undef_a, undef_y, cell, false); extendSignalWidthUnary(undef_a, undef_y, cell, false);
ez->assume(ez->vec_eq(undef_a, undef_y)); ez->assume(ez->vec_eq(undef_a, undef_y));
undefGating(y, yy, undef_y); undefGating(y, yy, undef_y);
@ -475,12 +475,12 @@ struct SatGen
return true; return true;
} }
if (cell->type == ID($_MUX_) || cell->type == ID($mux) || cell->type == ID($_NMUX_)) if (cell->type.in(ID($_MUX_), ID($mux), ID($_NMUX_)))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> s = importDefSigSpec(cell->getPort(ID(S)), timestep); std::vector<int> s = importDefSigSpec(cell->getPort(ID(S)), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
if (cell->type == ID($_NMUX_)) if (cell->type == ID($_NMUX_))
@ -490,10 +490,10 @@ struct SatGen
if (model_undef) if (model_undef)
{ {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> undef_s = importUndefSigSpec(cell->getPort(ID(S)), timestep); std::vector<int> undef_s = importUndefSigSpec(cell->getPort(ID(S)), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> unequal_ab = ez->vec_not(ez->vec_iff(a, b)); std::vector<int> unequal_ab = ez->vec_not(ez->vec_iff(a, b));
std::vector<int> undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b)); std::vector<int> undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b));
@ -506,10 +506,10 @@ struct SatGen
if (cell->type == ID($pmux)) if (cell->type == ID($pmux))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> s = importDefSigSpec(cell->getPort(ID(S)), timestep); std::vector<int> s = importDefSigSpec(cell->getPort(ID(S)), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
@ -522,10 +522,10 @@ struct SatGen
if (model_undef) if (model_undef)
{ {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> undef_s = importUndefSigSpec(cell->getPort(ID(S)), timestep); std::vector<int> undef_s = importUndefSigSpec(cell->getPort(ID(S)), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
int maybe_a = ez->CONST_TRUE; int maybe_a = ez->CONST_TRUE;
@ -555,10 +555,10 @@ struct SatGen
return true; return true;
} }
if (cell->type == ID($pos) || cell->type == ID($neg)) if (cell->type.in(ID($pos), ID($neg)))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidthUnary(a, y, cell); extendSignalWidthUnary(a, y, cell);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
@ -572,8 +572,8 @@ struct SatGen
if (model_undef) if (model_undef)
{ {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidthUnary(undef_a, undef_y, cell); extendSignalWidthUnary(undef_a, undef_y, cell);
if (cell->type == ID($pos)) { if (cell->type == ID($pos)) {
@ -589,17 +589,16 @@ struct SatGen
return true; return true;
} }
if (cell->type == ID($reduce_and) || cell->type == ID($reduce_or) || cell->type == ID($reduce_xor) || if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($logic_not)))
cell->type == ID($reduce_xnor) || cell->type == ID($reduce_bool) || cell->type == ID($logic_not))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
if (cell->type == ID($reduce_and)) if (cell->type == ID($reduce_and))
ez->SET(ez->expression(ez->OpAnd, a), yy.at(0)); ez->SET(ez->expression(ez->OpAnd, a), yy.at(0));
if (cell->type == ID($reduce_or) || cell->type == ID($reduce_bool)) if (cell->type.in(ID($reduce_or), ID($reduce_bool)))
ez->SET(ez->expression(ez->OpOr, a), yy.at(0)); ez->SET(ez->expression(ez->OpOr, a), yy.at(0));
if (cell->type == ID($reduce_xor)) if (cell->type == ID($reduce_xor))
ez->SET(ez->expression(ez->OpXor, a), yy.at(0)); ez->SET(ez->expression(ez->OpXor, a), yy.at(0));
@ -612,19 +611,19 @@ struct SatGen
if (model_undef) if (model_undef)
{ {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
int aX = ez->expression(ezSAT::OpOr, undef_a); int aX = ez->expression(ezSAT::OpOr, undef_a);
if (cell->type == ID($reduce_and)) { if (cell->type == ID($reduce_and)) {
int a0 = ez->expression(ezSAT::OpOr, ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a))); int a0 = ez->expression(ezSAT::OpOr, ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a)));
ez->assume(ez->IFF(ez->AND(ez->NOT(a0), aX), undef_y.at(0))); ez->assume(ez->IFF(ez->AND(ez->NOT(a0), aX), undef_y.at(0)));
} }
else if (cell->type == ID($reduce_or) || cell->type == ID($reduce_bool) || cell->type == ID($logic_not)) { else if (cell->type.in(ID($reduce_or), ID($reduce_bool), ID($logic_not))) {
int a1 = ez->expression(ezSAT::OpOr, ez->vec_and(a, ez->vec_not(undef_a))); int a1 = ez->expression(ezSAT::OpOr, ez->vec_and(a, ez->vec_not(undef_a)));
ez->assume(ez->IFF(ez->AND(ez->NOT(a1), aX), undef_y.at(0))); ez->assume(ez->IFF(ez->AND(ez->NOT(a1), aX), undef_y.at(0)));
} }
else if (cell->type == ID($reduce_xor) || cell->type == ID($reduce_xnor)) { else if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) {
ez->assume(ez->IFF(aX, undef_y.at(0))); ez->assume(ez->IFF(aX, undef_y.at(0)));
} else } else
log_abort(); log_abort();
@ -637,14 +636,14 @@ struct SatGen
return true; return true;
} }
if (cell->type == ID($logic_and) || cell->type == ID($logic_or)) if (cell->type.in(ID($logic_and), ID($logic_or)))
{ {
std::vector<int> vec_a = importDefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> vec_a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> vec_b = importDefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> vec_b = importDefSigSpec(cell->getPort(ID::B), timestep);
int a = ez->expression(ez->OpOr, vec_a); int a = ez->expression(ez->OpOr, vec_a);
int b = ez->expression(ez->OpOr, vec_b); int b = ez->expression(ez->OpOr, vec_b);
std::vector<int> y = importDefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
@ -657,9 +656,9 @@ struct SatGen
if (model_undef) if (model_undef)
{ {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
int a0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_a), ez->expression(ezSAT::OpOr, undef_a))); int a0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_a), ez->expression(ezSAT::OpOr, undef_a)));
int b0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_b), ez->expression(ezSAT::OpOr, undef_b))); int b0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_b), ez->expression(ezSAT::OpOr, undef_b)));
@ -683,19 +682,19 @@ struct SatGen
return true; return true;
} }
if (cell->type == ID($lt) || cell->type == ID($le) || cell->type == ID($eq) || cell->type == ID($ne) || cell->type == ID($eqx) || cell->type == ID($nex) || cell->type == ID($ge) || cell->type == ID($gt)) if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt)))
{ {
bool is_signed = cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool(); bool is_signed = cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool();
std::vector<int> a = importDefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidth(a, b, cell); extendSignalWidth(a, b, cell);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
if (model_undef && (cell->type == ID($eqx) || cell->type == ID($nex))) { if (model_undef && cell->type.in(ID($eqx), ID($nex))) {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
extendSignalWidth(undef_a, undef_b, cell, true); extendSignalWidth(undef_a, undef_b, cell, true);
a = ez->vec_or(a, undef_a); a = ez->vec_or(a, undef_a);
b = ez->vec_or(b, undef_b); b = ez->vec_or(b, undef_b);
@ -705,9 +704,9 @@ struct SatGen
ez->SET(is_signed ? ez->vec_lt_signed(a, b) : ez->vec_lt_unsigned(a, b), yy.at(0)); ez->SET(is_signed ? ez->vec_lt_signed(a, b) : ez->vec_lt_unsigned(a, b), yy.at(0));
if (cell->type == ID($le)) if (cell->type == ID($le))
ez->SET(is_signed ? ez->vec_le_signed(a, b) : ez->vec_le_unsigned(a, b), yy.at(0)); ez->SET(is_signed ? ez->vec_le_signed(a, b) : ez->vec_le_unsigned(a, b), yy.at(0));
if (cell->type == ID($eq) || cell->type == ID($eqx)) if (cell->type.in(ID($eq), ID($eqx)))
ez->SET(ez->vec_eq(a, b), yy.at(0)); ez->SET(ez->vec_eq(a, b), yy.at(0));
if (cell->type == ID($ne) || cell->type == ID($nex)) if (cell->type.in(ID($ne), ID($nex)))
ez->SET(ez->vec_ne(a, b), yy.at(0)); ez->SET(ez->vec_ne(a, b), yy.at(0));
if (cell->type == ID($ge)) if (cell->type == ID($ge))
ez->SET(is_signed ? ez->vec_ge_signed(a, b) : ez->vec_ge_unsigned(a, b), yy.at(0)); ez->SET(is_signed ? ez->vec_ge_signed(a, b) : ez->vec_ge_unsigned(a, b), yy.at(0));
@ -716,11 +715,11 @@ struct SatGen
for (size_t i = 1; i < y.size(); i++) for (size_t i = 1; i < y.size(); i++)
ez->SET(ez->CONST_FALSE, yy.at(i)); ez->SET(ez->CONST_FALSE, yy.at(i));
if (model_undef && (cell->type == ID($eqx) || cell->type == ID($nex))) if (model_undef && cell->type.in(ID($eqx), ID($nex)))
{ {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidth(undef_a, undef_b, cell, true); extendSignalWidth(undef_a, undef_b, cell, true);
if (cell->type == ID($eqx)) if (cell->type == ID($eqx))
@ -733,11 +732,11 @@ struct SatGen
ez->assume(ez->vec_eq(y, yy)); ez->assume(ez->vec_eq(y, yy));
} }
else if (model_undef && (cell->type == ID($eq) || cell->type == ID($ne))) else if (model_undef && cell->type.in(ID($eq), ID($ne)))
{ {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidth(undef_a, undef_b, cell, true); extendSignalWidth(undef_a, undef_b, cell, true);
int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); int undef_any_a = ez->expression(ezSAT::OpOr, undef_a);
@ -759,7 +758,7 @@ struct SatGen
else else
{ {
if (model_undef) { if (model_undef) {
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
undefGating(y, yy, undef_y); undefGating(y, yy, undef_y);
} }
log_assert(!model_undef || arith_undef_handled); log_assert(!model_undef || arith_undef_handled);
@ -767,11 +766,11 @@ struct SatGen
return true; return true;
} }
if (cell->type == ID($shl) || cell->type == ID($shr) || cell->type == ID($sshl) || cell->type == ID($sshr) || cell->type == ID($shift) || cell->type == ID($shiftx)) if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
int extend_bit = ez->CONST_FALSE; int extend_bit = ez->CONST_FALSE;
@ -786,7 +785,7 @@ struct SatGen
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
std::vector<int> shifted_a; std::vector<int> shifted_a;
if (cell->type == ID($shl) || cell->type == ID($sshl)) if (cell->type.in( ID($shl), ID($sshl)))
shifted_a = ez->vec_shift_left(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); shifted_a = ez->vec_shift_left(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($shr)) if (cell->type == ID($shr))
@ -795,16 +794,16 @@ struct SatGen
if (cell->type == ID($sshr)) if (cell->type == ID($sshr))
shifted_a = ez->vec_shift_right(a, b, false, cell->parameters[ID(A_SIGNED)].as_bool() ? a.back() : ez->CONST_FALSE, ez->CONST_FALSE); shifted_a = ez->vec_shift_right(a, b, false, cell->parameters[ID(A_SIGNED)].as_bool() ? a.back() : ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($shift) || cell->type == ID($shiftx)) if (cell->type.in(ID($shift), ID($shiftx)))
shifted_a = ez->vec_shift_right(a, b, cell->parameters[ID(B_SIGNED)].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE); shifted_a = ez->vec_shift_right(a, b, cell->parameters[ID(B_SIGNED)].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE);
ez->assume(ez->vec_eq(shifted_a, yy)); ez->assume(ez->vec_eq(shifted_a, yy));
if (model_undef) if (model_undef)
{ {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> undef_a_shifted; std::vector<int> undef_a_shifted;
extend_bit = cell->type == ID($shiftx) ? ez->CONST_TRUE : ez->CONST_FALSE; extend_bit = cell->type == ID($shiftx) ? ez->CONST_TRUE : ez->CONST_FALSE;
@ -816,7 +815,7 @@ struct SatGen
while (undef_y.size() > undef_a.size()) while (undef_y.size() > undef_a.size())
undef_a.push_back(extend_bit); undef_a.push_back(extend_bit);
if (cell->type == ID($shl) || cell->type == ID($sshl)) if (cell->type.in(ID($shl), ID($sshl)))
undef_a_shifted = ez->vec_shift_left(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); undef_a_shifted = ez->vec_shift_left(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($shr)) if (cell->type == ID($shr))
@ -841,9 +840,9 @@ struct SatGen
if (cell->type == ID($mul)) if (cell->type == ID($mul))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidth(a, b, y, cell); extendSignalWidth(a, b, y, cell);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
@ -860,7 +859,7 @@ struct SatGen
if (model_undef) { if (model_undef) {
log_assert(arith_undef_handled); log_assert(arith_undef_handled);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
undefGating(y, yy, undef_y); undefGating(y, yy, undef_y);
} }
return true; return true;
@ -868,9 +867,9 @@ struct SatGen
if (cell->type == ID($macc)) if (cell->type == ID($macc))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
Macc macc; Macc macc;
macc.from_cell(cell); macc.from_cell(cell);
@ -919,13 +918,13 @@ struct SatGen
if (model_undef) if (model_undef)
{ {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); int undef_any_a = ez->expression(ezSAT::OpOr, undef_a);
int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); int undef_any_b = ez->expression(ezSAT::OpOr, undef_b);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
ez->assume(ez->vec_eq(undef_y, std::vector<int>(GetSize(y), ez->OR(undef_any_a, undef_any_b)))); ez->assume(ez->vec_eq(undef_y, std::vector<int>(GetSize(y), ez->OR(undef_any_a, undef_any_b))));
undefGating(y, tmp, undef_y); undefGating(y, tmp, undef_y);
@ -936,11 +935,11 @@ struct SatGen
return true; return true;
} }
if (cell->type == ID($div) || cell->type == ID($mod)) if (cell->type.in(ID($div), ID($mod)))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidth(a, b, y, cell); extendSignalWidth(a, b, y, cell);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
@ -994,11 +993,11 @@ struct SatGen
only_first_one.at(0) = ez->CONST_TRUE; only_first_one.at(0) = ez->CONST_TRUE;
div_zero_result = ez->vec_ite(a.back(), only_first_one, all_ones); div_zero_result = ez->vec_ite(a.back(), only_first_one, all_ones);
} else { } else {
div_zero_result.insert(div_zero_result.end(), cell->getPort(ID(A)).size(), ez->CONST_TRUE); div_zero_result.insert(div_zero_result.end(), cell->getPort(ID::A).size(), ez->CONST_TRUE);
div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE); div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE);
} }
} else { } else {
int copy_a_bits = min(cell->getPort(ID(A)).size(), cell->getPort(ID(B)).size()); int copy_a_bits = min(cell->getPort(ID::A).size(), cell->getPort(ID::B).size());
div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits); div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits);
if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool()) if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool())
div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), div_zero_result.back()); div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), div_zero_result.back());
@ -1010,7 +1009,7 @@ struct SatGen
if (model_undef) { if (model_undef) {
log_assert(arith_undef_handled); log_assert(arith_undef_handled);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
undefGating(y, yy, undef_y); undefGating(y, yy, undef_y);
} }
return true; return true;
@ -1018,8 +1017,8 @@ struct SatGen
if (cell->type == ID($lut)) if (cell->type == ID($lut))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> lut; std::vector<int> lut;
for (auto bit : cell->getParam(ID(LUT)).bits) for (auto bit : cell->getParam(ID(LUT)).bits)
@ -1030,7 +1029,7 @@ struct SatGen
if (model_undef) if (model_undef)
{ {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> t(lut), u(GetSize(t), ez->CONST_FALSE); std::vector<int> t(lut), u(GetSize(t), ez->CONST_FALSE);
for (int i = GetSize(a)-1; i >= 0; i--) for (int i = GetSize(a)-1; i >= 0; i--)
@ -1048,7 +1047,7 @@ struct SatGen
log_assert(GetSize(t) == 1); log_assert(GetSize(t) == 1);
log_assert(GetSize(u) == 1); log_assert(GetSize(u) == 1);
undefGating(y, t, u); undefGating(y, t, u);
ez->assume(ez->vec_eq(importUndefSigSpec(cell->getPort(ID(Y)), timestep), u)); ez->assume(ez->vec_eq(importUndefSigSpec(cell->getPort(ID::Y), timestep), u));
} }
else else
{ {
@ -1068,8 +1067,8 @@ struct SatGen
if (cell->type == ID($sop)) if (cell->type == ID($sop))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
int y = importDefSigSpec(cell->getPort(ID(Y)), timestep).at(0); int y = importDefSigSpec(cell->getPort(ID::Y), timestep).at(0);
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();
@ -1097,8 +1096,8 @@ struct SatGen
if (model_undef) if (model_undef)
{ {
std::vector<int> products, undef_products; std::vector<int> products, undef_products;
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
int undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep).at(0); int undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep).at(0);
for (int i = 0; i < depth; i++) for (int i = 0; i < depth; i++)
{ {
@ -1150,10 +1149,10 @@ struct SatGen
if (cell->type == ID($fa)) if (cell->type == ID($fa))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> c = importDefSigSpec(cell->getPort(ID(C)), timestep); std::vector<int> c = importDefSigSpec(cell->getPort(ID(C)), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> x = importDefSigSpec(cell->getPort(ID(X)), timestep); std::vector<int> x = importDefSigSpec(cell->getPort(ID(X)), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
@ -1168,11 +1167,11 @@ struct SatGen
if (model_undef) if (model_undef)
{ {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> undef_c = importUndefSigSpec(cell->getPort(ID(C)), timestep); std::vector<int> undef_c = importUndefSigSpec(cell->getPort(ID(C)), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> undef_x = importUndefSigSpec(cell->getPort(ID(X)), timestep); std::vector<int> undef_x = importUndefSigSpec(cell->getPort(ID(X)), timestep);
ez->assume(ez->vec_eq(undef_y, ez->vec_or(ez->vec_or(undef_a, undef_b), undef_c))); ez->assume(ez->vec_eq(undef_y, ez->vec_or(ez->vec_or(undef_a, undef_b), undef_c)));
@ -1218,9 +1217,9 @@ struct SatGen
if (cell->type == ID($alu)) if (cell->type == ID($alu))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> x = importDefSigSpec(cell->getPort(ID(X)), timestep); std::vector<int> x = importDefSigSpec(cell->getPort(ID(X)), timestep);
std::vector<int> ci = importDefSigSpec(cell->getPort(ID(CI)), timestep); std::vector<int> ci = importDefSigSpec(cell->getPort(ID(CI)), timestep);
std::vector<int> bi = importDefSigSpec(cell->getPort(ID(BI)), timestep); std::vector<int> bi = importDefSigSpec(cell->getPort(ID(BI)), timestep);
@ -1249,12 +1248,12 @@ struct SatGen
if (model_undef) if (model_undef)
{ {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> undef_ci = importUndefSigSpec(cell->getPort(ID(CI)), timestep); std::vector<int> undef_ci = importUndefSigSpec(cell->getPort(ID(CI)), timestep);
std::vector<int> undef_bi = importUndefSigSpec(cell->getPort(ID(BI)), timestep); std::vector<int> undef_bi = importUndefSigSpec(cell->getPort(ID(BI)), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> undef_x = importUndefSigSpec(cell->getPort(ID(X)), timestep); std::vector<int> undef_x = importUndefSigSpec(cell->getPort(ID(X)), timestep);
std::vector<int> undef_co = importUndefSigSpec(cell->getPort(ID(CO)), timestep); std::vector<int> undef_co = importUndefSigSpec(cell->getPort(ID(CO)), timestep);
@ -1284,17 +1283,17 @@ struct SatGen
if (cell->type == ID($slice)) if (cell->type == ID($slice))
{ {
RTLIL::SigSpec a = cell->getPort(ID(A)); RTLIL::SigSpec a = cell->getPort(ID::A);
RTLIL::SigSpec y = cell->getPort(ID(Y)); RTLIL::SigSpec y = cell->getPort(ID::Y);
ez->assume(signals_eq(a.extract(cell->parameters.at(ID(OFFSET)).as_int(), y.size()), y, timestep)); ez->assume(signals_eq(a.extract(cell->parameters.at(ID(OFFSET)).as_int(), y.size()), y, timestep));
return true; return true;
} }
if (cell->type == ID($concat)) if (cell->type == ID($concat))
{ {
RTLIL::SigSpec a = cell->getPort(ID(A)); RTLIL::SigSpec a = cell->getPort(ID::A);
RTLIL::SigSpec b = cell->getPort(ID(B)); RTLIL::SigSpec b = cell->getPort(ID::B);
RTLIL::SigSpec y = cell->getPort(ID(Y)); RTLIL::SigSpec y = cell->getPort(ID::Y);
RTLIL::SigSpec ab = a; RTLIL::SigSpec ab = a;
ab.append(b); ab.append(b);
@ -1334,16 +1333,16 @@ struct SatGen
if (timestep < 2) if (timestep < 2)
return true; return true;
std::vector<int> d = importDefSigSpec(cell->getPort(ID(Y)), timestep-1); std::vector<int> d = importDefSigSpec(cell->getPort(ID::Y), timestep-1);
std::vector<int> q = importDefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> q = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> qq = model_undef ? ez->vec_var(q.size()) : q; std::vector<int> qq = model_undef ? ez->vec_var(q.size()) : q;
ez->assume(ez->vec_eq(d, qq)); ez->assume(ez->vec_eq(d, qq));
if (model_undef) if (model_undef)
{ {
std::vector<int> undef_d = importUndefSigSpec(cell->getPort(ID(Y)), timestep-1); std::vector<int> undef_d = importUndefSigSpec(cell->getPort(ID::Y), timestep-1);
std::vector<int> undef_q = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_q = importUndefSigSpec(cell->getPort(ID::Y), timestep);
ez->assume(ez->vec_eq(undef_d, undef_q)); ez->assume(ez->vec_eq(undef_d, undef_q));
undefGating(q, qq, undef_q); undefGating(q, qq, undef_q);
@ -1356,18 +1355,18 @@ struct SatGen
return true; return true;
} }
if (cell->type == ID($_BUF_) || cell->type == ID($equiv)) if (cell->type.in(ID($_BUF_), ID($equiv)))
{ {
std::vector<int> a = importDefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidthUnary(a, y, cell); extendSignalWidthUnary(a, y, cell);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
ez->assume(ez->vec_eq(a, yy)); ez->assume(ez->vec_eq(a, yy));
if (model_undef) { if (model_undef) {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidthUnary(undef_a, undef_y, cell, false); extendSignalWidthUnary(undef_a, undef_y, cell, false);
ez->assume(ez->vec_eq(undef_a, undef_y)); ez->assume(ez->vec_eq(undef_a, undef_y));
undefGating(y, yy, undef_y); undefGating(y, yy, undef_y);
@ -1381,12 +1380,12 @@ struct SatGen
if (initstates.count(key) == 0) if (initstates.count(key) == 0)
initstates[key] = false; initstates[key] = false;
std::vector<int> y = importDefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
log_assert(GetSize(y) == 1); log_assert(GetSize(y) == 1);
ez->SET(y[0], initstates[key] ? ez->CONST_TRUE : ez->CONST_FALSE); ez->SET(y[0], initstates[key] ? ez->CONST_TRUE : ez->CONST_FALSE);
if (model_undef) { if (model_undef) {
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
log_assert(GetSize(undef_y) == 1); log_assert(GetSize(undef_y) == 1);
ez->SET(undef_y[0], ez->CONST_FALSE); ez->SET(undef_y[0], ez->CONST_FALSE);
} }
@ -1397,7 +1396,7 @@ struct SatGen
if (cell->type == ID($assert)) if (cell->type == ID($assert))
{ {
std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep));
asserts_a[pf].append((*sigmap)(cell->getPort(ID(A)))); asserts_a[pf].append((*sigmap)(cell->getPort(ID::A)));
asserts_en[pf].append((*sigmap)(cell->getPort(ID(EN)))); asserts_en[pf].append((*sigmap)(cell->getPort(ID(EN))));
return true; return true;
} }
@ -1405,7 +1404,7 @@ struct SatGen
if (cell->type == ID($assume)) if (cell->type == ID($assume))
{ {
std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep));
assumes_a[pf].append((*sigmap)(cell->getPort(ID(A)))); assumes_a[pf].append((*sigmap)(cell->getPort(ID::A)));
assumes_en[pf].append((*sigmap)(cell->getPort(ID(EN)))); assumes_en[pf].append((*sigmap)(cell->getPort(ID(EN))));
return true; return true;
} }

View file

@ -315,6 +315,7 @@ RTLIL::IdString new_id(std::string file, int line, std::string func);
// //
#define ID(_id) ([]() { const char *p = "\\" #_id, *q = p[1] == '$' ? p+1 : p; \ #define ID(_id) ([]() { const char *p = "\\" #_id, *q = p[1] == '$' ? p+1 : p; \
static const YOSYS_NAMESPACE_PREFIX RTLIL::IdString id(q); return id; })() static const YOSYS_NAMESPACE_PREFIX RTLIL::IdString id(q); return id; })()
namespace ID = RTLIL::ID;
RTLIL::Design *yosys_get_design(); RTLIL::Design *yosys_get_design();
std::string proc_self_dirname(); std::string proc_self_dirname();

View file

@ -107,7 +107,7 @@ struct DeletePass : public Pass {
for (auto &it : module->cells_) { for (auto &it : module->cells_) {
if (design->selected(module, it.second)) if (design->selected(module, it.second))
delete_cells.insert(it.second); delete_cells.insert(it.second);
if ((it.second->type == "$memrd" || it.second->type == "$memwr") && if (it.second->type.in("$memrd", "$memwr") &&
delete_mems.count(it.second->parameters.at("\\MEMID").decode_string()) != 0) delete_mems.count(it.second->parameters.at("\\MEMID").decode_string()) != 0)
delete_cells.insert(it.second); delete_cells.insert(it.second);
} }

View file

@ -4,6 +4,7 @@ OBJS += passes/opt/opt_merge.o
OBJS += passes/opt/opt_muxtree.o OBJS += passes/opt/opt_muxtree.o
OBJS += passes/opt/opt_reduce.o OBJS += passes/opt/opt_reduce.o
OBJS += passes/opt/opt_rmdff.o OBJS += passes/opt/opt_rmdff.o
OBJS += passes/opt/opt_share.o
OBJS += passes/opt/opt_clean.o OBJS += passes/opt/opt_clean.o
OBJS += passes/opt/opt_expr.o OBJS += passes/opt/opt_expr.o
@ -16,4 +17,3 @@ OBJS += passes/opt/opt_lut.o
OBJS += passes/opt/pmux2shiftx.o OBJS += passes/opt/pmux2shiftx.o
OBJS += passes/opt/muxpack.o OBJS += passes/opt/muxpack.o
endif endif

View file

@ -38,19 +38,19 @@ struct ExclusiveDatabase
pool<Cell*> reduce_or; pool<Cell*> reduce_or;
for (auto cell : module->cells()) { for (auto cell : module->cells()) {
if (cell->type == ID($eq)) { if (cell->type == ID($eq)) {
nonconst_sig = sigmap(cell->getPort(ID(A))); nonconst_sig = sigmap(cell->getPort(ID::A));
const_sig = sigmap(cell->getPort(ID(B))); const_sig = sigmap(cell->getPort(ID::B));
if (!const_sig.is_fully_const()) { if (!const_sig.is_fully_const()) {
if (!nonconst_sig.is_fully_const()) if (!nonconst_sig.is_fully_const())
continue; continue;
std::swap(nonconst_sig, const_sig); std::swap(nonconst_sig, const_sig);
} }
y_port = sigmap(cell->getPort(ID(Y))); y_port = sigmap(cell->getPort(ID::Y));
} }
else if (cell->type == ID($logic_not)) { else if (cell->type == ID($logic_not)) {
nonconst_sig = sigmap(cell->getPort(ID(A))); nonconst_sig = sigmap(cell->getPort(ID::A));
const_sig = Const(State::S0, GetSize(nonconst_sig)); const_sig = Const(State::S0, GetSize(nonconst_sig));
y_port = sigmap(cell->getPort(ID(Y))); y_port = sigmap(cell->getPort(ID::Y));
} }
else if (cell->type == ID($reduce_or)) { else if (cell->type == ID($reduce_or)) {
reduce_or.insert(cell); reduce_or.insert(cell);
@ -66,7 +66,7 @@ struct ExclusiveDatabase
for (auto cell : reduce_or) { for (auto cell : reduce_or) {
nonconst_sig = SigSpec(); nonconst_sig = SigSpec();
std::vector<Const> values; std::vector<Const> values;
SigSpec a_port = sigmap(cell->getPort(ID(A))); SigSpec a_port = sigmap(cell->getPort(ID::A));
for (auto bit : a_port) { for (auto bit : a_port) {
auto it = sig_cmp_prev.find(bit); auto it = sig_cmp_prev.find(bit);
if (it == sig_cmp_prev.end()) { if (it == sig_cmp_prev.end()) {
@ -84,7 +84,7 @@ struct ExclusiveDatabase
} }
if (nonconst_sig.empty()) if (nonconst_sig.empty())
continue; continue;
y_port = sigmap(cell->getPort(ID(Y))); y_port = sigmap(cell->getPort(ID::Y));
sig_cmp_prev[y_port] = std::make_pair(nonconst_sig,std::move(values)); sig_cmp_prev[y_port] = std::make_pair(nonconst_sig,std::move(values));
} }
} }
@ -135,7 +135,7 @@ struct MuxpackWorker
{ {
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);
} }
@ -143,13 +143,13 @@ struct MuxpackWorker
for (auto cell : module->cells()) for (auto cell : module->cells())
{ {
if (cell->type.in(ID($mux), ID($pmux)) && !cell->get_bool_attribute(ID(keep))) if (cell->type.in(ID($mux), ID($pmux)) && !cell->get_bool_attribute(ID::keep))
{ {
SigSpec a_sig = sigmap(cell->getPort(ID(A))); SigSpec a_sig = sigmap(cell->getPort(ID::A));
SigSpec b_sig; SigSpec b_sig;
if (cell->type == ID($mux)) if (cell->type == ID($mux))
b_sig = sigmap(cell->getPort(ID(B))); b_sig = sigmap(cell->getPort(ID::B));
SigSpec y_sig = sigmap(cell->getPort(ID(Y))); SigSpec y_sig = sigmap(cell->getPort(ID::Y));
if (sig_chain_next.count(a_sig)) if (sig_chain_next.count(a_sig))
for (auto a_bit : a_sig.bits()) for (auto a_bit : a_sig.bits())
@ -186,9 +186,9 @@ struct MuxpackWorker
{ {
log_debug("Considering %s (%s)\n", log_id(cell), log_id(cell->type)); log_debug("Considering %s (%s)\n", log_id(cell), log_id(cell->type));
SigSpec a_sig = sigmap(cell->getPort(ID(A))); SigSpec a_sig = sigmap(cell->getPort(ID::A));
if (cell->type == ID($mux)) { if (cell->type == ID($mux)) {
SigSpec b_sig = sigmap(cell->getPort(ID(B))); SigSpec b_sig = sigmap(cell->getPort(ID::B));
if (sig_chain_prev.count(a_sig) + sig_chain_prev.count(b_sig) != 1) if (sig_chain_prev.count(a_sig) + sig_chain_prev.count(b_sig) != 1)
goto start_cell; goto start_cell;
@ -230,7 +230,7 @@ struct MuxpackWorker
{ {
chain.push_back(c); chain.push_back(c);
SigSpec y_sig = sigmap(c->getPort(ID(Y))); SigSpec y_sig = sigmap(c->getPort(ID::Y));
if (sig_chain_next.count(y_sig) == 0) if (sig_chain_next.count(y_sig) == 0)
break; break;
@ -270,28 +270,28 @@ struct MuxpackWorker
pmux_count += 1; pmux_count += 1;
first_cell->type = ID($pmux); first_cell->type = ID($pmux);
SigSpec b_sig = first_cell->getPort(ID(B)); SigSpec b_sig = first_cell->getPort(ID::B);
SigSpec s_sig = first_cell->getPort(ID(S)); SigSpec s_sig = first_cell->getPort(ID(S));
for (int i = 1; i < cases; i++) { for (int i = 1; i < cases; i++) {
Cell* prev_cell = chain[cursor+i-1]; Cell* prev_cell = chain[cursor+i-1];
Cell* cursor_cell = chain[cursor+i]; Cell* cursor_cell = chain[cursor+i];
if (sigmap(prev_cell->getPort(ID(Y))) == sigmap(cursor_cell->getPort(ID(A)))) { if (sigmap(prev_cell->getPort(ID::Y)) == sigmap(cursor_cell->getPort(ID::A))) {
b_sig.append(cursor_cell->getPort(ID(B))); b_sig.append(cursor_cell->getPort(ID::B));
s_sig.append(cursor_cell->getPort(ID(S))); s_sig.append(cursor_cell->getPort(ID(S)));
} }
else { else {
log_assert(cursor_cell->type == ID($mux)); log_assert(cursor_cell->type == ID($mux));
b_sig.append(cursor_cell->getPort(ID(A))); b_sig.append(cursor_cell->getPort(ID::A));
s_sig.append(module->LogicNot(NEW_ID, cursor_cell->getPort(ID(S)))); s_sig.append(module->LogicNot(NEW_ID, cursor_cell->getPort(ID(S))));
} }
remove_cells.insert(cursor_cell); remove_cells.insert(cursor_cell);
} }
first_cell->setPort(ID(B), b_sig); first_cell->setPort(ID::B, b_sig);
first_cell->setPort(ID(S), s_sig); first_cell->setPort(ID(S), s_sig);
first_cell->setParam(ID(S_WIDTH), GetSize(s_sig)); first_cell->setParam(ID(S_WIDTH), GetSize(s_sig));
first_cell->setPort(ID(Y), last_cell->getPort(ID(Y))); first_cell->setPort(ID::Y, last_cell->getPort(ID::Y));
cursor += cases; cursor += cases;
} }

View file

@ -44,6 +44,7 @@ struct OptPass : public Pass {
log(" opt_muxtree\n"); log(" opt_muxtree\n");
log(" opt_reduce [-fine] [-full]\n"); log(" opt_reduce [-fine] [-full]\n");
log(" opt_merge [-share_all]\n"); log(" opt_merge [-share_all]\n");
log(" opt_share (-full only)\n");
log(" opt_rmdff [-keepdc] [-sat]\n"); log(" opt_rmdff [-keepdc] [-sat]\n");
log(" opt_clean [-purge]\n"); log(" opt_clean [-purge]\n");
log(" opt_expr [-mux_undef] [-mux_bool] [-undriven] [-clkinv] [-fine] [-full] [-keepdc]\n"); log(" opt_expr [-mux_undef] [-mux_bool] [-undriven] [-clkinv] [-fine] [-full] [-keepdc]\n");
@ -70,6 +71,7 @@ struct OptPass : public Pass {
std::string opt_reduce_args; std::string opt_reduce_args;
std::string opt_merge_args; std::string opt_merge_args;
std::string opt_rmdff_args; std::string opt_rmdff_args;
bool opt_share = false;
bool fast_mode = false; bool fast_mode = false;
log_header(design, "Executing OPT pass (performing simple optimizations).\n"); log_header(design, "Executing OPT pass (performing simple optimizations).\n");
@ -105,6 +107,7 @@ struct OptPass : public Pass {
if (args[argidx] == "-full") { if (args[argidx] == "-full") {
opt_expr_args += " -full"; opt_expr_args += " -full";
opt_reduce_args += " -full"; opt_reduce_args += " -full";
opt_share = true;
continue; continue;
} }
if (args[argidx] == "-keepdc") { if (args[argidx] == "-keepdc") {
@ -151,6 +154,8 @@ struct OptPass : public Pass {
Pass::call(design, "opt_muxtree"); Pass::call(design, "opt_muxtree");
Pass::call(design, "opt_reduce" + opt_reduce_args); Pass::call(design, "opt_reduce" + opt_reduce_args);
Pass::call(design, "opt_merge" + opt_merge_args); Pass::call(design, "opt_merge" + opt_merge_args);
if (opt_share)
Pass::call(design, "opt_share");
Pass::call(design, "opt_rmdff" + opt_rmdff_args); Pass::call(design, "opt_rmdff" + opt_rmdff_args);
Pass::call(design, "opt_clean" + opt_clean_args); Pass::call(design, "opt_clean" + opt_clean_args);
Pass::call(design, "opt_expr" + opt_expr_args); Pass::call(design, "opt_expr" + opt_expr_args);

View file

@ -52,7 +52,7 @@ struct keep_cache_t
return cache.at(module); return cache.at(module);
cache[module] = true; cache[module] = true;
if (!module->get_bool_attribute(ID(keep))) { if (!module->get_bool_attribute(ID::keep)) {
bool found_keep = false; bool found_keep = false;
for (auto cell : module->cells()) for (auto cell : module->cells())
if (query(cell)) found_keep = true; if (query(cell)) found_keep = true;
@ -122,7 +122,7 @@ void rmunused_module_cells(Module *module, bool verbose)
for (auto &it : module->wires_) { for (auto &it : module->wires_) {
Wire *wire = it.second; Wire *wire = it.second;
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))
for (auto c : wire2driver[bit]) for (auto c : wire2driver[bit])
queue.insert(c), unused.erase(c); queue.insert(c), unused.erase(c);
@ -297,7 +297,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
if (!wire->port_input) if (!wire->port_input)
used_signals_nodrivers.add(sig); used_signals_nodrivers.add(sig);
} }
if (wire->get_bool_attribute(ID(keep))) { if (wire->get_bool_attribute(ID::keep)) {
RTLIL::SigSpec sig = RTLIL::SigSpec(wire); RTLIL::SigSpec sig = RTLIL::SigSpec(wire);
assign_map.apply(sig); assign_map.apply(sig);
used_signals.add(sig); used_signals.add(sig);
@ -323,7 +323,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
if (wire->port_id == 0) if (wire->port_id == 0)
goto delete_this_wire; goto delete_this_wire;
} else } else
if (wire->port_id != 0 || wire->get_bool_attribute(ID(keep)) || !initval.is_fully_undef()) { if (wire->port_id != 0 || wire->get_bool_attribute(ID::keep) || !initval.is_fully_undef()) {
// do not delete anything with "keep" or module ports or initialized wires // do not delete anything with "keep" or module ports or initialized wires
} else } else
if (!purge_mode && check_public_name(wire->name) && (raw_used_signals.check_any(s1) || used_signals.check_any(s2) || s1 != s2)) { if (!purge_mode && check_public_name(wire->name) && (raw_used_signals.check_any(s1) || used_signals.check_any(s2) || s1 != s2)) {
@ -482,8 +482,8 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool
for (auto cell : module->cells()) for (auto cell : module->cells())
if (cell->type.in(ID($pos), ID($_BUF_)) && !cell->has_keep_attr()) { if (cell->type.in(ID($pos), ID($_BUF_)) && !cell->has_keep_attr()) {
bool is_signed = cell->type == ID($pos) && cell->getParam(ID(A_SIGNED)).as_bool(); bool is_signed = cell->type == ID($pos) && cell->getParam(ID(A_SIGNED)).as_bool();
RTLIL::SigSpec a = cell->getPort(ID(A)); RTLIL::SigSpec a = cell->getPort(ID::A);
RTLIL::SigSpec y = cell->getPort(ID(Y)); RTLIL::SigSpec y = cell->getPort(ID::Y);
a.extend_u0(GetSize(y), is_signed); a.extend_u0(GetSize(y), is_signed);
module->connect(y, a); module->connect(y, a);
delcells.push_back(cell); delcells.push_back(cell);
@ -491,7 +491,7 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool
for (auto cell : delcells) { for (auto cell : delcells) {
if (verbose) if (verbose)
log_debug(" removing buffer cell `%s': %s = %s\n", cell->name.c_str(), log_debug(" removing buffer cell `%s': %s = %s\n", cell->name.c_str(),
log_signal(cell->getPort(ID(Y))), log_signal(cell->getPort(ID(A)))); log_signal(cell->getPort(ID::Y)), log_signal(cell->getPort(ID::A)));
module->remove(cell); module->remove(cell);
} }
if (!delcells.empty()) if (!delcells.empty())

View file

@ -38,7 +38,7 @@ void demorgan_worker(
if( (cell->type != ID($reduce_and)) && (cell->type != ID($reduce_or)) ) if( (cell->type != ID($reduce_and)) && (cell->type != ID($reduce_or)) )
return; return;
auto insig = sigmap(cell->getPort(ID(A))); auto insig = sigmap(cell->getPort(ID::A));
log("Inspecting %s cell %s (%d inputs)\n", log_id(cell->type), log_id(cell->name), GetSize(insig)); log("Inspecting %s cell %s (%d inputs)\n", log_id(cell->type), log_id(cell->name), GetSize(insig));
int num_inverted = 0; int num_inverted = 0;
for(int i=0; i<GetSize(insig); i++) for(int i=0; i<GetSize(insig); i++)
@ -51,7 +51,7 @@ void demorgan_worker(
bool inverted = false; bool inverted = false;
for(auto x : ports) for(auto x : ports)
{ {
if(x.port == ID(Y) && x.cell->type == ID($_NOT_)) if(x.port == ID::Y && x.cell->type == ID($_NOT_))
{ {
inverted = true; inverted = true;
break; break;
@ -85,7 +85,7 @@ void demorgan_worker(
RTLIL::Cell* srcinv = NULL; RTLIL::Cell* srcinv = NULL;
for(auto x : ports) for(auto x : ports)
{ {
if(x.port == ID(Y) && x.cell->type == ID($_NOT_)) if(x.port == ID::Y && x.cell->type == ID($_NOT_))
{ {
srcinv = x.cell; srcinv = x.cell;
break; break;
@ -103,7 +103,7 @@ void demorgan_worker(
//We ARE inverted - bypass it //We ARE inverted - bypass it
//Don't automatically delete the inverter since other stuff might still use it //Don't automatically delete the inverter since other stuff might still use it
else else
insig[i] = srcinv->getPort(ID(A)); insig[i] = srcinv->getPort(ID::A);
} }
//Cosmetic fixup: If our input is just a scrambled version of one bus, rearrange it //Cosmetic fixup: If our input is just a scrambled version of one bus, rearrange it
@ -151,7 +151,7 @@ void demorgan_worker(
} }
//Push the new input signal back to the reduction (after bypassing/adding inverters) //Push the new input signal back to the reduction (after bypassing/adding inverters)
cell->setPort(ID(A), insig); cell->setPort(ID::A, insig);
//Change the cell type //Change the cell type
if(cell->type == ID($reduce_and)) if(cell->type == ID($reduce_and))
@ -161,10 +161,10 @@ void demorgan_worker(
//don't change XOR //don't change XOR
//Add an inverter to the output //Add an inverter to the output
auto inverted_output = cell->getPort(ID(Y)); auto inverted_output = cell->getPort(ID::Y);
auto uninverted_output = m->addWire(NEW_ID); auto uninverted_output = m->addWire(NEW_ID);
m->addNot(NEW_ID, RTLIL::SigSpec(uninverted_output), inverted_output); m->addNot(NEW_ID, RTLIL::SigSpec(uninverted_output), inverted_output);
cell->setPort(ID(Y), uninverted_output); cell->setPort(ID::Y, uninverted_output);
} }
struct OptDemorganPass : public Pass { struct OptDemorganPass : public Pass {

View file

@ -61,7 +61,7 @@ void replace_undriven(RTLIL::Design *design, RTLIL::Module *module)
} }
if (wire->port_input) if (wire->port_input)
driven_signals.add(sigmap(wire)); driven_signals.add(sigmap(wire));
if (wire->port_output || wire->get_bool_attribute(ID(keep))) if (wire->port_output || wire->get_bool_attribute(ID::keep))
used_signals.add(sigmap(wire)); used_signals.add(sigmap(wire));
all_signals.add(sigmap(wire)); all_signals.add(sigmap(wire));
} }
@ -117,7 +117,8 @@ void replace_undriven(RTLIL::Design *design, RTLIL::Module *module)
} }
} }
void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, std::string info, IdString out_port, RTLIL::SigSpec out_val) void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell,
const std::string &info YS_ATTRIBUTE(unused), IdString out_port, RTLIL::SigSpec out_val)
{ {
RTLIL::SigSpec Y = cell->getPort(out_port); RTLIL::SigSpec Y = cell->getPort(out_port);
out_val.extend_u0(Y.size(), false); out_val.extend_u0(Y.size(), false);
@ -134,14 +135,14 @@ void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell,
bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutative, SigMap &sigmap) bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutative, SigMap &sigmap)
{ {
IdString b_name = cell->hasPort(ID(B)) ? ID(B) : ID(A); IdString b_name = cell->hasPort(ID::B) ? ID::B : ID::A;
bool a_signed = cell->parameters.at(ID(A_SIGNED)).as_bool(); bool a_signed = cell->parameters.at(ID(A_SIGNED)).as_bool();
bool b_signed = cell->parameters.at(b_name.str() + "_SIGNED").as_bool(); bool b_signed = cell->parameters.at(b_name.str() + "_SIGNED").as_bool();
RTLIL::SigSpec sig_a = sigmap(cell->getPort(ID(A))); RTLIL::SigSpec sig_a = sigmap(cell->getPort(ID::A));
RTLIL::SigSpec sig_b = sigmap(cell->getPort(b_name)); RTLIL::SigSpec sig_b = sigmap(cell->getPort(b_name));
RTLIL::SigSpec sig_y = sigmap(cell->getPort(ID(Y))); RTLIL::SigSpec sig_y = sigmap(cell->getPort(ID::Y));
sig_a.extend_u0(sig_y.size(), a_signed); sig_a.extend_u0(sig_y.size(), a_signed);
sig_b.extend_u0(sig_y.size(), b_signed); sig_b.extend_u0(sig_y.size(), b_signed);
@ -208,24 +209,24 @@ bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutativ
RTLIL::Cell *c = module->addCell(NEW_ID, cell->type); RTLIL::Cell *c = module->addCell(NEW_ID, cell->type);
c->setPort(ID(A), new_a); c->setPort(ID::A, new_a);
c->parameters[ID(A_WIDTH)] = new_a.size(); c->parameters[ID(A_WIDTH)] = new_a.size();
c->parameters[ID(A_SIGNED)] = false; c->parameters[ID(A_SIGNED)] = false;
if (b_name == ID(B)) { if (b_name == ID::B) {
c->setPort(ID(B), new_b); c->setPort(ID::B, new_b);
c->parameters[ID(B_WIDTH)] = new_b.size(); c->parameters[ID(B_WIDTH)] = new_b.size();
c->parameters[ID(B_SIGNED)] = false; c->parameters[ID(B_SIGNED)] = false;
} }
c->setPort(ID(Y), new_y); c->setPort(ID::Y, new_y);
c->parameters[ID(Y_WIDTH)] = new_y->width; c->parameters[ID(Y_WIDTH)] = new_y->width;
c->check(); c->check();
module->connect(new_conn); module->connect(new_conn);
log_debug(" New cell `%s': A=%s", log_id(c), log_signal(new_a)); log_debug(" New cell `%s': A=%s", log_id(c), log_signal(new_a));
if (b_name == ID(B)) if (b_name == ID::B)
log_debug(", B=%s", log_signal(new_b)); log_debug(", B=%s", log_signal(new_b));
log_debug("\n"); log_debug("\n");
} }
@ -368,11 +369,11 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
for (auto cell : module->cells()) for (auto cell : module->cells())
if (design->selected(module, cell) && cell->type[0] == '$') { if (design->selected(module, cell) && cell->type[0] == '$') {
if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) &&
cell->getPort(ID(A)).size() == 1 && cell->getPort(ID(Y)).size() == 1) cell->getPort(ID::A).size() == 1 && cell->getPort(ID::Y).size() == 1)
invert_map[assign_map(cell->getPort(ID(Y)))] = assign_map(cell->getPort(ID(A))); invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID::A));
if (cell->type.in(ID($mux), ID($_MUX_)) && if (cell->type.in(ID($mux), ID($_MUX_)) &&
cell->getPort(ID(A)) == SigSpec(State::S1) && cell->getPort(ID(B)) == SigSpec(State::S0)) cell->getPort(ID::A) == SigSpec(State::S1) && cell->getPort(ID::B) == SigSpec(State::S0))
invert_map[assign_map(cell->getPort(ID(Y)))] = assign_map(cell->getPort(ID(S))); invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID(S)));
if (ct_combinational.cell_known(cell->type)) if (ct_combinational.cell_known(cell->type))
for (auto &conn : cell->connections()) { for (auto &conn : cell->connections()) {
RTLIL::SigSpec sig = assign_map(conn.second); RTLIL::SigSpec sig = assign_map(conn.second);
@ -396,7 +397,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
for (auto cell : cells.sorted) for (auto cell : cells.sorted)
{ {
#define ACTION_DO(_p_, _s_) do { cover("opt.opt_expr.action_" S__LINE__); replace_cell(assign_map, module, cell, input.as_string(), _p_, _s_); goto next_cell; } while (0) #define ACTION_DO(_p_, _s_) do { cover("opt.opt_expr.action_" S__LINE__); replace_cell(assign_map, module, cell, input.as_string(), _p_, _s_); goto next_cell; } while (0)
#define ACTION_DO_Y(_v_) ACTION_DO(ID(Y), RTLIL::SigSpec(RTLIL::State::S ## _v_)) #define ACTION_DO_Y(_v_) ACTION_DO(ID::Y, RTLIL::SigSpec(RTLIL::State::S ## _v_))
if (clkinv) if (clkinv)
{ {
@ -439,23 +440,23 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (cell->type.in(ID($reduce_and), ID($_AND_))) if (cell->type.in(ID($reduce_and), ID($_AND_)))
detect_const_and = true; detect_const_and = true;
if (cell->type.in(ID($and), ID($logic_and)) && GetSize(cell->getPort(ID(A))) == 1 && GetSize(cell->getPort(ID(B))) == 1 && !cell->getParam(ID(A_SIGNED)).as_bool()) if (cell->type.in(ID($and), ID($logic_and)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::B)) == 1 && !cell->getParam(ID(A_SIGNED)).as_bool())
detect_const_and = true; detect_const_and = true;
if (cell->type.in(ID($reduce_or), ID($reduce_bool), ID($_OR_))) if (cell->type.in(ID($reduce_or), ID($reduce_bool), ID($_OR_)))
detect_const_or = true; detect_const_or = true;
if (cell->type.in(ID($or), ID($logic_or)) && GetSize(cell->getPort(ID(A))) == 1 && GetSize(cell->getPort(ID(B))) == 1 && !cell->getParam(ID(A_SIGNED)).as_bool()) if (cell->type.in(ID($or), ID($logic_or)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::B)) == 1 && !cell->getParam(ID(A_SIGNED)).as_bool())
detect_const_or = true; detect_const_or = true;
if (detect_const_and || detect_const_or) if (detect_const_and || detect_const_or)
{ {
pool<SigBit> input_bits = assign_map(cell->getPort(ID(A))).to_sigbit_pool(); pool<SigBit> input_bits = assign_map(cell->getPort(ID::A)).to_sigbit_pool();
bool found_zero = false, found_one = false, found_undef = false, found_inv = false, many_conconst = false; bool found_zero = false, found_one = false, found_undef = false, found_inv = false, many_conconst = false;
SigBit non_const_input = State::Sm; SigBit non_const_input = State::Sm;
if (cell->hasPort(ID(B))) { if (cell->hasPort(ID::B)) {
vector<SigBit> more_bits = assign_map(cell->getPort(ID(B))).to_sigbit_vector(); vector<SigBit> more_bits = assign_map(cell->getPort(ID::B)).to_sigbit_vector();
input_bits.insert(more_bits.begin(), more_bits.end()); input_bits.insert(more_bits.begin(), more_bits.end());
} }
@ -478,25 +479,25 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (detect_const_and && (found_zero || found_inv)) { if (detect_const_and && (found_zero || found_inv)) {
cover("opt.opt_expr.const_and"); cover("opt.opt_expr.const_and");
replace_cell(assign_map, module, cell, "const_and", "\\Y", RTLIL::State::S0); replace_cell(assign_map, module, cell, "const_and", ID::Y, RTLIL::State::S0);
goto next_cell; goto next_cell;
} }
if (detect_const_or && (found_one || found_inv)) { if (detect_const_or && (found_one || found_inv)) {
cover("opt.opt_expr.const_or"); cover("opt.opt_expr.const_or");
replace_cell(assign_map, module, cell, "const_or", "\\Y", RTLIL::State::S1); replace_cell(assign_map, module, cell, "const_or", ID::Y, RTLIL::State::S1);
goto next_cell; goto next_cell;
} }
if (non_const_input != State::Sm && !found_undef) { if (non_const_input != State::Sm && !found_undef) {
cover("opt.opt_expr.and_or_buffer"); cover("opt.opt_expr.and_or_buffer");
replace_cell(assign_map, module, cell, "and_or_buffer", "\\Y", non_const_input); replace_cell(assign_map, module, cell, "and_or_buffer", ID::Y, non_const_input);
goto next_cell; goto next_cell;
} }
} }
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool), ID($reduce_xor), ID($reduce_xnor), ID($neg)) && if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool), ID($reduce_xor), ID($reduce_xnor), ID($neg)) &&
GetSize(cell->getPort(ID(A))) == 1 && GetSize(cell->getPort(ID(Y))) == 1) GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::Y)) == 1)
{ {
if (cell->type == ID($reduce_xnor)) { if (cell->type == ID($reduce_xnor)) {
cover("opt.opt_expr.reduce_xnor_not"); cover("opt.opt_expr.reduce_xnor_not");
@ -506,7 +507,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
did_something = true; did_something = true;
} else { } else {
cover("opt.opt_expr.unary_buffer"); cover("opt.opt_expr.unary_buffer");
replace_cell(assign_map, module, cell, "unary_buffer", "\\Y", cell->getPort("\\A")); replace_cell(assign_map, module, cell, "unary_buffer", ID::Y, cell->getPort(ID::A));
} }
goto next_cell; goto next_cell;
} }
@ -521,7 +522,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
{ {
SigBit neutral_bit = cell->type == ID($reduce_and) ? State::S1 : State::S0; SigBit neutral_bit = cell->type == ID($reduce_and) ? State::S1 : State::S0;
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec new_sig_a; RTLIL::SigSpec new_sig_a;
for (auto bit : sig_a) for (auto bit : sig_a)
@ -534,7 +535,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cover_list("opt.opt_expr.fine.neutral_A", "$logic_not", "$logic_and", "$logic_or", "$reduce_or", "$reduce_and", "$reduce_bool", cell->type.str()); cover_list("opt.opt_expr.fine.neutral_A", "$logic_not", "$logic_and", "$logic_or", "$reduce_or", "$reduce_and", "$reduce_bool", cell->type.str());
log_debug("Replacing port A of %s cell `%s' in module `%s' with shorter expression: %s -> %s\n", log_debug("Replacing port A of %s cell `%s' in module `%s' with shorter expression: %s -> %s\n",
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_sig_a)); cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_sig_a));
cell->setPort(ID(A), new_sig_a); cell->setPort(ID::A, new_sig_a);
cell->parameters.at(ID(A_WIDTH)) = GetSize(new_sig_a); cell->parameters.at(ID(A_WIDTH)) = GetSize(new_sig_a);
did_something = true; did_something = true;
} }
@ -544,7 +545,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
{ {
SigBit neutral_bit = State::S0; SigBit neutral_bit = State::S0;
RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID(B))); RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B));
RTLIL::SigSpec new_sig_b; RTLIL::SigSpec new_sig_b;
for (auto bit : sig_b) for (auto bit : sig_b)
@ -557,7 +558,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cover_list("opt.opt_expr.fine.neutral_B", "$logic_and", "$logic_or", cell->type.str()); cover_list("opt.opt_expr.fine.neutral_B", "$logic_and", "$logic_or", cell->type.str());
log_debug("Replacing port B of %s cell `%s' in module `%s' with shorter expression: %s -> %s\n", log_debug("Replacing port B of %s cell `%s' in module `%s' with shorter expression: %s -> %s\n",
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_sig_b)); cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_sig_b));
cell->setPort(ID(B), new_sig_b); cell->setPort(ID::B, new_sig_b);
cell->parameters.at(ID(B_WIDTH)) = GetSize(new_sig_b); cell->parameters.at(ID(B_WIDTH)) = GetSize(new_sig_b);
did_something = true; did_something = true;
} }
@ -565,7 +566,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (cell->type == ID($reduce_and)) if (cell->type == ID($reduce_and))
{ {
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
RTLIL::State new_a = RTLIL::State::S1; RTLIL::State new_a = RTLIL::State::S1;
for (auto &bit : sig_a.to_sigbit_vector()) for (auto &bit : sig_a.to_sigbit_vector())
@ -583,7 +584,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cover("opt.opt_expr.fine.$reduce_and"); cover("opt.opt_expr.fine.$reduce_and");
log_debug("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", log_debug("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n",
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a));
cell->setPort(ID(A), sig_a = new_a); cell->setPort(ID::A, sig_a = new_a);
cell->parameters.at(ID(A_WIDTH)) = 1; cell->parameters.at(ID(A_WIDTH)) = 1;
did_something = true; did_something = true;
} }
@ -591,7 +592,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (cell->type.in(ID($logic_not), ID($logic_and), ID($logic_or), ID($reduce_or), ID($reduce_bool))) if (cell->type.in(ID($logic_not), ID($logic_and), ID($logic_or), ID($reduce_or), ID($reduce_bool)))
{ {
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
RTLIL::State new_a = RTLIL::State::S0; RTLIL::State new_a = RTLIL::State::S0;
for (auto &bit : sig_a.to_sigbit_vector()) for (auto &bit : sig_a.to_sigbit_vector())
@ -609,7 +610,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cover_list("opt.opt_expr.fine.A", "$logic_not", "$logic_and", "$logic_or", "$reduce_or", "$reduce_bool", cell->type.str()); cover_list("opt.opt_expr.fine.A", "$logic_not", "$logic_and", "$logic_or", "$reduce_or", "$reduce_bool", cell->type.str());
log_debug("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", log_debug("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n",
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a));
cell->setPort(ID(A), sig_a = new_a); cell->setPort(ID::A, sig_a = new_a);
cell->parameters.at(ID(A_WIDTH)) = 1; cell->parameters.at(ID(A_WIDTH)) = 1;
did_something = true; did_something = true;
} }
@ -617,7 +618,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (cell->type.in(ID($logic_and), ID($logic_or))) if (cell->type.in(ID($logic_and), ID($logic_or)))
{ {
RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID(B))); RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B));
RTLIL::State new_b = RTLIL::State::S0; RTLIL::State new_b = RTLIL::State::S0;
for (auto &bit : sig_b.to_sigbit_vector()) for (auto &bit : sig_b.to_sigbit_vector())
@ -635,7 +636,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cover_list("opt.opt_expr.fine.B", "$logic_and", "$logic_or", cell->type.str()); cover_list("opt.opt_expr.fine.B", "$logic_and", "$logic_or", cell->type.str());
log_debug("Replacing port B of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", log_debug("Replacing port B of %s cell `%s' in module `%s' with constant driver: %s -> %s\n",
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_b)); cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_b));
cell->setPort(ID(B), sig_b = new_b); cell->setPort(ID::B, sig_b = new_b);
cell->parameters.at(ID(B_WIDTH)) = 1; cell->parameters.at(ID(B_WIDTH)) = 1;
did_something = true; did_something = true;
} }
@ -643,9 +644,9 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (cell->type.in(ID($add), ID($sub))) if (cell->type.in(ID($add), ID($sub)))
{ {
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID(B))); RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B));
RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
bool sub = cell->type == ID($sub); bool sub = cell->type == ID($sub);
int i; int i;
@ -659,9 +660,9 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
} }
if (i > 0) { if (i > 0) {
cover_list("opt.opt_expr.fine", "$add", "$sub", cell->type.str()); cover_list("opt.opt_expr.fine", "$add", "$sub", cell->type.str());
cell->setPort(ID(A), sig_a.extract_end(i)); cell->setPort(ID::A, sig_a.extract_end(i));
cell->setPort(ID(B), sig_b.extract_end(i)); cell->setPort(ID::B, sig_b.extract_end(i));
cell->setPort(ID(Y), sig_y.extract_end(i)); cell->setPort(ID::Y, sig_y.extract_end(i));
cell->fixup_parameters(); cell->fixup_parameters();
did_something = true; did_something = true;
} }
@ -669,13 +670,13 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (cell->type == "$alu") if (cell->type == "$alu")
{ {
RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B));
RTLIL::SigBit sig_ci = assign_map(cell->getPort("\\CI")); RTLIL::SigBit sig_ci = assign_map(cell->getPort(ID(CI)));
RTLIL::SigBit sig_bi = assign_map(cell->getPort("\\BI")); RTLIL::SigBit sig_bi = assign_map(cell->getPort(ID(BI)));
RTLIL::SigSpec sig_x = cell->getPort("\\X"); RTLIL::SigSpec sig_x = cell->getPort(ID(X));
RTLIL::SigSpec sig_y = cell->getPort("\\Y"); RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
RTLIL::SigSpec sig_co = cell->getPort("\\CO"); RTLIL::SigSpec sig_co = cell->getPort(ID(CO));
if (sig_ci.wire || sig_bi.wire) if (sig_ci.wire || sig_bi.wire)
goto next_cell; goto next_cell;
@ -704,11 +705,11 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
} }
if (i > 0) { if (i > 0) {
cover("opt.opt_expr.fine.$alu"); cover("opt.opt_expr.fine.$alu");
cell->setPort("\\A", sig_a.extract_end(i)); cell->setPort(ID::A, sig_a.extract_end(i));
cell->setPort("\\B", sig_b.extract_end(i)); cell->setPort(ID::B, sig_b.extract_end(i));
cell->setPort("\\X", sig_x.extract_end(i)); cell->setPort(ID(X), sig_x.extract_end(i));
cell->setPort("\\Y", sig_y.extract_end(i)); cell->setPort(ID::Y, sig_y.extract_end(i));
cell->setPort("\\CO", sig_co.extract_end(i)); cell->setPort(ID(CO), sig_co.extract_end(i));
cell->fixup_parameters(); cell->fixup_parameters();
did_something = true; did_something = true;
} }
@ -718,8 +719,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (cell->type.in(ID($reduce_xor), ID($reduce_xnor), ID($shift), ID($shiftx), ID($shl), ID($shr), ID($sshl), ID($sshr), if (cell->type.in(ID($reduce_xor), ID($reduce_xnor), ID($shift), ID($shiftx), ID($shl), ID($shr), ID($sshl), ID($sshr),
ID($lt), ID($le), ID($ge), ID($gt), ID($neg), ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow))) ID($lt), ID($le), ID($ge), ID($gt), ID($neg), ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow)))
{ {
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec sig_b = cell->hasPort(ID(B)) ? assign_map(cell->getPort(ID(B))) : RTLIL::SigSpec(); RTLIL::SigSpec sig_b = cell->hasPort(ID::B) ? assign_map(cell->getPort(ID::B)) : RTLIL::SigSpec();
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)))
sig_a = RTLIL::SigSpec(); sig_a = RTLIL::SigSpec();
@ -737,33 +738,33 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cover_list("opt.opt_expr.xbit", "$reduce_xor", "$reduce_xnor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", cover_list("opt.opt_expr.xbit", "$reduce_xor", "$reduce_xnor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx",
"$lt", "$le", "$ge", "$gt", "$neg", "$add", "$sub", "$mul", "$div", "$mod", "$pow", cell->type.str()); "$lt", "$le", "$ge", "$gt", "$neg", "$add", "$sub", "$mul", "$div", "$mod", "$pow", cell->type.str());
if (cell->type.in(ID($reduce_xor), ID($reduce_xnor), ID($lt), ID($le), ID($ge), ID($gt))) if (cell->type.in(ID($reduce_xor), ID($reduce_xnor), ID($lt), ID($le), ID($ge), ID($gt)))
replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx); replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::State::Sx);
else else
replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->getPort("\\Y").size())); replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::SigSpec(RTLIL::State::Sx, cell->getPort(ID::Y).size()));
goto next_cell; goto next_cell;
} }
} }
if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && cell->getPort(ID(Y)).size() == 1 && if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && cell->getPort(ID::Y).size() == 1 &&
invert_map.count(assign_map(cell->getPort(ID(A)))) != 0) { invert_map.count(assign_map(cell->getPort(ID::A))) != 0) {
cover_list("opt.opt_expr.invert.double", "$_NOT_", "$not", "$logic_not", cell->type.str()); cover_list("opt.opt_expr.invert.double", "$_NOT_", "$not", "$logic_not", cell->type.str());
replace_cell(assign_map, module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->getPort("\\A")))); replace_cell(assign_map, module, cell, "double_invert", ID::Y, invert_map.at(assign_map(cell->getPort(ID::A))));
goto next_cell; goto next_cell;
} }
if (cell->type.in(ID($_MUX_), ID($mux)) && invert_map.count(assign_map(cell->getPort(ID(S)))) != 0) { if (cell->type.in(ID($_MUX_), ID($mux)) && invert_map.count(assign_map(cell->getPort(ID(S)))) != 0) {
cover_list("opt.opt_expr.invert.muxsel", "$_MUX_", "$mux", cell->type.str()); cover_list("opt.opt_expr.invert.muxsel", "$_MUX_", "$mux", cell->type.str());
log_debug("Optimizing away select inverter for %s cell `%s' in module `%s'.\n", log_id(cell->type), log_id(cell), log_id(module)); log_debug("Optimizing away select inverter for %s cell `%s' in module `%s'.\n", log_id(cell->type), log_id(cell), log_id(module));
RTLIL::SigSpec tmp = cell->getPort(ID(A)); RTLIL::SigSpec tmp = cell->getPort(ID::A);
cell->setPort(ID(A), cell->getPort(ID(B))); cell->setPort(ID::A, cell->getPort(ID::B));
cell->setPort(ID(B), tmp); cell->setPort(ID::B, tmp);
cell->setPort(ID(S), invert_map.at(assign_map(cell->getPort(ID(S))))); cell->setPort(ID(S), invert_map.at(assign_map(cell->getPort(ID(S)))));
did_something = true; did_something = true;
goto next_cell; goto next_cell;
} }
if (cell->type == ID($_NOT_)) { if (cell->type == ID($_NOT_)) {
RTLIL::SigSpec input = cell->getPort(ID(A)); RTLIL::SigSpec input = cell->getPort(ID::A);
assign_map.apply(input); assign_map.apply(input);
if (input.match("1")) ACTION_DO_Y(0); if (input.match("1")) ACTION_DO_Y(0);
if (input.match("0")) ACTION_DO_Y(1); if (input.match("0")) ACTION_DO_Y(1);
@ -772,8 +773,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (cell->type == ID($_AND_)) { if (cell->type == ID($_AND_)) {
RTLIL::SigSpec input; RTLIL::SigSpec input;
input.append(cell->getPort(ID(B))); input.append(cell->getPort(ID::B));
input.append(cell->getPort(ID(A))); input.append(cell->getPort(ID::A));
assign_map.apply(input); assign_map.apply(input);
if (input.match(" 0")) ACTION_DO_Y(0); if (input.match(" 0")) ACTION_DO_Y(0);
if (input.match("0 ")) ACTION_DO_Y(0); if (input.match("0 ")) ACTION_DO_Y(0);
@ -785,14 +786,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (input.match(" *")) ACTION_DO_Y(0); if (input.match(" *")) ACTION_DO_Y(0);
if (input.match("* ")) ACTION_DO_Y(0); if (input.match("* ")) ACTION_DO_Y(0);
} }
if (input.match(" 1")) ACTION_DO(ID(Y), input.extract(1, 1)); if (input.match(" 1")) ACTION_DO(ID::Y, input.extract(1, 1));
if (input.match("1 ")) ACTION_DO(ID(Y), input.extract(0, 1)); if (input.match("1 ")) ACTION_DO(ID::Y, input.extract(0, 1));
} }
if (cell->type == ID($_OR_)) { if (cell->type == ID($_OR_)) {
RTLIL::SigSpec input; RTLIL::SigSpec input;
input.append(cell->getPort(ID(B))); input.append(cell->getPort(ID::B));
input.append(cell->getPort(ID(A))); input.append(cell->getPort(ID::A));
assign_map.apply(input); assign_map.apply(input);
if (input.match(" 1")) ACTION_DO_Y(1); if (input.match(" 1")) ACTION_DO_Y(1);
if (input.match("1 ")) ACTION_DO_Y(1); if (input.match("1 ")) ACTION_DO_Y(1);
@ -804,14 +805,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (input.match(" *")) ACTION_DO_Y(1); if (input.match(" *")) ACTION_DO_Y(1);
if (input.match("* ")) ACTION_DO_Y(1); if (input.match("* ")) ACTION_DO_Y(1);
} }
if (input.match(" 0")) ACTION_DO(ID(Y), input.extract(1, 1)); if (input.match(" 0")) ACTION_DO(ID::Y, input.extract(1, 1));
if (input.match("0 ")) ACTION_DO(ID(Y), input.extract(0, 1)); if (input.match("0 ")) ACTION_DO(ID::Y, input.extract(0, 1));
} }
if (cell->type == ID($_XOR_)) { if (cell->type == ID($_XOR_)) {
RTLIL::SigSpec input; RTLIL::SigSpec input;
input.append(cell->getPort(ID(B))); input.append(cell->getPort(ID::B));
input.append(cell->getPort(ID(A))); input.append(cell->getPort(ID::A));
assign_map.apply(input); assign_map.apply(input);
if (input.match("00")) ACTION_DO_Y(0); if (input.match("00")) ACTION_DO_Y(0);
if (input.match("01")) ACTION_DO_Y(1); if (input.match("01")) ACTION_DO_Y(1);
@ -819,26 +820,26 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (input.match("11")) ACTION_DO_Y(0); if (input.match("11")) ACTION_DO_Y(0);
if (input.match(" *")) ACTION_DO_Y(x); if (input.match(" *")) ACTION_DO_Y(x);
if (input.match("* ")) ACTION_DO_Y(x); if (input.match("* ")) ACTION_DO_Y(x);
if (input.match(" 0")) ACTION_DO(ID(Y), input.extract(1, 1)); if (input.match(" 0")) ACTION_DO(ID::Y, input.extract(1, 1));
if (input.match("0 ")) ACTION_DO(ID(Y), input.extract(0, 1)); if (input.match("0 ")) ACTION_DO(ID::Y, input.extract(0, 1));
} }
if (cell->type == ID($_MUX_)) { if (cell->type == ID($_MUX_)) {
RTLIL::SigSpec input; RTLIL::SigSpec input;
input.append(cell->getPort(ID(S))); input.append(cell->getPort(ID(S)));
input.append(cell->getPort(ID(B))); input.append(cell->getPort(ID::B));
input.append(cell->getPort(ID(A))); input.append(cell->getPort(ID::A));
assign_map.apply(input); assign_map.apply(input);
if (input.extract(2, 1) == input.extract(1, 1)) if (input.extract(2, 1) == input.extract(1, 1))
ACTION_DO(ID(Y), input.extract(2, 1)); ACTION_DO(ID::Y, input.extract(2, 1));
if (input.match(" 0")) ACTION_DO(ID(Y), input.extract(2, 1)); if (input.match(" 0")) ACTION_DO(ID::Y, input.extract(2, 1));
if (input.match(" 1")) ACTION_DO(ID(Y), input.extract(1, 1)); if (input.match(" 1")) ACTION_DO(ID::Y, input.extract(1, 1));
if (input.match("01 ")) ACTION_DO(ID(Y), input.extract(0, 1)); if (input.match("01 ")) ACTION_DO(ID::Y, input.extract(0, 1));
if (input.match("10 ")) { if (input.match("10 ")) {
cover("opt.opt_expr.mux_to_inv"); cover("opt.opt_expr.mux_to_inv");
cell->type = ID($_NOT_); cell->type = ID($_NOT_);
cell->setPort(ID(A), input.extract(0, 1)); cell->setPort(ID::A, input.extract(0, 1));
cell->unsetPort(ID(B)); cell->unsetPort(ID::B);
cell->unsetPort(ID(S)); cell->unsetPort(ID(S));
goto next_cell; goto next_cell;
} }
@ -848,24 +849,24 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (input.match("01*")) ACTION_DO_Y(x); if (input.match("01*")) ACTION_DO_Y(x);
if (input.match("10*")) ACTION_DO_Y(x); if (input.match("10*")) ACTION_DO_Y(x);
if (mux_undef) { if (mux_undef) {
if (input.match("* ")) ACTION_DO(ID(Y), input.extract(1, 1)); if (input.match("* ")) ACTION_DO(ID::Y, input.extract(1, 1));
if (input.match(" * ")) ACTION_DO(ID(Y), input.extract(2, 1)); if (input.match(" * ")) ACTION_DO(ID::Y, input.extract(2, 1));
if (input.match(" *")) ACTION_DO(ID(Y), input.extract(2, 1)); if (input.match(" *")) ACTION_DO(ID::Y, input.extract(2, 1));
} }
} }
if (cell->type.in(ID($_TBUF_), ID($tribuf))) { if (cell->type.in(ID($_TBUF_), ID($tribuf))) {
RTLIL::SigSpec input = cell->getPort(cell->type == ID($_TBUF_) ? ID(E) : ID(EN)); RTLIL::SigSpec input = cell->getPort(cell->type == ID($_TBUF_) ? ID(E) : ID(EN));
RTLIL::SigSpec a = cell->getPort(ID(A)); RTLIL::SigSpec a = cell->getPort(ID::A);
assign_map.apply(input); assign_map.apply(input);
assign_map.apply(a); assign_map.apply(a);
if (input == State::S1) if (input == State::S1)
ACTION_DO(ID(Y), cell->getPort(ID(A))); ACTION_DO(ID::Y, cell->getPort(ID::A));
if (input == State::S0 && !a.is_fully_undef()) { if (input == State::S0 && !a.is_fully_undef()) {
cover("opt.opt_expr.action_" S__LINE__); cover("opt.opt_expr.action_" S__LINE__);
log_debug("Replacing data input of %s cell `%s' in module `%s' with constant undef.\n", log_debug("Replacing data input of %s cell `%s' in module `%s' with constant undef.\n",
cell->type.c_str(), cell->name.c_str(), module->name.c_str()); cell->type.c_str(), cell->name.c_str(), module->name.c_str());
cell->setPort(ID(A), SigSpec(State::Sx, GetSize(a))); cell->setPort(ID::A, SigSpec(State::Sx, GetSize(a)));
did_something = true; did_something = true;
goto next_cell; goto next_cell;
} }
@ -873,8 +874,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (cell->type.in(ID($eq), ID($ne), ID($eqx), ID($nex))) if (cell->type.in(ID($eq), ID($ne), ID($eqx), ID($nex)))
{ {
RTLIL::SigSpec a = cell->getPort(ID(A)); RTLIL::SigSpec a = cell->getPort(ID::A);
RTLIL::SigSpec b = cell->getPort(ID(B)); RTLIL::SigSpec b = cell->getPort(ID::B);
if (cell->parameters[ID(A_WIDTH)].as_int() != cell->parameters[ID(B_WIDTH)].as_int()) { if (cell->parameters[ID(A_WIDTH)].as_int() != cell->parameters[ID(B_WIDTH)].as_int()) {
int width = max(cell->parameters[ID(A_WIDTH)].as_int(), cell->parameters[ID(B_WIDTH)].as_int()); int width = max(cell->parameters[ID(A_WIDTH)].as_int(), cell->parameters[ID(B_WIDTH)].as_int());
@ -890,7 +891,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cover_list("opt.opt_expr.eqneq.isneq", "$eq", "$ne", "$eqx", "$nex", cell->type.str()); cover_list("opt.opt_expr.eqneq.isneq", "$eq", "$ne", "$eqx", "$nex", cell->type.str());
RTLIL::SigSpec new_y = RTLIL::SigSpec(cell->type.in(ID($eq), ID($eqx)) ? RTLIL::State::S0 : RTLIL::State::S1); RTLIL::SigSpec new_y = RTLIL::SigSpec(cell->type.in(ID($eq), ID($eqx)) ? RTLIL::State::S0 : RTLIL::State::S1);
new_y.extend_u0(cell->parameters[ID(Y_WIDTH)].as_int(), false); new_y.extend_u0(cell->parameters[ID(Y_WIDTH)].as_int(), false);
replace_cell(assign_map, module, cell, "isneq", "\\Y", new_y); replace_cell(assign_map, module, cell, "isneq", ID::Y, new_y);
goto next_cell; goto next_cell;
} }
if (a[i] == b[i]) if (a[i] == b[i])
@ -903,14 +904,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cover_list("opt.opt_expr.eqneq.empty", "$eq", "$ne", "$eqx", "$nex", cell->type.str()); cover_list("opt.opt_expr.eqneq.empty", "$eq", "$ne", "$eqx", "$nex", cell->type.str());
RTLIL::SigSpec new_y = RTLIL::SigSpec(cell->type.in(ID($eq), ID($eqx)) ? RTLIL::State::S1 : RTLIL::State::S0); RTLIL::SigSpec new_y = RTLIL::SigSpec(cell->type.in(ID($eq), ID($eqx)) ? RTLIL::State::S1 : RTLIL::State::S0);
new_y.extend_u0(cell->parameters[ID(Y_WIDTH)].as_int(), false); new_y.extend_u0(cell->parameters[ID(Y_WIDTH)].as_int(), false);
replace_cell(assign_map, module, cell, "empty", ID(Y), new_y); replace_cell(assign_map, module, cell, "empty", ID::Y, new_y);
goto next_cell; goto next_cell;
} }
if (new_a.size() < a.size() || new_b.size() < b.size()) { if (new_a.size() < a.size() || new_b.size() < b.size()) {
cover_list("opt.opt_expr.eqneq.resize", "$eq", "$ne", "$eqx", "$nex", cell->type.str()); cover_list("opt.opt_expr.eqneq.resize", "$eq", "$ne", "$eqx", "$nex", cell->type.str());
cell->setPort(ID(A), new_a); cell->setPort(ID::A, new_a);
cell->setPort(ID(B), new_b); cell->setPort(ID::B, new_b);
cell->parameters[ID(A_WIDTH)] = new_a.size(); cell->parameters[ID(A_WIDTH)] = new_a.size();
cell->parameters[ID(B_WIDTH)] = new_b.size(); cell->parameters[ID(B_WIDTH)] = new_b.size();
} }
@ -919,27 +920,27 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (cell->type.in(ID($eq), ID($ne)) && cell->parameters[ID(Y_WIDTH)].as_int() == 1 && if (cell->type.in(ID($eq), ID($ne)) && cell->parameters[ID(Y_WIDTH)].as_int() == 1 &&
cell->parameters[ID(A_WIDTH)].as_int() == 1 && cell->parameters[ID(B_WIDTH)].as_int() == 1) cell->parameters[ID(A_WIDTH)].as_int() == 1 && cell->parameters[ID(B_WIDTH)].as_int() == 1)
{ {
RTLIL::SigSpec a = assign_map(cell->getPort(ID(A))); RTLIL::SigSpec a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec b = assign_map(cell->getPort(ID(B))); RTLIL::SigSpec b = assign_map(cell->getPort(ID::B));
if (a.is_fully_const() && !b.is_fully_const()) { if (a.is_fully_const() && !b.is_fully_const()) {
cover_list("opt.opt_expr.eqneq.swapconst", "$eq", "$ne", cell->type.str()); cover_list("opt.opt_expr.eqneq.swapconst", "$eq", "$ne", cell->type.str());
cell->setPort(ID(A), b); cell->setPort(ID::A, b);
cell->setPort(ID(B), a); cell->setPort(ID::B, a);
std::swap(a, b); std::swap(a, b);
} }
if (b.is_fully_const()) { if (b.is_fully_const()) {
if (b.as_bool() == (cell->type == ID($eq))) { if (b.as_bool() == (cell->type == ID($eq))) {
RTLIL::SigSpec input = b; RTLIL::SigSpec input = b;
ACTION_DO(ID(Y), cell->getPort(ID(A))); ACTION_DO(ID::Y, cell->getPort(ID::A));
} else { } else {
cover_list("opt.opt_expr.eqneq.isnot", "$eq", "$ne", cell->type.str()); cover_list("opt.opt_expr.eqneq.isnot", "$eq", "$ne", cell->type.str());
log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module)); log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module));
cell->type = ID($not); cell->type = ID($not);
cell->parameters.erase(ID(B_WIDTH)); cell->parameters.erase(ID(B_WIDTH));
cell->parameters.erase(ID(B_SIGNED)); cell->parameters.erase(ID(B_SIGNED));
cell->unsetPort(ID(B)); cell->unsetPort(ID::B);
did_something = true; did_something = true;
} }
goto next_cell; goto next_cell;
@ -947,33 +948,33 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
} }
if (cell->type.in(ID($eq), ID($ne)) && if (cell->type.in(ID($eq), ID($ne)) &&
(assign_map(cell->getPort(ID(A))).is_fully_zero() || assign_map(cell->getPort(ID(B))).is_fully_zero())) (assign_map(cell->getPort(ID::A)).is_fully_zero() || assign_map(cell->getPort(ID::B)).is_fully_zero()))
{ {
cover_list("opt.opt_expr.eqneq.cmpzero", "$eq", "$ne", cell->type.str()); cover_list("opt.opt_expr.eqneq.cmpzero", "$eq", "$ne", cell->type.str());
log_debug("Replacing %s cell `%s' in module `%s' with %s.\n", log_id(cell->type), log_id(cell), log_debug("Replacing %s cell `%s' in module `%s' with %s.\n", log_id(cell->type), log_id(cell),
log_id(module), "$eq" ? "$logic_not" : "$reduce_bool"); log_id(module), "$eq" ? "$logic_not" : "$reduce_bool");
cell->type = cell->type == ID($eq) ? ID($logic_not) : ID($reduce_bool); cell->type = cell->type == ID($eq) ? ID($logic_not) : ID($reduce_bool);
if (assign_map(cell->getPort(ID(A))).is_fully_zero()) { if (assign_map(cell->getPort(ID::A)).is_fully_zero()) {
cell->setPort(ID(A), cell->getPort(ID(B))); cell->setPort(ID::A, cell->getPort(ID::B));
cell->setParam(ID(A_SIGNED), cell->getParam(ID(B_SIGNED))); cell->setParam(ID(A_SIGNED), cell->getParam(ID(B_SIGNED)));
cell->setParam(ID(A_WIDTH), cell->getParam(ID(B_WIDTH))); cell->setParam(ID(A_WIDTH), cell->getParam(ID(B_WIDTH)));
} }
cell->unsetPort(ID(B)); cell->unsetPort(ID::B);
cell->unsetParam(ID(B_SIGNED)); cell->unsetParam(ID(B_SIGNED));
cell->unsetParam(ID(B_WIDTH)); cell->unsetParam(ID(B_WIDTH));
did_something = true; did_something = true;
goto next_cell; goto next_cell;
} }
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)) && assign_map(cell->getPort(ID(B))).is_fully_const()) if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)) && assign_map(cell->getPort(ID::B)).is_fully_const())
{ {
bool sign_ext = cell->type == ID($sshr) && cell->getParam(ID(A_SIGNED)).as_bool(); bool sign_ext = cell->type == ID($sshr) && cell->getParam(ID(A_SIGNED)).as_bool();
int shift_bits = assign_map(cell->getPort(ID(B))).as_int(cell->type.in(ID($shift), ID($shiftx)) && cell->getParam(ID(B_SIGNED)).as_bool()); int shift_bits = assign_map(cell->getPort(ID::B)).as_int(cell->type.in(ID($shift), ID($shiftx)) && cell->getParam(ID(B_SIGNED)).as_bool());
if (cell->type.in(ID($shl), ID($sshl))) if (cell->type.in(ID($shl), ID($sshl)))
shift_bits *= -1; shift_bits *= -1;
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec sig_y(cell->type == ID($shiftx) ? RTLIL::State::Sx : RTLIL::State::S0, cell->getParam(ID(Y_WIDTH)).as_int()); RTLIL::SigSpec sig_y(cell->type == ID($shiftx) ? RTLIL::State::Sx : RTLIL::State::S0, cell->getParam(ID(Y_WIDTH)).as_int());
if (GetSize(sig_a) < GetSize(sig_y)) if (GetSize(sig_a) < GetSize(sig_y))
@ -990,9 +991,9 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cover_list("opt.opt_expr.constshift", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", cell->type.str()); cover_list("opt.opt_expr.constshift", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", cell->type.str());
log_debug("Replacing %s cell `%s' (B=%s, SHR=%d) in module `%s' with fixed wiring: %s\n", log_debug("Replacing %s cell `%s' (B=%s, SHR=%d) in module `%s' with fixed wiring: %s\n",
log_id(cell->type), log_id(cell), log_signal(assign_map(cell->getPort(ID(B)))), shift_bits, log_id(module), log_signal(sig_y)); log_id(cell->type), log_id(cell), log_signal(assign_map(cell->getPort(ID::B))), shift_bits, log_id(module), log_signal(sig_y));
module->connect(cell->getPort(ID(Y)), sig_y); module->connect(cell->getPort(ID::Y), sig_y);
module->remove(cell); module->remove(cell);
did_something = true; did_something = true;
@ -1007,8 +1008,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (cell->type.in(ID($add), ID($sub), ID($or), ID($xor))) if (cell->type.in(ID($add), ID($sub), ID($or), ID($xor)))
{ {
RTLIL::SigSpec a = assign_map(cell->getPort(ID(A))); RTLIL::SigSpec a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec b = assign_map(cell->getPort(ID(B))); RTLIL::SigSpec b = assign_map(cell->getPort(ID::B));
if (cell->type != ID($sub) && a.is_fully_const() && a.as_bool() == false) if (cell->type != ID($sub) && a.is_fully_const() && a.as_bool() == false)
identity_wrt_b = true; identity_wrt_b = true;
@ -1019,7 +1020,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)))
{ {
RTLIL::SigSpec b = assign_map(cell->getPort(ID(B))); RTLIL::SigSpec b = assign_map(cell->getPort(ID::B));
if (b.is_fully_const() && b.as_bool() == false) if (b.is_fully_const() && b.as_bool() == false)
identity_wrt_a = true; identity_wrt_a = true;
@ -1027,8 +1028,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (cell->type == ID($mul)) if (cell->type == ID($mul))
{ {
RTLIL::SigSpec a = assign_map(cell->getPort(ID(A))); RTLIL::SigSpec a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec b = assign_map(cell->getPort(ID(B))); RTLIL::SigSpec b = assign_map(cell->getPort(ID::B));
if (a.is_fully_const() && is_one_or_minus_one(a.as_const(), cell->getParam(ID(A_SIGNED)).as_bool(), arith_inverse)) if (a.is_fully_const() && is_one_or_minus_one(a.as_const(), cell->getParam(ID(A_SIGNED)).as_bool(), arith_inverse))
identity_wrt_b = true; identity_wrt_b = true;
@ -1039,7 +1040,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (cell->type == ID($div)) if (cell->type == ID($div))
{ {
RTLIL::SigSpec b = assign_map(cell->getPort(ID(B))); RTLIL::SigSpec b = assign_map(cell->getPort(ID::B));
if (b.is_fully_const() && b.size() <= 32 && b.as_int() == 1) if (b.is_fully_const() && b.size() <= 32 && b.as_int() == 1)
identity_wrt_a = true; identity_wrt_a = true;
@ -1056,13 +1057,13 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B'); cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B');
if (!identity_wrt_a) { if (!identity_wrt_a) {
cell->setPort(ID(A), cell->getPort(ID(B))); cell->setPort(ID::A, cell->getPort(ID::B));
cell->parameters.at(ID(A_WIDTH)) = cell->parameters.at(ID(B_WIDTH)); cell->parameters.at(ID(A_WIDTH)) = cell->parameters.at(ID(B_WIDTH));
cell->parameters.at(ID(A_SIGNED)) = cell->parameters.at(ID(B_SIGNED)); cell->parameters.at(ID(A_SIGNED)) = cell->parameters.at(ID(B_SIGNED));
} }
cell->type = arith_inverse ? ID($neg) : ID($pos); cell->type = arith_inverse ? ID($neg) : ID($pos);
cell->unsetPort(ID(B)); cell->unsetPort(ID::B);
cell->parameters.erase(ID(B_WIDTH)); cell->parameters.erase(ID(B_WIDTH));
cell->parameters.erase(ID(B_SIGNED)); cell->parameters.erase(ID(B_SIGNED));
cell->check(); cell->check();
@ -1073,18 +1074,18 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
} }
if (mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && if (mux_bool && cell->type.in(ID($mux), ID($_MUX_)) &&
cell->getPort(ID(A)) == State::S0 && cell->getPort(ID(B)) == State::S1) { cell->getPort(ID::A) == State::S0 && cell->getPort(ID::B) == State::S1) {
cover_list("opt.opt_expr.mux_bool", "$mux", "$_MUX_", cell->type.str()); cover_list("opt.opt_expr.mux_bool", "$mux", "$_MUX_", cell->type.str());
replace_cell(assign_map, module, cell, "mux_bool", ID(Y), cell->getPort(ID(S))); replace_cell(assign_map, module, cell, "mux_bool", ID::Y, cell->getPort(ID(S)));
goto next_cell; goto next_cell;
} }
if (mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && if (mux_bool && cell->type.in(ID($mux), ID($_MUX_)) &&
cell->getPort(ID(A)) == State::S1 && cell->getPort(ID(B)) == State::S0) { cell->getPort(ID::A) == State::S1 && cell->getPort(ID::B) == State::S0) {
cover_list("opt.opt_expr.mux_invert", "$mux", "$_MUX_", cell->type.str()); cover_list("opt.opt_expr.mux_invert", "$mux", "$_MUX_", cell->type.str());
log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module)); log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module));
cell->setPort(ID(A), cell->getPort(ID(S))); cell->setPort(ID::A, cell->getPort(ID(S)));
cell->unsetPort(ID(B)); cell->unsetPort(ID::B);
cell->unsetPort(ID(S)); cell->unsetPort(ID(S));
if (cell->type == ID($mux)) { if (cell->type == ID($mux)) {
Const width = cell->parameters[ID(WIDTH)]; Const width = cell->parameters[ID(WIDTH)];
@ -1099,10 +1100,10 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
goto next_cell; goto next_cell;
} }
if (consume_x && mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID(A)) == State::S0) { if (consume_x && mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID::A) == State::S0) {
cover_list("opt.opt_expr.mux_and", "$mux", "$_MUX_", cell->type.str()); cover_list("opt.opt_expr.mux_and", "$mux", "$_MUX_", cell->type.str());
log_debug("Replacing %s cell `%s' in module `%s' with and-gate.\n", log_id(cell->type), log_id(cell), log_id(module)); log_debug("Replacing %s cell `%s' in module `%s' with and-gate.\n", log_id(cell->type), log_id(cell), log_id(module));
cell->setPort(ID(A), cell->getPort(ID(S))); cell->setPort(ID::A, cell->getPort(ID(S)));
cell->unsetPort(ID(S)); cell->unsetPort(ID(S));
if (cell->type == ID($mux)) { if (cell->type == ID($mux)) {
Const width = cell->parameters[ID(WIDTH)]; Const width = cell->parameters[ID(WIDTH)];
@ -1119,10 +1120,10 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
goto next_cell; goto next_cell;
} }
if (consume_x && mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID(B)) == State::S1) { if (consume_x && mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID::B) == State::S1) {
cover_list("opt.opt_expr.mux_or", "$mux", "$_MUX_", cell->type.str()); cover_list("opt.opt_expr.mux_or", "$mux", "$_MUX_", cell->type.str());
log_debug("Replacing %s cell `%s' in module `%s' with or-gate.\n", log_id(cell->type), log_id(cell), log_id(module)); log_debug("Replacing %s cell `%s' in module `%s' with or-gate.\n", log_id(cell->type), log_id(cell), log_id(module));
cell->setPort(ID(B), cell->getPort(ID(S))); cell->setPort(ID::B, cell->getPort(ID(S)));
cell->unsetPort(ID(S)); cell->unsetPort(ID(S));
if (cell->type == ID($mux)) { if (cell->type == ID($mux)) {
Const width = cell->parameters[ID(WIDTH)]; Const width = cell->parameters[ID(WIDTH)];
@ -1141,22 +1142,22 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (mux_undef && cell->type.in(ID($mux), ID($pmux))) { if (mux_undef && cell->type.in(ID($mux), ID($pmux))) {
RTLIL::SigSpec new_a, new_b, new_s; RTLIL::SigSpec new_a, new_b, new_s;
int width = cell->getPort(ID(A)).size(); int width = cell->getPort(ID::A).size();
if ((cell->getPort(ID(A)).is_fully_undef() && cell->getPort(ID(B)).is_fully_undef()) || if ((cell->getPort(ID::A).is_fully_undef() && cell->getPort(ID::B).is_fully_undef()) ||
cell->getPort(ID(S)).is_fully_undef()) { cell->getPort(ID(S)).is_fully_undef()) {
cover_list("opt.opt_expr.mux_undef", "$mux", "$pmux", cell->type.str()); cover_list("opt.opt_expr.mux_undef", "$mux", "$pmux", cell->type.str());
replace_cell(assign_map, module, cell, "mux_undef", ID(Y), cell->getPort(ID(A))); replace_cell(assign_map, module, cell, "mux_undef", ID::Y, cell->getPort(ID::A));
goto next_cell; goto next_cell;
} }
for (int i = 0; i < cell->getPort(ID(S)).size(); i++) { for (int i = 0; i < cell->getPort(ID(S)).size(); i++) {
RTLIL::SigSpec old_b = cell->getPort(ID(B)).extract(i*width, width); RTLIL::SigSpec old_b = cell->getPort(ID::B).extract(i*width, width);
RTLIL::SigSpec old_s = cell->getPort(ID(S)).extract(i, 1); RTLIL::SigSpec old_s = cell->getPort(ID(S)).extract(i, 1);
if (old_b.is_fully_undef() || old_s.is_fully_undef()) if (old_b.is_fully_undef() || old_s.is_fully_undef())
continue; continue;
new_b.append(old_b); new_b.append(old_b);
new_s.append(old_s); new_s.append(old_s);
} }
new_a = cell->getPort(ID(A)); new_a = cell->getPort(ID::A);
if (new_a.is_fully_undef() && new_s.size() > 0) { if (new_a.is_fully_undef() && new_s.size() > 0) {
new_a = new_b.extract((new_s.size()-1)*width, width); new_a = new_b.extract((new_s.size()-1)*width, width);
new_b = new_b.extract(0, (new_s.size()-1)*width); new_b = new_b.extract(0, (new_s.size()-1)*width);
@ -1164,20 +1165,20 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
} }
if (new_s.size() == 0) { if (new_s.size() == 0) {
cover_list("opt.opt_expr.mux_empty", "$mux", "$pmux", cell->type.str()); cover_list("opt.opt_expr.mux_empty", "$mux", "$pmux", cell->type.str());
replace_cell(assign_map, module, cell, "mux_empty", ID(Y), new_a); replace_cell(assign_map, module, cell, "mux_empty", ID::Y, new_a);
goto next_cell; goto next_cell;
} }
if (new_a == RTLIL::SigSpec(RTLIL::State::S0) && new_b == RTLIL::SigSpec(RTLIL::State::S1)) { if (new_a == RTLIL::SigSpec(RTLIL::State::S0) && new_b == RTLIL::SigSpec(RTLIL::State::S1)) {
cover_list("opt.opt_expr.mux_sel01", "$mux", "$pmux", cell->type.str()); cover_list("opt.opt_expr.mux_sel01", "$mux", "$pmux", cell->type.str());
replace_cell(assign_map, module, cell, "mux_sel01", ID(Y), new_s); replace_cell(assign_map, module, cell, "mux_sel01", ID::Y, new_s);
goto next_cell; goto next_cell;
} }
if (cell->getPort(ID(S)).size() != new_s.size()) { if (cell->getPort(ID(S)).size() != new_s.size()) {
cover_list("opt.opt_expr.mux_reduce", "$mux", "$pmux", cell->type.str()); cover_list("opt.opt_expr.mux_reduce", "$mux", "$pmux", cell->type.str());
log_debug("Optimized away %d select inputs of %s cell `%s' in module `%s'.\n", log_debug("Optimized away %d select inputs of %s cell `%s' in module `%s'.\n",
GetSize(cell->getPort(ID(S))) - GetSize(new_s), log_id(cell->type), log_id(cell), log_id(module)); GetSize(cell->getPort(ID(S))) - GetSize(new_s), log_id(cell->type), log_id(cell), log_id(module));
cell->setPort(ID(A), new_a); cell->setPort(ID::A, new_a);
cell->setPort(ID(B), new_b); cell->setPort(ID::B, new_b);
cell->setPort(ID(S), new_s); cell->setPort(ID(S), new_s);
if (new_s.size() > 1) { if (new_s.size() > 1) {
cell->type = ID($pmux); cell->type = ID($pmux);
@ -1192,7 +1193,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
#define FOLD_1ARG_CELL(_t) \ #define FOLD_1ARG_CELL(_t) \
if (cell->type == "$" #_t) { \ if (cell->type == "$" #_t) { \
RTLIL::SigSpec a = cell->getPort(ID(A)); \ RTLIL::SigSpec a = cell->getPort(ID::A); \
assign_map.apply(a); \ assign_map.apply(a); \
if (a.is_fully_const()) { \ if (a.is_fully_const()) { \
RTLIL::Const dummy_arg(RTLIL::State::S0, 1); \ RTLIL::Const dummy_arg(RTLIL::State::S0, 1); \
@ -1200,14 +1201,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cell->parameters[ID(A_SIGNED)].as_bool(), false, \ cell->parameters[ID(A_SIGNED)].as_bool(), false, \
cell->parameters[ID(Y_WIDTH)].as_int())); \ cell->parameters[ID(Y_WIDTH)].as_int())); \
cover("opt.opt_expr.const.$" #_t); \ cover("opt.opt_expr.const.$" #_t); \
replace_cell(assign_map, module, cell, stringf("%s", log_signal(a)), ID(Y), y); \ replace_cell(assign_map, module, cell, stringf("%s", log_signal(a)), ID::Y, y); \
goto next_cell; \ goto next_cell; \
} \ } \
} }
#define FOLD_2ARG_CELL(_t) \ #define FOLD_2ARG_CELL(_t) \
if (cell->type == "$" #_t) { \ if (cell->type == "$" #_t) { \
RTLIL::SigSpec a = cell->getPort(ID(A)); \ RTLIL::SigSpec a = cell->getPort(ID::A); \
RTLIL::SigSpec b = cell->getPort(ID(B)); \ RTLIL::SigSpec b = cell->getPort(ID::B); \
assign_map.apply(a), assign_map.apply(b); \ assign_map.apply(a), assign_map.apply(b); \
if (a.is_fully_const() && b.is_fully_const()) { \ if (a.is_fully_const() && b.is_fully_const()) { \
RTLIL::SigSpec y(RTLIL::const_ ## _t(a.as_const(), b.as_const(), \ RTLIL::SigSpec y(RTLIL::const_ ## _t(a.as_const(), b.as_const(), \
@ -1215,7 +1216,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cell->parameters[ID(B_SIGNED)].as_bool(), \ cell->parameters[ID(B_SIGNED)].as_bool(), \
cell->parameters[ID(Y_WIDTH)].as_int())); \ cell->parameters[ID(Y_WIDTH)].as_int())); \
cover("opt.opt_expr.const.$" #_t); \ cover("opt.opt_expr.const.$" #_t); \
replace_cell(assign_map, module, cell, stringf("%s, %s", log_signal(a), log_signal(b)), ID(Y), y); \ replace_cell(assign_map, module, cell, stringf("%s, %s", log_signal(a), log_signal(b)), ID::Y, y); \
goto next_cell; \ goto next_cell; \
} \ } \
} }
@ -1263,12 +1264,12 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
// be very conservative with optimizing $mux cells as we do not want to break mux trees // be very conservative with optimizing $mux cells as we do not want to break mux trees
if (cell->type == ID($mux)) { if (cell->type == ID($mux)) {
RTLIL::SigSpec input = assign_map(cell->getPort(ID(S))); RTLIL::SigSpec input = assign_map(cell->getPort(ID(S)));
RTLIL::SigSpec inA = assign_map(cell->getPort(ID(A))); RTLIL::SigSpec inA = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec inB = assign_map(cell->getPort(ID(B))); RTLIL::SigSpec inB = assign_map(cell->getPort(ID::B));
if (input.is_fully_const()) if (input.is_fully_const())
ACTION_DO(ID(Y), input.as_bool() ? cell->getPort(ID(B)) : cell->getPort(ID(A))); ACTION_DO(ID::Y, input.as_bool() ? cell->getPort(ID::B) : cell->getPort(ID::A));
else if (inA == inB) else if (inA == inB)
ACTION_DO(ID(Y), cell->getPort(ID(A))); ACTION_DO(ID::Y, cell->getPort(ID::A));
} }
if (!keepdc && cell->type == ID($mul)) if (!keepdc && cell->type == ID($mul))
@ -1277,9 +1278,9 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
bool b_signed = cell->parameters[ID(B_SIGNED)].as_bool(); bool b_signed = cell->parameters[ID(B_SIGNED)].as_bool();
bool swapped_ab = false; bool swapped_ab = false;
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID(B))); RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B));
RTLIL::SigSpec sig_y = assign_map(cell->getPort(ID(Y))); RTLIL::SigSpec sig_y = assign_map(cell->getPort(ID::Y));
if (sig_b.is_fully_const() && sig_b.size() <= 32) if (sig_b.is_fully_const() && sig_b.size() <= 32)
std::swap(sig_a, sig_b), std::swap(a_signed, b_signed), swapped_ab = true; std::swap(sig_a, sig_b), std::swap(a_signed, b_signed), swapped_ab = true;
@ -1314,7 +1315,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
a_val, cell->name.c_str(), module->name.c_str(), i); a_val, cell->name.c_str(), module->name.c_str(), i);
if (!swapped_ab) { if (!swapped_ab) {
cell->setPort(ID(A), cell->getPort(ID(B))); cell->setPort(ID::A, cell->getPort(ID::B));
cell->parameters.at(ID(A_WIDTH)) = cell->parameters.at(ID(B_WIDTH)); cell->parameters.at(ID(A_WIDTH)) = cell->parameters.at(ID(B_WIDTH));
cell->parameters.at(ID(A_SIGNED)) = cell->parameters.at(ID(B_SIGNED)); cell->parameters.at(ID(A_SIGNED)) = cell->parameters.at(ID(B_SIGNED));
} }
@ -1327,7 +1328,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cell->type = ID($shl); cell->type = ID($shl);
cell->parameters[ID(B_WIDTH)] = GetSize(new_b); cell->parameters[ID(B_WIDTH)] = GetSize(new_b);
cell->parameters[ID(B_SIGNED)] = false; cell->parameters[ID(B_SIGNED)] = false;
cell->setPort(ID(B), new_b); cell->setPort(ID::B, new_b);
cell->check(); cell->check();
did_something = true; did_something = true;
@ -1339,8 +1340,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (!keepdc && cell->type.in(ID($div), ID($mod))) if (!keepdc && cell->type.in(ID($div), ID($mod)))
{ {
bool b_signed = cell->parameters[ID(B_SIGNED)].as_bool(); bool b_signed = cell->parameters[ID(B_SIGNED)].as_bool();
SigSpec sig_b = assign_map(cell->getPort(ID(B))); SigSpec sig_b = assign_map(cell->getPort(ID::B));
SigSpec sig_y = assign_map(cell->getPort(ID(Y))); SigSpec sig_y = assign_map(cell->getPort(ID::Y));
if (sig_b.is_fully_def() && sig_b.size() <= 32) if (sig_b.is_fully_def() && sig_b.size() <= 32)
{ {
@ -1378,7 +1379,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cell->type = ID($shr); cell->type = ID($shr);
cell->parameters[ID(B_WIDTH)] = GetSize(new_b); cell->parameters[ID(B_WIDTH)] = GetSize(new_b);
cell->parameters[ID(B_SIGNED)] = false; cell->parameters[ID(B_SIGNED)] = false;
cell->setPort(ID(B), new_b); cell->setPort(ID::B, new_b);
cell->check(); cell->check();
} }
else else
@ -1395,7 +1396,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cell->type = ID($and); cell->type = ID($and);
cell->parameters[ID(B_WIDTH)] = GetSize(new_b); cell->parameters[ID(B_WIDTH)] = GetSize(new_b);
cell->setPort(ID(B), new_b); cell->setPort(ID::B, new_b);
cell->check(); cell->check();
} }
@ -1421,8 +1422,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
int width = is_signed ? std::min(a_width, b_width) : std::max(a_width, b_width); int width = is_signed ? std::min(a_width, b_width) : std::max(a_width, b_width);
SigSpec sig_a = cell->getPort(ID(A)); SigSpec sig_a = cell->getPort(ID::A);
SigSpec sig_b = cell->getPort(ID(B)); SigSpec sig_b = cell->getPort(ID::B);
int redundant_bits = 0; int redundant_bits = 0;
@ -1452,7 +1453,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (contradiction_cache.find(State::S0) == contradiction_cache.find(State::S1)) if (contradiction_cache.find(State::S0) == contradiction_cache.find(State::S1))
{ {
SigSpec y_sig = cell->getPort(ID(Y)); SigSpec y_sig = cell->getPort(ID::Y);
Const y_value(cell->type.in(ID($eq), ID($eqx)) ? 0 : 1, GetSize(y_sig)); Const y_value(cell->type.in(ID($eq), ID($eqx)) ? 0 : 1, GetSize(y_sig));
log_debug("Replacing cell `%s' in module `%s' with constant driver %s.\n", log_debug("Replacing cell `%s' in module `%s' with constant driver %s.\n",
@ -1470,8 +1471,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
log_debug("Removed %d redundant input bits from %s cell `%s' in module `%s'.\n", log_debug("Removed %d redundant input bits from %s cell `%s' in module `%s'.\n",
redundant_bits, log_id(cell->type), log_id(cell), log_id(module)); redundant_bits, log_id(cell->type), log_id(cell), log_id(module));
cell->setPort(ID(A), sig_a); cell->setPort(ID::A, sig_a);
cell->setPort(ID(B), sig_b); cell->setPort(ID::B, sig_b);
cell->setParam(ID(A_WIDTH), GetSize(sig_a)); cell->setParam(ID(A_WIDTH), GetSize(sig_a));
cell->setParam(ID(B_WIDTH), GetSize(sig_b)); cell->setParam(ID(B_WIDTH), GetSize(sig_b));
@ -1484,8 +1485,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (do_fine && cell->type.in(ID($lt), ID($ge), ID($gt), ID($le))) if (do_fine && cell->type.in(ID($lt), ID($ge), ID($gt), ID($le)))
{ {
IdString cmp_type = cell->type; IdString cmp_type = cell->type;
SigSpec var_sig = cell->getPort(ID(A)); SigSpec var_sig = cell->getPort(ID::A);
SigSpec const_sig = cell->getPort(ID(B)); SigSpec const_sig = cell->getPort(ID::B);
int var_width = cell->parameters[ID(A_WIDTH)].as_int(); int var_width = cell->parameters[ID(A_WIDTH)].as_int();
int const_width = cell->parameters[ID(B_WIDTH)].as_int(); int const_width = cell->parameters[ID(B_WIDTH)].as_int();
bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
@ -1507,7 +1508,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (const_sig.is_fully_def() && const_sig.is_fully_const()) if (const_sig.is_fully_def() && const_sig.is_fully_const())
{ {
std::string condition, replacement; std::string condition, replacement;
SigSpec replace_sig(State::S0, GetSize(cell->getPort(ID(Y)))); SigSpec replace_sig(State::S0, GetSize(cell->getPort(ID::Y)));
bool replace = false; bool replace = false;
bool remove = false; bool remove = false;
@ -1550,14 +1551,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
{ {
condition = stringf("unsigned X<%s", log_signal(const_sig)); condition = stringf("unsigned X<%s", log_signal(const_sig));
replacement = stringf("!X[%d:%d]", var_width - 1, const_bit_hot); replacement = stringf("!X[%d:%d]", var_width - 1, const_bit_hot);
module->addLogicNot(NEW_ID, var_high_sig, cell->getPort(ID(Y))); module->addLogicNot(NEW_ID, var_high_sig, cell->getPort(ID::Y));
remove = true; remove = true;
} }
if (cmp_type == ID($ge)) if (cmp_type == ID($ge))
{ {
condition = stringf("unsigned X>=%s", log_signal(const_sig)); condition = stringf("unsigned X>=%s", log_signal(const_sig));
replacement = stringf("|X[%d:%d]", var_width - 1, const_bit_hot); replacement = stringf("|X[%d:%d]", var_width - 1, const_bit_hot);
module->addReduceOr(NEW_ID, var_high_sig, cell->getPort(ID(Y))); module->addReduceOr(NEW_ID, var_high_sig, cell->getPort(ID::Y));
remove = true; remove = true;
} }
} }
@ -1599,7 +1600,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
{ {
condition = "signed X>=0"; condition = "signed X>=0";
replacement = stringf("X[%d]", var_width - 1); replacement = stringf("X[%d]", var_width - 1);
module->addNot(NEW_ID, var_sig[var_width - 1], cell->getPort(ID(Y))); module->addNot(NEW_ID, var_sig[var_width - 1], cell->getPort(ID::Y));
remove = true; remove = true;
} }
} }
@ -1609,7 +1610,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
log_debug("Replacing %s cell `%s' (implementing %s) with %s.\n", log_debug("Replacing %s cell `%s' (implementing %s) with %s.\n",
log_id(cell->type), log_id(cell), condition.c_str(), replacement.c_str()); log_id(cell->type), log_id(cell), condition.c_str(), replacement.c_str());
if (replace) if (replace)
module->connect(cell->getPort(ID(Y)), replace_sig); module->connect(cell->getPort(ID::Y), replace_sig);
module->remove(cell); module->remove(cell);
did_something = true; did_something = true;
goto next_cell; goto next_cell;

View file

@ -40,7 +40,7 @@ struct OptLutWorker
bool evaluate_lut(RTLIL::Cell *lut, dict<SigBit, bool> inputs) bool evaluate_lut(RTLIL::Cell *lut, dict<SigBit, bool> inputs)
{ {
SigSpec lut_input = sigmap(lut->getPort(ID(A))); SigSpec lut_input = sigmap(lut->getPort(ID::A));
int lut_width = lut->getParam(ID(WIDTH)).as_int(); int lut_width = lut->getParam(ID(WIDTH)).as_int();
Const lut_table = lut->getParam(ID(LUT)); Const lut_table = lut->getParam(ID(LUT));
int lut_index = 0; int lut_index = 0;
@ -103,12 +103,12 @@ struct OptLutWorker
{ {
if (cell->has_keep_attr()) if (cell->has_keep_attr())
continue; continue;
SigBit lut_output = cell->getPort(ID(Y)); SigBit lut_output = cell->getPort(ID::Y);
if (lut_output.wire->get_bool_attribute(ID(keep))) if (lut_output.wire->get_bool_attribute(ID::keep))
continue; continue;
int lut_width = cell->getParam(ID(WIDTH)).as_int(); int lut_width = cell->getParam(ID(WIDTH)).as_int();
SigSpec lut_input = cell->getPort(ID(A)); SigSpec lut_input = cell->getPort(ID::A);
int lut_arity = 0; int lut_arity = 0;
log_debug("Found $lut\\WIDTH=%d cell %s.%s.\n", lut_width, log_id(module), log_id(cell)); log_debug("Found $lut\\WIDTH=%d cell %s.%s.\n", lut_width, log_id(module), log_id(cell));
@ -205,7 +205,7 @@ struct OptLutWorker
} }
auto lut = worklist.pop(); auto lut = worklist.pop();
SigSpec lut_input = sigmap(lut->getPort(ID(A))); SigSpec lut_input = sigmap(lut->getPort(ID::A));
pool<int> &lut_dlogic_inputs = luts_dlogic_inputs[lut]; pool<int> &lut_dlogic_inputs = luts_dlogic_inputs[lut];
vector<SigBit> lut_inputs; vector<SigBit> lut_inputs;
@ -267,7 +267,7 @@ struct OptLutWorker
log_debug(" Not eliminating cell (connected to dedicated logic).\n"); log_debug(" Not eliminating cell (connected to dedicated logic).\n");
else else
{ {
SigSpec lut_output = lut->getPort(ID(Y)); SigSpec lut_output = lut->getPort(ID::Y);
for (auto &port : index.query_ports(lut_output)) for (auto &port : index.query_ports(lut_output))
{ {
if (port.cell != lut && luts.count(port.cell)) if (port.cell != lut && luts.count(port.cell))
@ -303,13 +303,13 @@ struct OptLutWorker
} }
auto lutA = worklist.pop(); auto lutA = worklist.pop();
SigSpec lutA_input = sigmap(lutA->getPort(ID(A))); SigSpec lutA_input = sigmap(lutA->getPort(ID::A));
SigSpec lutA_output = sigmap(lutA->getPort(ID(Y))[0]); SigSpec lutA_output = sigmap(lutA->getPort(ID::Y)[0]);
int lutA_width = lutA->getParam(ID(WIDTH)).as_int(); int lutA_width = lutA->getParam(ID(WIDTH)).as_int();
int lutA_arity = luts_arity[lutA]; int lutA_arity = luts_arity[lutA];
pool<int> &lutA_dlogic_inputs = luts_dlogic_inputs[lutA]; pool<int> &lutA_dlogic_inputs = luts_dlogic_inputs[lutA];
auto lutA_output_ports = index.query_ports(lutA->getPort(ID(Y))); auto lutA_output_ports = index.query_ports(lutA->getPort(ID::Y));
if (lutA_output_ports.size() != 2) if (lutA_output_ports.size() != 2)
continue; continue;
@ -321,15 +321,15 @@ struct OptLutWorker
if (luts.count(port.cell)) if (luts.count(port.cell))
{ {
auto lutB = port.cell; auto lutB = port.cell;
SigSpec lutB_input = sigmap(lutB->getPort(ID(A))); SigSpec lutB_input = sigmap(lutB->getPort(ID::A));
SigSpec lutB_output = sigmap(lutB->getPort(ID(Y))[0]); SigSpec lutB_output = sigmap(lutB->getPort(ID::Y)[0]);
int lutB_width = lutB->getParam(ID(WIDTH)).as_int(); int lutB_width = lutB->getParam(ID(WIDTH)).as_int();
int lutB_arity = luts_arity[lutB]; int lutB_arity = luts_arity[lutB];
pool<int> &lutB_dlogic_inputs = luts_dlogic_inputs[lutB]; pool<int> &lutB_dlogic_inputs = luts_dlogic_inputs[lutB];
log_debug("Found %s.%s (cell A) feeding %s.%s (cell B).\n", log_id(module), log_id(lutA), log_id(module), log_id(lutB)); log_debug("Found %s.%s (cell A) feeding %s.%s (cell B).\n", log_id(module), log_id(lutA), log_id(module), log_id(lutB));
if (index.query_is_output(lutA->getPort(ID(Y)))) if (index.query_is_output(lutA->getPort(ID::Y)))
{ {
log_debug(" Not combining LUTs (cascade connection feeds module output).\n"); log_debug(" Not combining LUTs (cascade connection feeds module output).\n");
continue; continue;
@ -441,7 +441,7 @@ struct OptLutWorker
} }
int lutM_width = lutM->getParam(ID(WIDTH)).as_int(); int lutM_width = lutM->getParam(ID(WIDTH)).as_int();
SigSpec lutM_input = sigmap(lutM->getPort(ID(A))); SigSpec lutM_input = sigmap(lutM->getPort(ID::A));
std::vector<SigBit> lutM_new_inputs; std::vector<SigBit> lutM_new_inputs;
for (int i = 0; i < lutM_width; i++) for (int i = 0; i < lutM_width; i++)
{ {
@ -487,8 +487,8 @@ struct OptLutWorker
log_debug(" Merged truth table: %s.\n", lutM_new_table.as_string().c_str()); log_debug(" Merged truth table: %s.\n", lutM_new_table.as_string().c_str());
lutM->setParam(ID(LUT), lutM_new_table); lutM->setParam(ID(LUT), lutM_new_table);
lutM->setPort(ID(A), lutM_new_inputs); lutM->setPort(ID::A, lutM_new_inputs);
lutM->setPort(ID(Y), lutB_output); lutM->setPort(ID::Y, lutB_output);
luts_arity[lutM] = lutM_arity; luts_arity[lutM] = lutM_arity;
luts.erase(lutR); luts.erase(lutR);

View file

@ -48,7 +48,7 @@ struct OptMergeWorker
static void sort_pmux_conn(dict<RTLIL::IdString, RTLIL::SigSpec> &conn) static void sort_pmux_conn(dict<RTLIL::IdString, RTLIL::SigSpec> &conn)
{ {
SigSpec sig_s = conn.at(ID(S)); SigSpec sig_s = conn.at(ID(S));
SigSpec sig_b = conn.at(ID(B)); SigSpec sig_b = conn.at(ID::B);
int s_width = GetSize(sig_s); int s_width = GetSize(sig_s);
int width = GetSize(sig_b) / s_width; int width = GetSize(sig_b) / s_width;
@ -60,11 +60,11 @@ struct OptMergeWorker
std::sort(sb_pairs.begin(), sb_pairs.end()); std::sort(sb_pairs.begin(), sb_pairs.end());
conn[ID(S)] = SigSpec(); conn[ID(S)] = SigSpec();
conn[ID(B)] = SigSpec(); conn[ID::B] = SigSpec();
for (auto &it : sb_pairs) { for (auto &it : sb_pairs) {
conn[ID(S)].append(it.first); conn[ID(S)].append(it.first);
conn[ID(B)].append(it.second); conn[ID::B].append(it.second);
} }
} }
@ -97,28 +97,28 @@ struct OptMergeWorker
if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($mul), if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($mul),
ID($logic_and), ID($logic_or), ID($_AND_), ID($_OR_), ID($_XOR_))) { ID($logic_and), ID($logic_or), ID($_AND_), ID($_OR_), ID($_XOR_))) {
alt_conn = *conn; alt_conn = *conn;
if (assign_map(alt_conn.at(ID(A))) < assign_map(alt_conn.at(ID(B)))) { if (assign_map(alt_conn.at(ID::A)) < assign_map(alt_conn.at(ID::B))) {
alt_conn[ID(A)] = conn->at(ID(B)); alt_conn[ID::A] = conn->at(ID::B);
alt_conn[ID(B)] = conn->at(ID(A)); alt_conn[ID::B] = conn->at(ID::A);
} }
conn = &alt_conn; conn = &alt_conn;
} else } else
if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) { if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) {
alt_conn = *conn; alt_conn = *conn;
assign_map.apply(alt_conn.at(ID(A))); assign_map.apply(alt_conn.at(ID::A));
alt_conn.at(ID(A)).sort(); alt_conn.at(ID::A).sort();
conn = &alt_conn; conn = &alt_conn;
} else } else
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool))) { if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool))) {
alt_conn = *conn; alt_conn = *conn;
assign_map.apply(alt_conn.at(ID(A))); assign_map.apply(alt_conn.at(ID::A));
alt_conn.at(ID(A)).sort_and_unify(); alt_conn.at(ID::A).sort_and_unify();
conn = &alt_conn; conn = &alt_conn;
} else } else
if (cell->type == ID($pmux)) { if (cell->type == ID($pmux)) {
alt_conn = *conn; alt_conn = *conn;
assign_map.apply(alt_conn.at(ID(A))); assign_map.apply(alt_conn.at(ID::A));
assign_map.apply(alt_conn.at(ID(B))); assign_map.apply(alt_conn.at(ID::B));
assign_map.apply(alt_conn.at(ID(S))); assign_map.apply(alt_conn.at(ID(S)));
sort_pmux_conn(alt_conn); sort_pmux_conn(alt_conn);
conn = &alt_conn; conn = &alt_conn;
@ -191,24 +191,24 @@ struct OptMergeWorker
if (cell1->type == ID($and) || cell1->type == ID($or) || cell1->type == ID($xor) || cell1->type == ID($xnor) || cell1->type == ID($add) || cell1->type == ID($mul) || if (cell1->type == ID($and) || cell1->type == ID($or) || cell1->type == ID($xor) || cell1->type == ID($xnor) || cell1->type == ID($add) || cell1->type == ID($mul) ||
cell1->type == ID($logic_and) || cell1->type == ID($logic_or) || cell1->type == ID($_AND_) || cell1->type == ID($_OR_) || cell1->type == ID($_XOR_)) { cell1->type == ID($logic_and) || cell1->type == ID($logic_or) || cell1->type == ID($_AND_) || cell1->type == ID($_OR_) || cell1->type == ID($_XOR_)) {
if (conn1.at(ID(A)) < conn1.at(ID(B))) { if (conn1.at(ID::A) < conn1.at(ID::B)) {
RTLIL::SigSpec tmp = conn1[ID(A)]; RTLIL::SigSpec tmp = conn1[ID::A];
conn1[ID(A)] = conn1[ID(B)]; conn1[ID::A] = conn1[ID::B];
conn1[ID(B)] = tmp; conn1[ID::B] = tmp;
} }
if (conn2.at(ID(A)) < conn2.at(ID(B))) { if (conn2.at(ID::A) < conn2.at(ID::B)) {
RTLIL::SigSpec tmp = conn2[ID(A)]; RTLIL::SigSpec tmp = conn2[ID::A];
conn2[ID(A)] = conn2[ID(B)]; conn2[ID::A] = conn2[ID::B];
conn2[ID(B)] = tmp; conn2[ID::B] = tmp;
} }
} else } else
if (cell1->type == ID($reduce_xor) || cell1->type == ID($reduce_xnor)) { if (cell1->type == ID($reduce_xor) || cell1->type == ID($reduce_xnor)) {
conn1[ID(A)].sort(); conn1[ID::A].sort();
conn2[ID(A)].sort(); conn2[ID::A].sort();
} else } else
if (cell1->type == ID($reduce_and) || cell1->type == ID($reduce_or) || cell1->type == ID($reduce_bool)) { if (cell1->type == ID($reduce_and) || cell1->type == ID($reduce_or) || cell1->type == ID($reduce_bool)) {
conn1[ID(A)].sort_and_unify(); conn1[ID::A].sort_and_unify();
conn2[ID(A)].sort_and_unify(); conn2[ID::A].sort_and_unify();
} else } else
if (cell1->type == ID($pmux)) { if (cell1->type == ID($pmux)) {
sort_pmux_conn(conn1); sort_pmux_conn(conn1);

View file

@ -86,10 +86,10 @@ struct OptMuxtreeWorker
{ {
if (cell->type.in(ID($mux), ID($pmux))) if (cell->type.in(ID($mux), ID($pmux)))
{ {
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);
muxinfo_t muxinfo; muxinfo_t muxinfo;
muxinfo.cell = cell; muxinfo.cell = cell;
@ -137,7 +137,7 @@ struct OptMuxtreeWorker
} }
} }
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 (int idx : sig2bits(RTLIL::SigSpec(wire))) for (int idx : sig2bits(RTLIL::SigSpec(wire)))
bit2info[idx].seen_non_mux = true; bit2info[idx].seen_non_mux = true;
} }
@ -227,10 +227,10 @@ struct OptMuxtreeWorker
continue; continue;
} }
RTLIL::SigSpec sig_a = mi.cell->getPort(ID(A)); RTLIL::SigSpec sig_a = mi.cell->getPort(ID::A);
RTLIL::SigSpec sig_b = mi.cell->getPort(ID(B)); RTLIL::SigSpec sig_b = mi.cell->getPort(ID::B);
RTLIL::SigSpec sig_s = mi.cell->getPort(ID(S)); RTLIL::SigSpec sig_s = mi.cell->getPort(ID(S));
RTLIL::SigSpec sig_y = mi.cell->getPort(ID(Y)); RTLIL::SigSpec sig_y = mi.cell->getPort(ID::Y);
RTLIL::SigSpec sig_ports = sig_b; RTLIL::SigSpec sig_ports = sig_b;
sig_ports.append(sig_a); sig_ports.append(sig_a);
@ -255,8 +255,8 @@ struct OptMuxtreeWorker
} }
} }
mi.cell->setPort(ID(A), new_sig_a); mi.cell->setPort(ID::A, new_sig_a);
mi.cell->setPort(ID(B), new_sig_b); mi.cell->setPort(ID::B, new_sig_b);
mi.cell->setPort(ID(S), new_sig_s); mi.cell->setPort(ID(S), new_sig_s);
if (GetSize(new_sig_s) == 1) { if (GetSize(new_sig_s) == 1) {
mi.cell->type = ID($mux); mi.cell->type = ID($mux);
@ -364,8 +364,8 @@ struct OptMuxtreeWorker
int width = 0; int width = 0;
idict<int> ctrl_bits; idict<int> ctrl_bits;
if (portname == ID(B)) if (portname == ID::B)
width = GetSize(muxinfo.cell->getPort(ID(A))); width = GetSize(muxinfo.cell->getPort(ID::A));
for (int bit : sig2bits(muxinfo.cell->getPort(ID(S)), false)) for (int bit : sig2bits(muxinfo.cell->getPort(ID(S)), false))
ctrl_bits(bit); ctrl_bits(bit);
@ -414,8 +414,8 @@ struct OptMuxtreeWorker
// set input ports to constants if we find known active or inactive signals // set input ports to constants if we find known active or inactive signals
if (do_replace_known) { if (do_replace_known) {
replace_known(knowledge, muxinfo, ID(A)); replace_known(knowledge, muxinfo, ID::A);
replace_known(knowledge, muxinfo, ID(B)); replace_known(knowledge, muxinfo, ID::B);
} }
// if there is a constant activated port we just use it // if there is a constant activated port we just use it

View file

@ -43,7 +43,7 @@ struct OptReduceWorker
return; return;
cells.erase(cell); cells.erase(cell);
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
pool<RTLIL::SigBit> new_sig_a_bits; pool<RTLIL::SigBit> new_sig_a_bits;
for (auto &bit : sig_a.to_sigbit_set()) for (auto &bit : sig_a.to_sigbit_set())
@ -73,8 +73,8 @@ struct OptReduceWorker
for (auto child_cell : drivers.find(bit)) { for (auto child_cell : drivers.find(bit)) {
if (child_cell->type == cell->type) { if (child_cell->type == cell->type) {
opt_reduce(cells, drivers, child_cell); opt_reduce(cells, drivers, child_cell);
if (child_cell->getPort(ID(Y))[0] == bit) { if (child_cell->getPort(ID::Y)[0] == bit) {
pool<RTLIL::SigBit> child_sig_a_bits = assign_map(child_cell->getPort(ID(A))).to_sigbit_pool(); pool<RTLIL::SigBit> child_sig_a_bits = assign_map(child_cell->getPort(ID::A)).to_sigbit_pool();
new_sig_a_bits.insert(child_sig_a_bits.begin(), child_sig_a_bits.end()); new_sig_a_bits.insert(child_sig_a_bits.begin(), child_sig_a_bits.end());
} else } else
new_sig_a_bits.insert(RTLIL::State::S0); new_sig_a_bits.insert(RTLIL::State::S0);
@ -87,21 +87,21 @@ struct OptReduceWorker
RTLIL::SigSpec new_sig_a(new_sig_a_bits); RTLIL::SigSpec new_sig_a(new_sig_a_bits);
if (new_sig_a != sig_a || sig_a.size() != cell->getPort(ID(A)).size()) { if (new_sig_a != sig_a || sig_a.size() != cell->getPort(ID::A).size()) {
log(" New input vector for %s cell %s: %s\n", cell->type.c_str(), cell->name.c_str(), log_signal(new_sig_a)); log(" New input vector for %s cell %s: %s\n", cell->type.c_str(), cell->name.c_str(), log_signal(new_sig_a));
did_something = true; did_something = true;
total_count++; total_count++;
} }
cell->setPort(ID(A), new_sig_a); cell->setPort(ID::A, new_sig_a);
cell->parameters[ID(A_WIDTH)] = RTLIL::Const(new_sig_a.size()); cell->parameters[ID(A_WIDTH)] = RTLIL::Const(new_sig_a.size());
return; return;
} }
void opt_mux(RTLIL::Cell *cell) void opt_mux(RTLIL::Cell *cell)
{ {
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID(B))); RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B));
RTLIL::SigSpec sig_s = assign_map(cell->getPort(ID(S))); RTLIL::SigSpec sig_s = assign_map(cell->getPort(ID(S)));
RTLIL::SigSpec new_sig_b, new_sig_s; RTLIL::SigSpec new_sig_b, new_sig_s;
@ -124,14 +124,14 @@ struct OptReduceWorker
if (this_s.size() > 1) if (this_s.size() > 1)
{ {
RTLIL::Cell *reduce_or_cell = module->addCell(NEW_ID, ID($reduce_or)); RTLIL::Cell *reduce_or_cell = module->addCell(NEW_ID, ID($reduce_or));
reduce_or_cell->setPort(ID(A), this_s); reduce_or_cell->setPort(ID::A, this_s);
reduce_or_cell->parameters[ID(A_SIGNED)] = RTLIL::Const(0); reduce_or_cell->parameters[ID(A_SIGNED)] = RTLIL::Const(0);
reduce_or_cell->parameters[ID(A_WIDTH)] = RTLIL::Const(this_s.size()); reduce_or_cell->parameters[ID(A_WIDTH)] = RTLIL::Const(this_s.size());
reduce_or_cell->parameters[ID(Y_WIDTH)] = RTLIL::Const(1); reduce_or_cell->parameters[ID(Y_WIDTH)] = RTLIL::Const(1);
RTLIL::Wire *reduce_or_wire = module->addWire(NEW_ID); RTLIL::Wire *reduce_or_wire = module->addWire(NEW_ID);
this_s = RTLIL::SigSpec(reduce_or_wire); this_s = RTLIL::SigSpec(reduce_or_wire);
reduce_or_cell->setPort(ID(Y), this_s); reduce_or_cell->setPort(ID::Y, this_s);
} }
new_sig_b.append(this_b); new_sig_b.append(this_b);
@ -147,13 +147,13 @@ struct OptReduceWorker
if (new_sig_s.size() == 0) if (new_sig_s.size() == 0)
{ {
module->connect(RTLIL::SigSig(cell->getPort(ID(Y)), cell->getPort(ID(A)))); module->connect(RTLIL::SigSig(cell->getPort(ID::Y), cell->getPort(ID::A)));
assign_map.add(cell->getPort(ID(Y)), cell->getPort(ID(A))); assign_map.add(cell->getPort(ID::Y), cell->getPort(ID::A));
module->remove(cell); module->remove(cell);
} }
else else
{ {
cell->setPort(ID(B), new_sig_b); cell->setPort(ID::B, new_sig_b);
cell->setPort(ID(S), new_sig_s); cell->setPort(ID(S), new_sig_s);
if (new_sig_s.size() > 1) { if (new_sig_s.size() > 1) {
cell->parameters[ID(S_WIDTH)] = RTLIL::Const(new_sig_s.size()); cell->parameters[ID(S_WIDTH)] = RTLIL::Const(new_sig_s.size());
@ -166,9 +166,9 @@ struct OptReduceWorker
void opt_mux_bits(RTLIL::Cell *cell) void opt_mux_bits(RTLIL::Cell *cell)
{ {
std::vector<RTLIL::SigBit> sig_a = assign_map(cell->getPort(ID(A))).to_sigbit_vector(); std::vector<RTLIL::SigBit> sig_a = assign_map(cell->getPort(ID::A)).to_sigbit_vector();
std::vector<RTLIL::SigBit> sig_b = assign_map(cell->getPort(ID(B))).to_sigbit_vector(); std::vector<RTLIL::SigBit> sig_b = assign_map(cell->getPort(ID::B)).to_sigbit_vector();
std::vector<RTLIL::SigBit> sig_y = assign_map(cell->getPort(ID(Y))).to_sigbit_vector(); std::vector<RTLIL::SigBit> sig_y = assign_map(cell->getPort(ID::Y)).to_sigbit_vector();
std::vector<RTLIL::SigBit> new_sig_y; std::vector<RTLIL::SigBit> new_sig_y;
RTLIL::SigSig old_sig_conn; RTLIL::SigSig old_sig_conn;
@ -209,29 +209,29 @@ struct OptReduceWorker
if (new_sig_y.size() != sig_y.size()) if (new_sig_y.size() != sig_y.size())
{ {
log(" Consolidated identical input bits for %s cell %s:\n", cell->type.c_str(), cell->name.c_str()); log(" Consolidated identical input bits for %s cell %s:\n", cell->type.c_str(), cell->name.c_str());
log(" Old ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort(ID(A))), log(" Old ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort(ID::A)),
log_signal(cell->getPort(ID(B))), log_signal(cell->getPort(ID(Y)))); log_signal(cell->getPort(ID::B)), log_signal(cell->getPort(ID::Y)));
cell->setPort(ID(A), RTLIL::SigSpec()); cell->setPort(ID::A, RTLIL::SigSpec());
for (auto &in_tuple : consolidated_in_tuples) { for (auto &in_tuple : consolidated_in_tuples) {
RTLIL::SigSpec new_a = cell->getPort(ID(A)); RTLIL::SigSpec new_a = cell->getPort(ID::A);
new_a.append(in_tuple.at(0)); new_a.append(in_tuple.at(0));
cell->setPort(ID(A), new_a); cell->setPort(ID::A, new_a);
} }
cell->setPort(ID(B), RTLIL::SigSpec()); cell->setPort(ID::B, RTLIL::SigSpec());
for (int i = 1; i <= cell->getPort(ID(S)).size(); i++) for (int i = 1; i <= cell->getPort(ID(S)).size(); i++)
for (auto &in_tuple : consolidated_in_tuples) { for (auto &in_tuple : consolidated_in_tuples) {
RTLIL::SigSpec new_b = cell->getPort(ID(B)); RTLIL::SigSpec new_b = cell->getPort(ID::B);
new_b.append(in_tuple.at(i)); new_b.append(in_tuple.at(i));
cell->setPort(ID(B), new_b); cell->setPort(ID::B, new_b);
} }
cell->parameters[ID(WIDTH)] = RTLIL::Const(new_sig_y.size()); cell->parameters[ID(WIDTH)] = RTLIL::Const(new_sig_y.size());
cell->setPort(ID(Y), new_sig_y); cell->setPort(ID::Y, new_sig_y);
log(" New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort(ID(A))), log(" New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort(ID::A)),
log_signal(cell->getPort(ID(B))), log_signal(cell->getPort(ID(Y)))); log_signal(cell->getPort(ID::B)), log_signal(cell->getPort(ID::Y)));
log(" New connections: %s = %s\n", log_signal(old_sig_conn.first), log_signal(old_sig_conn.second)); log(" New connections: %s = %s\n", log_signal(old_sig_conn.first), log_signal(old_sig_conn.second));
module->connect(old_sig_conn); module->connect(old_sig_conn);
@ -269,12 +269,12 @@ struct OptReduceWorker
keep_expanding_mem_wren_sigs = false; keep_expanding_mem_wren_sigs = false;
for (auto &cell_it : module->cells_) { for (auto &cell_it : module->cells_) {
RTLIL::Cell *cell = cell_it.second; RTLIL::Cell *cell = cell_it.second;
if (cell->type == ID($mux) && mem_wren_sigs.check_any(assign_map(cell->getPort(ID(Y))))) { if (cell->type == ID($mux) && mem_wren_sigs.check_any(assign_map(cell->getPort(ID::Y)))) {
if (!mem_wren_sigs.check_all(assign_map(cell->getPort(ID(A)))) || if (!mem_wren_sigs.check_all(assign_map(cell->getPort(ID::A))) ||
!mem_wren_sigs.check_all(assign_map(cell->getPort(ID(B))))) !mem_wren_sigs.check_all(assign_map(cell->getPort(ID::B))))
keep_expanding_mem_wren_sigs = true; keep_expanding_mem_wren_sigs = true;
mem_wren_sigs.add(assign_map(cell->getPort(ID(A)))); mem_wren_sigs.add(assign_map(cell->getPort(ID::A)));
mem_wren_sigs.add(assign_map(cell->getPort(ID(B)))); mem_wren_sigs.add(assign_map(cell->getPort(ID::B)));
} }
} }
} }
@ -296,7 +296,7 @@ struct OptReduceWorker
RTLIL::Cell *cell = cell_it.second; RTLIL::Cell *cell = cell_it.second;
if (cell->type != type || !design->selected(module, cell)) if (cell->type != type || !design->selected(module, cell))
continue; continue;
drivers.insert(assign_map(cell->getPort(ID(Y))), cell); drivers.insert(assign_map(cell->getPort(ID::Y)), cell);
cells.insert(cell); cells.insert(cell);
} }
@ -318,7 +318,7 @@ struct OptReduceWorker
{ {
// this optimization is to aggressive for most coarse-grain applications. // this optimization is to aggressive for most coarse-grain applications.
// but we always want it for multiplexers driving write enable ports. // but we always want it for multiplexers driving write enable ports.
if (do_fine || mem_wren_sigs.check_any(assign_map(cell->getPort(ID(Y))))) if (do_fine || mem_wren_sigs.check_any(assign_map(cell->getPort(ID::Y))))
opt_mux_bits(cell); opt_mux_bits(cell);
opt_mux(cell); opt_mux(cell);

View file

@ -347,8 +347,8 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
std::set<RTLIL::Cell*> muxes; std::set<RTLIL::Cell*> muxes;
mux_drivers.find(sig_d, muxes); mux_drivers.find(sig_d, muxes);
for (auto mux : muxes) { for (auto mux : muxes) {
RTLIL::SigSpec sig_a = assign_map(mux->getPort(ID(A))); RTLIL::SigSpec sig_a = assign_map(mux->getPort(ID::A));
RTLIL::SigSpec sig_b = assign_map(mux->getPort(ID(B))); RTLIL::SigSpec sig_b = assign_map(mux->getPort(ID::B));
if (sig_a == sig_q && sig_b.is_fully_const() && (!has_init || val_init == sig_b.as_const())) { if (sig_a == sig_q && sig_b.is_fully_const() && (!has_init || val_init == sig_b.as_const())) {
mod->connect(sig_q, sig_b); mod->connect(sig_q, sig_b);
goto delete_dff; goto delete_dff;
@ -625,8 +625,8 @@ struct OptRmdffPass : public Pass {
} }
if (cell->type.in(ID($mux), ID($pmux))) { if (cell->type.in(ID($mux), ID($pmux))) {
if (cell->getPort(ID(A)).size() == cell->getPort(ID(B)).size()) if (cell->getPort(ID::A).size() == cell->getPort(ID::B).size())
mux_drivers.insert(assign_map(cell->getPort(ID(Y))), cell); mux_drivers.insert(assign_map(cell->getPort(ID::Y)), cell);
continue; continue;
} }

649
passes/opt/opt_share.cc Normal file
View file

@ -0,0 +1,649 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
* 2019 Bogdan Vukobratovic <bogdan.vukobratovic@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "kernel/log.h"
#include "kernel/register.h"
#include "kernel/rtlil.h"
#include "kernel/sigtools.h"
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
SigMap assign_map;
struct OpMuxConn {
RTLIL::SigSpec sig;
RTLIL::Cell *mux;
RTLIL::Cell *op;
int mux_port_id;
int mux_port_offset;
int op_outsig_offset;
bool operator<(const OpMuxConn &other) const
{
if (mux != other.mux)
return mux < other.mux;
if (mux_port_id != other.mux_port_id)
return mux_port_id < other.mux_port_id;
return mux_port_offset < other.mux_port_offset;
}
};
// Helper class to track additiona information about a SigSpec, like whether it is signed and the semantics of the port it is connected to
struct ExtSigSpec {
RTLIL::SigSpec sig;
RTLIL::SigSpec sign;
bool is_signed;
RTLIL::IdString semantics;
ExtSigSpec() {}
ExtSigSpec(RTLIL::SigSpec s, RTLIL::SigSpec sign = RTLIL::Const(0, 1), bool is_signed = false, RTLIL::IdString semantics = RTLIL::IdString()) : sig(s), sign(sign), is_signed(is_signed), semantics(semantics) {}
bool empty() const { return sig.empty(); }
bool operator<(const ExtSigSpec &other) const
{
if (sig != other.sig)
return sig < other.sig;
if (sign != other.sign)
return sign < other.sign;
if (is_signed != other.is_signed)
return is_signed < other.is_signed;
return semantics < other.semantics;
}
bool operator==(const RTLIL::SigSpec &other) const { return (sign != RTLIL::Const(0, 1)) ? false : sig == other; }
bool operator==(const ExtSigSpec &other) const { return is_signed == other.is_signed && sign == other.sign && sig == other.sig && semantics == other.semantics; }
};
#define BITWISE_OPS ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), ID($and), ID($or), ID($xor), ID($xnor)
#define REDUCTION_OPS ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($reduce_nand)
#define LOGICAL_OPS ID($logic_and), ID($logic_or)
#define SHIFT_OPS ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)
#define RELATIONAL_OPS ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt)
bool cell_supported(RTLIL::Cell *cell)
{
if (cell->type.in(ID($alu))) {
RTLIL::SigSpec sig_bi = cell->getPort(ID(BI));
RTLIL::SigSpec sig_ci = cell->getPort(ID(CI));
if (sig_bi.is_fully_const() && sig_ci.is_fully_const() && sig_bi == sig_ci)
return true;
} else if (cell->type.in(LOGICAL_OPS, SHIFT_OPS, BITWISE_OPS, RELATIONAL_OPS, ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($concat))) {
return true;
}
return false;
}
std::map<IdString, IdString> mergeable_type_map{
{ID($sub), ID($add)},
};
bool mergeable(RTLIL::Cell *a, RTLIL::Cell *b)
{
auto a_type = a->type;
if (mergeable_type_map.count(a_type))
a_type = mergeable_type_map.at(a_type);
auto b_type = b->type;
if (mergeable_type_map.count(b_type))
b_type = mergeable_type_map.at(b_type);
return a_type == b_type;
}
RTLIL::IdString decode_port_semantics(RTLIL::Cell *cell, RTLIL::IdString port_name)
{
if (cell->type.in(ID($lt), ID($le), ID($ge), ID($gt), ID($div), ID($mod), ID($concat), SHIFT_OPS) && port_name == ID::B)
return port_name;
return "";
}
RTLIL::SigSpec decode_port_sign(RTLIL::Cell *cell, RTLIL::IdString port_name) {
if (cell->type == ID($alu) && port_name == ID::B)
return cell->getPort(ID(BI));
else if (cell->type == ID($sub) && port_name == ID::B)
return RTLIL::Const(1, 1);
return RTLIL::Const(0, 1);
}
bool decode_port_signed(RTLIL::Cell *cell, RTLIL::IdString port_name)
{
if (cell->type.in(BITWISE_OPS, LOGICAL_OPS))
return false;
if (cell->hasParam(port_name.str() + "_SIGNED"))
return cell->getParam(port_name.str() + "_SIGNED").as_bool();
return false;
}
ExtSigSpec decode_port(RTLIL::Cell *cell, RTLIL::IdString port_name, SigMap *sigmap)
{
auto sig = (*sigmap)(cell->getPort(port_name));
RTLIL::SigSpec sign = decode_port_sign(cell, port_name);
RTLIL::IdString semantics = decode_port_semantics(cell, port_name);
bool is_signed = decode_port_signed(cell, port_name);
return ExtSigSpec(sig, sign, is_signed, semantics);
}
void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<OpMuxConn> &ports, const ExtSigSpec &operand)
{
std::vector<ExtSigSpec> muxed_operands;
int max_width = 0;
for (const auto& p : ports) {
auto op = p.op;
RTLIL::IdString muxed_port_name = ID::A;
if (decode_port(op, ID::A, &assign_map) == operand)
muxed_port_name = ID::B;
auto operand = decode_port(op, muxed_port_name, &assign_map);
if (operand.sig.size() > max_width)
max_width = operand.sig.size();
muxed_operands.push_back(operand);
}
auto shared_op = ports[0].op;
if (std::any_of(muxed_operands.begin(), muxed_operands.end(), [&](ExtSigSpec &op) { return op.sign != muxed_operands[0].sign; }))
max_width = std::max(max_width, shared_op->getParam(ID(Y_WIDTH)).as_int());
for (auto &operand : muxed_operands)
operand.sig.extend_u0(max_width, operand.is_signed);
for (const auto& p : ports) {
auto op = p.op;
if (op == shared_op)
continue;
module->remove(op);
}
for (auto &muxed_op : muxed_operands)
if (muxed_op.sign != muxed_operands[0].sign)
muxed_op = ExtSigSpec(module->Neg(NEW_ID, muxed_op.sig, muxed_op.is_signed));
RTLIL::SigSpec mux_y = mux->getPort(ID::Y);
RTLIL::SigSpec mux_a = mux->getPort(ID::A);
RTLIL::SigSpec mux_b = mux->getPort(ID::B);
RTLIL::SigSpec mux_s = mux->getPort(ID(S));
RTLIL::SigSpec shared_pmux_a = RTLIL::Const(RTLIL::State::Sx, max_width);
RTLIL::SigSpec shared_pmux_b;
RTLIL::SigSpec shared_pmux_s;
int conn_width = ports[0].sig.size();
int conn_offset = ports[0].mux_port_offset;
shared_op->setPort(ID::Y, shared_op->getPort(ID::Y).extract(0, conn_width));
if (mux->type == ID($pmux)) {
shared_pmux_s = RTLIL::SigSpec();
for (const auto &p : ports) {
shared_pmux_s.append(mux_s[p.mux_port_id]);
mux_b.replace(p.mux_port_id * mux_a.size() + conn_offset, shared_op->getPort(ID::Y));
}
} else {
shared_pmux_s = RTLIL::SigSpec{mux_s, module->Not(NEW_ID, mux_s)};
mux_a.replace(conn_offset, shared_op->getPort(ID::Y));
mux_b.replace(conn_offset, shared_op->getPort(ID::Y));
}
mux->setPort(ID::A, mux_a);
mux->setPort(ID::B, mux_b);
mux->setPort(ID::Y, mux_y);
mux->setPort(ID(S), mux_s);
for (const auto &op : muxed_operands)
shared_pmux_b.append(op.sig);
auto mux_to_oper = module->Pmux(NEW_ID, shared_pmux_a, shared_pmux_b, shared_pmux_s);
if (shared_op->type.in(ID($alu))) {
RTLIL::SigSpec alu_x = shared_op->getPort(ID(X));
RTLIL::SigSpec alu_co = shared_op->getPort(ID(CO));
shared_op->setPort(ID(X), alu_x.extract(0, conn_width));
shared_op->setPort(ID(CO), alu_co.extract(0, conn_width));
}
shared_op->setParam(ID(Y_WIDTH), conn_width);
if (decode_port(shared_op, ID::A, &assign_map) == operand) {
shared_op->setPort(ID::B, mux_to_oper);
shared_op->setParam(ID(B_WIDTH), max_width);
} else {
shared_op->setPort(ID::A, mux_to_oper);
shared_op->setParam(ID(A_WIDTH), max_width);
}
}
typedef struct {
RTLIL::Cell *mux;
std::vector<OpMuxConn> ports;
ExtSigSpec shared_operand;
} merged_op_t;
template <typename T> void remove_val(std::vector<T> &v, const std::vector<T> &vals)
{
auto val_iter = vals.rbegin();
for (auto i = v.rbegin(); i != v.rend(); ++i)
if ((val_iter != vals.rend()) && (*i == *val_iter)) {
v.erase(i.base() - 1);
++val_iter;
}
}
void check_muxed_operands(std::vector<const OpMuxConn *> &ports, const ExtSigSpec &shared_operand)
{
auto it = ports.begin();
ExtSigSpec seed;
while (it != ports.end()) {
auto p = *it;
auto op = p->op;
RTLIL::IdString muxed_port_name = ID::A;
if (decode_port(op, ID::A, &assign_map) == shared_operand) {
muxed_port_name = ID::B;
}
auto operand = decode_port(op, muxed_port_name, &assign_map);
if (seed.empty())
seed = operand;
if (operand.is_signed != seed.is_signed) {
ports.erase(it);
} else {
++it;
}
}
}
ExtSigSpec find_shared_operand(const OpMuxConn* seed, std::vector<const OpMuxConn *> &ports, const std::map<ExtSigSpec, std::set<RTLIL::Cell *>> &operand_to_users)
{
std::set<RTLIL::Cell *> ops_using_operand;
std::set<RTLIL::Cell *> ops_set;
for(const auto& p: ports)
ops_set.insert(p->op);
ExtSigSpec oper;
auto op_a = seed->op;
for (RTLIL::IdString port_name : {ID::A, ID::B}) {
oper = decode_port(op_a, port_name, &assign_map);
auto operand_users = operand_to_users.at(oper);
if (operand_users.size() == 1)
continue;
ops_using_operand.clear();
for (auto mux_ops: ops_set)
if (operand_users.count(mux_ops))
ops_using_operand.insert(mux_ops);
if (ops_using_operand.size() > 1) {
ports.erase(std::remove_if(ports.begin(), ports.end(), [&](const OpMuxConn *p) { return !ops_using_operand.count(p->op); }),
ports.end());
return oper;
}
}
return ExtSigSpec();
}
dict<RTLIL::SigSpec, OpMuxConn> find_valid_op_mux_conns(RTLIL::Module *module, dict<RTLIL::SigBit, RTLIL::SigSpec> &op_outbit_to_outsig,
dict<RTLIL::SigSpec, RTLIL::Cell *> outsig_to_operator,
dict<RTLIL::SigBit, RTLIL::SigSpec> &op_aux_to_outsig)
{
dict<RTLIL::SigSpec, int> op_outsig_user_track;
dict<RTLIL::SigSpec, OpMuxConn> op_mux_conn_map;
std::function<void(RTLIL::SigSpec)> remove_outsig = [&](RTLIL::SigSpec outsig) {
for (auto op_outbit : outsig)
op_outbit_to_outsig.erase(op_outbit);
if (op_mux_conn_map.count(outsig))
op_mux_conn_map.erase(outsig);
};
std::function<void(RTLIL::SigBit)> remove_outsig_from_aux_bit = [&](RTLIL::SigBit auxbit) {
auto aux_outsig = op_aux_to_outsig.at(auxbit);
auto op = outsig_to_operator.at(aux_outsig);
auto op_outsig = assign_map(op->getPort(ID::Y));
remove_outsig(op_outsig);
for (auto aux_outbit : aux_outsig)
op_aux_to_outsig.erase(aux_outbit);
};
std::function<void(RTLIL::Cell *)> find_op_mux_conns = [&](RTLIL::Cell *mux) {
RTLIL::SigSpec sig;
int mux_port_size;
if (mux->type.in(ID($mux), ID($_MUX_))) {
mux_port_size = mux->getPort(ID::A).size();
sig = RTLIL::SigSpec{mux->getPort(ID::B), mux->getPort(ID::A)};
} else {
mux_port_size = mux->getPort(ID::A).size();
sig = mux->getPort(ID::B);
}
auto mux_insig = assign_map(sig);
for (int i = 0; i < mux_insig.size(); ++i) {
if (op_aux_to_outsig.count(mux_insig[i])) {
remove_outsig_from_aux_bit(mux_insig[i]);
continue;
}
if (!op_outbit_to_outsig.count(mux_insig[i]))
continue;
auto op_outsig = op_outbit_to_outsig.at(mux_insig[i]);
if (op_mux_conn_map.count(op_outsig)) {
remove_outsig(op_outsig);
continue;
}
int mux_port_id = i / mux_port_size;
int mux_port_offset = i % mux_port_size;
int op_outsig_offset;
for (op_outsig_offset = 0; op_outsig[op_outsig_offset] != mux_insig[i]; ++op_outsig_offset)
;
int j = op_outsig_offset;
do {
if (!op_outbit_to_outsig.count(mux_insig[i]))
break;
if (op_outbit_to_outsig.at(mux_insig[i]) != op_outsig)
break;
++i;
++j;
} while ((i / mux_port_size == mux_port_id) && (j < op_outsig.size()));
int op_conn_width = j - op_outsig_offset;
OpMuxConn inp = {
op_outsig.extract(op_outsig_offset, op_conn_width),
mux,
outsig_to_operator.at(op_outsig),
mux_port_id,
mux_port_offset,
op_outsig_offset,
};
op_mux_conn_map[op_outsig] = inp;
--i;
}
};
std::function<void(RTLIL::SigSpec)> remove_connected_ops = [&](RTLIL::SigSpec sig) {
auto mux_insig = assign_map(sig);
for (auto outbit : mux_insig) {
if (op_aux_to_outsig.count(outbit)) {
remove_outsig_from_aux_bit(outbit);
continue;
}
if (!op_outbit_to_outsig.count(outbit))
continue;
remove_outsig(op_outbit_to_outsig.at(outbit));
}
};
for (auto cell : module->cells()) {
if (cell->type.in(ID($mux), ID($_MUX_), ID($pmux))) {
remove_connected_ops(cell->getPort(ID(S)));
find_op_mux_conns(cell);
} else {
for (auto &conn : cell->connections())
if (cell->input(conn.first))
remove_connected_ops(conn.second);
}
}
for (auto w : module->wires()) {
if (!w->port_output)
continue;
remove_connected_ops(w);
}
return op_mux_conn_map;
}
struct OptSharePass : public Pass {
OptSharePass() : Pass("opt_share", "merge mutually exclusive cells of the same type that share an input signal") {}
void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" opt_share [selection]\n");
log("\n");
log("This pass identifies mutually exclusive cells of the same type that:\n");
log(" (a) share an input signal,\n");
log(" (b) drive the same $mux, $_MUX_, or $pmux multiplexing cell,\n");
log("\n");
log("allowing the cell to be merged and the multiplexer to be moved from\n");
log("multiplexing its output to multiplexing the non-shared input signals.\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing OPT_SHARE pass.\n");
extra_args(args, 1, design);
for (auto module : design->selected_modules()) {
assign_map.clear();
assign_map.set(module);
std::map<ExtSigSpec, std::set<RTLIL::Cell *>> operand_to_users;
dict<RTLIL::SigSpec, RTLIL::Cell *> outsig_to_operator;
dict<RTLIL::SigBit, RTLIL::SigSpec> op_outbit_to_outsig;
dict<RTLIL::SigBit, RTLIL::SigSpec> op_aux_to_outsig;
bool any_shared_operands = false;
std::vector<ExtSigSpec> op_insigs;
for (auto cell : module->cells()) {
if (!cell_supported(cell))
continue;
if (cell->type == ID($alu)) {
for (RTLIL::IdString port_name : {ID(X), ID(CO)}) {
auto mux_insig = assign_map(cell->getPort(port_name));
outsig_to_operator[mux_insig] = cell;
for (auto outbit : mux_insig)
op_aux_to_outsig[outbit] = mux_insig;
}
}
auto mux_insig = assign_map(cell->getPort(ID::Y));
outsig_to_operator[mux_insig] = cell;
for (auto outbit : mux_insig)
op_outbit_to_outsig[outbit] = mux_insig;
for (RTLIL::IdString port_name : {ID::A, ID::B}) {
auto op_insig = decode_port(cell, port_name, &assign_map);
op_insigs.push_back(op_insig);
operand_to_users[op_insig].insert(cell);
if (operand_to_users[op_insig].size() > 1)
any_shared_operands = true;
}
}
if (!any_shared_operands)
continue;
// Operator outputs need to be exclusively connected to the $mux inputs in order to be mergeable. Hence we count to
// how many points are operator output bits connected.
dict<RTLIL::SigSpec, OpMuxConn> op_mux_conn_map =
find_valid_op_mux_conns(module, op_outbit_to_outsig, outsig_to_operator, op_aux_to_outsig);
// Group op connections connected to same ports of the same $mux. Sort them in ascending order of their port offset
dict<RTLIL::Cell*, std::vector<std::set<OpMuxConn>>> mux_port_op_conns;
for (auto& val: op_mux_conn_map) {
OpMuxConn p = val.second;
auto& mux_port_conns = mux_port_op_conns[p.mux];
if (mux_port_conns.size() == 0) {
int mux_port_num;
if (p.mux->type.in(ID($mux), ID($_MUX_)))
mux_port_num = 2;
else
mux_port_num = p.mux->getPort(ID(S)).size();
mux_port_conns.resize(mux_port_num);
}
mux_port_conns[p.mux_port_id].insert(p);
}
std::vector<merged_op_t> merged_ops;
for (auto& val: mux_port_op_conns) {
RTLIL::Cell* cell = val.first;
auto &mux_port_conns = val.second;
const OpMuxConn *seed = NULL;
// Look through the bits of the $mux inputs and see which of them are connected to the operator
// results. Operator results can be concatenated with other signals before led to the $mux.
while (true) {
// Remove either the merged ports from the last iteration or the seed that failed to yield a merger
if (seed != NULL) {
mux_port_conns[seed->mux_port_id].erase(*seed);
seed = NULL;
}
// For a new merger, find the seed op connection that starts at lowest port offset among port connections
for (auto &port_conns : mux_port_conns) {
if (!port_conns.size())
continue;
const OpMuxConn *next_p = &(*port_conns.begin());
if ((seed == NULL) || (seed->mux_port_offset > next_p->mux_port_offset))
seed = next_p;
}
// Cannot find the seed -> nothing to do for this $mux anymore
if (seed == NULL)
break;
// Find all other op connections that start from the same port offset, and whose ops can be merged with the seed op
std::vector<const OpMuxConn *> mergeable_conns;
for (auto &port_conns : mux_port_conns) {
if (!port_conns.size())
continue;
const OpMuxConn *next_p = &(*port_conns.begin());
if ((next_p->op_outsig_offset == seed->op_outsig_offset) &&
(next_p->mux_port_offset == seed->mux_port_offset) && mergeable(next_p->op, seed->op) &&
next_p->sig.size() == seed->sig.size())
mergeable_conns.push_back(next_p);
}
// We need at least two mergeable connections for the merger
if (mergeable_conns.size() < 2)
continue;
// Filter mergeable connections whose ops share an operand with seed connection's op
auto shared_operand = find_shared_operand(seed, mergeable_conns, operand_to_users);
if (shared_operand.empty())
continue;
check_muxed_operands(mergeable_conns, shared_operand);
if (mergeable_conns.size() < 2)
continue;
// Remember the combination for the merger
std::vector<OpMuxConn> merged_ports;
for (auto p : mergeable_conns) {
merged_ports.push_back(*p);
mux_port_conns[p->mux_port_id].erase(*p);
}
seed = NULL;
merged_ops.push_back(merged_op_t{cell, merged_ports, shared_operand});
design->scratchpad_set_bool("opt.did_something", true);
}
}
for (auto &shared : merged_ops) {
log(" Found cells that share an operand and can be merged by moving the %s %s in front "
"of "
"them:\n",
log_id(shared.mux->type), log_id(shared.mux));
for (const auto& op : shared.ports)
log(" %s\n", log_id(op.op));
log("\n");
merge_operators(module, shared.mux, shared.ports, shared.shared_operand);
}
}
}
} OptSharePass;
PRIVATE_NAMESPACE_END

View file

@ -73,9 +73,9 @@ struct OnehotDatabase
if (cell->type.in(ID($mux), ID($pmux))) if (cell->type.in(ID($mux), ID($pmux)))
{ {
output = cell->getPort(ID(Y)); output = cell->getPort(ID::Y);
inputs.push_back(cell->getPort(ID(A))); inputs.push_back(cell->getPort(ID::A));
SigSpec B = cell->getPort(ID(B)); SigSpec B = cell->getPort(ID::B);
for (int i = 0; i < GetSize(B); i += GetSize(output)) for (int i = 0; i < GetSize(B); i += GetSize(output))
inputs.push_back(B.extract(i, GetSize(output))); inputs.push_back(B.extract(i, GetSize(output)));
} }
@ -296,8 +296,8 @@ struct Pmux2ShiftxPass : public Pass {
{ {
dict<SigBit, State> bits; dict<SigBit, State> bits;
SigSpec A = sigmap(cell->getPort(ID(A))); SigSpec A = sigmap(cell->getPort(ID::A));
SigSpec B = sigmap(cell->getPort(ID(B))); SigSpec B = sigmap(cell->getPort(ID::B));
int a_width = cell->getParam(ID(A_WIDTH)).as_int(); int a_width = cell->getParam(ID(A_WIDTH)).as_int();
int b_width = cell->getParam(ID(B_WIDTH)).as_int(); int b_width = cell->getParam(ID(B_WIDTH)).as_int();
@ -335,7 +335,7 @@ struct Pmux2ShiftxPass : public Pass {
entry.second.bits.push_back(it.second); entry.second.bits.push_back(it.second);
} }
eqdb[sigmap(cell->getPort(ID(Y))[0])] = entry; eqdb[sigmap(cell->getPort(ID::Y)[0])] = entry;
goto next_cell; goto next_cell;
} }
@ -343,7 +343,7 @@ struct Pmux2ShiftxPass : public Pass {
{ {
dict<SigBit, State> bits; dict<SigBit, State> bits;
SigSpec A = sigmap(cell->getPort(ID(A))); SigSpec A = sigmap(cell->getPort(ID::A));
for (int i = 0; i < GetSize(A); i++) for (int i = 0; i < GetSize(A); i++)
bits[A[i]] = State::S0; bits[A[i]] = State::S0;
@ -356,7 +356,7 @@ struct Pmux2ShiftxPass : public Pass {
entry.second.bits.push_back(it.second); entry.second.bits.push_back(it.second);
} }
eqdb[sigmap(cell->getPort(ID(Y))[0])] = entry; eqdb[sigmap(cell->getPort(ID::Y)[0])] = entry;
goto next_cell; goto next_cell;
} }
next_cell:; next_cell:;
@ -377,8 +377,8 @@ struct Pmux2ShiftxPass : public Pass {
dict<SigSpec, pool<int>> seldb; dict<SigSpec, pool<int>> seldb;
SigSpec A = cell->getPort(ID(A)); SigSpec A = cell->getPort(ID::A);
SigSpec B = cell->getPort(ID(B)); SigSpec B = cell->getPort(ID::B);
SigSpec S = sigmap(cell->getPort(ID(S))); SigSpec S = sigmap(cell->getPort(ID(S)));
for (int i = 0; i < GetSize(S); i++) for (int i = 0; i < GetSize(S); i++)
{ {
@ -401,7 +401,7 @@ struct Pmux2ShiftxPass : public Pass {
} }
SigSpec updated_S = cell->getPort(ID(S)); SigSpec updated_S = cell->getPort(ID(S));
SigSpec updated_B = cell->getPort(ID(B)); SigSpec updated_B = cell->getPort(ID::B);
while (!seldb.empty()) while (!seldb.empty())
{ {
@ -728,7 +728,7 @@ struct Pmux2ShiftxPass : public Pass {
// update $pmux cell // update $pmux cell
cell->setPort(ID(S), updated_S); cell->setPort(ID(S), updated_S);
cell->setPort(ID(B), updated_B); cell->setPort(ID::B, updated_B);
cell->setParam(ID(S_WIDTH), GetSize(updated_S)); cell->setParam(ID(S_WIDTH), GetSize(updated_S));
} }
} }
@ -782,8 +782,8 @@ struct OnehotPass : public Pass {
if (cell->type != ID($eq)) if (cell->type != ID($eq))
continue; continue;
SigSpec A = sigmap(cell->getPort(ID(A))); SigSpec A = sigmap(cell->getPort(ID::A));
SigSpec B = sigmap(cell->getPort(ID(B))); SigSpec B = sigmap(cell->getPort(ID::B));
int a_width = cell->getParam(ID(A_WIDTH)).as_int(); int a_width = cell->getParam(ID(A_WIDTH)).as_int();
int b_width = cell->getParam(ID(B_WIDTH)).as_int(); int b_width = cell->getParam(ID(B_WIDTH)).as_int();
@ -830,7 +830,7 @@ struct OnehotPass : public Pass {
continue; continue;
} }
SigSpec Y = cell->getPort(ID(Y)); SigSpec Y = cell->getPort(ID::Y);
if (not_onehot) if (not_onehot)
{ {

View file

@ -128,7 +128,7 @@ struct ShareWorker
static int bits_macc(RTLIL::Cell *c) static int bits_macc(RTLIL::Cell *c)
{ {
Macc m(c); Macc m(c);
int width = GetSize(c->getPort(ID(Y))); int width = GetSize(c->getPort(ID::Y));
return bits_macc(m, width); return bits_macc(m, width);
} }
@ -242,7 +242,7 @@ struct ShareWorker
{ {
Macc m1(c1), m2(c2), supermacc; Macc m1(c1), m2(c2), supermacc;
int w1 = GetSize(c1->getPort(ID(Y))), w2 = GetSize(c2->getPort(ID(Y))); int w1 = GetSize(c1->getPort(ID::Y)), w2 = GetSize(c2->getPort(ID::Y));
int width = max(w1, w2); int width = max(w1, w2);
m1.optimize(w1); m1.optimize(w1);
@ -328,11 +328,11 @@ struct ShareWorker
{ {
RTLIL::SigSpec sig_y = module->addWire(NEW_ID, width); RTLIL::SigSpec sig_y = module->addWire(NEW_ID, width);
supercell_aux->insert(module->addPos(NEW_ID, sig_y, c1->getPort(ID(Y)))); supercell_aux->insert(module->addPos(NEW_ID, sig_y, c1->getPort(ID::Y)));
supercell_aux->insert(module->addPos(NEW_ID, sig_y, c2->getPort(ID(Y)))); supercell_aux->insert(module->addPos(NEW_ID, sig_y, c2->getPort(ID::Y)));
supercell->setParam(ID(Y_WIDTH), width); supercell->setParam(ID(Y_WIDTH), width);
supercell->setPort(ID(Y), sig_y); supercell->setPort(ID::Y, sig_y);
supermacc.optimize(width); supermacc.optimize(width);
supermacc.to_cell(supercell); supermacc.to_cell(supercell);
@ -513,11 +513,11 @@ struct ShareWorker
if (c1->parameters.at(ID(A_SIGNED)).as_bool() != c2->parameters.at(ID(A_SIGNED)).as_bool()) if (c1->parameters.at(ID(A_SIGNED)).as_bool() != c2->parameters.at(ID(A_SIGNED)).as_bool())
{ {
RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(A_SIGNED)).as_bool() ? c2 : c1; RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(A_SIGNED)).as_bool() ? c2 : c1;
if (unsigned_cell->getPort(ID(A)).to_sigbit_vector().back() != RTLIL::State::S0) { if (unsigned_cell->getPort(ID::A).to_sigbit_vector().back() != RTLIL::State::S0) {
unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1; unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1;
RTLIL::SigSpec new_a = unsigned_cell->getPort(ID(A)); RTLIL::SigSpec new_a = unsigned_cell->getPort(ID::A);
new_a.append_bit(RTLIL::State::S0); new_a.append_bit(RTLIL::State::S0);
unsigned_cell->setPort(ID(A), new_a); unsigned_cell->setPort(ID::A, new_a);
} }
unsigned_cell->parameters.at(ID(A_SIGNED)) = true; unsigned_cell->parameters.at(ID(A_SIGNED)) = true;
unsigned_cell->check(); unsigned_cell->check();
@ -526,11 +526,11 @@ struct ShareWorker
bool a_signed = c1->parameters.at(ID(A_SIGNED)).as_bool(); bool a_signed = c1->parameters.at(ID(A_SIGNED)).as_bool();
log_assert(a_signed == c2->parameters.at(ID(A_SIGNED)).as_bool()); log_assert(a_signed == c2->parameters.at(ID(A_SIGNED)).as_bool());
RTLIL::SigSpec a1 = c1->getPort(ID(A)); RTLIL::SigSpec a1 = c1->getPort(ID::A);
RTLIL::SigSpec y1 = c1->getPort(ID(Y)); RTLIL::SigSpec y1 = c1->getPort(ID::Y);
RTLIL::SigSpec a2 = c2->getPort(ID(A)); RTLIL::SigSpec a2 = c2->getPort(ID::A);
RTLIL::SigSpec y2 = c2->getPort(ID(Y)); RTLIL::SigSpec y2 = c2->getPort(ID::Y);
int a_width = max(a1.size(), a2.size()); int a_width = max(a1.size(), a2.size());
int y_width = max(y1.size(), y2.size()); int y_width = max(y1.size(), y2.size());
@ -547,8 +547,8 @@ struct ShareWorker
supercell->parameters[ID(A_SIGNED)] = a_signed; supercell->parameters[ID(A_SIGNED)] = a_signed;
supercell->parameters[ID(A_WIDTH)] = a_width; supercell->parameters[ID(A_WIDTH)] = a_width;
supercell->parameters[ID(Y_WIDTH)] = y_width; supercell->parameters[ID(Y_WIDTH)] = y_width;
supercell->setPort(ID(A), a); supercell->setPort(ID::A, a);
supercell->setPort(ID(Y), y); supercell->setPort(ID::Y, y);
supercell_aux.insert(module->addPos(NEW_ID, y, y1)); supercell_aux.insert(module->addPos(NEW_ID, y, y1));
supercell_aux.insert(module->addPos(NEW_ID, y, y2)); supercell_aux.insert(module->addPos(NEW_ID, y, y2));
@ -571,9 +571,9 @@ struct ShareWorker
if (score_flipped < score_unflipped) if (score_flipped < score_unflipped)
{ {
RTLIL::SigSpec tmp = c2->getPort(ID(A)); RTLIL::SigSpec tmp = c2->getPort(ID::A);
c2->setPort(ID(A), c2->getPort(ID(B))); c2->setPort(ID::A, c2->getPort(ID::B));
c2->setPort(ID(B), tmp); c2->setPort(ID::B, tmp);
std::swap(c2->parameters.at(ID(A_WIDTH)), c2->parameters.at(ID(B_WIDTH))); std::swap(c2->parameters.at(ID(A_WIDTH)), c2->parameters.at(ID(B_WIDTH)));
std::swap(c2->parameters.at(ID(A_SIGNED)), c2->parameters.at(ID(B_SIGNED))); std::swap(c2->parameters.at(ID(A_SIGNED)), c2->parameters.at(ID(B_SIGNED)));
@ -585,11 +585,11 @@ struct ShareWorker
{ {
RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(A_SIGNED)).as_bool() ? c2 : c1; RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(A_SIGNED)).as_bool() ? c2 : c1;
if (unsigned_cell->getPort(ID(A)).to_sigbit_vector().back() != RTLIL::State::S0) { if (unsigned_cell->getPort(ID::A).to_sigbit_vector().back() != RTLIL::State::S0) {
unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1; unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1;
RTLIL::SigSpec new_a = unsigned_cell->getPort(ID(A)); RTLIL::SigSpec new_a = unsigned_cell->getPort(ID::A);
new_a.append_bit(RTLIL::State::S0); new_a.append_bit(RTLIL::State::S0);
unsigned_cell->setPort(ID(A), new_a); unsigned_cell->setPort(ID::A, new_a);
} }
unsigned_cell->parameters.at(ID(A_SIGNED)) = true; unsigned_cell->parameters.at(ID(A_SIGNED)) = true;
modified_src_cells = true; modified_src_cells = true;
@ -598,11 +598,11 @@ struct ShareWorker
if (c1->parameters.at(ID(B_SIGNED)).as_bool() != c2->parameters.at(ID(B_SIGNED)).as_bool()) if (c1->parameters.at(ID(B_SIGNED)).as_bool() != c2->parameters.at(ID(B_SIGNED)).as_bool())
{ {
RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(B_SIGNED)).as_bool() ? c2 : c1; RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(B_SIGNED)).as_bool() ? c2 : c1;
if (unsigned_cell->getPort(ID(B)).to_sigbit_vector().back() != RTLIL::State::S0) { if (unsigned_cell->getPort(ID::B).to_sigbit_vector().back() != RTLIL::State::S0) {
unsigned_cell->parameters.at(ID(B_WIDTH)) = unsigned_cell->parameters.at(ID(B_WIDTH)).as_int() + 1; unsigned_cell->parameters.at(ID(B_WIDTH)) = unsigned_cell->parameters.at(ID(B_WIDTH)).as_int() + 1;
RTLIL::SigSpec new_b = unsigned_cell->getPort(ID(B)); RTLIL::SigSpec new_b = unsigned_cell->getPort(ID::B);
new_b.append_bit(RTLIL::State::S0); new_b.append_bit(RTLIL::State::S0);
unsigned_cell->setPort(ID(B), new_b); unsigned_cell->setPort(ID::B, new_b);
} }
unsigned_cell->parameters.at(ID(B_SIGNED)) = true; unsigned_cell->parameters.at(ID(B_SIGNED)) = true;
modified_src_cells = true; modified_src_cells = true;
@ -622,13 +622,13 @@ struct ShareWorker
if (c1->type == ID($shl) || c1->type == ID($shr) || c1->type == ID($sshl) || c1->type == ID($sshr)) if (c1->type == ID($shl) || c1->type == ID($shr) || c1->type == ID($sshl) || c1->type == ID($sshr))
b_signed = false; b_signed = false;
RTLIL::SigSpec a1 = c1->getPort(ID(A)); RTLIL::SigSpec a1 = c1->getPort(ID::A);
RTLIL::SigSpec b1 = c1->getPort(ID(B)); RTLIL::SigSpec b1 = c1->getPort(ID::B);
RTLIL::SigSpec y1 = c1->getPort(ID(Y)); RTLIL::SigSpec y1 = c1->getPort(ID::Y);
RTLIL::SigSpec a2 = c2->getPort(ID(A)); RTLIL::SigSpec a2 = c2->getPort(ID::A);
RTLIL::SigSpec b2 = c2->getPort(ID(B)); RTLIL::SigSpec b2 = c2->getPort(ID::B);
RTLIL::SigSpec y2 = c2->getPort(ID(Y)); RTLIL::SigSpec y2 = c2->getPort(ID::Y);
int a_width = max(a1.size(), a2.size()); int a_width = max(a1.size(), a2.size());
int b_width = max(b1.size(), b2.size()); int b_width = max(b1.size(), b2.size());
@ -669,9 +669,9 @@ struct ShareWorker
supercell->parameters[ID(A_WIDTH)] = a_width; supercell->parameters[ID(A_WIDTH)] = a_width;
supercell->parameters[ID(B_WIDTH)] = b_width; supercell->parameters[ID(B_WIDTH)] = b_width;
supercell->parameters[ID(Y_WIDTH)] = y_width; supercell->parameters[ID(Y_WIDTH)] = y_width;
supercell->setPort(ID(A), a); supercell->setPort(ID::A, a);
supercell->setPort(ID(B), b); supercell->setPort(ID::B, b);
supercell->setPort(ID(Y), y); supercell->setPort(ID::Y, y);
if (c1->type == ID($alu)) { if (c1->type == ID($alu)) {
RTLIL::Wire *ci = module->addWire(NEW_ID), *bi = module->addWire(NEW_ID); RTLIL::Wire *ci = module->addWire(NEW_ID), *bi = module->addWire(NEW_ID);
supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID(CI)), c1->getPort(ID(CI)), act, ci)); supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID(CI)), c1->getPort(ID(CI)), act, ci));
@ -874,7 +874,7 @@ struct ShareWorker
} }
for (auto &pbit : modwalker.signal_consumers[bit]) { for (auto &pbit : modwalker.signal_consumers[bit]) {
log_assert(fwd_ct.cell_known(pbit.cell->type)); log_assert(fwd_ct.cell_known(pbit.cell->type));
if ((pbit.cell->type == ID($mux) || pbit.cell->type == ID($pmux)) && (pbit.port == ID(A) || pbit.port == ID(B))) if ((pbit.cell->type == ID($mux) || pbit.cell->type == ID($pmux)) && (pbit.port == ID::A || pbit.port == ID::B))
driven_data_muxes.insert(pbit.cell); driven_data_muxes.insert(pbit.cell);
else else
driven_cells.insert(pbit.cell); driven_cells.insert(pbit.cell);
@ -891,8 +891,8 @@ struct ShareWorker
std::set<int> used_in_b_parts; std::set<int> used_in_b_parts;
int width = c->parameters.at(ID(WIDTH)).as_int(); int width = c->parameters.at(ID(WIDTH)).as_int();
std::vector<RTLIL::SigBit> sig_a = modwalker.sigmap(c->getPort(ID(A))); std::vector<RTLIL::SigBit> sig_a = modwalker.sigmap(c->getPort(ID::A));
std::vector<RTLIL::SigBit> sig_b = modwalker.sigmap(c->getPort(ID(B))); std::vector<RTLIL::SigBit> sig_b = modwalker.sigmap(c->getPort(ID::B));
std::vector<RTLIL::SigBit> sig_s = modwalker.sigmap(c->getPort(ID(S))); std::vector<RTLIL::SigBit> sig_s = modwalker.sigmap(c->getPort(ID(S)));
for (auto &bit : sig_a) for (auto &bit : sig_a)

View file

@ -22,7 +22,6 @@
#include "kernel/modtools.h" #include "kernel/modtools.h"
USING_YOSYS_NAMESPACE USING_YOSYS_NAMESPACE
using namespace RTLIL;
PRIVATE_NAMESPACE_BEGIN PRIVATE_NAMESPACE_BEGIN
@ -64,10 +63,10 @@ struct WreduceWorker
{ {
// Reduce size of MUX if inputs agree on a value for a bit or a output bit is unused // Reduce size of MUX if inputs agree on a value for a bit or a output bit is unused
SigSpec sig_a = mi.sigmap(cell->getPort(ID(A))); SigSpec sig_a = mi.sigmap(cell->getPort(ID::A));
SigSpec sig_b = mi.sigmap(cell->getPort(ID(B))); SigSpec sig_b = mi.sigmap(cell->getPort(ID::B));
SigSpec sig_s = mi.sigmap(cell->getPort(ID(S))); SigSpec sig_s = mi.sigmap(cell->getPort(ID(S)));
SigSpec sig_y = mi.sigmap(cell->getPort(ID(Y))); SigSpec sig_y = mi.sigmap(cell->getPort(ID::Y));
std::vector<SigBit> bits_removed; std::vector<SigBit> bits_removed;
if (sig_y.has_const()) if (sig_y.has_const())
@ -77,15 +76,15 @@ struct WreduceWorker
{ {
auto info = mi.query(sig_y[i]); auto info = mi.query(sig_y[i]);
if (!info->is_output && GetSize(info->ports) <= 1 && !keep_bits.count(mi.sigmap(sig_y[i]))) { if (!info->is_output && GetSize(info->ports) <= 1 && !keep_bits.count(mi.sigmap(sig_y[i]))) {
bits_removed.push_back(Sx); bits_removed.push_back(State::Sx);
continue; continue;
} }
SigBit ref = sig_a[i]; SigBit ref = sig_a[i];
for (int k = 0; k < GetSize(sig_s); k++) { for (int k = 0; k < GetSize(sig_s); k++) {
if ((config->keepdc || (ref != Sx && sig_b[k*GetSize(sig_a) + i] != Sx)) && ref != sig_b[k*GetSize(sig_a) + i]) if ((config->keepdc || (ref != State::Sx && sig_b[k*GetSize(sig_a) + i] != State::Sx)) && ref != sig_b[k*GetSize(sig_a) + i])
goto no_match_ab; goto no_match_ab;
if (sig_b[k*GetSize(sig_a) + i] != Sx) if (sig_b[k*GetSize(sig_a) + i] != State::Sx)
ref = sig_b[k*GetSize(sig_a) + i]; ref = sig_b[k*GetSize(sig_a) + i];
} }
if (0) if (0)
@ -130,9 +129,9 @@ struct WreduceWorker
for (auto bit : new_work_queue_bits) for (auto bit : new_work_queue_bits)
work_queue_bits.insert(bit); work_queue_bits.insert(bit);
cell->setPort(ID(A), new_sig_a); cell->setPort(ID::A, new_sig_a);
cell->setPort(ID(B), new_sig_b); cell->setPort(ID::B, new_sig_b);
cell->setPort(ID(Y), new_sig_y); cell->setPort(ID::Y, new_sig_y);
cell->fixup_parameters(); cell->fixup_parameters();
module->connect(sig_y.extract(n_kept, n_removed), sig_removed); module->connect(sig_y.extract(n_kept, n_removed), sig_removed);
@ -245,7 +244,7 @@ struct WreduceWorker
while (GetSize(sig) > 1 && sig[GetSize(sig)-1] == sig[GetSize(sig)-2]) while (GetSize(sig) > 1 && sig[GetSize(sig)-1] == sig[GetSize(sig)-2])
work_queue_bits.insert(sig[GetSize(sig)-1]), sig.remove(GetSize(sig)-1), bits_removed++; work_queue_bits.insert(sig[GetSize(sig)-1]), sig.remove(GetSize(sig)-1), bits_removed++;
} else { } else {
while (GetSize(sig) > 1 && sig[GetSize(sig)-1] == S0) while (GetSize(sig) > 1 && sig[GetSize(sig)-1] == State::S0)
work_queue_bits.insert(sig[GetSize(sig)-1]), sig.remove(GetSize(sig)-1), bits_removed++; work_queue_bits.insert(sig[GetSize(sig)-1]), sig.remove(GetSize(sig)-1), bits_removed++;
} }
@ -270,7 +269,7 @@ struct WreduceWorker
if (cell->type.in(ID($dff), ID($adff))) if (cell->type.in(ID($dff), ID($adff)))
return run_cell_dff(cell); return run_cell_dff(cell);
SigSpec sig = mi.sigmap(cell->getPort(ID(Y))); SigSpec sig = mi.sigmap(cell->getPort(ID::Y));
if (sig.has_const()) if (sig.has_const())
return; return;
@ -278,8 +277,8 @@ struct WreduceWorker
// Reduce size of ports A and B based on constant input bits and size of output port // Reduce size of ports A and B based on constant input bits and size of output port
int max_port_a_size = cell->hasPort(ID(A)) ? GetSize(cell->getPort(ID(A))) : -1; int max_port_a_size = cell->hasPort(ID::A) ? GetSize(cell->getPort(ID::A)) : -1;
int max_port_b_size = cell->hasPort(ID(B)) ? GetSize(cell->getPort(ID(B))) : -1; int max_port_b_size = cell->hasPort(ID::B) ? GetSize(cell->getPort(ID::B)) : -1;
if (cell->type.in(ID($not), ID($pos), ID($neg), ID($and), ID($or), ID($xor), ID($add), ID($sub))) { if (cell->type.in(ID($not), ID($pos), ID($neg), ID($and), ID($or), ID($xor), ID($add), ID($sub))) {
max_port_a_size = min(max_port_a_size, GetSize(sig)); max_port_a_size = min(max_port_a_size, GetSize(sig));
@ -295,8 +294,8 @@ struct WreduceWorker
if (max_port_b_size >= 0) if (max_port_b_size >= 0)
run_reduce_inport(cell, 'B', max_port_b_size, port_b_signed, did_something); run_reduce_inport(cell, 'B', max_port_b_size, port_b_signed, did_something);
if (cell->hasPort(ID(A)) && cell->hasPort(ID(B)) && port_a_signed && port_b_signed) { if (cell->hasPort(ID::A) && cell->hasPort(ID::B) && port_a_signed && port_b_signed) {
SigSpec sig_a = mi.sigmap(cell->getPort(ID(A))), sig_b = mi.sigmap(cell->getPort(ID(B))); SigSpec sig_a = mi.sigmap(cell->getPort(ID::A)), sig_b = mi.sigmap(cell->getPort(ID::B));
if (GetSize(sig_a) > 0 && sig_a[GetSize(sig_a)-1] == State::S0 && if (GetSize(sig_a) > 0 && sig_a[GetSize(sig_a)-1] == State::S0 &&
GetSize(sig_b) > 0 && sig_b[GetSize(sig_b)-1] == State::S0) { GetSize(sig_b) > 0 && sig_b[GetSize(sig_b)-1] == State::S0) {
log("Converting cell %s.%s (%s) from signed to unsigned.\n", log("Converting cell %s.%s (%s) from signed to unsigned.\n",
@ -309,8 +308,8 @@ struct WreduceWorker
} }
} }
if (cell->hasPort(ID(A)) && !cell->hasPort(ID(B)) && port_a_signed) { if (cell->hasPort(ID::A) && !cell->hasPort(ID::B) && port_a_signed) {
SigSpec sig_a = mi.sigmap(cell->getPort(ID(A))); SigSpec sig_a = mi.sigmap(cell->getPort(ID::A));
if (GetSize(sig_a) > 0 && sig_a[GetSize(sig_a)-1] == State::S0) { if (GetSize(sig_a) > 0 && sig_a[GetSize(sig_a)-1] == State::S0) {
log("Converting cell %s.%s (%s) from signed to unsigned.\n", log("Converting cell %s.%s (%s) from signed to unsigned.\n",
log_id(module), log_id(cell), log_id(cell->type)); log_id(module), log_id(cell), log_id(cell->type));
@ -347,8 +346,8 @@ struct WreduceWorker
bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool() || cell->type == ID($sub); bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool() || cell->type == ID($sub);
int a_size = 0, b_size = 0; int a_size = 0, b_size = 0;
if (cell->hasPort(ID(A))) a_size = GetSize(cell->getPort(ID(A))); if (cell->hasPort(ID::A)) a_size = GetSize(cell->getPort(ID::A));
if (cell->hasPort(ID(B))) b_size = GetSize(cell->getPort(ID(B))); if (cell->hasPort(ID::B)) b_size = GetSize(cell->getPort(ID::B));
int max_y_size = max(a_size, b_size); int max_y_size = max(a_size, b_size);
@ -359,7 +358,7 @@ struct WreduceWorker
max_y_size = a_size + b_size; max_y_size = a_size + b_size;
while (GetSize(sig) > 1 && GetSize(sig) > max_y_size) { while (GetSize(sig) > 1 && GetSize(sig) > max_y_size) {
module->connect(sig[GetSize(sig)-1], is_signed ? sig[GetSize(sig)-2] : S0); module->connect(sig[GetSize(sig)-1], is_signed ? sig[GetSize(sig)-2] : State::S0);
sig.remove(GetSize(sig)-1); sig.remove(GetSize(sig)-1);
bits_removed++; bits_removed++;
} }
@ -374,7 +373,7 @@ struct WreduceWorker
if (bits_removed) { if (bits_removed) {
log("Removed top %d bits (of %d) from port Y of cell %s.%s (%s).\n", log("Removed top %d bits (of %d) from port Y of cell %s.%s (%s).\n",
bits_removed, GetSize(sig) + bits_removed, log_id(module), log_id(cell), log_id(cell->type)); bits_removed, GetSize(sig) + bits_removed, log_id(module), log_id(cell), log_id(cell->type));
cell->setPort(ID(Y), sig); cell->setPort(ID::Y, sig);
did_something = true; did_something = true;
} }
@ -398,7 +397,7 @@ struct WreduceWorker
SigMap init_attr_sigmap = mi.sigmap; SigMap init_attr_sigmap = mi.sigmap;
for (auto w : module->wires()) { for (auto w : module->wires()) {
if (w->get_bool_attribute(ID(keep))) if (w->get_bool_attribute(ID::keep))
for (auto bit : mi.sigmap(w)) for (auto bit : mi.sigmap(w))
keep_bits.insert(bit); keep_bits.insert(bit);
if (w->attributes.count(ID(init))) { if (w->attributes.count(ID(init))) {
@ -530,10 +529,10 @@ struct WreducePass : public Pass {
{ {
if (c->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), if (c->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool),
ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt), ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt),
ID($logic_not), ID($logic_and), ID($logic_or)) && GetSize(c->getPort(ID(Y))) > 1) { ID($logic_not), ID($logic_and), ID($logic_or)) && GetSize(c->getPort(ID::Y)) > 1) {
SigSpec sig = c->getPort(ID(Y)); SigSpec sig = c->getPort(ID::Y);
if (!sig.has_const()) { if (!sig.has_const()) {
c->setPort(ID(Y), sig[0]); c->setPort(ID::Y, sig[0]);
c->setParam(ID(Y_WIDTH), 1); c->setParam(ID(Y_WIDTH), 1);
sig.remove(0); sig.remove(0);
module->connect(sig, Const(0, GetSize(sig))); module->connect(sig, Const(0, GetSize(sig)));
@ -542,7 +541,7 @@ struct WreducePass : public Pass {
if (c->type.in(ID($div), ID($mod), ID($pow))) if (c->type.in(ID($div), ID($mod), ID($pow)))
{ {
SigSpec A = c->getPort(ID(A)); SigSpec A = c->getPort(ID::A);
int original_a_width = GetSize(A); int original_a_width = GetSize(A);
if (c->getParam(ID(A_SIGNED)).as_bool()) { if (c->getParam(ID(A_SIGNED)).as_bool()) {
while (GetSize(A) > 1 && A[GetSize(A)-1] == State::S0 && A[GetSize(A)-2] == State::S0) while (GetSize(A) > 1 && A[GetSize(A)-1] == State::S0 && A[GetSize(A)-2] == State::S0)
@ -554,11 +553,11 @@ struct WreducePass : public Pass {
if (original_a_width != GetSize(A)) { if (original_a_width != GetSize(A)) {
log("Removed top %d bits (of %d) from port A of cell %s.%s (%s).\n", log("Removed top %d bits (of %d) from port A of cell %s.%s (%s).\n",
original_a_width-GetSize(A), original_a_width, log_id(module), log_id(c), log_id(c->type)); original_a_width-GetSize(A), original_a_width, log_id(module), log_id(c), log_id(c->type));
c->setPort(ID(A), A); c->setPort(ID::A, A);
c->setParam(ID(A_WIDTH), GetSize(A)); c->setParam(ID(A_WIDTH), GetSize(A));
} }
SigSpec B = c->getPort(ID(B)); SigSpec B = c->getPort(ID::B);
int original_b_width = GetSize(B); int original_b_width = GetSize(B);
if (c->getParam(ID(B_SIGNED)).as_bool()) { if (c->getParam(ID(B_SIGNED)).as_bool()) {
while (GetSize(B) > 1 && B[GetSize(B)-1] == State::S0 && B[GetSize(B)-2] == State::S0) while (GetSize(B) > 1 && B[GetSize(B)-1] == State::S0 && B[GetSize(B)-2] == State::S0)
@ -570,7 +569,7 @@ struct WreducePass : public Pass {
if (original_b_width != GetSize(B)) { if (original_b_width != GetSize(B)) {
log("Removed top %d bits (of %d) from port B of cell %s.%s (%s).\n", log("Removed top %d bits (of %d) from port B of cell %s.%s (%s).\n",
original_b_width-GetSize(B), original_b_width, log_id(module), log_id(c), log_id(c->type)); original_b_width-GetSize(B), original_b_width, log_id(module), log_id(c), log_id(c->type));
c->setPort(ID(B), B); c->setPort(ID::B, B);
c->setParam(ID(B_WIDTH), GetSize(B)); c->setParam(ID(B_WIDTH), GetSize(B));
} }
} }

View file

@ -1,25 +1,35 @@
%_pm.h: passes/pmgen/pmgen.py %.pmg
$(P) mkdir -p passes/pmgen && python3 $< -o $@ -p $(subst _pm.h,,$(notdir $@)) $(filter-out $<,$^)
# --------------------------------------
OBJS += passes/pmgen/test_pmgen.o
passes/pmgen/test_pmgen.o: passes/pmgen/test_pmgen_pm.h
$(eval $(call add_extra_objs,passes/pmgen/test_pmgen_pm.h))
# --------------------------------------
OBJS += passes/pmgen/ice40_dsp.o OBJS += passes/pmgen/ice40_dsp.o
OBJS += passes/pmgen/xilinx_dsp.o
OBJS += passes/pmgen/peepopt.o
# --------------------------------------
passes/pmgen/%.o: passes/pmgen/%_pm.h
passes/pmgen/ice40_dsp.o: passes/pmgen/ice40_dsp_pm.h passes/pmgen/ice40_dsp.o: passes/pmgen/ice40_dsp_pm.h
passes/pmgen/xilinx_dsp.o: passes/pmgen/xilinx_dsp_pm.h $(eval $(call add_extra_objs,passes/pmgen/ice40_dsp_pm.h))
EXTRA_OBJS += passes/pmgen/ice40_dsp_pm.h
EXTRA_OBJS += passes/pmgen/xilinx_dsp_pm.h
.SECONDARY: passes/pmgen/ice40_dsp_pm.h
.SECONDARY: passes/pmgen/xilinx_dsp_pm.h
passes/pmgen/%_pm.h: passes/pmgen/pmgen.py passes/pmgen/%.pmg
$(P) mkdir -p passes/pmgen && python3 $< -o $@ -p $* $(filter-out $<,$^)
# -------------------------------------- # --------------------------------------
OBJS += passes/pmgen/ice40_wrapcarry.o
passes/pmgen/ice40_wrapcarry.o: passes/pmgen/ice40_wrapcarry_pm.h
$(eval $(call add_extra_objs,passes/pmgen/ice40_wrapcarry_pm.h))
# --------------------------------------
OBJS += passes/pmgen/xilinx_dsp.o
passes/pmgen/xilinx_dsp.o: passes/pmgen/xilinx_dsp_pm.h
$(eval $(call add_extra_objs,passes/pmgen/xilinx_dsp.h))
# --------------------------------------
OBJS += passes/pmgen/peepopt.o
passes/pmgen/peepopt.o: passes/pmgen/peepopt_pm.h passes/pmgen/peepopt.o: passes/pmgen/peepopt_pm.h
EXTRA_OBJS += passes/pmgen/peepopt_pm.h $(eval $(call add_extra_objs,passes/pmgen/peepopt_pm.h))
.SECONDARY: passes/pmgen/peepopt_pm.h
PEEPOPT_PATTERN = passes/pmgen/peepopt_shiftmul.pmg PEEPOPT_PATTERN = passes/pmgen/peepopt_shiftmul.pmg
PEEPOPT_PATTERN += passes/pmgen/peepopt_muldiv.pmg PEEPOPT_PATTERN += passes/pmgen/peepopt_muldiv.pmg

View file

@ -45,9 +45,9 @@ of type `foobar_pm::state_<pattern_name>_t`.)
Similarly the `.pmg` file declares user data variables that become members of Similarly the `.pmg` file declares user data variables that become members of
`.ud_<pattern_name>`, a struct of type `foobar_pm::udata_<pattern_name>_t`. `.ud_<pattern_name>`, a struct of type `foobar_pm::udata_<pattern_name>_t`.
There are four versions of the `run_<pattern_name>()` method: Without callback, There are three versions of the `run_<pattern_name>()` method: Without callback,
callback without arguments, callback with reference to `pm`, and callback with callback without arguments, and callback with reference to `pm`. All versions
reference to `pm.st_<pattern_name>`. of the `run_<pattern_name>()` method return the number of found matches.
The .pmg File Format The .pmg File Format
@ -118,8 +118,8 @@ write matchers:
connected to any of the given signal bits, plus one if any of the signal connected to any of the given signal bits, plus one if any of the signal
bits is also a primary input or primary output. bits is also a primary input or primary output.
- In `code..endcode` blocks there exist `accept`, `reject`, and `branch` - In `code..endcode` blocks there exist `accept`, `reject`, `branch`,
statements. `finish`, and `subpattern` statements.
- In `index` statements there is a special `===` operator for the index - In `index` statements there is a special `===` operator for the index
lookup. lookup.
@ -175,6 +175,9 @@ explore the case where `mul` is set to `nullptr`. Without the `optional`
statement a match may only be assigned nullptr when one of the `if` expressions statement a match may only be assigned nullptr when one of the `if` expressions
evaluates to `false`. evaluates to `false`.
The `semioptional` statement marks matches that must match if at least one
matching cell exists, but if no matching cell exists it is set to `nullptr`.
Additional code Additional code
--------------- ---------------
@ -232,5 +235,108 @@ But in some cases it is more natural to utilize the implicit branch statement:
portAB = \B; portAB = \B;
endcode endcode
There is an implicit `code..endcode` block at the end of each `.pmg` file There is an implicit `code..endcode` block at the end of each (sub)pattern
that just accepts everything that gets all the way there. that just rejects.
A `code..finally..endcode` block executes the code after `finally` during
back-tracking. This is useful for maintaining user data state or printing
debug messages. For example:
udata <vector<Cell*>> stack
code
stack.push_back(addAB);
...
finally
stack.pop_back();
endcode
`accept` and `finish` statements can be used inside the `finally` section,
but not `reject`, `branch`, or `subpattern`.
Declaring a subpattern
----------------------
A subpattern starts with a line containing the `subpattern` keyword followed
by the name of the subpattern. Subpatterns can be called from a `code` block
using a `subpattern(<subpattern_name>);` C statement.
Arguments may be passed to subpattern via state variables. The `subpattern`
line must be followed by a `arg <arg1> <arg2> ...` line that lists the
state variables used to pass arguments.
state <IdString> foobar_type
state <bool> foobar_state
code foobar_type foobar_state
foobar_state = false;
foobar_type = $add;
subpattern(foo);
foobar_type = $sub;
subpattern(bar);
endcode
subpattern foo
arg foobar_type foobar_state
match addsub
index <IdString> addsub->type === foobar_type
...
endmatch
code
if (foobar_state) {
subpattern(tail);
} else {
foobar_state = true;
subpattern(bar);
}
endcode
subpattern bar
arg foobar_type foobar_state
match addsub
index <IdString> addsub->type === foobar_type
...
endmatch
code
if (foobar_state) {
subpattern(tail);
} else {
foobar_state = true;
subpattern(foo);
}
endcode
subpattern tail
...
Subpatterns cann be called recursively.
If a `subpattern` statement is preceded by a `fallthrough` statement, this is
equivalent to calling the subpattern at the end of the preceding block.
Generate Blocks
---------------
Match blocks may contain an optional `generate` section that is used for automatic
test-case generation. For example:
match mul
...
generate 10
SigSpec Y = port(ff, \D);
SigSpec A = module->addWire(NEW_ID, GetSize(Y) - rng(GetSize(Y)/2));
SigSpec B = module->addWire(NEW_ID, GetSize(Y) - rng(GetSize(Y)/2));
module->addMul(NEW_ID, A, B, Y, rng(2));
endmatch
The expression `rng(n)` returns a non-negative integer less than `n`.
The argument to `generate` is the chance of this generate block being executed
when the match block did not match anything, in percent.
The special statement `finish` can be used within generate blocks to terminate
the current pattern matcher run.

View file

@ -289,4 +289,5 @@ code clock clock_pol sigO sigCD
sigCD.extend_u0(32, addAB && param(addAB, \A_SIGNED).as_bool() && param(addAB, \B_SIGNED).as_bool()); sigCD.extend_u0(32, addAB && param(addAB, \A_SIGNED).as_bool() && param(addAB, \B_SIGNED).as_bool());
} }
} }
accept;
endcode endcode

View file

@ -0,0 +1,90 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "kernel/yosys.h"
#include "kernel/sigtools.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
#include "passes/pmgen/ice40_wrapcarry_pm.h"
void create_ice40_wrapcarry(ice40_wrapcarry_pm &pm)
{
auto &st = pm.st_ice40_wrapcarry;
#if 0
log("\n");
log("carry: %s\n", log_id(st.carry, "--"));
log("lut: %s\n", log_id(st.lut, "--"));
#endif
log(" replacing SB_LUT + SB_CARRY with $__ICE40_CARRY_WRAPPER cell.\n");
Cell *cell = pm.module->addCell(NEW_ID, "$__ICE40_CARRY_WRAPPER");
pm.module->swap_names(cell, st.carry);
cell->setPort("\\A", st.carry->getPort("\\I0"));
cell->setPort("\\B", st.carry->getPort("\\I1"));
cell->setPort("\\CI", st.carry->getPort("\\CI"));
cell->setPort("\\CO", st.carry->getPort("\\CO"));
cell->setPort("\\I0", st.lut->getPort("\\I0"));
cell->setPort("\\I3", st.lut->getPort("\\I3"));
cell->setPort("\\O", st.lut->getPort("\\O"));
cell->setParam("\\LUT", st.lut->getParam("\\LUT_INIT"));
pm.autoremove(st.carry);
pm.autoremove(st.lut);
}
struct Ice40WrapCarryPass : public Pass {
Ice40WrapCarryPass() : Pass("ice40_wrapcarry", "iCE40: wrap carries") { }
void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" ice40_wrapcarry [selection]\n");
log("\n");
log("Wrap manually instantiated SB_CARRY cells, along with their associated SB_LUTs,\n");
log("into an internal $__ICE40_CARRY_WRAPPER cell for preservation across technology\n");
log("mapping.");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing ICE40_WRAPCARRY pass (wrap carries).\n");
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
{
// if (args[argidx] == "-singleton") {
// singleton_mode = true;
// continue;
// }
break;
}
extra_args(args, argidx, design);
for (auto module : design->selected_modules())
ice40_wrapcarry_pm(module, module->selected_cells()).run_ice40_wrapcarry(create_ice40_wrapcarry);
}
} Ice40WrapCarryPass;
PRIVATE_NAMESPACE_END

View file

@ -0,0 +1,11 @@
pattern ice40_wrapcarry
match carry
select carry->type.in(\SB_CARRY)
endmatch
match lut
select lut->type.in(\SB_LUT4)
index <SigSpec> port(lut, \I1) === port(carry, \I0)
index <SigSpec> port(lut, \I2) === port(carry, \I1)
endmatch

View file

@ -32,5 +32,5 @@ code
log("muldiv pattern in %s: mul=%s, div=%s\n", log_id(module), log_id(mul), log_id(div)); log("muldiv pattern in %s: mul=%s, div=%s\n", log_id(module), log_id(mul), log_id(div));
module->connect(div_y, val_y); module->connect(div_y, val_y);
autoremove(div); autoremove(div);
reject; accept;
endcode endcode

View file

@ -34,6 +34,7 @@ match mul
endmatch endmatch
code code
{
IdString const_factor_port = port(mul, \A).is_fully_const() ? \A : \B; IdString const_factor_port = port(mul, \A).is_fully_const() ? \A : \B;
IdString const_factor_signed = const_factor_port == \A ? \A_SIGNED : \B_SIGNED; IdString const_factor_signed = const_factor_port == \A ? \A_SIGNED : \B_SIGNED;
Const const_factor_cnst = port(mul, const_factor_port).as_const(); Const const_factor_cnst = port(mul, const_factor_port).as_const();
@ -90,5 +91,6 @@ code
shift->setParam(\B_WIDTH, GetSize(new_b)); shift->setParam(\B_WIDTH, GetSize(new_b));
blacklist(shift); blacklist(shift);
reject; accept;
}
endcode endcode

View file

@ -38,7 +38,10 @@ for a in args:
assert prefix is not None assert prefix is not None
current_pattern = None current_pattern = None
current_subpattern = None
patterns = dict() patterns = dict()
subpatterns = dict()
subpattern_args = dict()
state_types = dict() state_types = dict()
udata_types = dict() udata_types = dict()
blocks = list() blocks = list()
@ -104,9 +107,12 @@ def rewrite_cpp(s):
return "".join(t) return "".join(t)
def process_pmgfile(f): def process_pmgfile(f, filename):
linenr = 0
global current_pattern global current_pattern
global current_subpattern
while True: while True:
linenr += 1
line = f.readline() line = f.readline()
if line == "": break if line == "": break
line = line.strip() line = line.strip()
@ -119,19 +125,52 @@ def process_pmgfile(f):
if current_pattern is not None: if current_pattern is not None:
block = dict() block = dict()
block["type"] = "final" block["type"] = "final"
block["pattern"] = current_pattern block["pattern"] = (current_pattern, current_subpattern)
blocks.append(block) blocks.append(block)
line = line.split() line = line.split()
assert len(line) == 2 assert len(line) == 2
assert line[1] not in patterns assert line[1] not in patterns
current_pattern = line[1] current_pattern = line[1]
current_subpattern = ""
patterns[current_pattern] = len(blocks) patterns[current_pattern] = len(blocks)
subpatterns[(current_pattern, current_subpattern)] = len(blocks)
subpattern_args[(current_pattern, current_subpattern)] = list()
state_types[current_pattern] = dict() state_types[current_pattern] = dict()
udata_types[current_pattern] = dict() udata_types[current_pattern] = dict()
continue continue
assert current_pattern is not None assert current_pattern is not None
if cmd == "fallthrough":
block = dict()
block["type"] = "fallthrough"
blocks.append(block)
line = line.split()
assert len(line) == 1
continue
if cmd == "subpattern":
if len(blocks) == 0 or blocks[-1]["type"] != "fallthrough":
block = dict()
block["type"] = "final"
block["pattern"] = (current_pattern, current_subpattern)
blocks.append(block)
elif len(blocks) and blocks[-1]["type"] == "fallthrough":
del blocks[-1]
line = line.split()
assert len(line) == 2
current_subpattern = line[1]
subpattern_args[(current_pattern, current_subpattern)] = list()
assert (current_pattern, current_subpattern) not in subpatterns
subpatterns[(current_pattern, current_subpattern)] = len(blocks)
continue
if cmd == "arg":
line = line.split()
assert len(line) > 1
subpattern_args[(current_pattern, current_subpattern)] += line[1:]
continue
if cmd == "state": if cmd == "state":
m = re.match(r"^state\s+<(.*?)>\s+(([A-Za-z_][A-Za-z_0-9]*\s+)*[A-Za-z_][A-Za-z_0-9]*)\s*$", line) m = re.match(r"^state\s+<(.*?)>\s+(([A-Za-z_][A-Za-z_0-9]*\s+)*[A-Za-z_][A-Za-z_0-9]*)\s*$", line)
assert m assert m
@ -155,11 +194,15 @@ def process_pmgfile(f):
if cmd == "match": if cmd == "match":
block = dict() block = dict()
block["type"] = "match" block["type"] = "match"
block["pattern"] = current_pattern block["src"] = "%s:%d" % (filename, linenr)
block["pattern"] = (current_pattern, current_subpattern)
block["genargs"] = None
block["gencode"] = None
line = line.split() line = line.split()
assert len(line) == 2 assert len(line) == 2
assert line[1] not in state_types[current_pattern] assert (line[1] not in state_types[current_pattern]) or (state_types[current_pattern][line[1]] == "Cell*")
block["cell"] = line[1] block["cell"] = line[1]
state_types[current_pattern][line[1]] = "Cell*"; state_types[current_pattern][line[1]] = "Cell*";
@ -168,8 +211,10 @@ def process_pmgfile(f):
block["index"] = list() block["index"] = list()
block["filter"] = list() block["filter"] = list()
block["optional"] = False block["optional"] = False
block["semioptional"] = False
while True: while True:
linenr += 1
l = f.readline() l = f.readline()
assert l != "" assert l != ""
a = l.split() a = l.split()
@ -201,31 +246,60 @@ def process_pmgfile(f):
block["optional"] = True block["optional"] = True
continue continue
if a[0] == "semioptional":
block["semioptional"] = True
continue
if a[0] == "generate":
block["genargs"] = list([int(s) for s in a[1:]])
block["gencode"] = list()
assert len(block["genargs"]) < 2
while True:
linenr += 1
l = f.readline()
assert l != ""
a = l.split()
if a[0] == "endmatch": break
block["gencode"].append(rewrite_cpp(l.rstrip()))
break
assert False assert False
if block["optional"]:
assert not block["semioptional"]
blocks.append(block) blocks.append(block)
continue continue
if cmd == "code": if cmd == "code":
block = dict() block = dict()
block["type"] = "code" block["type"] = "code"
block["pattern"] = current_pattern block["src"] = "%s:%d" % (filename, linenr)
block["pattern"] = (current_pattern, current_subpattern)
block["code"] = list() block["code"] = list()
block["fcode"] = list()
block["states"] = set() block["states"] = set()
for s in line.split()[1:]: for s in line.split()[1:]:
assert s in state_types[current_pattern] assert s in state_types[current_pattern]
block["states"].add(s) block["states"].add(s)
codetype = "code"
while True: while True:
linenr += 1
l = f.readline() l = f.readline()
assert l != "" assert l != ""
a = l.split() a = l.split()
if len(a) == 0: continue if len(a) == 0: continue
if a[0] == "endcode": break if a[0] == "endcode": break
block["code"].append(rewrite_cpp(l.rstrip())) if a[0] == "finally":
codetype = "fcode"
continue
block[codetype].append(rewrite_cpp(l.rstrip()))
blocks.append(block) blocks.append(block)
continue continue
@ -234,15 +308,16 @@ def process_pmgfile(f):
for fn in pmgfiles: for fn in pmgfiles:
with open(fn, "r") as f: with open(fn, "r") as f:
process_pmgfile(f) process_pmgfile(f, fn)
if current_pattern is not None: if current_pattern is not None:
block = dict() block = dict()
block["type"] = "final" block["type"] = "final"
block["pattern"] = current_pattern block["pattern"] = (current_pattern, current_subpattern)
blocks.append(block) blocks.append(block)
current_pattern = None current_pattern = None
current_subpattern = None
if debug: if debug:
pp.pprint(blocks) pp.pprint(blocks)
@ -262,7 +337,18 @@ with open(outfile, "w") as f:
print("struct {}_pm {{".format(prefix), file=f) print("struct {}_pm {{".format(prefix), file=f)
print(" Module *module;", file=f) print(" Module *module;", file=f)
print(" SigMap sigmap;", file=f) print(" SigMap sigmap;", file=f)
print(" std::function<void()> on_accept;".format(prefix), file=f) print(" std::function<void()> on_accept;", file=f)
print(" bool generate_mode;", file=f)
print(" int accept_cnt;", file=f)
print("", file=f)
print(" uint32_t rngseed;", file=f)
print(" int rng(unsigned int n) {", file=f)
print(" rngseed ^= rngseed << 13;", file=f)
print(" rngseed ^= rngseed >> 17;", file=f)
print(" rngseed ^= rngseed << 5;", file=f)
print(" return rngseed % n;", file=f)
print(" }", file=f)
print("", file=f) print("", file=f)
for index in range(len(blocks)): for index in range(len(blocks)):
@ -276,7 +362,7 @@ with open(outfile, "w") as f:
print(" dict<SigBit, pool<Cell*>> sigusers;", file=f) print(" dict<SigBit, pool<Cell*>> sigusers;", file=f)
print(" pool<Cell*> blacklist_cells;", file=f) print(" pool<Cell*> blacklist_cells;", file=f)
print(" pool<Cell*> autoremove_cells;", file=f) print(" pool<Cell*> autoremove_cells;", file=f)
print(" bool blacklist_dirty;", file=f) print(" dict<Cell*,int> rollback_cache;", file=f)
print(" int rollback;", file=f) print(" int rollback;", file=f)
print("", file=f) print("", file=f)
@ -312,39 +398,24 @@ with open(outfile, "w") as f:
print("", file=f) print("", file=f)
print(" void blacklist(Cell *cell) {", file=f) print(" void blacklist(Cell *cell) {", file=f)
print(" if (cell != nullptr) {", file=f) print(" if (cell != nullptr && blacklist_cells.insert(cell).second) {", file=f)
print(" if (blacklist_cells.insert(cell).second)", file=f) print(" auto ptr = rollback_cache.find(cell);", file=f)
print(" blacklist_dirty = true;", file=f) print(" if (ptr == rollback_cache.end()) return;", file=f)
print(" int rb = ptr->second;", file=f)
print(" if (rollback == 0 || rollback > rb)", file=f)
print(" rollback = rb;", file=f)
print(" }", file=f) print(" }", file=f)
print(" }", file=f) print(" }", file=f)
print("", file=f) print("", file=f)
print(" void autoremove(Cell *cell) {", file=f) print(" void autoremove(Cell *cell) {", file=f)
print(" if (cell != nullptr) {", file=f) print(" if (cell != nullptr) {", file=f)
print(" if (blacklist_cells.insert(cell).second)", file=f)
print(" blacklist_dirty = true;", file=f)
print(" autoremove_cells.insert(cell);", file=f) print(" autoremove_cells.insert(cell);", file=f)
print(" blacklist(cell);", file=f)
print(" }", file=f) print(" }", file=f)
print(" }", file=f) print(" }", file=f)
print("", file=f) print("", file=f)
for current_pattern in sorted(patterns.keys()):
print(" void check_blacklist_{}() {{".format(current_pattern), file=f)
print(" if (!blacklist_dirty)", file=f)
print(" return;", file=f)
print(" blacklist_dirty = false;", file=f)
for index in range(len(blocks)):
block = blocks[index]
if block["pattern"] != current_pattern:
continue
if block["type"] == "match":
print(" if (st_{}.{} != nullptr && blacklist_cells.count(st_{}.{})) {{".format(current_pattern, block["cell"], current_pattern, block["cell"]), file=f)
print(" rollback = {};".format(index+1), file=f)
print(" return;", file=f)
print(" }", file=f)
print(" rollback = 0;", file=f)
print(" }", file=f)
print("", file=f)
current_pattern = None current_pattern = None
print(" SigSpec port(Cell *cell, IdString portname) {", file=f) print(" SigSpec port(Cell *cell, IdString portname) {", file=f)
@ -367,7 +438,7 @@ with open(outfile, "w") as f:
print("", file=f) print("", file=f)
print(" {}_pm(Module *module, const vector<Cell*> &cells) :".format(prefix), file=f) print(" {}_pm(Module *module, const vector<Cell*> &cells) :".format(prefix), file=f)
print(" module(module), sigmap(module) {", file=f) print(" module(module), sigmap(module), generate_mode(false), rngseed(12345678) {", file=f)
for current_pattern in sorted(patterns.keys()): for current_pattern in sorted(patterns.keys()):
for s, t in sorted(udata_types[current_pattern].items()): for s, t in sorted(udata_types[current_pattern].items()):
if t.endswith("*"): if t.endswith("*"):
@ -405,41 +476,47 @@ with open(outfile, "w") as f:
print("", file=f) print("", file=f)
for current_pattern in sorted(patterns.keys()): for current_pattern in sorted(patterns.keys()):
print(" void run_{}(std::function<void()> on_accept_f) {{".format(current_pattern), file=f) print(" int run_{}(std::function<void()> on_accept_f) {{".format(current_pattern), file=f)
print(" accept_cnt = 0;", file=f)
print(" on_accept = on_accept_f;", file=f) print(" on_accept = on_accept_f;", file=f)
print(" rollback = 0;", file=f) print(" rollback = 0;", file=f)
print(" blacklist_dirty = false;", file=f)
for s, t in sorted(state_types[current_pattern].items()): for s, t in sorted(state_types[current_pattern].items()):
if t.endswith("*"): if t.endswith("*"):
print(" st_{}.{} = nullptr;".format(current_pattern, s), file=f) print(" st_{}.{} = nullptr;".format(current_pattern, s), file=f)
else: else:
print(" st_{}.{} = {}();".format(current_pattern, s, t), file=f) print(" st_{}.{} = {}();".format(current_pattern, s, t), file=f)
print(" block_{}();".format(patterns[current_pattern]), file=f) print(" block_{}(1);".format(patterns[current_pattern]), file=f)
print(" log_assert(rollback_cache.empty());", file=f)
print(" return accept_cnt;", file=f)
print(" }", file=f) print(" }", file=f)
print("", file=f) print("", file=f)
print(" void run_{}(std::function<void({}_pm&)> on_accept_f) {{".format(current_pattern, prefix), file=f) print(" int run_{}(std::function<void({}_pm&)> on_accept_f) {{".format(current_pattern, prefix), file=f)
print(" run_{}([&](){{on_accept_f(*this);}});".format(current_pattern), file=f) print(" return run_{}([&](){{on_accept_f(*this);}});".format(current_pattern), file=f)
print(" }", file=f) print(" }", file=f)
print("", file=f) print("", file=f)
print(" void run_{}(std::function<void(state_{}_t&)> on_accept_f) {{".format(current_pattern, current_pattern), file=f) print(" int run_{}() {{".format(current_pattern), file=f)
print(" run_{}([&](){{on_accept_f(st_{});}});".format(current_pattern, current_pattern), file=f) print(" return run_{}([](){{}});".format(current_pattern, current_pattern), file=f)
print(" }", file=f) print(" }", file=f)
print("", file=f) print("", file=f)
print(" void run_{}() {{".format(current_pattern), file=f)
print(" run_{}([](){{}});".format(current_pattern, current_pattern), file=f) if len(subpatterns):
print(" }", file=f) for p, s in sorted(subpatterns.keys()):
print(" void block_subpattern_{}_{}(int recursion) {{ block_{}(recursion); }}".format(p, s, subpatterns[(p, s)]), file=f)
print("", file=f) print("", file=f)
current_pattern = None current_pattern = None
current_subpattern = None
for index in range(len(blocks)): for index in range(len(blocks)):
block = blocks[index] block = blocks[index]
print(" void block_{}() {{".format(index), file=f) if block["type"] in ("match", "code"):
current_pattern = block["pattern"] print(" // {}".format(block["src"]), file=f)
print(" void block_{}(int recursion YS_ATTRIBUTE(unused)) {{".format(index), file=f)
current_pattern, current_subpattern = block["pattern"]
if block["type"] == "final": if block["type"] == "final":
print(" on_accept();", file=f)
print(" check_blacklist_{}();".format(current_pattern), file=f)
print(" }", file=f) print(" }", file=f)
if index+1 != len(blocks): if index+1 != len(blocks):
print("", file=f) print("", file=f)
@ -449,7 +526,10 @@ with open(outfile, "w") as f:
nonconst_st = set() nonconst_st = set()
restore_st = set() restore_st = set()
for i in range(patterns[current_pattern], index): for s in subpattern_args[(current_pattern, current_subpattern)]:
const_st.add(s)
for i in range(subpatterns[(current_pattern, current_subpattern)], index):
if blocks[i]["type"] == "code": if blocks[i]["type"] == "code":
for s in blocks[i]["states"]: for s in blocks[i]["states"]:
const_st.add(s) const_st.add(s)
@ -482,6 +562,10 @@ with open(outfile, "w") as f:
t = state_types[current_pattern][s] t = state_types[current_pattern][s]
print(" {} &{} YS_ATTRIBUTE(unused) = st_{}.{};".format(t, s, current_pattern, s), file=f) print(" {} &{} YS_ATTRIBUTE(unused) = st_{}.{};".format(t, s, current_pattern, s), file=f)
for u in sorted(udata_types[current_pattern].keys()):
t = udata_types[current_pattern][u]
print(" {} &{} YS_ATTRIBUTE(unused) = ud_{}.{};".format(t, u, current_pattern, u), file=f)
if len(restore_st): if len(restore_st):
print("", file=f) print("", file=f)
for s in sorted(restore_st): for s in sorted(restore_st):
@ -490,24 +574,38 @@ with open(outfile, "w") as f:
if block["type"] == "code": if block["type"] == "code":
print("", file=f) print("", file=f)
print(" do {", file=f) print("#define reject do { goto rollback_label; } while(0)", file=f)
print("#define reject do {{ check_blacklist_{}(); goto rollback_label; }} while(0)".format(current_pattern), file=f) print("#define accept do { accept_cnt++; on_accept(); if (rollback) goto rollback_label; } while(0)", file=f)
print("#define accept do {{ on_accept(); check_blacklist_{}(); if (rollback) goto rollback_label; }} while(0)".format(current_pattern), file=f) print("#define finish do { rollback = -1; goto rollback_label; } while(0)", file=f)
print("#define branch do {{ block_{}(); if (rollback) goto rollback_label; }} while(0)".format(index+1), file=f) print("#define branch do {{ block_{}(recursion+1); if (rollback) goto rollback_label; }} while(0)".format(index+1), file=f)
print("#define subpattern(pattern_name) do {{ block_subpattern_{}_ ## pattern_name (recursion+1); if (rollback) goto rollback_label; }} while(0)".format(current_pattern), file=f)
for line in block["code"]: for line in block["code"]:
print(" " + line, file=f) print(" " + line, file=f)
print("", file=f) print("", file=f)
print(" block_{}();".format(index+1), file=f) print(" block_{}(recursion+1);".format(index+1), file=f)
print("#undef reject", file=f) print("#undef reject", file=f)
print("#undef accept", file=f) print("#undef accept", file=f)
print("#undef finish", file=f)
print("#undef branch", file=f) print("#undef branch", file=f)
print(" } while (0);", file=f) print("#undef subpattern", file=f)
print("", file=f) print("", file=f)
print("rollback_label:", file=f) print("rollback_label:", file=f)
print(" YS_ATTRIBUTE(unused);", file=f) print(" YS_ATTRIBUTE(unused);", file=f)
if len(block["fcode"]):
print("#define accept do { accept_cnt++; on_accept(); } while(0)", file=f)
print("#define finish do { rollback = -1; goto finish_label; } while(0)", file=f)
for line in block["fcode"]:
print(" " + line, file=f)
print("finish_label:", file=f)
print(" YS_ATTRIBUTE(unused);", file=f)
print("#undef accept", file=f)
print("#undef finish", file=f)
if len(restore_st) or len(nonconst_st): if len(restore_st) or len(nonconst_st):
print("", file=f) print("", file=f)
for s in sorted(restore_st): for s in sorted(restore_st):
@ -524,12 +622,15 @@ with open(outfile, "w") as f:
elif block["type"] == "match": elif block["type"] == "match":
assert len(restore_st) == 0 assert len(restore_st) == 0
print(" Cell* backup_{} = {};".format(block["cell"], block["cell"]), file=f)
if len(block["if"]): if len(block["if"]):
for expr in block["if"]: for expr in block["if"]:
print("", file=f) print("", file=f)
print(" if (!({})) {{".format(expr), file=f) print(" if (!({})) {{".format(expr), file=f)
print(" {} = nullptr;".format(block["cell"]), file=f) print(" {} = nullptr;".format(block["cell"]), file=f)
print(" block_{}();".format(index+1), file=f) print(" block_{}(recursion+1);".format(index+1), file=f)
print(" {} = backup_{};".format(block["cell"], block["cell"]), file=f)
print(" return;", file=f) print(" return;", file=f)
print(" }", file=f) print(" }", file=f)
@ -537,30 +638,55 @@ with open(outfile, "w") as f:
print(" index_{}_key_type key;".format(index), file=f) print(" index_{}_key_type key;".format(index), file=f)
for field, entry in enumerate(block["index"]): for field, entry in enumerate(block["index"]):
print(" std::get<{}>(key) = {};".format(field, entry[2]), file=f) print(" std::get<{}>(key) = {};".format(field, entry[2]), file=f)
print(" const vector<Cell*> &cells = index_{}[key];".format(index), file=f) print(" auto cells_ptr = index_{}.find(key);".format(index), file=f)
if block["semioptional"] or block["genargs"] is not None:
print(" bool found_any_match = false;", file=f)
print("", file=f) print("", file=f)
print(" if (cells_ptr != index_{}.end()) {{".format(index), file=f)
print(" const vector<Cell*> &cells = cells_ptr->second;".format(index), file=f)
print(" for (int idx = 0; idx < GetSize(cells); idx++) {", file=f) print(" for (int idx = 0; idx < GetSize(cells); idx++) {", file=f)
print(" {} = cells[idx];".format(block["cell"]), file=f) print(" {} = cells[idx];".format(block["cell"]), file=f)
print(" if (blacklist_cells.count({})) continue;".format(block["cell"]), file=f) print(" if (blacklist_cells.count({})) continue;".format(block["cell"]), file=f)
for expr in block["filter"]: for expr in block["filter"]:
print(" if (!({})) continue;".format(expr), file=f) print(" if (!({})) continue;".format(expr), file=f)
print(" block_{}();".format(index+1), file=f) if block["semioptional"] or block["genargs"] is not None:
print(" found_any_match = true;", file=f)
print(" auto rollback_ptr = rollback_cache.insert(make_pair(cells[idx], recursion));", file=f)
print(" block_{}(recursion+1);".format(index+1), file=f)
print(" if (rollback_ptr.second)", file=f)
print(" rollback_cache.erase(rollback_ptr.first);", file=f)
print(" if (rollback) {", file=f) print(" if (rollback) {", file=f)
print(" if (rollback != {}) {{".format(index+1), file=f) print(" if (rollback != recursion) {{".format(index+1), file=f)
print(" {} = nullptr;".format(block["cell"]), file=f) print(" {} = backup_{};".format(block["cell"], block["cell"]), file=f)
print(" return;", file=f) print(" return;", file=f)
print(" }", file=f) print(" }", file=f)
print(" rollback = 0;", file=f) print(" rollback = 0;", file=f)
print(" }", file=f) print(" }", file=f)
print(" }", file=f) print(" }", file=f)
print(" }", file=f)
print("", file=f) print("", file=f)
print(" {} = nullptr;".format(block["cell"]), file=f) print(" {} = nullptr;".format(block["cell"]), file=f)
if block["optional"]: if block["optional"]:
print(" block_{}();".format(index+1), file=f) print(" block_{}(recursion+1);".format(index+1), file=f)
if block["semioptional"]:
print(" if (!found_any_match) block_{}(recursion+1);".format(index+1), file=f)
print(" {} = backup_{};".format(block["cell"], block["cell"]), file=f)
if block["genargs"] is not None:
print("#define finish do { rollback = -1; return; } while(0)", file=f)
print(" if (generate_mode && !found_any_match) {", file=f)
if len(block["genargs"]) == 1:
print(" if (rng(100) >= {}) return;".format(block["genargs"][0]), file=f)
for line in block["gencode"]:
print(" " + line, file=f)
print(" }", file=f)
print("#undef finish", file=f)
else: else:
assert False assert False

330
passes/pmgen/test_pmgen.cc Normal file
View file

@ -0,0 +1,330 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "kernel/yosys.h"
#include "kernel/sigtools.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
// for peepopt_pm
bool did_something;
#include "passes/pmgen/test_pmgen_pm.h"
#include "passes/pmgen/ice40_dsp_pm.h"
#include "passes/pmgen/peepopt_pm.h"
void reduce_chain(test_pmgen_pm &pm)
{
auto &st = pm.st_reduce;
auto &ud = pm.ud_reduce;
if (ud.longest_chain.empty())
return;
log("Found chain of length %d (%s):\n", GetSize(ud.longest_chain), log_id(st.first->type));
SigSpec A;
SigSpec Y = ud.longest_chain.front().first->getPort(ID(Y));
auto last_cell = ud.longest_chain.back().first;
for (auto it : ud.longest_chain) {
auto cell = it.first;
if (cell == last_cell) {
A.append(cell->getPort(ID(A)));
A.append(cell->getPort(ID(B)));
} else {
A.append(cell->getPort(it.second == ID(A) ? ID(B) : ID(A)));
}
log(" %s\n", log_id(cell));
pm.autoremove(cell);
}
Cell *c;
if (last_cell->type == ID($_AND_))
c = pm.module->addReduceAnd(NEW_ID, A, Y);
else if (last_cell->type == ID($_OR_))
c = pm.module->addReduceOr(NEW_ID, A, Y);
else if (last_cell->type == ID($_XOR_))
c = pm.module->addReduceXor(NEW_ID, A, Y);
else
log_abort();
log(" -> %s (%s)\n", log_id(c), log_id(c->type));
}
void reduce_tree(test_pmgen_pm &pm)
{
auto &st = pm.st_reduce;
auto &ud = pm.ud_reduce;
if (ud.longest_chain.empty())
return;
SigSpec A = ud.leaves;
SigSpec Y = st.first->getPort(ID(Y));
pm.autoremove(st.first);
log("Found %s tree with %d leaves for %s (%s).\n", log_id(st.first->type),
GetSize(A), log_signal(Y), log_id(st.first));
Cell *c;
if (st.first->type == ID($_AND_))
c = pm.module->addReduceAnd(NEW_ID, A, Y);
else if (st.first->type == ID($_OR_))
c = pm.module->addReduceOr(NEW_ID, A, Y);
else if (st.first->type == ID($_XOR_))
c = pm.module->addReduceXor(NEW_ID, A, Y);
else
log_abort();
log(" -> %s (%s)\n", log_id(c), log_id(c->type));
}
#define GENERATE_PATTERN(pmclass, pattern) \
generate_pattern<pmclass>([](pmclass &pm, std::function<void()> f){ return pm.run_ ## pattern(f); }, #pmclass, #pattern, design)
void pmtest_addports(Module *module)
{
pool<SigBit> driven_bits, used_bits;
SigMap sigmap(module);
int icnt = 0, ocnt = 0;
for (auto cell : module->cells())
for (auto conn : cell->connections())
{
if (cell->input(conn.first))
for (auto bit : sigmap(conn.second))
used_bits.insert(bit);
if (cell->output(conn.first))
for (auto bit : sigmap(conn.second))
driven_bits.insert(bit);
}
for (auto wire : vector<Wire*>(module->wires()))
{
SigSpec ibits, obits;
for (auto bit : sigmap(wire)) {
if (!used_bits.count(bit))
obits.append(bit);
if (!driven_bits.count(bit))
ibits.append(bit);
}
if (!ibits.empty()) {
Wire *w = module->addWire(stringf("\\i%d", icnt++), GetSize(ibits));
w->port_input = true;
module->connect(ibits, w);
}
if (!obits.empty()) {
Wire *w = module->addWire(stringf("\\o%d", ocnt++), GetSize(obits));
w->port_output = true;
module->connect(w, obits);
}
}
module->fixup_ports();
}
template <class pm>
void generate_pattern(std::function<void(pm&,std::function<void()>)> run, const char *pmclass, const char *pattern, Design *design)
{
log("Generating \"%s\" patterns for pattern matcher \"%s\".\n", pattern, pmclass);
int modcnt = 0;
int maxsubcnt = 4;
int timeout = 0;
vector<Module*> mods;
while (modcnt < 100)
{
int submodcnt = 0, itercnt = 0, cellcnt = 0;
Module *mod = design->addModule(NEW_ID);
while (modcnt < 100 && submodcnt < maxsubcnt && itercnt++ < 1000)
{
if (timeout++ > 10000)
log_error("pmgen generator is stuck: 10000 iterations an no matching module generated.\n");
pm matcher(mod, mod->cells());
matcher.rng(1);
matcher.rngseed += modcnt;
matcher.rng(1);
matcher.rngseed += submodcnt;
matcher.rng(1);
matcher.rngseed += itercnt;
matcher.rng(1);
matcher.rngseed += cellcnt;
matcher.rng(1);
if (GetSize(mod->cells()) != cellcnt)
{
bool found_match = false;
run(matcher, [&](){ found_match = true; });
cellcnt = GetSize(mod->cells());
if (found_match) {
Module *m = design->addModule(stringf("\\pmtest_%s_%s_%05d",
pmclass, pattern, modcnt++));
log("Creating module %s with %d cells.\n", log_id(m), cellcnt);
mod->cloneInto(m);
pmtest_addports(m);
mods.push_back(m);
submodcnt++;
timeout = 0;
}
}
matcher.generate_mode = true;
run(matcher, [](){});
}
if (submodcnt)
maxsubcnt *= 2;
design->remove(mod);
}
Module *m = design->addModule(stringf("\\pmtest_%s_%s", pmclass, pattern));
log("Creating module %s with %d cells.\n", log_id(m), GetSize(mods));
for (auto mod : mods) {
Cell *c = m->addCell(mod->name, mod->name);
for (auto port : mod->ports) {
Wire *w = m->addWire(NEW_ID, GetSize(mod->wire(port)));
c->setPort(port, w);
}
}
pmtest_addports(m);
}
struct TestPmgenPass : public Pass {
TestPmgenPass() : Pass("test_pmgen", "test pass for pmgen") { }
void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" test_pmgen -reduce_chain [options] [selection]\n");
log("\n");
log("Demo for recursive pmgen patterns. Map chains of AND/OR/XOR to $reduce_*.\n");
log("\n");
log("\n");
log(" test_pmgen -reduce_tree [options] [selection]\n");
log("\n");
log("Demo for recursive pmgen patterns. Map trees of AND/OR/XOR to $reduce_*.\n");
log("\n");
log("\n");
log(" test_pmgen -generate [options] <pattern_name>\n");
log("\n");
log("Create modules that match the specified pattern.\n");
log("\n");
}
void execute_reduce_chain(std::vector<std::string> args, RTLIL::Design *design)
{
log_header(design, "Executing TEST_PMGEN pass (-reduce_chain).\n");
size_t argidx;
for (argidx = 2; argidx < args.size(); argidx++)
{
// if (args[argidx] == "-singleton") {
// singleton_mode = true;
// continue;
// }
break;
}
extra_args(args, argidx, design);
for (auto module : design->selected_modules())
while (test_pmgen_pm(module, module->selected_cells()).run_reduce(reduce_chain)) {}
}
void execute_reduce_tree(std::vector<std::string> args, RTLIL::Design *design)
{
log_header(design, "Executing TEST_PMGEN pass (-reduce_tree).\n");
size_t argidx;
for (argidx = 2; argidx < args.size(); argidx++)
{
// if (args[argidx] == "-singleton") {
// singleton_mode = true;
// continue;
// }
break;
}
extra_args(args, argidx, design);
for (auto module : design->selected_modules())
test_pmgen_pm(module, module->selected_cells()).run_reduce(reduce_tree);
}
void execute_generate(std::vector<std::string> args, RTLIL::Design *design)
{
log_header(design, "Executing TEST_PMGEN pass (-generate).\n");
size_t argidx;
for (argidx = 2; argidx < args.size(); argidx++)
{
// if (args[argidx] == "-singleton") {
// singleton_mode = true;
// continue;
// }
break;
}
if (argidx+1 != args.size())
log_cmd_error("Expected exactly one pattern.\n");
string pattern = args[argidx];
if (pattern == "reduce")
return GENERATE_PATTERN(test_pmgen_pm, reduce);
if (pattern == "ice40_dsp")
return GENERATE_PATTERN(ice40_dsp_pm, ice40_dsp);
if (pattern == "peepopt-muldiv")
return GENERATE_PATTERN(peepopt_pm, muldiv);
if (pattern == "peepopt-shiftmul")
return GENERATE_PATTERN(peepopt_pm, shiftmul);
log_cmd_error("Unkown pattern: %s\n", pattern.c_str());
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
if (GetSize(args) > 1)
{
if (args[1] == "-reduce_chain")
return execute_reduce_chain(args, design);
if (args[1] == "-reduce_tree")
return execute_reduce_tree(args, design);
if (args[1] == "-generate")
return execute_generate(args, design);
}
help();
log_cmd_error("Missing or unsupported mode parameter.\n");
}
} TestPmgenPass;
PRIVATE_NAMESPACE_END

106
passes/pmgen/test_pmgen.pmg Normal file
View file

@ -0,0 +1,106 @@
pattern reduce
state <IdString> portname
udata <vector<pair<Cell*, IdString>>> chain longest_chain
udata <pool<Cell*>> non_first_cells
udata <SigSpec> leaves
code
non_first_cells.clear();
subpattern(setup);
endcode
match first
select first->type.in($_AND_, $_OR_, $_XOR_)
filter !non_first_cells.count(first)
generate
SigSpec A = module->addWire(NEW_ID);
SigSpec B = module->addWire(NEW_ID);
SigSpec Y = module->addWire(NEW_ID);
switch (rng(3))
{
case 0:
module->addAndGate(NEW_ID, A, B, Y);
break;
case 1:
module->addOrGate(NEW_ID, A, B, Y);
break;
case 2:
module->addXorGate(NEW_ID, A, B, Y);
break;
}
endmatch
code
leaves = SigSpec();
longest_chain.clear();
chain.push_back(make_pair(first, \A));
subpattern(tail);
chain.back().second = \B;
subpattern(tail);
finally
chain.pop_back();
log_assert(chain.empty());
if (GetSize(longest_chain) > 1)
accept;
endcode
// ------------------------------------------------------------------
subpattern setup
match first
select first->type.in($_AND_, $_OR_, $_XOR_)
endmatch
code portname
portname = \A;
branch;
portname = \B;
endcode
match next
select nusers(port(next, \Y)) == 2
select next->type.in($_AND_, $_OR_, $_XOR_)
index <IdString> next->type === first->type
index <SigSpec> port(next, \Y) === port(first, portname)
endmatch
code
non_first_cells.insert(next);
endcode
// ------------------------------------------------------------------
subpattern tail
arg first
match next
semioptional
select nusers(port(next, \Y)) == 2
select next->type.in($_AND_, $_OR_, $_XOR_)
index <IdString> next->type === chain.back().first->type
index <SigSpec> port(next, \Y) === port(chain.back().first, chain.back().second)
generate 10
SigSpec A = module->addWire(NEW_ID);
SigSpec B = module->addWire(NEW_ID);
SigSpec Y = port(chain.back().first, chain.back().second);
Cell *c = module->addAndGate(NEW_ID, A, B, Y);
c->type = chain.back().first->type;
endmatch
code
if (next) {
chain.push_back(make_pair(next, \A));
subpattern(tail);
chain.back().second = \B;
subpattern(tail);
} else {
if (GetSize(chain) > GetSize(longest_chain))
longest_chain = chain;
leaves.append(port(chain.back().first, chain.back().second));
}
finally
if (next)
chain.pop_back();
endcode

View file

@ -69,8 +69,7 @@ void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did
did_something = true; did_something = true;
for (auto &action : sw->cases[0]->actions) for (auto &action : sw->cases[0]->actions)
parent->actions.push_back(action); parent->actions.push_back(action);
for (auto sw2 : sw->cases[0]->switches) parent->switches.insert(parent->switches.begin(), sw->cases[0]->switches.begin(), sw->cases[0]->switches.end());
parent->switches.push_back(sw2);
sw->cases[0]->switches.clear(); sw->cases[0]->switches.clear();
delete sw->cases[0]; delete sw->cases[0];
sw->cases.clear(); sw->cases.clear();

View file

@ -143,7 +143,7 @@ void create_dff_dq_map(std::map<RTLIL::IdString, dff_map_info_t> &map, RTLIL::De
continue; continue;
} }
if (info.cell->type == "$_DFF_N_" || info.cell->type == "$_DFF_P_") { if (info.cell->type.in("$_DFF_N_", "$_DFF_P_")) {
info.bit_clk = sigmap(info.cell->getPort("\\C")).as_bit(); info.bit_clk = sigmap(info.cell->getPort("\\C")).as_bit();
info.clk_polarity = info.cell->type == "$_DFF_P_"; info.clk_polarity = info.cell->type == "$_DFF_P_";
info.bit_d = sigmap(info.cell->getPort("\\D")).as_bit(); info.bit_d = sigmap(info.cell->getPort("\\D")).as_bit();

View file

@ -166,39 +166,39 @@ void mark_port(RTLIL::SigSpec sig)
void extract_cell(RTLIL::Cell *cell, bool keepff) void extract_cell(RTLIL::Cell *cell, bool keepff)
{ {
if (cell->type.in("$_DFF_N_", "$_DFF_P_")) if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_)))
{ {
if (clk_polarity != (cell->type == "$_DFF_P_")) if (clk_polarity != (cell->type == ID($_DFF_P_)))
return; return;
if (clk_sig != assign_map(cell->getPort("\\C"))) if (clk_sig != assign_map(cell->getPort(ID(C))))
return; return;
if (GetSize(en_sig) != 0) if (GetSize(en_sig) != 0)
return; return;
goto matching_dff; goto matching_dff;
} }
if (cell->type.in("$_DFFE_NN_", "$_DFFE_NP_", "$_DFFE_PN_", "$_DFFE_PP_")) if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
{ {
if (clk_polarity != cell->type.in("$_DFFE_PN_", "$_DFFE_PP_")) if (clk_polarity != cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_)))
return; return;
if (en_polarity != cell->type.in("$_DFFE_NP_", "$_DFFE_PP_")) if (en_polarity != cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)))
return; return;
if (clk_sig != assign_map(cell->getPort("\\C"))) if (clk_sig != assign_map(cell->getPort(ID(C))))
return; return;
if (en_sig != assign_map(cell->getPort("\\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("\\D"); RTLIL::SigSpec sig_d = cell->getPort(ID(D));
RTLIL::SigSpec sig_q = cell->getPort("\\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["\\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);
@ -209,25 +209,25 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
return; return;
} }
if (cell->type.in("$_BUF_", "$_NOT_")) if (cell->type.in(ID($_BUF_), ID($_NOT_)))
{ {
RTLIL::SigSpec sig_a = cell->getPort("\\A"); RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_y = cell->getPort("\\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);
map_signal(sig_y, cell->type == "$_BUF_" ? G(BUF) : G(NOT), map_signal(sig_a)); map_signal(sig_y, cell->type == ID($_BUF_) ? G(BUF) : G(NOT), map_signal(sig_a));
module->remove(cell); module->remove(cell);
return; return;
} }
if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_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("\\A"); RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_b = cell->getPort("\\B"); RTLIL::SigSpec sig_b = cell->getPort(ID::B);
RTLIL::SigSpec sig_y = cell->getPort("\\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);
@ -236,21 +236,21 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
int mapped_a = map_signal(sig_a); int mapped_a = map_signal(sig_a);
int mapped_b = map_signal(sig_b); int mapped_b = map_signal(sig_b);
if (cell->type == "$_AND_") if (cell->type == ID($_AND_))
map_signal(sig_y, G(AND), mapped_a, mapped_b); map_signal(sig_y, G(AND), mapped_a, mapped_b);
else if (cell->type == "$_NAND_") else if (cell->type == ID($_NAND_))
map_signal(sig_y, G(NAND), mapped_a, mapped_b); map_signal(sig_y, G(NAND), mapped_a, mapped_b);
else if (cell->type == "$_OR_") else if (cell->type == ID($_OR_))
map_signal(sig_y, G(OR), mapped_a, mapped_b); map_signal(sig_y, G(OR), mapped_a, mapped_b);
else if (cell->type == "$_NOR_") else if (cell->type == ID($_NOR_))
map_signal(sig_y, G(NOR), mapped_a, mapped_b); map_signal(sig_y, G(NOR), mapped_a, mapped_b);
else if (cell->type == "$_XOR_") else if (cell->type == ID($_XOR_))
map_signal(sig_y, G(XOR), mapped_a, mapped_b); map_signal(sig_y, G(XOR), mapped_a, mapped_b);
else if (cell->type == "$_XNOR_") else if (cell->type == ID($_XNOR_))
map_signal(sig_y, G(XNOR), mapped_a, mapped_b); map_signal(sig_y, G(XNOR), mapped_a, mapped_b);
else if (cell->type == "$_ANDNOT_") else if (cell->type == ID($_ANDNOT_))
map_signal(sig_y, G(ANDNOT), mapped_a, mapped_b); map_signal(sig_y, G(ANDNOT), mapped_a, mapped_b);
else if (cell->type == "$_ORNOT_") else if (cell->type == ID($_ORNOT_))
map_signal(sig_y, G(ORNOT), mapped_a, mapped_b); map_signal(sig_y, G(ORNOT), mapped_a, mapped_b);
else else
log_abort(); log_abort();
@ -259,12 +259,12 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
return; return;
} }
if (cell->type.in("$_MUX_", "$_NMUX_")) if (cell->type.in(ID($_MUX_), ID($_NMUX_)))
{ {
RTLIL::SigSpec sig_a = cell->getPort("\\A"); RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_b = cell->getPort("\\B"); RTLIL::SigSpec sig_b = cell->getPort(ID::B);
RTLIL::SigSpec sig_s = cell->getPort("\\S"); RTLIL::SigSpec sig_s = cell->getPort(ID(S));
RTLIL::SigSpec sig_y = cell->getPort("\\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);
@ -275,18 +275,18 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
int mapped_b = map_signal(sig_b); int mapped_b = map_signal(sig_b);
int mapped_s = map_signal(sig_s); int mapped_s = map_signal(sig_s);
map_signal(sig_y, cell->type == "$_MUX_" ? G(MUX) : G(NMUX), mapped_a, mapped_b, mapped_s); map_signal(sig_y, cell->type == ID($_MUX_) ? G(MUX) : G(NMUX), mapped_a, mapped_b, mapped_s);
module->remove(cell); module->remove(cell);
return; return;
} }
if (cell->type.in("$_AOI3_", "$_OAI3_")) if (cell->type.in(ID($_AOI3_), ID($_OAI3_)))
{ {
RTLIL::SigSpec sig_a = cell->getPort("\\A"); RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_b = cell->getPort("\\B"); RTLIL::SigSpec sig_b = cell->getPort(ID::B);
RTLIL::SigSpec sig_c = cell->getPort("\\C"); RTLIL::SigSpec sig_c = cell->getPort(ID(C));
RTLIL::SigSpec sig_y = cell->getPort("\\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);
@ -297,19 +297,19 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
int mapped_b = map_signal(sig_b); int mapped_b = map_signal(sig_b);
int mapped_c = map_signal(sig_c); int mapped_c = map_signal(sig_c);
map_signal(sig_y, cell->type == "$_AOI3_" ? G(AOI3) : G(OAI3), mapped_a, mapped_b, mapped_c); map_signal(sig_y, cell->type == ID($_AOI3_) ? G(AOI3) : G(OAI3), mapped_a, mapped_b, mapped_c);
module->remove(cell); module->remove(cell);
return; return;
} }
if (cell->type.in("$_AOI4_", "$_OAI4_")) if (cell->type.in(ID($_AOI4_), ID($_OAI4_)))
{ {
RTLIL::SigSpec sig_a = cell->getPort("\\A"); RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_b = cell->getPort("\\B"); RTLIL::SigSpec sig_b = cell->getPort(ID::B);
RTLIL::SigSpec sig_c = cell->getPort("\\C"); RTLIL::SigSpec sig_c = cell->getPort(ID(C));
RTLIL::SigSpec sig_d = cell->getPort("\\D"); RTLIL::SigSpec sig_d = cell->getPort(ID(D));
RTLIL::SigSpec sig_y = cell->getPort("\\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);
@ -322,7 +322,7 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
int mapped_c = map_signal(sig_c); int mapped_c = map_signal(sig_c);
int mapped_d = map_signal(sig_d); int mapped_d = map_signal(sig_d);
map_signal(sig_y, cell->type == "$_AOI4_" ? G(AOI4) : G(OAI4), mapped_a, mapped_b, mapped_c, mapped_d); map_signal(sig_y, cell->type == ID($_AOI4_) ? G(AOI4) : G(OAI4), mapped_a, mapped_b, mapped_c, mapped_d);
module->remove(cell); module->remove(cell);
return; return;
@ -352,23 +352,20 @@ std::string remap_name(RTLIL::IdString abc_name, RTLIL::Wire **orig_wire = nullp
auto sig = signal_list.at(sid); auto sig = signal_list.at(sid);
if (sig.bit.wire != nullptr) if (sig.bit.wire != nullptr)
{ {
std::stringstream sstr; std::string s = stringf("$abc$%d$%s", map_autoidx, sig.bit.wire->name.c_str()+1);
sstr << "$abc$" << map_autoidx << "$" << sig.bit.wire->name.substr(1);
if (sig.bit.wire->width != 1) if (sig.bit.wire->width != 1)
sstr << "[" << sig.bit.offset << "]"; s += stringf("[%d]", sig.bit.offset);
if (isnew) if (isnew)
sstr << "_new"; s += "_new";
sstr << postfix; s += postfix;
if (orig_wire != nullptr) if (orig_wire != nullptr)
*orig_wire = sig.bit.wire; *orig_wire = sig.bit.wire;
return sstr.str(); return s;
} }
} }
} }
} }
std::stringstream sstr; return stringf("$abc$%d$%s", map_autoidx, abc_name.c_str()+1);
sstr << "$abc$" << map_autoidx << "$" << abc_name.substr(1);
return sstr.str();
} }
void dump_loop_graph(FILE *f, int &nr, std::map<int, std::set<int>> &edges, std::set<int> &workpool, std::vector<int> &in_counts) void dump_loop_graph(FILE *f, int &nr, std::map<int, std::set<int>> &edges, std::set<int> &workpool, std::vector<int> &in_counts)
@ -790,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("\\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));
} }
@ -939,42 +936,42 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno)); log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno));
fprintf(f, "GATE ZERO 1 Y=CONST0;\n"); fprintf(f, "GATE ZERO 1 Y=CONST0;\n");
fprintf(f, "GATE ONE 1 Y=CONST1;\n"); fprintf(f, "GATE ONE 1 Y=CONST1;\n");
fprintf(f, "GATE BUF %d Y=A; PIN * NONINV 1 999 1 0 1 0\n", cell_cost.at("$_BUF_")); fprintf(f, "GATE BUF %d Y=A; PIN * NONINV 1 999 1 0 1 0\n", cell_cost.at(ID($_BUF_)));
fprintf(f, "GATE NOT %d Y=!A; PIN * INV 1 999 1 0 1 0\n", cell_cost.at("$_NOT_")); fprintf(f, "GATE NOT %d Y=!A; PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_NOT_)));
if (enabled_gates.count("AND")) if (enabled_gates.count("AND"))
fprintf(f, "GATE AND %d Y=A*B; PIN * NONINV 1 999 1 0 1 0\n", cell_cost.at("$_AND_")); fprintf(f, "GATE AND %d Y=A*B; PIN * NONINV 1 999 1 0 1 0\n", cell_cost.at(ID($_AND_)));
if (enabled_gates.count("NAND")) if (enabled_gates.count("NAND"))
fprintf(f, "GATE NAND %d Y=!(A*B); PIN * INV 1 999 1 0 1 0\n", cell_cost.at("$_NAND_")); fprintf(f, "GATE NAND %d Y=!(A*B); PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_NAND_)));
if (enabled_gates.count("OR")) if (enabled_gates.count("OR"))
fprintf(f, "GATE OR %d Y=A+B; PIN * NONINV 1 999 1 0 1 0\n", cell_cost.at("$_OR_")); fprintf(f, "GATE OR %d Y=A+B; PIN * NONINV 1 999 1 0 1 0\n", cell_cost.at(ID($_OR_)));
if (enabled_gates.count("NOR")) if (enabled_gates.count("NOR"))
fprintf(f, "GATE NOR %d Y=!(A+B); PIN * INV 1 999 1 0 1 0\n", cell_cost.at("$_NOR_")); fprintf(f, "GATE NOR %d Y=!(A+B); PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_NOR_)));
if (enabled_gates.count("XOR")) if (enabled_gates.count("XOR"))
fprintf(f, "GATE XOR %d Y=(A*!B)+(!A*B); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at("$_XOR_")); fprintf(f, "GATE XOR %d Y=(A*!B)+(!A*B); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_XOR_)));
if (enabled_gates.count("XNOR")) if (enabled_gates.count("XNOR"))
fprintf(f, "GATE XNOR %d Y=(A*B)+(!A*!B); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at("$_XNOR_")); fprintf(f, "GATE XNOR %d Y=(A*B)+(!A*!B); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_XNOR_)));
if (enabled_gates.count("ANDNOT")) if (enabled_gates.count("ANDNOT"))
fprintf(f, "GATE ANDNOT %d Y=A*!B; PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at("$_ANDNOT_")); fprintf(f, "GATE ANDNOT %d Y=A*!B; PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_ANDNOT_)));
if (enabled_gates.count("ORNOT")) if (enabled_gates.count("ORNOT"))
fprintf(f, "GATE ORNOT %d Y=A+!B; PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at("$_ORNOT_")); fprintf(f, "GATE ORNOT %d Y=A+!B; PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_ORNOT_)));
if (enabled_gates.count("AOI3")) if (enabled_gates.count("AOI3"))
fprintf(f, "GATE AOI3 %d Y=!((A*B)+C); PIN * INV 1 999 1 0 1 0\n", cell_cost.at("$_AOI3_")); fprintf(f, "GATE AOI3 %d Y=!((A*B)+C); PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_AOI3_)));
if (enabled_gates.count("OAI3")) if (enabled_gates.count("OAI3"))
fprintf(f, "GATE OAI3 %d Y=!((A+B)*C); PIN * INV 1 999 1 0 1 0\n", cell_cost.at("$_OAI3_")); fprintf(f, "GATE OAI3 %d Y=!((A+B)*C); PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_OAI3_)));
if (enabled_gates.count("AOI4")) if (enabled_gates.count("AOI4"))
fprintf(f, "GATE AOI4 %d Y=!((A*B)+(C*D)); PIN * INV 1 999 1 0 1 0\n", cell_cost.at("$_AOI4_")); fprintf(f, "GATE AOI4 %d Y=!((A*B)+(C*D)); PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_AOI4_)));
if (enabled_gates.count("OAI4")) if (enabled_gates.count("OAI4"))
fprintf(f, "GATE OAI4 %d Y=!((A+B)*(C+D)); PIN * INV 1 999 1 0 1 0\n", cell_cost.at("$_OAI4_")); fprintf(f, "GATE OAI4 %d Y=!((A+B)*(C+D)); PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_OAI4_)));
if (enabled_gates.count("MUX")) if (enabled_gates.count("MUX"))
fprintf(f, "GATE MUX %d Y=(A*B)+(S*B)+(!S*A); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at("$_MUX_")); fprintf(f, "GATE MUX %d Y=(A*B)+(S*B)+(!S*A); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_MUX_)));
if (enabled_gates.count("NMUX")) if (enabled_gates.count("NMUX"))
fprintf(f, "GATE NMUX %d Y=!((A*B)+(S*B)+(!S*A)); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at("$_NMUX_")); fprintf(f, "GATE NMUX %d Y=!((A*B)+(S*B)+(!S*A)); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_NMUX_)));
if (map_mux4) if (map_mux4)
fprintf(f, "GATE MUX4 %d Y=(!S*!T*A)+(S*!T*B)+(!S*T*C)+(S*T*D); PIN * UNKNOWN 1 999 1 0 1 0\n", 2*cell_cost.at("$_MUX_")); fprintf(f, "GATE MUX4 %d Y=(!S*!T*A)+(S*!T*B)+(!S*T*C)+(S*T*D); PIN * UNKNOWN 1 999 1 0 1 0\n", 2*cell_cost.at(ID($_MUX_)));
if (map_mux8) if (map_mux8)
fprintf(f, "GATE MUX8 %d Y=(!S*!T*!U*A)+(S*!T*!U*B)+(!S*T*!U*C)+(S*T*!U*D)+(!S*!T*U*E)+(S*!T*U*F)+(!S*T*U*G)+(S*T*U*H); PIN * UNKNOWN 1 999 1 0 1 0\n", 4*cell_cost.at("$_MUX_")); fprintf(f, "GATE MUX8 %d Y=(!S*!T*!U*A)+(S*!T*!U*B)+(!S*T*!U*C)+(S*T*!U*D)+(!S*!T*U*E)+(S*!T*U*F)+(!S*T*U*G)+(S*T*U*H); PIN * UNKNOWN 1 999 1 0 1 0\n", 4*cell_cost.at(ID($_MUX_)));
if (map_mux16) if (map_mux16)
fprintf(f, "GATE MUX16 %d Y=(!S*!T*!U*!V*A)+(S*!T*!U*!V*B)+(!S*T*!U*!V*C)+(S*T*!U*!V*D)+(!S*!T*U*!V*E)+(S*!T*U*!V*F)+(!S*T*U*!V*G)+(S*T*U*!V*H)+(!S*!T*!U*V*I)+(S*!T*!U*V*J)+(!S*T*!U*V*K)+(S*T*!U*V*L)+(!S*!T*U*V*M)+(S*!T*U*V*N)+(!S*T*U*V*O)+(S*T*U*V*P); PIN * UNKNOWN 1 999 1 0 1 0\n", 8*cell_cost.at("$_MUX_")); fprintf(f, "GATE MUX16 %d Y=(!S*!T*!U*!V*A)+(S*!T*!U*!V*B)+(!S*T*!U*!V*C)+(S*T*!U*!V*D)+(!S*!T*U*!V*E)+(S*!T*U*!V*F)+(!S*T*U*!V*G)+(S*T*U*!V*H)+(!S*!T*!U*V*I)+(S*!T*!U*V*J)+(!S*T*!U*V*K)+(S*T*!U*V*L)+(!S*!T*U*V*M)+(S*!T*U*V*N)+(!S*T*U*V*O)+(S*T*U*V*P); PIN * UNKNOWN 1 999 1 0 1 0\n", 8*cell_cost.at(ID($_MUX_)));
fclose(f); fclose(f);
if (!lut_costs.empty()) { if (!lut_costs.empty()) {
@ -1019,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 ? "\\DFF" : "\\_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_["\\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("\\src")) if (orig_wire != nullptr && orig_wire->attributes.count(ID(src)))
wire->attributes["\\src"] = orig_wire->attributes["\\src"]; wire->attributes[ID(src)] = orig_wire->attributes[ID(src)];
if (markgroups) wire->attributes["\\abcgroup"] = map_autoidx; if (markgroups) wire->attributes[ID(abcgroup)] = map_autoidx;
design->select(module, wire); design->select(module, wire);
} }
@ -1043,141 +1040,140 @@ 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 == "\\ZERO" || c->type == "\\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("\\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 == "\\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 == "\\BUF") { if (c->type == ID(BUF)) {
RTLIL::SigSig conn; RTLIL::SigSig conn;
conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\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("\\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 == "\\NOT") { if (c->type == ID(NOT)) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_NOT_"); RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_NOT_));
if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\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 == "\\AND" || c->type == "\\OR" || c->type == "\\XOR" || c->type == "\\NAND" || c->type == "\\NOR" || if (c->type.in(ID(AND), ID(OR), ID(XOR), ID(NAND), ID(NOR), ID(XNOR), ID(ANDNOT), ID(ORNOT))) {
c->type == "\\XNOR" || c->type == "\\ANDNOT" || c->type == "\\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), "$_" + c->type.substr(1) + "_"); if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)]));
design->select(module, cell); design->select(module, cell);
continue; continue;
} }
if (c->type == "\\MUX" || c->type == "\\NMUX") { if (c->type.in(ID(MUX), ID(NMUX))) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_"); RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
cell->setPort("\\S", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\S").as_wire()->name)])); cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\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 == "\\MUX4") { if (c->type == ID(MUX4)) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX4_"); RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX4_));
if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)])); cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)])); cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
cell->setPort("\\S", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\S").as_wire()->name)])); cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
cell->setPort("\\T", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\T").as_wire()->name)])); cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)]));
cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\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 == "\\MUX8") { if (c->type == ID(MUX8)) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX8_"); RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX8_));
if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)])); cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)])); cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
cell->setPort("\\E", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\E").as_wire()->name)])); cell->setPort(ID(E), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(E)).as_wire()->name)]));
cell->setPort("\\F", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\F").as_wire()->name)])); cell->setPort(ID(F), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(F)).as_wire()->name)]));
cell->setPort("\\G", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\G").as_wire()->name)])); cell->setPort(ID(G), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(G)).as_wire()->name)]));
cell->setPort("\\H", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\H").as_wire()->name)])); cell->setPort(ID(H), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(H)).as_wire()->name)]));
cell->setPort("\\S", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\S").as_wire()->name)])); cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
cell->setPort("\\T", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\T").as_wire()->name)])); cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)]));
cell->setPort("\\U", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\U").as_wire()->name)])); cell->setPort(ID(U), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(U)).as_wire()->name)]));
cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\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 == "\\MUX16") { if (c->type == ID(MUX16)) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX16_"); RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX16_));
if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)])); cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)])); cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
cell->setPort("\\E", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\E").as_wire()->name)])); cell->setPort(ID(E), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(E)).as_wire()->name)]));
cell->setPort("\\F", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\F").as_wire()->name)])); cell->setPort(ID(F), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(F)).as_wire()->name)]));
cell->setPort("\\G", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\G").as_wire()->name)])); cell->setPort(ID(G), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(G)).as_wire()->name)]));
cell->setPort("\\H", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\H").as_wire()->name)])); cell->setPort(ID(H), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(H)).as_wire()->name)]));
cell->setPort("\\I", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\I").as_wire()->name)])); cell->setPort(ID(I), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(I)).as_wire()->name)]));
cell->setPort("\\J", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\J").as_wire()->name)])); cell->setPort(ID(J), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(J)).as_wire()->name)]));
cell->setPort("\\K", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\K").as_wire()->name)])); cell->setPort(ID(K), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(K)).as_wire()->name)]));
cell->setPort("\\L", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\L").as_wire()->name)])); cell->setPort(ID(L), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(L)).as_wire()->name)]));
cell->setPort("\\M", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\M").as_wire()->name)])); cell->setPort(ID(M), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(M)).as_wire()->name)]));
cell->setPort("\\N", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\N").as_wire()->name)])); cell->setPort(ID(N), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(N)).as_wire()->name)]));
cell->setPort("\\O", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\O").as_wire()->name)])); cell->setPort(ID(O), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(O)).as_wire()->name)]));
cell->setPort("\\P", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\P").as_wire()->name)])); cell->setPort(ID(P), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(P)).as_wire()->name)]));
cell->setPort("\\S", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\S").as_wire()->name)])); cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
cell->setPort("\\T", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\T").as_wire()->name)])); cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)]));
cell->setPort("\\U", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\U").as_wire()->name)])); cell->setPort(ID(U), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(U)).as_wire()->name)]));
cell->setPort("\\V", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\V").as_wire()->name)])); cell->setPort(ID(V), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(V)).as_wire()->name)]));
cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\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 == "\\AOI3" || c->type == "\\OAI3") { if (c->type.in(ID(AOI3), ID(OAI3))) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_"); RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)])); cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\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 == "\\AOI4" || c->type == "\\OAI4") { if (c->type.in(ID(AOI4), ID(OAI4))) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_"); RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)])); cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)])); cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\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 == "\\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) {
cell = module->addCell(remap_name(c->name), clk_polarity ? "$_DFF_P_" : "$_DFF_N_"); cell = module->addCell(remap_name(c->name), clk_polarity ? ID($_DFF_P_) : ID($_DFF_N_));
} 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("\\E", en_sig); cell->setPort(ID(E), en_sig);
} }
if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)])); cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
cell->setPort("\\Q", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Q").as_wire()->name)])); cell->setPort(ID(Q), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Q)).as_wire()->name)]));
cell->setPort("\\C", clk_sig); cell->setPort(ID(C), clk_sig);
design->select(module, cell); design->select(module, cell);
continue; continue;
} }
@ -1185,41 +1181,41 @@ 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 == "\\_const0_" || c->type == "\\_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 == "\\_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 == "\\_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) {
cell = module->addCell(remap_name(c->name), clk_polarity ? "$_DFF_P_" : "$_DFF_N_"); cell = module->addCell(remap_name(c->name), clk_polarity ? ID($_DFF_P_) : ID($_DFF_N_));
} 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("\\E", en_sig); cell->setPort(ID(E), en_sig);
} }
if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)])); cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
cell->setPort("\\Q", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Q").as_wire()->name)])); cell->setPort(ID(Q), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Q)).as_wire()->name)]));
cell->setPort("\\C", clk_sig); cell->setPort(ID(C), clk_sig);
design->select(module, cell); design->select(module, cell);
continue; continue;
} }
if (c->type == "$lut" && GetSize(c->getPort("\\A")) == 1 && c->getParam("\\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("\\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("\\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["\\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;
@ -1244,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("\\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("\\init") == 0); log_assert(w->attributes.count(ID(init)) == 0);
w->attributes["\\init"] = wire->attributes.at("\\init"); w->attributes[ID(init)] = wire->attributes.at(ID(init));
} }
} }
@ -1634,6 +1630,7 @@ struct AbcPass : public Pass {
if (g == "ANDNOT") goto ok_gate; if (g == "ANDNOT") goto ok_gate;
if (g == "ORNOT") goto ok_gate; if (g == "ORNOT") goto ok_gate;
if (g == "MUX") goto ok_gate; if (g == "MUX") goto ok_gate;
if (g == "NMUX") goto ok_gate;
if (g == "AOI3") goto ok_gate; if (g == "AOI3") goto ok_gate;
if (g == "OAI3") goto ok_gate; if (g == "OAI3") goto ok_gate;
if (g == "AOI4") goto ok_gate; if (g == "AOI4") goto ok_gate;
@ -1802,9 +1799,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("\\init")) { if (wire->attributes.count(ID(init))) {
SigSpec initsig = assign_map(wire); SigSpec initsig = assign_map(wire);
Const initval = wire->attributes.at("\\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:
@ -1861,16 +1858,16 @@ struct AbcPass : public Pass {
} }
} }
if (cell->type.in("$_DFF_N_", "$_DFF_P_")) if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_)))
{ {
key = clkdomain_t(cell->type == "$_DFF_P_", assign_map(cell->getPort("\\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("$_DFFE_NN_", "$_DFFE_NP_" "$_DFFE_PN_", "$_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("$_DFFE_PN_", "$_DFFE_PP_"); bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_));
bool this_en_pol = cell->type.in("$_DFFE_NP_", "$_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("\\C")), this_en_pol, assign_map(cell->getPort("\\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;

View file

@ -71,25 +71,22 @@ RTLIL::Module *module;
bool clk_polarity, en_polarity; bool clk_polarity, en_polarity;
RTLIL::SigSpec clk_sig, en_sig; RTLIL::SigSpec clk_sig, en_sig;
std::string remap_name(RTLIL::IdString abc_name) inline std::string remap_name(RTLIL::IdString abc_name)
{ {
std::stringstream sstr; return stringf("$abc$%d$%s", map_autoidx, abc_name.c_str()+1);
sstr << "$abc$" << map_autoidx << "$" << abc_name.substr(1);
return sstr.str();
} }
void handle_loops(RTLIL::Design *design) void handle_loops(RTLIL::Design *design,
const dict<IdString,pool<IdString>> &scc_break_inputs)
{ {
Pass::call(design, "scc -set_attr abc_scc_id {}"); Pass::call(design, "scc -set_attr abc_scc_id {}");
dict<IdString, vector<IdString>> abc_scc_break;
// For every unique SCC found, (arbitrarily) find the first // For every unique SCC found, (arbitrarily) find the first
// cell in the component, and select (and mark) all its output // cell in the component, and select (and mark) all its output
// 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("\\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) {
@ -109,7 +106,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("\\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);
} }
@ -118,23 +115,8 @@ void handle_loops(RTLIL::Design *design)
cell->attributes.erase(it); cell->attributes.erase(it);
} }
auto jt = abc_scc_break.find(cell->type); auto jt = scc_break_inputs.find(cell->type);
if (jt == abc_scc_break.end()) { if (jt != scc_break_inputs.end())
std::vector<IdString> ports;
RTLIL::Module* box_module = design->module(cell->type);
if (box_module) {
auto ports_csv = box_module->attributes.at("\\abc_scc_break", RTLIL::Const::from_string("")).decode_string();
for (const auto &port_name : split_tokens(ports_csv, ",")) {
auto port_id = RTLIL::escape_id(port_name);
auto kt = cell->connections_.find(port_id);
if (kt == cell->connections_.end())
log_error("abc_scc_break attribute value '%s' does not exist as port on module '%s'\n", port_name.c_str(), log_id(box_module));
ports.push_back(port_id);
}
}
jt = abc_scc_break.insert(std::make_pair(cell->type, std::move(ports))).first;
}
for (auto port_name : jt->second) { for (auto port_name : jt->second) {
RTLIL::SigSpec sig; RTLIL::SigSpec sig;
auto &rhs = cell->connections_.at(port_name); auto &rhs = cell->connections_.at(port_name);
@ -142,7 +124,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("\\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));
@ -290,7 +272,9 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
bool cleanup, vector<int> lut_costs, bool dff_mode, std::string clk_str, bool cleanup, vector<int> lut_costs, bool dff_mode, std::string clk_str,
bool /*keepff*/, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, bool /*keepff*/, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode,
bool show_tempdir, std::string box_file, std::string lut_file, bool show_tempdir, std::string box_file, std::string lut_file,
std::string wire_delay, const dict<int,IdString> &box_lookup) std::string wire_delay, const dict<int,IdString> &box_lookup,
const dict<IdString,pool<IdString>> &scc_break_inputs
)
{ {
module = current_module; module = current_module;
map_autoidx = autoidx++; map_autoidx = autoidx++;
@ -429,7 +413,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
RTLIL::Selection& sel = design->selection_stack.back(); RTLIL::Selection& sel = design->selection_stack.back();
sel.select(module); sel.select(module);
handle_loops(design); handle_loops(design, scc_break_inputs);
Pass::call(design, "aigmap"); Pass::call(design, "aigmap");
@ -446,14 +430,14 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
if (ifs.fail()) if (ifs.fail())
log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); log_error("Can't open ABC output file `%s'.\n", buffer.c_str());
buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym"); buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym");
log_assert(!design->module("$__abc9__")); log_assert(!design->module(ID($__abc9__)));
{ {
AigerReader reader(design, ifs, "$__abc9__", "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */);
reader.parse_xaiger(); reader.parse_xaiger();
} }
ifs.close(); ifs.close();
Pass::call(design, stringf("write_verilog -noexpr -norename")); Pass::call(design, stringf("write_verilog -noexpr -norename"));
design->remove(design->module("$__abc9__")); design->remove(design->module(ID($__abc9__)));
#endif #endif
design->selection_stack.pop_back(); design->selection_stack.pop_back();
@ -462,7 +446,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("\\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);
@ -518,9 +502,9 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); log_error("Can't open ABC output file `%s'.\n", buffer.c_str());
buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym"); buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym");
log_assert(!design->module("$__abc9__")); log_assert(!design->module(ID($__abc9__)));
AigerReader reader(design, ifs, "$__abc9__", "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */);
reader.parse_xaiger(box_lookup); reader.parse_xaiger(box_lookup);
ifs.close(); ifs.close();
@ -529,7 +513,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
#endif #endif
log_header(design, "Re-integrating ABC9 results.\n"); log_header(design, "Re-integrating ABC9 results.\n");
RTLIL::Module *mapped_mod = design->module("$__abc9__"); RTLIL::Module *mapped_mod = design->module(ID($__abc9__));
if (mapped_mod == NULL) if (mapped_mod == NULL)
log_error("ABC output file does not contain a module `$__abc9__'.\n"); log_error("ABC output file does not contain a module `$__abc9__'.\n");
@ -537,7 +521,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["\\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);
@ -559,14 +543,14 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
vector<RTLIL::Cell*> boxes; vector<RTLIL::Cell*> boxes;
for (const auto &it : module->cells_) { for (const auto &it : module->cells_) {
auto cell = it.second; auto cell = it.second;
if (cell->type.in("$_AND_", "$_NOT_")) { if (cell->type.in(ID($_AND_), ID($_NOT_))) {
module->remove(cell); module->remove(cell);
continue; continue;
} }
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("\\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);
@ -577,20 +561,20 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
dict<RTLIL::Cell*,RTLIL::Cell*> not2drivers; dict<RTLIL::Cell*,RTLIL::Cell*> not2drivers;
dict<SigBit, std::vector<RTLIL::Cell*>> bit2sinks; dict<SigBit, std::vector<RTLIL::Cell*>> bit2sinks;
std::map<std::string, int> cell_stats; std::map<IdString, int> cell_stats;
for (auto c : mapped_mod->cells()) for (auto c : mapped_mod->cells())
{ {
toposort.node(c->name); toposort.node(c->name);
RTLIL::Cell *cell = nullptr; RTLIL::Cell *cell = nullptr;
if (c->type == "$_NOT_") { if (c->type == ID($_NOT_)) {
RTLIL::SigBit a_bit = c->getPort("\\A"); RTLIL::SigBit a_bit = c->getPort(ID::A);
RTLIL::SigBit y_bit = c->getPort("\\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("\\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);
@ -618,8 +602,8 @@ 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("\\A")].push_back(cell); bit2sinks[cell->getPort(ID::A)].push_back(cell);
cell_stats["$lut"]++; cell_stats[ID($lut)]++;
} }
else else
not2drivers[c] = driver_lut; not2drivers[c] = driver_lut;
@ -627,18 +611,18 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
} }
else else
log_abort(); log_abort();
if (cell && markgroups) cell->attributes["\\abcgroup"] = map_autoidx; if (cell && markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
continue; continue;
} }
cell_stats[RTLIL::unescape_id(c->type)]++; cell_stats[c->type]++;
RTLIL::Cell *existing_cell = nullptr; RTLIL::Cell *existing_cell = nullptr;
if (c->type == "$lut") { if (c->type == ID($lut)) {
if (GetSize(c->getPort("\\A")) == 1 && c->getParam("\\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("\\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("\\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["\\abcgroup"] = map_autoidx; if (markgroups) c->attributes[ID(abcgroup)] = map_autoidx;
log_abort(); log_abort();
continue; continue;
} }
@ -651,7 +635,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["\\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;
@ -741,20 +725,20 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
for (auto driver_cell : bit_drivers.at(it.first)) for (auto driver_cell : bit_drivers.at(it.first))
for (auto user_cell : it.second) for (auto user_cell : it.second)
toposort.edge(driver_cell, user_cell); toposort.edge(driver_cell, user_cell);
bool no_loops = toposort.sort(); bool no_loops YS_ATTRIBUTE(unused) = toposort.sort();
log_assert(no_loops); log_assert(no_loops);
for (auto ii = toposort.sorted.rbegin(); ii != toposort.sorted.rend(); ii++) { for (auto ii = toposort.sorted.rbegin(); ii != toposort.sorted.rend(); ii++) {
RTLIL::Cell *not_cell = mapped_mod->cell(*ii); RTLIL::Cell *not_cell = mapped_mod->cell(*ii);
log_assert(not_cell); log_assert(not_cell);
if (not_cell->type != "$_NOT_") if (not_cell->type != ID($_NOT_))
continue; continue;
auto it = not2drivers.find(not_cell); auto it = not2drivers.find(not_cell);
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("\\A"); RTLIL::SigBit a_bit = not_cell->getPort(ID::A);
RTLIL::SigBit y_bit = not_cell->getPort("\\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));
@ -765,13 +749,13 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
goto clone_lut; goto clone_lut;
for (auto sink_cell : jt->second) for (auto sink_cell : jt->second)
if (sink_cell->type != "$lut") if (sink_cell->type != ID($lut))
goto clone_lut; goto clone_lut;
// 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("\\A"); SigSpec A = sink_cell->getPort(ID::A);
RTLIL::Const mask = sink_cell->getParam("\\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)
@ -784,8 +768,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("\\A", A); sink_cell->setPort(ID::A, A);
sink_cell->setParam("\\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
@ -794,16 +778,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("\\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("\\A"), driver_lut->getPort(ID::A),
y_bit, y_bit,
driver_mask); driver_mask);
for (auto &bit : cell->connections_.at("\\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);
} }
@ -1083,8 +1067,9 @@ struct Abc9Pass : public Pass {
extra_args(args, argidx, design); extra_args(args, argidx, design);
dict<int,IdString> box_lookup; dict<int,IdString> box_lookup;
dict<IdString,pool<IdString>> scc_break_inputs;
for (auto m : design->modules()) { for (auto m : design->modules()) {
auto it = m->attributes.find("\\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"))
@ -1095,11 +1080,61 @@ struct Abc9Pass : public Pass {
log_error("Module '%s' has the same abc_box_id = %d value as '%s'.\n", log_error("Module '%s' has the same abc_box_id = %d value as '%s'.\n",
log_id(m), id, log_id(r.first->second)); log_id(m), id, log_id(r.first->second));
log_assert(r.second); log_assert(r.second);
RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr;
for (auto p : m->ports) {
auto w = m->wire(p);
log_assert(w);
if (w->port_input) {
if (w->attributes.count(ID(abc_scc_break)))
scc_break_inputs[m->name].insert(p);
if (w->attributes.count(ID(abc_carry))) {
if (carry_in)
log_error("Module '%s' contains more than one 'abc_carry' input port.\n", log_id(m));
carry_in = w;
}
}
if (w->port_output) {
if (w->attributes.count(ID(abc_carry))) {
if (carry_out)
log_error("Module '%s' contains more than one 'abc_carry' input port.\n", log_id(m));
carry_out = w;
}
}
}
if (carry_in || carry_out) {
if (carry_in && !carry_out)
log_error("Module '%s' contains an 'abc_carry' input port but no output port.\n", log_id(m));
if (!carry_in && carry_out)
log_error("Module '%s' contains an 'abc_carry' output port but no input port.\n", log_id(m));
// Make carry_in the last PI, and carry_out the last PO
// since ABC requires it this way
auto &ports = m->ports;
for (auto it = ports.begin(); it != ports.end(); ) {
RTLIL::Wire* w = m->wire(*it);
log_assert(w);
if (w == carry_in || w == carry_out) {
it = ports.erase(it);
continue;
}
if (w->port_id > carry_in->port_id)
--w->port_id;
if (w->port_id > carry_out->port_id)
--w->port_id;
log_assert(w->port_input || w->port_output);
log_assert(ports[w->port_id-1] == w->name);
++it;
}
ports.push_back(carry_in->name);
carry_in->port_id = ports.size();
ports.push_back(carry_out->name);
carry_out->port_id = ports.size();
}
} }
for (auto mod : design->selected_modules()) for (auto mod : design->selected_modules())
{ {
if (mod->attributes.count("\\abc_box_id")) if (mod->attributes.count(ID(abc_box_id)))
continue; continue;
if (mod->processes.size() > 0) { if (mod->processes.size() > 0) {
@ -1112,7 +1147,7 @@ struct Abc9Pass : public Pass {
if (!dff_mode || !clk_str.empty()) { if (!dff_mode || !clk_str.empty()) {
abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, dff_mode, clk_str, keepff, abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, dff_mode, clk_str, keepff,
delay_target, lutin_shared, fast_mode, show_tempdir, delay_target, lutin_shared, fast_mode, show_tempdir,
box_file, lut_file, wire_delay, box_lookup); box_file, lut_file, wire_delay, box_lookup, scc_break_inputs);
continue; continue;
} }
@ -1153,16 +1188,16 @@ struct Abc9Pass : public Pass {
} }
} }
if (cell->type.in("$_DFF_N_", "$_DFF_P_")) if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_)))
{ {
key = clkdomain_t(cell->type == "$_DFF_P_", assign_map(cell->getPort("\\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("$_DFFE_NN_", "$_DFFE_NP_", "$_DFFE_PN_", "$_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("$_DFFE_PN_", "$_DFFE_PP_"); bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_));
bool this_en_pol = cell->type.in("$_DFFE_NP_", "$_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("\\C")), this_en_pol, assign_map(cell->getPort("\\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;
@ -1258,7 +1293,7 @@ struct Abc9Pass : public Pass {
en_sig = assign_map(std::get<3>(it.first)); en_sig = assign_map(std::get<3>(it.first));
abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, !clk_sig.empty(), "$", abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, !clk_sig.empty(), "$",
keepff, delay_target, lutin_shared, fast_mode, show_tempdir, keepff, delay_target, lutin_shared, fast_mode, show_tempdir,
box_file, lut_file, wire_delay, box_lookup); box_file, lut_file, wire_delay, box_lookup, scc_break_inputs);
assign_map.set(mod); assign_map.set(mod);
} }
} }

View file

@ -66,10 +66,10 @@ struct AigmapPass : public Pass {
{ {
Aig aig(cell); Aig aig(cell);
if (cell->type.in("$_AND_", "$_NOT_")) if (cell->type.in(ID($_AND_), ID($_NOT_)))
aig.name.clear(); aig.name.clear();
if (nand_mode && cell->type == "$_NAND_") if (nand_mode && cell->type == ID($_NAND_))
aig.name.clear(); aig.name.clear();
if (aig.name.empty()) { if (aig.name.empty()) {

View file

@ -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("\\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("\\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("\\CO"), alu_cell->getPort("\\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("\\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;
@ -125,7 +125,7 @@ struct AlumaccWorker
{ {
for (auto cell : module->selected_cells()) for (auto cell : module->selected_cells())
{ {
if (!cell->type.in("$pos", "$neg", "$add", "$sub", "$mul")) if (!cell->type.in(ID($pos), ID($neg), ID($add), ID($sub), ID($mul)))
continue; continue;
log(" creating $macc model for %s (%s).\n", log_id(cell), log_id(cell->type)); log(" creating $macc model for %s (%s).\n", log_id(cell), log_id(cell->type));
@ -134,38 +134,38 @@ struct AlumaccWorker
Macc::port_t new_port; Macc::port_t new_port;
n->cell = cell; n->cell = cell;
n->y = sigmap(cell->getPort("\\Y")); n->y = sigmap(cell->getPort(ID::Y));
n->users = 0; n->users = 0;
for (auto bit : n->y) for (auto bit : n->y)
n->users = max(n->users, bit_users.at(bit) - 1); n->users = max(n->users, bit_users.at(bit) - 1);
if (cell->type.in("$pos", "$neg")) if (cell->type.in(ID($pos), ID($neg)))
{ {
new_port.in_a = sigmap(cell->getPort("\\A")); new_port.in_a = sigmap(cell->getPort(ID::A));
new_port.is_signed = cell->getParam("\\A_SIGNED").as_bool(); new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
new_port.do_subtract = cell->type == "$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("$add", "$sub")) if (cell->type.in(ID($add), ID($sub)))
{ {
new_port.in_a = sigmap(cell->getPort("\\A")); new_port.in_a = sigmap(cell->getPort(ID::A));
new_port.is_signed = cell->getParam("\\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("\\B")); new_port.in_a = sigmap(cell->getPort(ID::B));
new_port.is_signed = cell->getParam("\\B_SIGNED").as_bool(); new_port.is_signed = cell->getParam(ID(B_SIGNED)).as_bool();
new_port.do_subtract = cell->type == "$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("$mul")) if (cell->type.in(ID($mul)))
{ {
new_port.in_a = sigmap(cell->getPort("\\A")); new_port.in_a = sigmap(cell->getPort(ID::A));
new_port.in_b = sigmap(cell->getPort("\\B")); new_port.in_b = sigmap(cell->getPort(ID::B));
new_port.is_signed = cell->getParam("\\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);
} }
@ -351,7 +351,7 @@ struct AlumaccWorker
for (auto &it : sig_macc) for (auto &it : sig_macc)
{ {
auto n = it.second; auto n = it.second;
auto cell = module->addCell(NEW_ID, "$macc"); auto cell = module->addCell(NEW_ID, ID($macc));
macc_counter++; macc_counter++;
@ -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("\\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;
@ -376,9 +376,9 @@ struct AlumaccWorker
for (auto cell : module->selected_cells()) for (auto cell : module->selected_cells())
{ {
if (cell->type.in("$lt", "$le", "$ge", "$gt")) if (cell->type.in(ID($lt), ID($le), ID($ge), ID($gt)))
lge_cells.push_back(cell); lge_cells.push_back(cell);
if (cell->type.in("$eq", "$eqx", "$ne", "$nex")) if (cell->type.in(ID($eq), ID($eqx), ID($ne), ID($nex)))
eq_cells.push_back(cell); eq_cells.push_back(cell);
} }
@ -386,13 +386,13 @@ struct AlumaccWorker
{ {
log(" creating $alu model for %s (%s):", log_id(cell), log_id(cell->type)); log(" creating $alu model for %s (%s):", log_id(cell), log_id(cell->type));
bool cmp_less = cell->type.in("$lt", "$le"); bool cmp_less = cell->type.in(ID($lt), ID($le));
bool cmp_equal = cell->type.in("$le", "$ge"); bool cmp_equal = cell->type.in(ID($le), ID($ge));
bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
RTLIL::SigSpec A = sigmap(cell->getPort("\\A")); RTLIL::SigSpec A = sigmap(cell->getPort(ID::A));
RTLIL::SigSpec B = sigmap(cell->getPort("\\B")); RTLIL::SigSpec B = sigmap(cell->getPort(ID::B));
RTLIL::SigSpec Y = sigmap(cell->getPort("\\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;
@ -427,12 +427,12 @@ struct AlumaccWorker
for (auto cell : eq_cells) for (auto cell : eq_cells)
{ {
bool cmp_equal = cell->type.in("$eq", "$eqx"); bool cmp_equal = cell->type.in(ID($eq), ID($eqx));
bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
RTLIL::SigSpec A = sigmap(cell->getPort("\\A")); RTLIL::SigSpec A = sigmap(cell->getPort(ID::A));
RTLIL::SigSpec B = sigmap(cell->getPort("\\B")); RTLIL::SigSpec B = sigmap(cell->getPort(ID::B));
RTLIL::SigSpec Y = sigmap(cell->getPort("\\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);
@ -471,7 +471,7 @@ struct AlumaccWorker
goto delete_node; goto delete_node;
} }
n->alu_cell = module->addCell(NEW_ID, "$alu"); n->alu_cell = module->addCell(NEW_ID, ID($alu));
alu_counter++; alu_counter++;
log(" creating $alu cell for "); log(" creating $alu cell for ");
@ -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("\\A", n->a); n->alu_cell->setPort(ID::A, n->a);
n->alu_cell->setPort("\\B", n->b); n->alu_cell->setPort(ID::B, n->b);
n->alu_cell->setPort("\\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("\\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("\\Y", n->y); n->alu_cell->setPort(ID::Y, n->y);
n->alu_cell->setPort("\\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("\\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)

View file

@ -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 == "\\Y" && cell->type.in("$mux", "$pmux", "$_MUX_", "$_TBUF_", "$tribuf")) if (conn.first == ID::Y && cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_TBUF_), ID($tribuf)))
{ {
bool tribuf = cell->type.in("$_TBUF_", "$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("\\A", "\\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)

View file

@ -52,13 +52,13 @@ struct Dff2dffeWorker
} }
for (auto cell : module->cells()) { for (auto cell : module->cells()) {
if (cell->type.in("$mux", "$pmux", "$_MUX_")) { if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_))) {
RTLIL::SigSpec sig_y = sigmap(cell->getPort("\\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);
} }
if (direct_dict.empty()) { if (direct_dict.empty()) {
if (cell->type.in("$dff", "$_DFF_N_", "$_DFF_P_")) if (cell->type.in(ID($dff), ID($_DFF_N_), ID($_DFF_P_)))
dff_cells.push_back(cell); dff_cells.push_back(cell);
} else { } else {
if (direct_dict.count(cell->type)) if (direct_dict.count(cell->type))
@ -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("\\A")); RTLIL::SigSpec sig_a = sigmap(mux_cell_int.first->getPort(ID::A));
RTLIL::SigSpec sig_b = sigmap(mux_cell_int.first->getPort("\\B")); RTLIL::SigSpec sig_b = sigmap(mux_cell_int.first->getPort(ID::B));
RTLIL::SigSpec sig_s = sigmap(mux_cell_int.first->getPort("\\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("\\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("\\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("\\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("\\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("\\A"); RTLIL::SigSpec s = mux_cell_int.first->getPort(ID::A);
s[index] = RTLIL::Sx; s[index] = RTLIL::Sx;
mux_cell_int.first->setPort("\\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("\\D")); RTLIL::SigSpec sig_d = sigmap(dff_cell->getPort(ID(D)));
RTLIL::SigSpec sig_q = sigmap(dff_cell->getPort("\\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,16 +208,16 @@ 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("\\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 == "$dff") { if (dff_cell->type == ID($dff)) {
RTLIL::Cell *new_cell = module->addDffe(NEW_ID, dff_cell->getPort("\\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("\\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("\\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 == "$_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("\\D", new_sig_d); dff_cell->setPort(ID(D), new_sig_d);
dff_cell->setPort("\\Q", new_sig_q); dff_cell->setPort(ID(Q), new_sig_q);
dff_cell->setParam("\\WIDTH", GetSize(remaining_indices)); dff_cell->setParam(ID(WIDTH), GetSize(remaining_indices));
} }
} }
@ -265,7 +265,7 @@ struct Dff2dffePass : public Pass {
log("\n"); log("\n");
log(" -unmap\n"); log(" -unmap\n");
log(" operate in the opposite direction: replace $dffe cells with combinations\n"); log(" operate in the opposite direction: replace $dffe cells with combinations\n");
log(" of $dff and $mux cells. the options below are ignore in unmap mode.\n"); log(" of $dff and $mux cells. the options below are ignored in unmap mode.\n");
log("\n"); log("\n");
log(" -unmap-mince N\n"); log(" -unmap-mince N\n");
log(" Same as -unmap but only unmap $dffe where the clock enable port\n"); log(" Same as -unmap but only unmap $dffe where the clock enable port\n");
@ -316,25 +316,25 @@ struct Dff2dffePass : public Pass {
if (args[argidx] == "-direct-match" && argidx + 1 < args.size()) { if (args[argidx] == "-direct-match" && argidx + 1 < args.size()) {
bool found_match = false; bool found_match = false;
const char *pattern = args[++argidx].c_str(); const char *pattern = args[++argidx].c_str();
if (patmatch(pattern, "$_DFF_P_" )) found_match = true, direct_dict["$_DFF_P_" ] = "$_DFFE_PP_"; if (patmatch(pattern, "$_DFF_P_" )) found_match = true, direct_dict[ID($_DFF_P_) ] = ID($_DFFE_PP_);
if (patmatch(pattern, "$_DFF_N_" )) found_match = true, direct_dict["$_DFF_N_" ] = "$_DFFE_NP_"; if (patmatch(pattern, "$_DFF_N_" )) found_match = true, direct_dict[ID($_DFF_N_) ] = ID($_DFFE_NP_);
if (patmatch(pattern, "$_DFF_NN0_")) found_match = true, direct_dict["$_DFF_NN0_"] = "$__DFFE_NN0"; if (patmatch(pattern, "$_DFF_NN0_")) found_match = true, direct_dict[ID($_DFF_NN0_)] = ID($__DFFE_NN0);
if (patmatch(pattern, "$_DFF_NN1_")) found_match = true, direct_dict["$_DFF_NN1_"] = "$__DFFE_NN1"; if (patmatch(pattern, "$_DFF_NN1_")) found_match = true, direct_dict[ID($_DFF_NN1_)] = ID($__DFFE_NN1);
if (patmatch(pattern, "$_DFF_NP0_")) found_match = true, direct_dict["$_DFF_NP0_"] = "$__DFFE_NP0"; if (patmatch(pattern, "$_DFF_NP0_")) found_match = true, direct_dict[ID($_DFF_NP0_)] = ID($__DFFE_NP0);
if (patmatch(pattern, "$_DFF_NP1_")) found_match = true, direct_dict["$_DFF_NP1_"] = "$__DFFE_NP1"; if (patmatch(pattern, "$_DFF_NP1_")) found_match = true, direct_dict[ID($_DFF_NP1_)] = ID($__DFFE_NP1);
if (patmatch(pattern, "$_DFF_PN0_")) found_match = true, direct_dict["$_DFF_PN0_"] = "$__DFFE_PN0"; if (patmatch(pattern, "$_DFF_PN0_")) found_match = true, direct_dict[ID($_DFF_PN0_)] = ID($__DFFE_PN0);
if (patmatch(pattern, "$_DFF_PN1_")) found_match = true, direct_dict["$_DFF_PN1_"] = "$__DFFE_PN1"; if (patmatch(pattern, "$_DFF_PN1_")) found_match = true, direct_dict[ID($_DFF_PN1_)] = ID($__DFFE_PN1);
if (patmatch(pattern, "$_DFF_PP0_")) found_match = true, direct_dict["$_DFF_PP0_"] = "$__DFFE_PP0"; if (patmatch(pattern, "$_DFF_PP0_")) found_match = true, direct_dict[ID($_DFF_PP0_)] = ID($__DFFE_PP0);
if (patmatch(pattern, "$_DFF_PP1_")) found_match = true, direct_dict["$_DFF_PP1_"] = "$__DFFE_PP1"; if (patmatch(pattern, "$_DFF_PP1_")) found_match = true, direct_dict[ID($_DFF_PP1_)] = ID($__DFFE_PP1);
if (patmatch(pattern, "$__DFFS_NN0_")) found_match = true, direct_dict["$__DFFS_NN0_"] = "$__DFFSE_NN0"; if (patmatch(pattern, "$__DFFS_NN0_")) found_match = true, direct_dict[ID($__DFFS_NN0_)] = ID($__DFFSE_NN0);
if (patmatch(pattern, "$__DFFS_NN1_")) found_match = true, direct_dict["$__DFFS_NN1_"] = "$__DFFSE_NN1"; if (patmatch(pattern, "$__DFFS_NN1_")) found_match = true, direct_dict[ID($__DFFS_NN1_)] = ID($__DFFSE_NN1);
if (patmatch(pattern, "$__DFFS_NP0_")) found_match = true, direct_dict["$__DFFS_NP0_"] = "$__DFFSE_NP0"; if (patmatch(pattern, "$__DFFS_NP0_")) found_match = true, direct_dict[ID($__DFFS_NP0_)] = ID($__DFFSE_NP0);
if (patmatch(pattern, "$__DFFS_NP1_")) found_match = true, direct_dict["$__DFFS_NP1_"] = "$__DFFSE_NP1"; if (patmatch(pattern, "$__DFFS_NP1_")) found_match = true, direct_dict[ID($__DFFS_NP1_)] = ID($__DFFSE_NP1);
if (patmatch(pattern, "$__DFFS_PN0_")) found_match = true, direct_dict["$__DFFS_PN0_"] = "$__DFFSE_PN0"; if (patmatch(pattern, "$__DFFS_PN0_")) found_match = true, direct_dict[ID($__DFFS_PN0_)] = ID($__DFFSE_PN0);
if (patmatch(pattern, "$__DFFS_PN1_")) found_match = true, direct_dict["$__DFFS_PN1_"] = "$__DFFSE_PN1"; if (patmatch(pattern, "$__DFFS_PN1_")) found_match = true, direct_dict[ID($__DFFS_PN1_)] = ID($__DFFSE_PN1);
if (patmatch(pattern, "$__DFFS_PP0_")) found_match = true, direct_dict["$__DFFS_PP0_"] = "$__DFFSE_PP0"; if (patmatch(pattern, "$__DFFS_PP0_")) found_match = true, direct_dict[ID($__DFFS_PP0_)] = ID($__DFFSE_PP0);
if (patmatch(pattern, "$__DFFS_PP1_")) found_match = true, direct_dict["$__DFFS_PP1_"] = "$__DFFSE_PP1"; if (patmatch(pattern, "$__DFFS_PP1_")) found_match = true, direct_dict[ID($__DFFS_PP1_)] = ID($__DFFSE_PP1);
if (!found_match) if (!found_match)
log_cmd_error("No cell types matched pattern '%s'.\n", pattern); log_cmd_error("No cell types matched pattern '%s'.\n", pattern);
continue; continue;
@ -355,25 +355,25 @@ struct Dff2dffePass : public Pass {
if (unmap_mode) { if (unmap_mode) {
SigMap sigmap(mod); SigMap sigmap(mod);
for (auto cell : mod->selected_cells()) { for (auto cell : mod->selected_cells()) {
if (cell->type == "$dffe") { if (cell->type == ID($dffe)) {
if (min_ce_use >= 0) { if (min_ce_use >= 0) {
int ce_use = 0; int ce_use = 0;
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("\\EN")) == sigmap(cell_other->getPort("\\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("\\D"))); RTLIL::SigSpec tmp = mod->addWire(NEW_ID, GetSize(cell->getPort(ID(D))));
mod->addDff(NEW_ID, cell->getPort("\\CLK"), tmp, cell->getPort("\\Q"), cell->getParam("\\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("\\EN_POLARITY").as_bool()) if (cell->getParam(ID(EN_POLARITY)).as_bool())
mod->addMux(NEW_ID, cell->getPort("\\Q"), cell->getPort("\\D"), cell->getPort("\\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("\\D"), cell->getPort("\\Q"), cell->getPort("\\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("\\E")) == sigmap(cell_other->getPort("\\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("\\C"), tmp, cell->getPort("\\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("\\Q"), cell->getPort("\\D"), cell->getPort("\\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("\\D"), cell->getPort("\\Q"), cell->getPort("\\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;
} }

View file

@ -51,8 +51,8 @@ struct Dff2dffsPass : public Pass {
extra_args(args, argidx, design); extra_args(args, argidx, design);
pool<IdString> dff_types; pool<IdString> dff_types;
dff_types.insert("$_DFF_N_"); dff_types.insert(ID($_DFF_N_));
dff_types.insert("$_DFF_P_"); dff_types.insert(ID($_DFF_P_));
for (auto module : design->selected_modules()) for (auto module : design->selected_modules())
{ {
@ -69,19 +69,19 @@ struct Dff2dffsPass : public Pass {
continue; continue;
} }
if (cell->type != "$_MUX_") if (cell->type != ID($_MUX_))
continue; continue;
SigBit bit_a = sigmap(cell->getPort("\\A")); SigBit bit_a = sigmap(cell->getPort(ID::A));
SigBit bit_b = sigmap(cell->getPort("\\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("\\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("\\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("\\A")); SigBit bit_a = sigmap(mux_cell->getPort(ID::A));
SigBit bit_b = sigmap(mux_cell->getPort("\\B")); SigBit bit_b = sigmap(mux_cell->getPort(ID::B));
SigBit bit_s = sigmap(mux_cell->getPort("\\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));
@ -114,26 +114,26 @@ struct Dff2dffsPass : public Pass {
} }
if (sr_val == State::S1) { if (sr_val == State::S1) {
if (cell->type == "$_DFF_N_") { if (cell->type == ID($_DFF_N_)) {
if (invert_sr) cell->type = "$__DFFS_NN1_"; if (invert_sr) cell->type = ID($__DFFS_NN1_);
else cell->type = "$__DFFS_NP1_"; else cell->type = ID($__DFFS_NP1_);
} else { } else {
log_assert(cell->type == "$_DFF_P_"); log_assert(cell->type == ID($_DFF_P_));
if (invert_sr) cell->type = "$__DFFS_PN1_"; if (invert_sr) cell->type = ID($__DFFS_PN1_);
else cell->type = "$__DFFS_PP1_"; else cell->type = ID($__DFFS_PP1_);
} }
} else { } else {
if (cell->type == "$_DFF_N_") { if (cell->type == ID($_DFF_N_)) {
if (invert_sr) cell->type = "$__DFFS_NN0_"; if (invert_sr) cell->type = ID($__DFFS_NN0_);
else cell->type = "$__DFFS_NP0_"; else cell->type = ID($__DFFS_NP0_);
} else { } else {
log_assert(cell->type == "$_DFF_P_"); log_assert(cell->type == ID($_DFF_P_));
if (invert_sr) cell->type = "$__DFFS_PN0_"; if (invert_sr) cell->type = ID($__DFFS_PN0_);
else cell->type = "$__DFFS_PP0_"; else cell->type = ID($__DFFS_PP0_);
} }
} }
cell->setPort("\\R", sr_sig); cell->setPort(ID(R), sr_sig);
cell->setPort("\\D", bit_d); cell->setPort(ID(D), bit_d);
} }
} }
} }

View file

@ -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("\\init")) { if (wire->attributes.count(ID(init))) {
Const value = wire->attributes.at("\\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("\\init")) { if (wire->attributes.count(ID(init))) {
Const &value = wire->attributes.at("\\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("\\init"); wire->attributes.erase(ID(init));
} }
} }
} }

View file

@ -27,12 +27,12 @@ USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN PRIVATE_NAMESPACE_BEGIN
struct cell_mapping { struct cell_mapping {
std::string cell_name; IdString cell_name;
std::map<std::string, char> ports; std::map<std::string, char> ports;
}; };
static std::map<RTLIL::IdString, cell_mapping> cell_mappings; static std::map<RTLIL::IdString, cell_mapping> cell_mappings;
static void logmap(std::string dff) static void logmap(IdString dff)
{ {
if (cell_mappings.count(dff) == 0) { if (cell_mappings.count(dff) == 0) {
log(" unmapped dff cell: %s\n", dff.c_str()); log(" unmapped dff cell: %s\n", dff.c_str());
@ -54,26 +54,26 @@ static void logmap(std::string dff)
static void logmap_all() static void logmap_all()
{ {
logmap("$_DFF_N_"); logmap(ID($_DFF_N_));
logmap("$_DFF_P_"); logmap(ID($_DFF_P_));
logmap("$_DFF_NN0_"); logmap(ID($_DFF_NN0_));
logmap("$_DFF_NN1_"); logmap(ID($_DFF_NN1_));
logmap("$_DFF_NP0_"); logmap(ID($_DFF_NP0_));
logmap("$_DFF_NP1_"); logmap(ID($_DFF_NP1_));
logmap("$_DFF_PN0_"); logmap(ID($_DFF_PN0_));
logmap("$_DFF_PN1_"); logmap(ID($_DFF_PN1_));
logmap("$_DFF_PP0_"); logmap(ID($_DFF_PP0_));
logmap("$_DFF_PP1_"); logmap(ID($_DFF_PP1_));
logmap("$_DFFSR_NNN_"); logmap(ID($_DFFSR_NNN_));
logmap("$_DFFSR_NNP_"); logmap(ID($_DFFSR_NNP_));
logmap("$_DFFSR_NPN_"); logmap(ID($_DFFSR_NPN_));
logmap("$_DFFSR_NPP_"); logmap(ID($_DFFSR_NPP_));
logmap("$_DFFSR_PNN_"); logmap(ID($_DFFSR_PNN_));
logmap("$_DFFSR_PNP_"); logmap(ID($_DFFSR_PNP_));
logmap("$_DFFSR_PPN_"); logmap(ID($_DFFSR_PPN_));
logmap("$_DFFSR_PPP_"); logmap(ID($_DFFSR_PPP_));
} }
static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name, bool &pin_pol) static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name, bool &pin_pol)
@ -115,7 +115,7 @@ static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name,
return false; return false;
} }
static void find_cell(LibertyAst *ast, std::string cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval, bool prepare_mode) static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval, bool prepare_mode)
{ {
LibertyAst *best_cell = NULL; LibertyAst *best_cell = NULL;
std::map<std::string, char> best_cell_ports; std::map<std::string, char> best_cell_ports;
@ -230,13 +230,13 @@ static void find_cell(LibertyAst *ast, std::string cell_type, bool clkpol, bool
cell_mappings[cell_type].ports["D"] = 'D'; cell_mappings[cell_type].ports["D"] = 'D';
cell_mappings[cell_type].ports["Q"] = 'Q'; cell_mappings[cell_type].ports["Q"] = 'Q';
} else { } else {
cell_mappings[cell_type].cell_name = best_cell->args[0]; cell_mappings[cell_type].cell_name = RTLIL::escape_id(best_cell->args[0]);
cell_mappings[cell_type].ports = best_cell_ports; cell_mappings[cell_type].ports = best_cell_ports;
} }
} }
} }
static void find_cell_sr(LibertyAst *ast, std::string cell_type, bool clkpol, bool setpol, bool clrpol, bool prepare_mode) static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool setpol, bool clrpol, bool prepare_mode)
{ {
LibertyAst *best_cell = NULL; LibertyAst *best_cell = NULL;
std::map<std::string, char> best_cell_ports; std::map<std::string, char> best_cell_ports;
@ -347,7 +347,7 @@ static void find_cell_sr(LibertyAst *ast, std::string cell_type, bool clkpol, bo
cell_mappings[cell_type].ports["D"] = 'D'; cell_mappings[cell_type].ports["D"] = 'D';
cell_mappings[cell_type].ports["Q"] = 'Q'; cell_mappings[cell_type].ports["Q"] = 'Q';
} else { } else {
cell_mappings[cell_type].cell_name = best_cell->args[0]; cell_mappings[cell_type].cell_name = RTLIL::escape_id(best_cell->args[0]);
cell_mappings[cell_type].ports = best_cell_ports; cell_mappings[cell_type].ports = best_cell_ports;
} }
} }
@ -404,7 +404,7 @@ static bool expand_cellmap(std::string pattern, std::string inv)
return return_status; return return_status;
} }
static void map_sr_to_arst(const char *from, const char *to) static void map_sr_to_arst(IdString from, IdString to)
{ {
if (!cell_mappings.count(from) || cell_mappings.count(to) > 0) if (!cell_mappings.count(from) || cell_mappings.count(to) > 0)
return; return;
@ -419,7 +419,7 @@ static void map_sr_to_arst(const char *from, const char *to)
log_assert(from_clk_pol == to_clk_pol); log_assert(from_clk_pol == to_clk_pol);
log_assert(to_rst_pol == from_set_pol && to_rst_pol == from_clr_pol); log_assert(to_rst_pol == from_set_pol && to_rst_pol == from_clr_pol);
log(" create mapping for %s from mapping for %s.\n", to, from); log(" create mapping for %s from mapping for %s.\n", to.c_str(), from.c_str());
cell_mappings[to].cell_name = cell_mappings[from].cell_name; cell_mappings[to].cell_name = cell_mappings[from].cell_name;
cell_mappings[to].ports = cell_mappings[from].ports; cell_mappings[to].ports = cell_mappings[from].ports;
@ -450,7 +450,7 @@ static void map_sr_to_arst(const char *from, const char *to)
} }
} }
static void map_adff_to_dff(const char *from, const char *to) static void map_adff_to_dff(IdString from, IdString to)
{ {
if (!cell_mappings.count(from) || cell_mappings.count(to) > 0) if (!cell_mappings.count(from) || cell_mappings.count(to) > 0)
return; return;
@ -461,7 +461,7 @@ static void map_adff_to_dff(const char *from, const char *to)
log_assert(from_clk_pol == to_clk_pol); log_assert(from_clk_pol == to_clk_pol);
log(" create mapping for %s from mapping for %s.\n", to, from); log(" create mapping for %s from mapping for %s.\n", to.c_str(), from.c_str());
cell_mappings[to].cell_name = cell_mappings[from].cell_name; cell_mappings[to].cell_name = cell_mappings[from].cell_name;
cell_mappings[to].ports = cell_mappings[from].ports; cell_mappings[to].ports = cell_mappings[from].ports;
@ -484,8 +484,8 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module, bool prepare
for (auto &it : module->cells_) { for (auto &it : module->cells_) {
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 == "$_NOT_") if (it.second->type == ID($_NOT_))
notmap[sigmap(it.second->getPort("\\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;
@ -499,7 +499,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module, bool prepare
module->remove(cell); module->remove(cell);
cell_mapping &cm = cell_mappings[cell_type]; cell_mapping &cm = cell_mappings[cell_type];
RTLIL::Cell *new_cell = module->addCell(cell_name, prepare_mode ? cm.cell_name : "\\" + cm.cell_name); RTLIL::Cell *new_cell = module->addCell(cell_name, prepare_mode ? cm.cell_name : cm.cell_name);
new_cell->set_src_attribute(src); new_cell->set_src_attribute(src);
@ -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("\\Y"), sig); module->connect(it->getPort(ID::Y), sig);
it->setPort("\\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);
@ -599,26 +599,26 @@ struct DfflibmapPass : public Pass {
LibertyParser libparser(f); LibertyParser libparser(f);
f.close(); f.close();
find_cell(libparser.ast, "$_DFF_N_", false, false, false, false, prepare_mode); find_cell(libparser.ast, ID($_DFF_N_), false, false, false, false, prepare_mode);
find_cell(libparser.ast, "$_DFF_P_", true, false, false, false, prepare_mode); find_cell(libparser.ast, ID($_DFF_P_), true, false, false, false, prepare_mode);
find_cell(libparser.ast, "$_DFF_NN0_", false, true, false, false, prepare_mode); find_cell(libparser.ast, ID($_DFF_NN0_), false, true, false, false, prepare_mode);
find_cell(libparser.ast, "$_DFF_NN1_", false, true, false, true, prepare_mode); find_cell(libparser.ast, ID($_DFF_NN1_), false, true, false, true, prepare_mode);
find_cell(libparser.ast, "$_DFF_NP0_", false, true, true, false, prepare_mode); find_cell(libparser.ast, ID($_DFF_NP0_), false, true, true, false, prepare_mode);
find_cell(libparser.ast, "$_DFF_NP1_", false, true, true, true, prepare_mode); find_cell(libparser.ast, ID($_DFF_NP1_), false, true, true, true, prepare_mode);
find_cell(libparser.ast, "$_DFF_PN0_", true, true, false, false, prepare_mode); find_cell(libparser.ast, ID($_DFF_PN0_), true, true, false, false, prepare_mode);
find_cell(libparser.ast, "$_DFF_PN1_", true, true, false, true, prepare_mode); find_cell(libparser.ast, ID($_DFF_PN1_), true, true, false, true, prepare_mode);
find_cell(libparser.ast, "$_DFF_PP0_", true, true, true, false, prepare_mode); find_cell(libparser.ast, ID($_DFF_PP0_), true, true, true, false, prepare_mode);
find_cell(libparser.ast, "$_DFF_PP1_", true, true, true, true, prepare_mode); find_cell(libparser.ast, ID($_DFF_PP1_), true, true, true, true, prepare_mode);
find_cell_sr(libparser.ast, "$_DFFSR_NNN_", false, false, false, prepare_mode); find_cell_sr(libparser.ast, ID($_DFFSR_NNN_), false, false, false, prepare_mode);
find_cell_sr(libparser.ast, "$_DFFSR_NNP_", false, false, true, prepare_mode); find_cell_sr(libparser.ast, ID($_DFFSR_NNP_), false, false, true, prepare_mode);
find_cell_sr(libparser.ast, "$_DFFSR_NPN_", false, true, false, prepare_mode); find_cell_sr(libparser.ast, ID($_DFFSR_NPN_), false, true, false, prepare_mode);
find_cell_sr(libparser.ast, "$_DFFSR_NPP_", false, true, true, prepare_mode); find_cell_sr(libparser.ast, ID($_DFFSR_NPP_), false, true, true, prepare_mode);
find_cell_sr(libparser.ast, "$_DFFSR_PNN_", true, false, false, prepare_mode); find_cell_sr(libparser.ast, ID($_DFFSR_PNN_), true, false, false, prepare_mode);
find_cell_sr(libparser.ast, "$_DFFSR_PNP_", true, false, true, prepare_mode); find_cell_sr(libparser.ast, ID($_DFFSR_PNP_), true, false, true, prepare_mode);
find_cell_sr(libparser.ast, "$_DFFSR_PPN_", true, true, false, prepare_mode); find_cell_sr(libparser.ast, ID($_DFFSR_PPN_), true, true, false, prepare_mode);
find_cell_sr(libparser.ast, "$_DFFSR_PPP_", true, true, true, prepare_mode); find_cell_sr(libparser.ast, ID($_DFFSR_PPP_), true, true, true, prepare_mode);
// try to implement as many cells as possible just by inverting // try to implement as many cells as possible just by inverting
// the SET and RESET pins. If necessary, implement cell types // the SET and RESET pins. If necessary, implement cell types
@ -642,23 +642,23 @@ struct DfflibmapPass : public Pass {
break; break;
} }
map_sr_to_arst("$_DFFSR_NNN_", "$_DFF_NN0_"); map_sr_to_arst(ID($_DFFSR_NNN_), ID($_DFF_NN0_));
map_sr_to_arst("$_DFFSR_NNN_", "$_DFF_NN1_"); map_sr_to_arst(ID($_DFFSR_NNN_), ID($_DFF_NN1_));
map_sr_to_arst("$_DFFSR_NPP_", "$_DFF_NP0_"); map_sr_to_arst(ID($_DFFSR_NPP_), ID($_DFF_NP0_));
map_sr_to_arst("$_DFFSR_NPP_", "$_DFF_NP1_"); map_sr_to_arst(ID($_DFFSR_NPP_), ID($_DFF_NP1_));
map_sr_to_arst("$_DFFSR_PNN_", "$_DFF_PN0_"); map_sr_to_arst(ID($_DFFSR_PNN_), ID($_DFF_PN0_));
map_sr_to_arst("$_DFFSR_PNN_", "$_DFF_PN1_"); map_sr_to_arst(ID($_DFFSR_PNN_), ID($_DFF_PN1_));
map_sr_to_arst("$_DFFSR_PPP_", "$_DFF_PP0_"); map_sr_to_arst(ID($_DFFSR_PPP_), ID($_DFF_PP0_));
map_sr_to_arst("$_DFFSR_PPP_", "$_DFF_PP1_"); map_sr_to_arst(ID($_DFFSR_PPP_), ID($_DFF_PP1_));
map_adff_to_dff("$_DFF_NN0_", "$_DFF_N_"); map_adff_to_dff(ID($_DFF_NN0_), ID($_DFF_N_));
map_adff_to_dff("$_DFF_NN1_", "$_DFF_N_"); map_adff_to_dff(ID($_DFF_NN1_), ID($_DFF_N_));
map_adff_to_dff("$_DFF_NP0_", "$_DFF_N_"); map_adff_to_dff(ID($_DFF_NP0_), ID($_DFF_N_));
map_adff_to_dff("$_DFF_NP1_", "$_DFF_N_"); map_adff_to_dff(ID($_DFF_NP1_), ID($_DFF_N_));
map_adff_to_dff("$_DFF_PN0_", "$_DFF_P_"); map_adff_to_dff(ID($_DFF_PN0_), ID($_DFF_P_));
map_adff_to_dff("$_DFF_PN1_", "$_DFF_P_"); map_adff_to_dff(ID($_DFF_PN1_), ID($_DFF_P_));
map_adff_to_dff("$_DFF_PP0_", "$_DFF_P_"); map_adff_to_dff(ID($_DFF_PP0_), ID($_DFF_P_));
map_adff_to_dff("$_DFF_PP1_", "$_DFF_P_"); map_adff_to_dff(ID($_DFF_PP1_), ID($_DFF_P_));
log(" final dff cell mappings:\n"); log(" final dff cell mappings:\n");
logmap_all(); logmap_all();

View file

@ -25,17 +25,17 @@ PRIVATE_NAMESPACE_BEGIN
void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell) void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell)
{ {
if (cell->type == "$dffsr") if (cell->type == ID($dffsr))
{ {
int width = cell->getParam("\\WIDTH").as_int(); int width = cell->getParam(ID(WIDTH)).as_int();
bool setpol = cell->getParam("\\SET_POLARITY").as_bool(); bool setpol = cell->getParam(ID(SET_POLARITY)).as_bool();
bool clrpol = cell->getParam("\\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("\\SET")); SigSpec setsig = sigmap(cell->getPort(ID(SET)));
SigSpec clrsig = sigmap(cell->getPort("\\CLR")); SigSpec clrsig = sigmap(cell->getPort(ID(CLR)));
Const reset_val; Const reset_val;
SigSpec setctrl, clrctrl; SigSpec setctrl, clrctrl;
@ -78,32 +78,32 @@ 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("\\ARST", setctrl); cell->setPort(ID(ARST), setctrl);
cell->setParam("\\ARST_POLARITY", setpol); cell->setParam(ID(ARST_POLARITY), setpol);
} else { } else {
cell->setPort("\\ARST", clrctrl); cell->setPort(ID(ARST), clrctrl);
cell->setParam("\\ARST_POLARITY", clrpol); cell->setParam(ID(ARST_POLARITY), clrpol);
} }
cell->type = "$adff"; cell->type = ID($adff);
cell->unsetPort("\\SET"); cell->unsetPort(ID(SET));
cell->unsetPort("\\CLR"); cell->unsetPort(ID(CLR));
cell->setParam("\\ARST_VALUE", reset_val); cell->setParam(ID(ARST_VALUE), reset_val);
cell->unsetParam("\\SET_POLARITY"); cell->unsetParam(ID(SET_POLARITY));
cell->unsetParam("\\CLR_POLARITY"); cell->unsetParam(ID(CLR_POLARITY));
return; return;
} }
if (cell->type.in("$_DFFSR_NNN_", "$_DFFSR_NNP_", "$_DFFSR_NPN_", "$_DFFSR_NPP_", if (cell->type.in(ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_),
"$_DFFSR_PNN_", "$_DFFSR_PNP_", "$_DFFSR_PPN_", "$_DFFSR_PPP_")) ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_)))
{ {
char clkpol = cell->type.c_str()[8]; char clkpol = cell->type.c_str()[8];
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("\\S")); SigBit setbit = sigmap(cell->getPort(ID(S)));
SigBit clrbit = sigmap(cell->getPort("\\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("\\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("\\R", cell->getPort("\\S")); cell->setPort(ID(R), cell->getPort(ID(S)));
cell->unsetPort("\\S"); cell->unsetPort(ID(S));
goto converted_gate; goto converted_gate;
} }
@ -133,32 +133,32 @@ void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell)
void adff_worker(SigMap &sigmap, Module *module, Cell *cell) void adff_worker(SigMap &sigmap, Module *module, Cell *cell)
{ {
if (cell->type == "$adff") if (cell->type == ID($adff))
{ {
bool rstpol = cell->getParam("\\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("\\ARST")); SigSpec rstsig = sigmap(cell->getPort(ID(ARST)));
if (rstsig != rstunused) if (rstsig != rstunused)
return; return;
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 = "$dff"; cell->type = ID($dff);
cell->unsetPort("\\ARST"); cell->unsetPort(ID(ARST));
cell->unsetParam("\\ARST_VALUE"); cell->unsetParam(ID(ARST_VALUE));
cell->unsetParam("\\ARST_POLARITY"); cell->unsetParam(ID(ARST_POLARITY));
return; return;
} }
if (cell->type.in("$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_),
"$_DFF_PN0_", "$_DFF_PN1_", "$_DFF_PP0_", "$_DFF_PP1_")) ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_)))
{ {
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("\\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("\\R"); cell->unsetPort(ID(R));
return; return;
} }

View file

@ -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("\\ARST_POLARITY"); param_bool(ID(ARST_POLARITY));
param_bool("\\A_SIGNED"); param_bool(ID(A_SIGNED));
param_bool("\\B_SIGNED"); param_bool(ID(B_SIGNED));
param_bool("\\CLK_ENABLE"); param_bool(ID(CLK_ENABLE));
param_bool("\\CLK_POLARITY"); param_bool(ID(CLK_POLARITY));
param_bool("\\CLR_POLARITY"); param_bool(ID(CLR_POLARITY));
param_bool("\\EN_POLARITY"); param_bool(ID(EN_POLARITY));
param_bool("\\SET_POLARITY"); param_bool(ID(SET_POLARITY));
param_bool("\\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("\\ABITS") param_int(ID(ABITS))
param_int("\\A_WIDTH") param_int(ID(A_WIDTH))
param_int("\\B_WIDTH") param_int(ID(B_WIDTH))
param_int("\\CTRL_IN_WIDTH") param_int(ID(CTRL_IN_WIDTH))
param_int("\\CTRL_OUT_WIDTH") param_int(ID(CTRL_OUT_WIDTH))
param_int("\\OFFSET") param_int(ID(OFFSET))
param_int("\\PRIORITY") param_int(ID(PRIORITY))
param_int("\\RD_PORTS") param_int(ID(RD_PORTS))
param_int("\\SIZE") param_int(ID(SIZE))
param_int("\\STATE_BITS") param_int(ID(STATE_BITS))
param_int("\\STATE_NUM") param_int(ID(STATE_NUM))
param_int("\\STATE_NUM_LOG2") param_int(ID(STATE_NUM_LOG2))
param_int("\\STATE_RST") param_int(ID(STATE_RST))
param_int("\\S_WIDTH") param_int(ID(S_WIDTH))
param_int("\\TRANS_NUM") param_int(ID(TRANS_NUM))
param_int("\\WIDTH") param_int(ID(WIDTH))
param_int("\\WR_PORTS") param_int(ID(WR_PORTS))
param_int("\\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("\\extract_order") > 0) if (left->attributes.count(ID(extract_order)) > 0)
left_idx = left->attributes.at("\\extract_order").as_int(); left_idx = left->attributes.at(ID(extract_order)).as_int();
if (right->attributes.count("\\extract_order") > 0) if (right->attributes.count(ID(extract_order)) > 0)
right_idx = right->attributes.at("\\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;

View file

@ -120,71 +120,71 @@ 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("\\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("\\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("\\A_SIGNED").as_bool(); bool a_sign = cell->getParam(ID(A_SIGNED)).as_bool();
bool b_sign = cell->getParam("\\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("\\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("\\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("\\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("\\CO")), index)) if(!is_unconnected(sigmap(cell->getPort(ID(CO))), index))
return 7; return 7;
if(!is_unconnected(sigmap(cell->getPort("\\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("\\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;
Cell* count_mux = *y_loads.begin(); Cell* count_mux = *y_loads.begin();
extract.count_mux = count_mux; extract.count_mux = count_mux;
if(count_mux->type != "$mux") if(count_mux->type != ID($mux))
return 10; return 10;
if(!is_full_bus(aluy, index, cell, "\\Y", count_mux, "\\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("\\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("\\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;
for(auto c : muxsel_conns) for(auto c : muxsel_conns)
{ {
if(c->type != "$logic_not") if(c->type != ID($logic_not))
continue; continue;
if(!is_full_bus(muxsel, index, c, "\\Y", count_mux, "\\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("\\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;
@ -204,12 +204,12 @@ int counter_tryextract(
Cell* count_reg = muxload; Cell* count_reg = muxload;
Cell* cemux = NULL; Cell* cemux = NULL;
RTLIL::SigSpec cey; RTLIL::SigSpec cey;
if(muxload->type == "$mux") if(muxload->type == ID($mux))
{ {
//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("\\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,32 +217,32 @@ 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("\\B")) != muxy) if(sigmap(cemux->getPort(ID::B)) != muxy)
return 24; return 24;
if(sigmap(cemux->getPort("\\A")) != sigmap(count_reg->getPort("\\Q"))) if(sigmap(cemux->getPort(ID::A)) != sigmap(count_reg->getPort(ID(Q))))
return 24; return 24;
if(sigmap(cemux->getPort("\\Y")) != sigmap(count_reg->getPort("\\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("\\S")); extract.ce = sigmap(cemux->getPort(ID(S)));
} }
else else
extract.has_ce = false; extract.has_ce = false;
extract.count_reg = count_reg; extract.count_reg = count_reg;
if(count_reg->type == "$dff") if(count_reg->type == ID($dff))
extract.has_reset = false; extract.has_reset = false;
else if(count_reg->type == "$adff") else if(count_reg->type == ID($adff))
{ {
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("\\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("\\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("\\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, "\\Y", cemux, "\\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, "\\Y", count_reg, "\\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, "\\Y", count_reg, "\\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("\\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, "\\Q", underflow_inv, "\\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, "\\Q", cell, "\\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("\\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("\\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["\\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;
@ -343,21 +343,21 @@ void counter_worker(
SigMap& sigmap = index.sigmap; SigMap& sigmap = index.sigmap;
//Core of the counter must be an ALU //Core of the counter must be an ALU
if (cell->type != "$alu") if (cell->type != ID($alu))
return; return;
//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("\\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["\\src"].decode_string().c_str(); string count_reg_src = a_wire->attributes[ID(src)].decode_string().c_str();
if(a_wire->attributes.find("\\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("\\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,66 +434,66 @@ 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("\\A"); cell->unsetPort(ID::A);
cell->unsetPort("\\B"); cell->unsetPort(ID::B);
cell->unsetPort("\\BI"); cell->unsetPort(ID(BI));
cell->unsetPort("\\CI"); cell->unsetPort(ID(CI));
cell->unsetPort("\\CO"); cell->unsetPort(ID(CO));
cell->unsetPort("\\X"); cell->unsetPort(ID(X));
cell->unsetPort("\\Y"); cell->unsetPort(ID::Y);
cell->unsetParam("\\A_SIGNED"); cell->unsetParam(ID(A_SIGNED));
cell->unsetParam("\\A_WIDTH"); cell->unsetParam(ID(A_WIDTH));
cell->unsetParam("\\B_SIGNED"); cell->unsetParam(ID(B_SIGNED));
cell->unsetParam("\\B_WIDTH"); cell->unsetParam(ID(B_WIDTH));
cell->unsetParam("\\Y_WIDTH"); cell->unsetParam(ID(Y_WIDTH));
//Change the cell type //Change the cell type
cell->type = "$__COUNT_"; cell->type = ID($__COUNT_);
//Hook up resets //Hook up resets
if(extract.has_reset) if(extract.has_reset)
{ {
//TODO: support other kinds of reset //TODO: support other kinds of reset
cell->setParam("\\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("\\RST", realreset); cell->setPort(ID(RST), realreset);
} }
else else
cell->setPort("\\RST", extract.rst); cell->setPort(ID(RST), extract.rst);
} }
else else
{ {
cell->setParam("\\RESET_MODE", RTLIL::Const("RISING")); cell->setParam(ID(RESET_MODE), RTLIL::Const("RISING"));
cell->setPort("\\RST", RTLIL::SigSpec(false)); cell->setPort(ID(RST), RTLIL::SigSpec(false));
} }
//Hook up other stuff //Hook up other stuff
//cell->setParam("\\CLKIN_DIVIDE", RTLIL::Const(1)); //cell->setParam(ID(CLKIN_DIVIDE), RTLIL::Const(1));
cell->setParam("\\COUNT_TO", RTLIL::Const(extract.count_value)); cell->setParam(ID(COUNT_TO), RTLIL::Const(extract.count_value));
cell->setParam("\\WIDTH", RTLIL::Const(extract.width)); cell->setParam(ID(WIDTH), RTLIL::Const(extract.width));
cell->setPort("\\CLK", extract.clk); cell->setPort(ID(CLK), extract.clk);
cell->setPort("\\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("\\HAS_CE", RTLIL::Const(1)); cell->setParam(ID(HAS_CE), RTLIL::Const(1));
cell->setPort("\\CE", extract.ce); cell->setPort(ID(CE), extract.ce);
} }
else else
cell->setParam("\\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("\\HAS_POUT", RTLIL::Const(0)); cell->setParam(ID(HAS_POUT), RTLIL::Const(0));
cell->setParam("\\RESET_TO_MAX", RTLIL::Const(0)); cell->setParam(ID(RESET_TO_MAX), RTLIL::Const(0));
cell->setParam("\\DIRECTION", RTLIL::Const("DOWN")); cell->setParam(ID(DIRECTION), RTLIL::Const("DOWN"));
cell->setPort("\\CE", RTLIL::Const(1)); cell->setPort(ID(CE), RTLIL::Const(1));
cell->setPort("\\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("\\POUT", sig); cell->setPort(ID(POUT), sig);
cell->setParam("\\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("\\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);

View file

@ -85,11 +85,11 @@ struct ExtractFaWorker
{ {
for (auto cell : module->selected_cells()) for (auto cell : module->selected_cells())
{ {
if (cell->type.in( "$_BUF_", "$_NOT_", "$_AND_", "$_NAND_", "$_OR_", "$_NOR_", if (cell->type.in( ID($_BUF_), ID($_NOT_), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_),
"$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_", "$_MUX_", "$_NMUX_", ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), ID($_MUX_), ID($_NMUX_),
"$_AOI3_", "$_OAI3_", "$_AOI4_", "$_OAI4_")) ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_)))
{ {
SigBit y = sigmap(SigBit(cell->getPort("\\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("\\A")) new_leaves.insert(sigmap(SigBit(cell->getPort("\\A")))); if (cell->hasPort(ID::A)) new_leaves.insert(sigmap(SigBit(cell->getPort(ID::A))));
if (cell->hasPort("\\B")) new_leaves.insert(sigmap(SigBit(cell->getPort("\\B")))); if (cell->hasPort(ID::B)) new_leaves.insert(sigmap(SigBit(cell->getPort(ID::B))));
if (cell->hasPort("\\C")) new_leaves.insert(sigmap(SigBit(cell->getPort("\\C")))); if (cell->hasPort(ID(C))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(C)))));
if (cell->hasPort("\\D")) new_leaves.insert(sigmap(SigBit(cell->getPort("\\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("\\Y")) == bit) { if (sigmap(cell->getPort(ID::Y)) == bit) {
cell->setPort("\\Y", module->addWire(NEW_ID)); cell->setPort(ID::Y, module->addWire(NEW_ID));
module->connect(bit, new_driver); module->connect(bit, new_driver);
} }
} }
@ -289,7 +289,7 @@ struct ExtractFaWorker
for (auto it : driver) for (auto it : driver)
{ {
if (it.second->type.in("$_BUF_", "$_NOT_")) if (it.second->type.in(ID($_BUF_), ID($_NOT_)))
continue; continue;
SigBit root = it.first; SigBit root = it.first;
@ -390,20 +390,20 @@ struct ExtractFaWorker
} }
else else
{ {
Cell *cell = module->addCell(NEW_ID, "$fa"); Cell *cell = module->addCell(NEW_ID, ID($fa));
cell->setParam("\\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("\\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("\\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("\\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("\\X", X); cell->setPort(ID(X), X);
cell->setPort("\\Y", Y); cell->setPort(ID::Y, Y);
facache[fakey] = make_tuple(X, Y, cell); facache[fakey] = make_tuple(X, Y, cell);
} }
@ -496,20 +496,20 @@ struct ExtractFaWorker
} }
else else
{ {
Cell *cell = module->addCell(NEW_ID, "$fa"); Cell *cell = module->addCell(NEW_ID, ID($fa));
cell->setParam("\\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("\\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("\\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("\\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("\\X", X); cell->setPort(ID(X), X);
cell->setPort("\\Y", Y); cell->setPort(ID::Y, Y);
} }
if (func2.at(key).count(xor2_func)) { if (func2.at(key).count(xor2_func)) {

View file

@ -58,9 +58,9 @@ struct ExtractReducePass : public Pass
inline bool IsRightType(Cell* cell, GateType gt) inline bool IsRightType(Cell* cell, GateType gt)
{ {
return (cell->type == "$_AND_" && gt == GateType::And) || return (cell->type == ID($_AND_) && gt == GateType::And) ||
(cell->type == "$_OR_" && gt == GateType::Or) || (cell->type == ID($_OR_) && gt == GateType::Or) ||
(cell->type == "$_XOR_" && gt == GateType::Xor); (cell->type == ID($_XOR_) && gt == GateType::Xor);
} }
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@ -124,11 +124,11 @@ struct ExtractReducePass : public Pass
GateType gt; GateType gt;
if (cell->type == "$_AND_") if (cell->type == ID($_AND_))
gt = GateType::And; gt = GateType::And;
else if (cell->type == "$_OR_") else if (cell->type == ID($_OR_))
gt = GateType::Or; gt = GateType::Or;
else if (cell->type == "$_XOR_") else if (cell->type == ID($_XOR_))
gt = GateType::Xor; gt = GateType::Xor;
else else
continue; continue;
@ -148,7 +148,7 @@ struct ExtractReducePass : public Pass
head_cell = x; head_cell = x;
auto y = sigmap(x->getPort("\\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("\\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("\\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("\\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("\\A"))[0]); input_pool.insert(sigmap(x->getPort(ID::A))[0]);
input_pool.insert(sigmap(x->getPort("\\B"))[0]); input_pool.insert(sigmap(x->getPort(ID::B))[0]);
input_pool_intermed.insert(sigmap(x->getPort("\\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("\\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 ? "$reduce_and" : gt == GateType::And ? ID($reduce_and) :
gt == GateType::Or ? "$reduce_or" : gt == GateType::Or ? ID($reduce_or) :
gt == GateType::Xor ? "$reduce_xor" : ""); gt == GateType::Xor ? ID($reduce_xor) : "");
new_reduce_cell->setParam("\\A_SIGNED", 0); new_reduce_cell->setParam(ID(A_SIGNED), 0);
new_reduce_cell->setParam("\\A_WIDTH", input.size()); new_reduce_cell->setParam(ID(A_WIDTH), input.size());
new_reduce_cell->setParam("\\Y_WIDTH", 1); new_reduce_cell->setParam(ID(Y_WIDTH), 1);
new_reduce_cell->setPort("\\A", input); new_reduce_cell->setPort(ID::A, input);
new_reduce_cell->setPort("\\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);

View file

@ -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("\\$flowmap_level")) if (input.wire->attributes.count(ID($flowmap_level)))
labels[input] = input.wire->attributes["\\$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("\\src", gate_origin.cell->get_strpool_attribute("\\src")); lut->add_strpool_attribute(ID(src), gate_origin.cell->get_strpool_attribute(ID(src)));
packed_count++; packed_count++;
} }
lut_count++; lut_count++;
@ -1586,7 +1586,7 @@ struct FlowmapPass : public Pass {
} }
else else
{ {
cell_types = {"$_NOT_", "$_AND_", "$_OR_", "$_XOR_", "$_MUX_"}; cell_types = {ID($_NOT_), ID($_AND_), ID($_OR_), ID($_XOR_), ID($_MUX_)};
} }
const char *algo_r = relax ? "-r" : ""; const char *algo_r = relax ? "-r" : "";

View file

@ -179,8 +179,8 @@ struct IopadmapPass : public Pass {
SigMap rewrites; SigMap rewrites;
for (auto cell : module->cells()) for (auto cell : module->cells())
if (cell->type == "$_TBUF_") { if (cell->type == ID($_TBUF_)) {
SigBit bit = sigmap(cell->getPort("\\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("\\E").as_bit(); SigBit en_sig = tbuf_cell->getPort(ID(E)).as_bit();
SigBit data_sig = tbuf_cell->getPort("\\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["\\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["\\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["\\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["\\keep"] = RTLIL::Const(1); cell->attributes[ID::keep] = RTLIL::Const(1);
} }
wire->port_id = 0; wire->port_id = 0;

View file

@ -25,9 +25,9 @@ PRIVATE_NAMESPACE_BEGIN
int lut2mux(Cell *cell) int lut2mux(Cell *cell)
{ {
SigSpec sig_a = cell->getPort("\\A"); SigSpec sig_a = cell->getPort(ID::A);
SigSpec sig_y = cell->getPort("\\Y"); SigSpec sig_y = cell->getPort(ID::Y);
Const lut = cell->getParam("\\LUT"); Const lut = cell->getParam(ID(LUT));
int count = 1; int count = 1;
if (GetSize(sig_a) == 1) if (GetSize(sig_a) == 1)
@ -81,7 +81,7 @@ struct Lut2muxPass : public Pass {
for (auto module : design->selected_modules()) for (auto module : design->selected_modules())
for (auto cell : module->selected_cells()) { for (auto cell : module->selected_cells()) {
if (cell->type == "$lut") { if (cell->type == ID($lut)) {
IdString cell_name = cell->name; IdString cell_name = cell->name;
int count = lut2mux(cell); int count = lut2mux(cell);
log("Converted %s.%s to %d MUX cells.\n", log_id(module), log_id(cell_name), count); log("Converted %s.%s to %d MUX cells.\n", log_id(module), log_id(cell_name), count);

View file

@ -111,13 +111,13 @@ struct MaccmapWorker
RTLIL::Wire *w1 = module->addWire(NEW_ID, width); RTLIL::Wire *w1 = module->addWire(NEW_ID, width);
RTLIL::Wire *w2 = module->addWire(NEW_ID, width); RTLIL::Wire *w2 = module->addWire(NEW_ID, width);
RTLIL::Cell *cell = module->addCell(NEW_ID, "$fa"); RTLIL::Cell *cell = module->addCell(NEW_ID, ID($fa));
cell->setParam("\\WIDTH", width); cell->setParam(ID(WIDTH), width);
cell->setPort("\\A", in1); cell->setPort(ID::A, in1);
cell->setPort("\\B", in2); cell->setPort(ID::B, in2);
cell->setPort("\\C", in3); cell->setPort(ID(C), in3);
cell->setPort("\\Y", w1); cell->setPort(ID::Y, w1);
cell->setPort("\\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};
@ -237,23 +237,23 @@ struct MaccmapWorker
} }
RTLIL::Cell *c = module->addCell(NEW_ID, "$alu"); RTLIL::Cell *c = module->addCell(NEW_ID, ID($alu));
c->setPort("\\A", summands.front()); c->setPort(ID::A, summands.front());
c->setPort("\\B", summands.back()); c->setPort(ID::B, summands.back());
c->setPort("\\CI", State::S0); c->setPort(ID(CI), State::S0);
c->setPort("\\BI", State::S0); c->setPort(ID(BI), State::S0);
c->setPort("\\Y", module->addWire(NEW_ID, width)); c->setPort(ID::Y, module->addWire(NEW_ID, width));
c->setPort("\\X", module->addWire(NEW_ID, width)); c->setPort(ID(X), module->addWire(NEW_ID, width));
c->setPort("\\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("\\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("\\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("\\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("\\A")); all_input_bits.append(cell->getPort(ID::A));
all_input_bits.append(cell->getPort("\\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("\\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("\\Y")); module->addNeg(NEW_ID, summands.front().first, cell->getPort(ID::Y));
else else
module->connect(cell->getPort("\\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("\\Y"), worker.synth()); module->connect(cell->getPort(ID::Y), worker.synth());
} }
} }
@ -393,7 +393,7 @@ struct MaccmapPass : public Pass {
for (auto mod : design->selected_modules()) for (auto mod : design->selected_modules())
for (auto cell : mod->selected_cells()) for (auto cell : mod->selected_cells())
if (cell->type == "$macc") { if (cell->type == ID($macc)) {
log("Mapping %s.%s (%s).\n", log_id(mod), log_id(cell), log_id(cell->type)); log("Mapping %s.%s (%s).\n", log_id(mod), log_id(cell), log_id(cell->type));
maccmap(mod, cell, unmap_mode); maccmap(mod, cell, unmap_mode);
mod->remove(cell); mod->remove(cell);

View file

@ -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 != "$_MUX_" || conn.first == "\\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 == "$_MUX_") if (cell->type == ID($_MUX_))
sig_to_mux[sigmap(cell->getPort("\\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("\\A"))); wavefront.insert(sigmap(c->getPort(ID::A)));
wavefront.insert(sigmap(c->getPort("\\B"))); wavefront.insert(sigmap(c->getPort(ID::B)));
} }
} }
@ -516,69 +516,69 @@ 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, "$_MUX_"); Cell *cell = module->addCell(NEW_ID, ID($_MUX_));
cell->setPort("\\A", mux.inputs[0]); cell->setPort(ID::A, mux.inputs[0]);
cell->setPort("\\B", mux.inputs[1]); cell->setPort(ID::B, mux.inputs[1]);
cell->setPort("\\S", mux.selects[0]); cell->setPort(ID(S), mux.selects[0]);
cell->setPort("\\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, "$_MUX4_"); Cell *cell = module->addCell(NEW_ID, ID($_MUX4_));
cell->setPort("\\A", mux.inputs[0]); cell->setPort(ID::A, mux.inputs[0]);
cell->setPort("\\B", mux.inputs[1]); cell->setPort(ID::B, mux.inputs[1]);
cell->setPort("\\C", mux.inputs[2]); cell->setPort(ID(C), mux.inputs[2]);
cell->setPort("\\D", mux.inputs[3]); cell->setPort(ID(D), mux.inputs[3]);
cell->setPort("\\S", mux.selects[0]); cell->setPort(ID(S), mux.selects[0]);
cell->setPort("\\T", mux.selects[1]); cell->setPort(ID(T), mux.selects[1]);
cell->setPort("\\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, "$_MUX8_"); Cell *cell = module->addCell(NEW_ID, ID($_MUX8_));
cell->setPort("\\A", mux.inputs[0]); cell->setPort(ID::A, mux.inputs[0]);
cell->setPort("\\B", mux.inputs[1]); cell->setPort(ID::B, mux.inputs[1]);
cell->setPort("\\C", mux.inputs[2]); cell->setPort(ID(C), mux.inputs[2]);
cell->setPort("\\D", mux.inputs[3]); cell->setPort(ID(D), mux.inputs[3]);
cell->setPort("\\E", mux.inputs[4]); cell->setPort(ID(E), mux.inputs[4]);
cell->setPort("\\F", mux.inputs[5]); cell->setPort(ID(F), mux.inputs[5]);
cell->setPort("\\G", mux.inputs[6]); cell->setPort(ID(G), mux.inputs[6]);
cell->setPort("\\H", mux.inputs[7]); cell->setPort(ID(H), mux.inputs[7]);
cell->setPort("\\S", mux.selects[0]); cell->setPort(ID(S), mux.selects[0]);
cell->setPort("\\T", mux.selects[1]); cell->setPort(ID(T), mux.selects[1]);
cell->setPort("\\U", mux.selects[2]); cell->setPort(ID(U), mux.selects[2]);
cell->setPort("\\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, "$_MUX16_"); Cell *cell = module->addCell(NEW_ID, ID($_MUX16_));
cell->setPort("\\A", mux.inputs[0]); cell->setPort(ID::A, mux.inputs[0]);
cell->setPort("\\B", mux.inputs[1]); cell->setPort(ID::B, mux.inputs[1]);
cell->setPort("\\C", mux.inputs[2]); cell->setPort(ID(C), mux.inputs[2]);
cell->setPort("\\D", mux.inputs[3]); cell->setPort(ID(D), mux.inputs[3]);
cell->setPort("\\E", mux.inputs[4]); cell->setPort(ID(E), mux.inputs[4]);
cell->setPort("\\F", mux.inputs[5]); cell->setPort(ID(F), mux.inputs[5]);
cell->setPort("\\G", mux.inputs[6]); cell->setPort(ID(G), mux.inputs[6]);
cell->setPort("\\H", mux.inputs[7]); cell->setPort(ID(H), mux.inputs[7]);
cell->setPort("\\I", mux.inputs[8]); cell->setPort(ID(I), mux.inputs[8]);
cell->setPort("\\J", mux.inputs[9]); cell->setPort(ID(J), mux.inputs[9]);
cell->setPort("\\K", mux.inputs[10]); cell->setPort(ID(K), mux.inputs[10]);
cell->setPort("\\L", mux.inputs[11]); cell->setPort(ID(L), mux.inputs[11]);
cell->setPort("\\M", mux.inputs[12]); cell->setPort(ID(M), mux.inputs[12]);
cell->setPort("\\N", mux.inputs[13]); cell->setPort(ID(N), mux.inputs[13]);
cell->setPort("\\O", mux.inputs[14]); cell->setPort(ID(O), mux.inputs[14]);
cell->setPort("\\P", mux.inputs[15]); cell->setPort(ID(P), mux.inputs[15]);
cell->setPort("\\S", mux.selects[0]); cell->setPort(ID(S), mux.selects[0]);
cell->setPort("\\T", mux.selects[1]); cell->setPort(ID(T), mux.selects[1]);
cell->setPort("\\U", mux.selects[2]); cell->setPort(ID(U), mux.selects[2]);
cell->setPort("\\V", mux.selects[3]); cell->setPort(ID(V), mux.selects[3]);
cell->setPort("\\Y", bit); cell->setPort(ID::Y, bit);
return; return;
} }

View file

@ -82,10 +82,10 @@ struct NlutmapWorker
for (auto cell : module->cells()) for (auto cell : module->cells())
{ {
if (cell->type != "$lut" || mapped_cells.count(cell)) if (cell->type != ID($lut) || mapped_cells.count(cell))
continue; continue;
if (GetSize(cell->getPort("\\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())
@ -119,7 +119,7 @@ struct NlutmapWorker
if (config.assert_mode) { if (config.assert_mode) {
for (auto cell : module->cells()) for (auto cell : module->cells())
if (cell->type == "$lut" && !mapped_cells.count(cell)) if (cell->type == ID($lut) && !mapped_cells.count(cell))
log_error("Insufficient number of LUTs to map all logic cells!\n"); log_error("Insufficient number of LUTs to map all logic cells!\n");
} }

View file

@ -89,21 +89,21 @@ struct PmuxtreePass : public Pass {
for (auto module : design->selected_modules()) for (auto module : design->selected_modules())
for (auto cell : module->selected_cells()) for (auto cell : module->selected_cells())
{ {
if (cell->type != "$pmux") if (cell->type != ID($pmux))
continue; continue;
SigSpec sig_data = cell->getPort("\\B"); SigSpec sig_data = cell->getPort(ID::B);
SigSpec sig_sel = cell->getPort("\\S"); SigSpec sig_sel = cell->getPort(ID(S));
if (!cell->getPort("\\A").is_fully_undef()) { if (!cell->getPort(ID::A).is_fully_undef()) {
sig_data.append(cell->getPort("\\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("\\Y"), result); module->connect(cell->getPort(ID::Y), result);
module->remove(cell); module->remove(cell);
} }
} }

View file

@ -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("\\D"); auto D = cell->getPort(ID(D));
auto C = cell->getPort("\\C"); auto C = cell->getPort(ID(C));
auto newcell = cell->module->addCell(NEW_ID, "\\GP_SHREG"); auto newcell = cell->module->addCell(NEW_ID, ID(GP_SHREG));
newcell->setPort("\\nRST", State::S1); newcell->setPort(ID(nRST), State::S1);
newcell->setPort("\\CLK", C); newcell->setPort(ID(CLK), C);
newcell->setPort("\\IN", D); newcell->setPort(ID(IN), D);
int i = 0; int i = 0;
for (auto tap : taps) { for (auto tap : taps) {
newcell->setPort(i ? "\\OUTB" : "\\OUTA", tap.second); newcell->setPort(i ? ID(OUTB) : ID(OUTA), tap.second);
newcell->setParam(i ? "\\OUTB_TAP" : "\\OUTA_TAP", tap.first + 1); newcell->setParam(i ? ID(OUTB_TAP) : ID(OUTA_TAP), tap.first + 1);
i++; i++;
} }
cell->setParam("\\OUTA_INVERT", 0); cell->setParam(ID(OUTA_INVERT), 0);
return false; return false;
} }
}; };
@ -104,19 +104,19 @@ 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 == "$shiftx") { if (cell->type == ID($shiftx)) {
if (cell->getParam("\\Y_WIDTH") != 1) continue; if (cell->getParam(ID(Y_WIDTH)) != 1) continue;
int j = 0; int j = 0;
for (auto bit : sigmap(cell->getPort("\\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("\\A_WIDTH").as_int()); log_assert(j == cell->getParam(ID(A_WIDTH)).as_int());
} }
else if (cell->type == "$mux") { else if (cell->type == ID($mux)) {
int j = 0; int j = 0;
for (auto bit : sigmap(cell->getPort("\\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("\\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 == "$shiftx" && port == "\\A") if (cell->type == ID($shiftx) && port == ID::A)
return; return;
if (cell->type == "$mux" && (port == "\\A" || port == "\\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);
@ -177,21 +177,21 @@ struct ShregmapTechXilinx7 : ShregmapTech
log_assert(shiftx); log_assert(shiftx);
// Only map if $shiftx exclusively covers the shift register // Only map if $shiftx exclusively covers the shift register
if (shiftx->type == "$shiftx") { if (shiftx->type == ID($shiftx)) {
if (GetSize(taps) > shiftx->getParam("\\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("\\A_WIDTH").as_int()) { if (GetSize(taps) < shiftx->getParam(ID(A_WIDTH)).as_int()) {
const SigSpec A = shiftx->getPort("\\A"); const SigSpec A = shiftx->getPort(ID::A);
const int A_width = shiftx->getParam("\\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("\\A_WIDTH").as_int()) else if (GetSize(taps) != shiftx->getParam(ID(A_WIDTH)).as_int())
return false; return false;
} }
else if (shiftx->type == "$mux") { else if (shiftx->type == ID($mux)) {
if (GetSize(taps) != 2) if (GetSize(taps) != 2)
return false; return false;
} }
@ -208,34 +208,34 @@ struct ShregmapTechXilinx7 : ShregmapTech
auto it = sigbit_to_shiftx_offset.find(bit); auto it = sigbit_to_shiftx_offset.find(bit);
log_assert(it != sigbit_to_shiftx_offset.end()); log_assert(it != sigbit_to_shiftx_offset.end());
auto newcell = cell->module->addCell(NEW_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("\\DEPTH", cell->getParam("\\DEPTH")); newcell->setParam(ID(DEPTH), cell->getParam(ID(DEPTH)));
newcell->setParam("\\INIT", cell->getParam("\\INIT")); newcell->setParam(ID(INIT), cell->getParam(ID(INIT)));
newcell->setParam("\\CLKPOL", cell->getParam("\\CLKPOL")); newcell->setParam(ID(CLKPOL), cell->getParam(ID(CLKPOL)));
newcell->setParam("\\ENPOL", cell->getParam("\\ENPOL")); newcell->setParam(ID(ENPOL), cell->getParam(ID(ENPOL)));
newcell->setPort("\\C", cell->getPort("\\C")); newcell->setPort(ID(C), cell->getPort(ID(C)));
newcell->setPort("\\D", cell->getPort("\\D")); newcell->setPort(ID(D), cell->getPort(ID(D)));
if (cell->hasPort("\\E")) if (cell->hasPort(ID(E)))
newcell->setPort("\\E", cell->getPort("\\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 == "$shiftx") { if (shiftx->type == ID($shiftx)) {
l_wire = shiftx->getPort("\\B"); l_wire = shiftx->getPort(ID::B);
q_wire = shiftx->getPort("\\Y"); q_wire = shiftx->getPort(ID::Y);
shiftx->setPort("\\Y", cell->module->addWire(NEW_ID)); shiftx->setPort(ID::Y, cell->module->addWire(NEW_ID));
} }
else if (shiftx->type == "$mux") { else if (shiftx->type == ID($mux)) {
l_wire = shiftx->getPort("\\S"); l_wire = shiftx->getPort(ID(S));
q_wire = shiftx->getPort("\\Y"); q_wire = shiftx->getPort(ID::Y);
shiftx->setPort("\\Y", cell->module->addWire(NEW_ID)); shiftx->setPort(ID::Y, cell->module->addWire(NEW_ID));
} }
else log_abort(); else log_abort();
newcell->setPort("\\Q", q_wire); newcell->setPort(ID(Q), q_wire);
newcell->setPort("\\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("\\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("\\init")) { if (wire->attributes.count(ID(init))) {
SigSpec initsig = sigmap(wire); SigSpec initsig = sigmap(wire);
Const initval = wire->attributes.at("\\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("\\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("\\INIT", initval); first_cell->setParam(ID(INIT), initval);
} }
if (opts.zinit) if (opts.zinit)
@ -488,22 +488,22 @@ struct ShregmapWorker
int param_clkpol = -1; int param_clkpol = -1;
int param_enpol = 2; int param_enpol = 2;
if (first_cell->type == "$_DFF_N_") param_clkpol = 0; if (first_cell->type == ID($_DFF_N_)) param_clkpol = 0;
if (first_cell->type == "$_DFF_P_") param_clkpol = 1; if (first_cell->type == ID($_DFF_P_)) param_clkpol = 1;
if (first_cell->type == "$_DFFE_NN_") param_clkpol = 0, param_enpol = 0; if (first_cell->type == ID($_DFFE_NN_)) param_clkpol = 0, param_enpol = 0;
if (first_cell->type == "$_DFFE_NP_") param_clkpol = 0, param_enpol = 1; if (first_cell->type == ID($_DFFE_NP_)) param_clkpol = 0, param_enpol = 1;
if (first_cell->type == "$_DFFE_PN_") param_clkpol = 1, param_enpol = 0; if (first_cell->type == ID($_DFFE_PN_)) param_clkpol = 1, param_enpol = 0;
if (first_cell->type == "$_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("\\CLKPOL", param_clkpol); first_cell->setParam(ID(CLKPOL), param_clkpol);
if (opts.ffe) first_cell->setParam("\\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("\\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("\\init") == 0) if (wire->attributes.count(ID(init)) == 0)
continue; continue;
SigSpec initsig = sigmap(wire); SigSpec initsig = sigmap(wire);
Const &initval = wire->attributes.at("\\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("\\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["$_DFF_P_"] = make_pair(IdString("\\D"), IdString("\\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["$_DFF_N_"] = make_pair(IdString("\\D"), IdString("\\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["$_DFFE_PP_"] = make_pair(IdString("\\D"), IdString("\\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["$_DFFE_PN_"] = make_pair(IdString("\\D"), IdString("\\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["$_DFFE_NP_"] = make_pair(IdString("\\D"), IdString("\\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["$_DFFE_NN_"] = make_pair(IdString("\\D"), IdString("\\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;

View file

@ -28,82 +28,82 @@ 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("\\A"); RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_y = cell->getPort("\\Y"); RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
sig_a.extend_u0(GetSize(sig_y), cell->parameters.at("\\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, "$_NOT_"); RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
gate->setPort("\\A", sig_a[i]); gate->setPort(ID::A, sig_a[i]);
gate->setPort("\\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("\\A"); RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_y = cell->getPort("\\Y"); RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
sig_a.extend_u0(GetSize(sig_y), cell->parameters.at("\\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("\\A"); RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_b = cell->getPort("\\B"); RTLIL::SigSpec sig_b = cell->getPort(ID::B);
RTLIL::SigSpec sig_y = cell->getPort("\\Y"); RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
sig_a.extend_u0(GetSize(sig_y), cell->parameters.at("\\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("\\B_SIGNED").as_bool()); sig_b.extend_u0(GetSize(sig_y), cell->parameters.at(ID(B_SIGNED)).as_bool());
if (cell->type == "$xnor") if (cell->type == ID($xnor))
{ {
RTLIL::SigSpec sig_t = module->addWire(NEW_ID, GetSize(sig_y)); RTLIL::SigSpec sig_t = module->addWire(NEW_ID, GetSize(sig_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, "$_NOT_"); RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
gate->setPort("\\A", sig_t[i]); gate->setPort(ID::A, sig_t[i]);
gate->setPort("\\Y", sig_y[i]); gate->setPort(ID::Y, sig_y[i]);
} }
sig_y = sig_t; sig_y = sig_t;
} }
std::string gate_type; IdString gate_type;
if (cell->type == "$and") gate_type = "$_AND_"; if (cell->type == ID($and)) gate_type = ID($_AND_);
if (cell->type == "$or") gate_type = "$_OR_"; if (cell->type == ID($or)) gate_type = ID($_OR_);
if (cell->type == "$xor") gate_type = "$_XOR_"; if (cell->type == ID($xor)) gate_type = ID($_XOR_);
if (cell->type == "$xnor") gate_type = "$_XOR_"; if (cell->type == ID($xnor)) gate_type = ID($_XOR_);
log_assert(!gate_type.empty()); log_assert(!gate_type.empty());
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("\\src", cell->get_strpool_attribute("\\src")); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
gate->setPort("\\A", sig_a[i]); gate->setPort(ID::A, sig_a[i]);
gate->setPort("\\B", sig_b[i]); gate->setPort(ID::B, sig_b[i]);
gate->setPort("\\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("\\A"); RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_y = cell->getPort("\\Y"); RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
if (sig_y.size() == 0) if (sig_y.size() == 0)
return; return;
if (sig_a.size() == 0) { if (sig_a.size() == 0) {
if (cell->type == "$reduce_and") module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); if (cell->type == ID($reduce_and)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size())));
if (cell->type == "$reduce_or") module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); if (cell->type == ID($reduce_or)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size())));
if (cell->type == "$reduce_xor") module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); if (cell->type == ID($reduce_xor)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size())));
if (cell->type == "$reduce_xnor") module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); if (cell->type == ID($reduce_xnor)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size())));
if (cell->type == "$reduce_bool") module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); if (cell->type == ID($reduce_bool)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size())));
return; return;
} }
@ -112,12 +112,12 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
sig_y = sig_y.extract(0, 1); sig_y = sig_y.extract(0, 1);
} }
std::string gate_type; IdString gate_type;
if (cell->type == "$reduce_and") gate_type = "$_AND_"; if (cell->type == ID($reduce_and)) gate_type = ID($_AND_);
if (cell->type == "$reduce_or") gate_type = "$_OR_"; if (cell->type == ID($reduce_or)) gate_type = ID($_OR_);
if (cell->type == "$reduce_xor") gate_type = "$_XOR_"; if (cell->type == ID($reduce_xor)) gate_type = ID($_XOR_);
if (cell->type == "$reduce_xnor") gate_type = "$_XOR_"; if (cell->type == ID($reduce_xnor)) gate_type = ID($_XOR_);
if (cell->type == "$reduce_bool") gate_type = "$_OR_"; if (cell->type == ID($reduce_bool)) gate_type = ID($_OR_);
log_assert(!gate_type.empty()); log_assert(!gate_type.empty());
RTLIL::Cell *last_output_cell = NULL; RTLIL::Cell *last_output_cell = NULL;
@ -134,22 +134,22 @@ 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("\\src", cell->get_strpool_attribute("\\src")); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
gate->setPort("\\A", sig_a[i]); gate->setPort(ID::A, sig_a[i]);
gate->setPort("\\B", sig_a[i+1]); gate->setPort(ID::B, sig_a[i+1]);
gate->setPort("\\Y", sig_t[i/2]); gate->setPort(ID::Y, sig_t[i/2]);
last_output_cell = gate; last_output_cell = gate;
} }
sig_a = sig_t; sig_a = sig_t;
} }
if (cell->type == "$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, "$_NOT_"); RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
gate->setPort("\\A", sig_a); gate->setPort(ID::A, sig_a);
gate->setPort("\\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("\\Y", sig_y); last_output_cell->setPort(ID::Y, sig_y);
} }
} }
@ -174,11 +174,11 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLIL::Cell
continue; continue;
} }
RTLIL::Cell *gate = module->addCell(NEW_ID, "$_OR_"); RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_OR_));
gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
gate->setPort("\\A", sig[i]); gate->setPort(ID::A, sig[i]);
gate->setPort("\\B", sig[i+1]); gate->setPort(ID::B, sig[i+1]);
gate->setPort("\\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("\\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("\\Y"); RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
if (sig_y.size() == 0) if (sig_y.size() == 0)
return; return;
@ -203,21 +203,21 @@ void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell)
sig_y = sig_y.extract(0, 1); sig_y = sig_y.extract(0, 1);
} }
RTLIL::Cell *gate = module->addCell(NEW_ID, "$_NOT_"); RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
gate->setPort("\\A", sig_a); gate->setPort(ID::A, sig_a);
gate->setPort("\\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("\\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("\\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("\\Y"); RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
if (sig_y.size() == 0) if (sig_y.size() == 0)
return; return;
@ -227,41 +227,41 @@ void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell)
sig_y = sig_y.extract(0, 1); sig_y = sig_y.extract(0, 1);
} }
std::string gate_type; IdString gate_type;
if (cell->type == "$logic_and") gate_type = "$_AND_"; if (cell->type == ID($logic_and)) gate_type = ID($_AND_);
if (cell->type == "$logic_or") gate_type = "$_OR_"; if (cell->type == ID($logic_or)) gate_type = ID($_OR_);
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("\\src", cell->get_strpool_attribute("\\src")); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
gate->setPort("\\A", sig_a); gate->setPort(ID::A, sig_a);
gate->setPort("\\B", sig_b); gate->setPort(ID::B, sig_b);
gate->setPort("\\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("\\A"); RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_b = cell->getPort("\\B"); RTLIL::SigSpec sig_b = cell->getPort(ID::B);
RTLIL::SigSpec sig_y = cell->getPort("\\Y"); RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
bool is_signed = cell->parameters.at("\\A_SIGNED").as_bool(); bool is_signed = cell->parameters.at(ID(A_SIGNED)).as_bool();
bool is_ne = cell->type.in("$ne", "$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("\\src", cell->get_strpool_attribute("\\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("\\src", cell->get_strpool_attribute("\\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("\\src", cell->get_strpool_attribute("\\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("\\A"); RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_b = cell->getPort("\\B"); RTLIL::SigSpec sig_b = cell->getPort(ID::B);
RTLIL::SigSpec sig_y = cell->getPort("\\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, "$_MUX_"); RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_));
gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
gate->setPort("\\A", sig_a[i]); gate->setPort(ID::A, sig_a[i]);
gate->setPort("\\B", sig_b[i]); gate->setPort(ID::B, sig_b[i]);
gate->setPort("\\S", cell->getPort("\\S")); gate->setPort(ID(S), cell->getPort(ID(S)));
gate->setPort("\\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("\\A"); RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_e = cell->getPort("\\EN"); RTLIL::SigSpec sig_e = cell->getPort(ID(EN));
RTLIL::SigSpec sig_y = cell->getPort("\\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, "$_TBUF_"); RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_TBUF_));
gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
gate->setPort("\\A", sig_a[i]); gate->setPort(ID::A, sig_a[i]);
gate->setPort("\\E", sig_e); gate->setPort(ID(E), sig_e);
gate->setPort("\\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("\\A"); SigSpec lut_ctrl = cell->getPort(ID::A);
SigSpec lut_data = cell->getParam("\\LUT"); SigSpec lut_data = cell->getParam(ID(LUT));
lut_data.extend_u0(1 << cell->getParam("\\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, "$_MUX_"); RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_));
gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
gate->setPort("\\A", lut_data[i]); gate->setPort(ID::A, lut_data[i]);
gate->setPort("\\B", lut_data[i+1]); gate->setPort(ID::B, lut_data[i+1]);
gate->setPort("\\S", lut_ctrl[idx]); gate->setPort(ID(S), lut_ctrl[idx]);
gate->setPort("\\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("\\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("\\A"); SigSpec ctrl = cell->getPort(ID::A);
SigSpec table = cell->getParam("\\TABLE"); SigSpec table = cell->getParam(ID(TABLE));
int width = cell->getParam("\\WIDTH").as_int(); int width = cell->getParam(ID(WIDTH)).as_int();
int depth = cell->getParam("\\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,213 +348,213 @@ 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("\\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("\\OFFSET").as_int(); int offset = cell->parameters.at(ID(OFFSET)).as_int();
RTLIL::SigSpec sig_a = cell->getPort("\\A"); RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_y = cell->getPort("\\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("\\A"); RTLIL::SigSpec sig_ab = cell->getPort(ID::A);
sig_ab.append(cell->getPort("\\B")); sig_ab.append(cell->getPort(ID::B));
RTLIL::SigSpec sig_y = cell->getPort("\\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("\\WIDTH").as_int(); int width = cell->parameters.at(ID(WIDTH)).as_int();
char set_pol = cell->parameters.at("\\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("\\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("\\SET"); RTLIL::SigSpec sig_s = cell->getPort(ID(SET));
RTLIL::SigSpec sig_r = cell->getPort("\\CLR"); RTLIL::SigSpec sig_r = cell->getPort(ID(CLR));
RTLIL::SigSpec sig_q = cell->getPort("\\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("\\src", cell->get_strpool_attribute("\\src")); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
gate->setPort("\\S", sig_s[i]); gate->setPort(ID(S), sig_s[i]);
gate->setPort("\\R", sig_r[i]); gate->setPort(ID(R), sig_r[i]);
gate->setPort("\\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("\\WIDTH").as_int(); int width = cell->parameters.at(ID(WIDTH)).as_int();
RTLIL::SigSpec sig_d = cell->getPort("\\D"); RTLIL::SigSpec sig_d = cell->getPort(ID(D));
RTLIL::SigSpec sig_q = cell->getPort("\\Q"); RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
std::string gate_type = "$_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("\\src", cell->get_strpool_attribute("\\src")); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
gate->setPort("\\D", sig_d[i]); gate->setPort(ID(D), sig_d[i]);
gate->setPort("\\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("\\WIDTH").as_int(); int width = cell->parameters.at(ID(WIDTH)).as_int();
char clk_pol = cell->parameters.at("\\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("\\CLK"); RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK));
RTLIL::SigSpec sig_d = cell->getPort("\\D"); RTLIL::SigSpec sig_d = cell->getPort(ID(D));
RTLIL::SigSpec sig_q = cell->getPort("\\Q"); RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
std::string 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("\\src", cell->get_strpool_attribute("\\src")); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
gate->setPort("\\C", sig_clk); gate->setPort(ID(C), sig_clk);
gate->setPort("\\D", sig_d[i]); gate->setPort(ID(D), sig_d[i]);
gate->setPort("\\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("\\WIDTH").as_int(); int width = cell->parameters.at(ID(WIDTH)).as_int();
char clk_pol = cell->parameters.at("\\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("\\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("\\CLK"); RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK));
RTLIL::SigSpec sig_en = cell->getPort("\\EN"); RTLIL::SigSpec sig_en = cell->getPort(ID(EN));
RTLIL::SigSpec sig_d = cell->getPort("\\D"); RTLIL::SigSpec sig_d = cell->getPort(ID(D));
RTLIL::SigSpec sig_q = cell->getPort("\\Q"); RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
std::string 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("\\src", cell->get_strpool_attribute("\\src")); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
gate->setPort("\\C", sig_clk); gate->setPort(ID(C), sig_clk);
gate->setPort("\\E", sig_en); gate->setPort(ID(E), sig_en);
gate->setPort("\\D", sig_d[i]); gate->setPort(ID(D), sig_d[i]);
gate->setPort("\\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("\\WIDTH").as_int(); int width = cell->parameters.at(ID(WIDTH)).as_int();
char clk_pol = cell->parameters.at("\\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("\\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("\\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("\\CLK"); RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK));
RTLIL::SigSpec sig_s = cell->getPort("\\SET"); RTLIL::SigSpec sig_s = cell->getPort(ID(SET));
RTLIL::SigSpec sig_r = cell->getPort("\\CLR"); RTLIL::SigSpec sig_r = cell->getPort(ID(CLR));
RTLIL::SigSpec sig_d = cell->getPort("\\D"); RTLIL::SigSpec sig_d = cell->getPort(ID(D));
RTLIL::SigSpec sig_q = cell->getPort("\\Q"); RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
std::string 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("\\src", cell->get_strpool_attribute("\\src")); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
gate->setPort("\\C", sig_clk); gate->setPort(ID(C), sig_clk);
gate->setPort("\\S", sig_s[i]); gate->setPort(ID(S), sig_s[i]);
gate->setPort("\\R", sig_r[i]); gate->setPort(ID(R), sig_r[i]);
gate->setPort("\\D", sig_d[i]); gate->setPort(ID(D), sig_d[i]);
gate->setPort("\\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("\\WIDTH").as_int(); int width = cell->parameters.at(ID(WIDTH)).as_int();
char clk_pol = cell->parameters.at("\\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("\\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("\\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("\\CLK"); RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK));
RTLIL::SigSpec sig_rst = cell->getPort("\\ARST"); RTLIL::SigSpec sig_rst = cell->getPort(ID(ARST));
RTLIL::SigSpec sig_d = cell->getPort("\\D"); RTLIL::SigSpec sig_d = cell->getPort(ID(D));
RTLIL::SigSpec sig_q = cell->getPort("\\Q"); RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
std::string gate_type_0 = stringf("$_DFF_%c%c0_", clk_pol, rst_pol); IdString gate_type_0 = stringf("$_DFF_%c%c0_", clk_pol, rst_pol);
std::string 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("\\src", cell->get_strpool_attribute("\\src")); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
gate->setPort("\\C", sig_clk); gate->setPort(ID(C), sig_clk);
gate->setPort("\\R", sig_rst); gate->setPort(ID(R), sig_rst);
gate->setPort("\\D", sig_d[i]); gate->setPort(ID(D), sig_d[i]);
gate->setPort("\\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("\\WIDTH").as_int(); int width = cell->parameters.at(ID(WIDTH)).as_int();
char en_pol = cell->parameters.at("\\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("\\EN"); RTLIL::SigSpec sig_en = cell->getPort(ID(EN));
RTLIL::SigSpec sig_d = cell->getPort("\\D"); RTLIL::SigSpec sig_d = cell->getPort(ID(D));
RTLIL::SigSpec sig_q = cell->getPort("\\Q"); RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
std::string 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("\\src", cell->get_strpool_attribute("\\src")); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
gate->setPort("\\E", sig_en); gate->setPort(ID(E), sig_en);
gate->setPort("\\D", sig_d[i]); gate->setPort(ID(D), sig_d[i]);
gate->setPort("\\Q", sig_q[i]); gate->setPort(ID(Q), sig_q[i]);
} }
} }
void simplemap_get_mappers(std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> &mappers) void simplemap_get_mappers(std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> &mappers)
{ {
mappers["$not"] = simplemap_not; mappers[ID($not)] = simplemap_not;
mappers["$pos"] = simplemap_pos; mappers[ID($pos)] = simplemap_pos;
mappers["$and"] = simplemap_bitop; mappers[ID($and)] = simplemap_bitop;
mappers["$or"] = simplemap_bitop; mappers[ID($or)] = simplemap_bitop;
mappers["$xor"] = simplemap_bitop; mappers[ID($xor)] = simplemap_bitop;
mappers["$xnor"] = simplemap_bitop; mappers[ID($xnor)] = simplemap_bitop;
mappers["$reduce_and"] = simplemap_reduce; mappers[ID($reduce_and)] = simplemap_reduce;
mappers["$reduce_or"] = simplemap_reduce; mappers[ID($reduce_or)] = simplemap_reduce;
mappers["$reduce_xor"] = simplemap_reduce; mappers[ID($reduce_xor)] = simplemap_reduce;
mappers["$reduce_xnor"] = simplemap_reduce; mappers[ID($reduce_xnor)] = simplemap_reduce;
mappers["$reduce_bool"] = simplemap_reduce; mappers[ID($reduce_bool)] = simplemap_reduce;
mappers["$logic_not"] = simplemap_lognot; mappers[ID($logic_not)] = simplemap_lognot;
mappers["$logic_and"] = simplemap_logbin; mappers[ID($logic_and)] = simplemap_logbin;
mappers["$logic_or"] = simplemap_logbin; mappers[ID($logic_or)] = simplemap_logbin;
mappers["$eq"] = simplemap_eqne; mappers[ID($eq)] = simplemap_eqne;
mappers["$eqx"] = simplemap_eqne; mappers[ID($eqx)] = simplemap_eqne;
mappers["$ne"] = simplemap_eqne; mappers[ID($ne)] = simplemap_eqne;
mappers["$nex"] = simplemap_eqne; mappers[ID($nex)] = simplemap_eqne;
mappers["$mux"] = simplemap_mux; mappers[ID($mux)] = simplemap_mux;
mappers["$tribuf"] = simplemap_tribuf; mappers[ID($tribuf)] = simplemap_tribuf;
mappers["$lut"] = simplemap_lut; mappers[ID($lut)] = simplemap_lut;
mappers["$sop"] = simplemap_sop; mappers[ID($sop)] = simplemap_sop;
mappers["$slice"] = simplemap_slice; mappers[ID($slice)] = simplemap_slice;
mappers["$concat"] = simplemap_concat; mappers[ID($concat)] = simplemap_concat;
mappers["$sr"] = simplemap_sr; mappers[ID($sr)] = simplemap_sr;
mappers["$ff"] = simplemap_ff; mappers[ID($ff)] = simplemap_ff;
mappers["$dff"] = simplemap_dff; mappers[ID($dff)] = simplemap_dff;
mappers["$dffe"] = simplemap_dffe; mappers[ID($dffe)] = simplemap_dffe;
mappers["$dffsr"] = simplemap_dffsr; mappers[ID($dffsr)] = simplemap_dffsr;
mappers["$adff"] = simplemap_adff; mappers[ID($adff)] = simplemap_adff;
mappers["$dlatch"] = simplemap_dlatch; mappers[ID($dlatch)] = simplemap_dlatch;
} }
void simplemap(RTLIL::Module *module, RTLIL::Cell *cell) void simplemap(RTLIL::Module *module, RTLIL::Cell *cell)

View file

@ -39,20 +39,20 @@ YOSYS_NAMESPACE_END
USING_YOSYS_NAMESPACE USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN PRIVATE_NAMESPACE_BEGIN
void apply_prefix(std::string prefix, std::string &id) void apply_prefix(IdString prefix, IdString &id)
{ {
if (id[0] == '\\') if (id[0] == '\\')
id = prefix + "." + id.substr(1); id = stringf("%s.%s", prefix.c_str(), id.c_str()+1);
else else
id = "$techmap" + prefix + "." + id; id = stringf("$techmap%s.%s", prefix.c_str(), id.c_str());
} }
void apply_prefix(std::string prefix, RTLIL::SigSpec &sig, RTLIL::Module *module) void apply_prefix(IdString prefix, RTLIL::SigSpec &sig, RTLIL::Module *module)
{ {
vector<SigChunk> chunks = sig; vector<SigChunk> chunks = sig;
for (auto &chunk : chunks) for (auto &chunk : chunks)
if (chunk.wire != NULL) { if (chunk.wire != NULL) {
std::string wire_name = chunk.wire->name.str(); IdString wire_name = chunk.wire->name;
apply_prefix(prefix, wire_name); apply_prefix(prefix, wire_name);
log_assert(module->wires_.count(wire_name) > 0); log_assert(module->wires_.count(wire_name) > 0);
chunk.wire = module->wires_[wire_name]; chunk.wire = module->wires_[wire_name];
@ -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["\\keep"] = RTLIL::Const(1); it.second->attributes[ID::keep] = RTLIL::Const(1);
it.second->attributes["\\_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("\\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 == "\\_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;
@ -189,16 +189,16 @@ struct TechmapWorker
dict<IdString, IdString> memory_renames; dict<IdString, IdString> memory_renames;
for (auto &it : tpl->memories) { for (auto &it : tpl->memories) {
std::string m_name = it.first.str(); IdString m_name = it.first;
apply_prefix(cell->name.str(), m_name); apply_prefix(cell->name, m_name);
RTLIL::Memory *m = new RTLIL::Memory; RTLIL::Memory *m = new RTLIL::Memory;
m->name = m_name; m->name = m_name;
m->width = it.second->width; m->width = it.second->width;
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("\\src")) if (m->attributes.count(ID(src)))
m->add_strpool_attribute("\\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);
@ -209,16 +209,16 @@ struct TechmapWorker
for (auto &it : tpl->wires_) { for (auto &it : tpl->wires_) {
if (it.second->port_id > 0) if (it.second->port_id > 0)
positional_ports[stringf("$%d", it.second->port_id)] = it.first; positional_ports[stringf("$%d", it.second->port_id)] = it.first;
std::string w_name = it.second->name.str(); IdString w_name = it.second->name;
apply_prefix(cell->name.str(), w_name); apply_prefix(cell->name, w_name);
RTLIL::Wire *w = module->addWire(w_name, it.second); RTLIL::Wire *w = module->addWire(w_name, it.second);
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("\\_techmap_special_")) if (it.second->get_bool_attribute(ID(_techmap_special_)))
w->attributes.clear(); w->attributes.clear();
if (w->attributes.count("\\src")) if (w->attributes.count(ID(src)))
w->add_strpool_attribute("\\src", extra_src_attrs); w->add_strpool_attribute(ID(src), extra_src_attrs);
design->select(module, w); design->select(module, w);
} }
@ -257,18 +257,18 @@ struct TechmapWorker
if (w->port_output && !w->port_input) { if (w->port_output && !w->port_input) {
c.first = it.second; c.first = it.second;
c.second = RTLIL::SigSpec(w); c.second = RTLIL::SigSpec(w);
apply_prefix(cell->name.str(), c.second, module); apply_prefix(cell->name, c.second, module);
extra_connect.first = c.second; extra_connect.first = c.second;
extra_connect.second = c.first; extra_connect.second = c.first;
} else if (!w->port_output && w->port_input) { } else if (!w->port_output && w->port_input) {
c.first = RTLIL::SigSpec(w); c.first = RTLIL::SigSpec(w);
c.second = it.second; c.second = it.second;
apply_prefix(cell->name.str(), c.first, module); apply_prefix(cell->name, c.first, module);
extra_connect.first = c.first; extra_connect.first = c.first;
extra_connect.second = c.second; extra_connect.second = c.second;
} else { } else {
SigSpec sig_tpl = w, sig_tpl_pf = w, sig_mod = it.second; SigSpec sig_tpl = w, sig_tpl_pf = w, sig_mod = it.second;
apply_prefix(cell->name.str(), sig_tpl_pf, module); apply_prefix(cell->name, sig_tpl_pf, module);
for (int i = 0; i < GetSize(sig_tpl) && i < GetSize(sig_mod); i++) { for (int i = 0; i < GetSize(sig_tpl) && i < GetSize(sig_mod); i++) {
if (tpl_written_bits.count(tpl_sigmap(sig_tpl[i]))) { if (tpl_written_bits.count(tpl_sigmap(sig_tpl[i]))) {
c.first.append(sig_mod[i]); c.first.append(sig_mod[i]);
@ -320,7 +320,7 @@ struct TechmapWorker
} }
for (auto &attr : w->attributes) { for (auto &attr : w->attributes) {
if (attr.first == "\\src") if (attr.first == ID(src))
continue; continue;
module->connect(extra_connect); module->connect(extra_connect);
break; break;
@ -330,13 +330,13 @@ struct TechmapWorker
for (auto &it : tpl->cells_) for (auto &it : tpl->cells_)
{ {
std::string c_name = it.second->name.str(); IdString c_name = it.second->name.str();
bool techmap_replace_cell = (!flatten_mode) && (c_name == "\\_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;
else else
apply_prefix(cell->name.str(), c_name); apply_prefix(cell->name, c_name);
RTLIL::Cell *c = module->addCell(c_name, it.second); RTLIL::Cell *c = module->addCell(c_name, it.second);
design->select(module, c); design->select(module, c);
@ -345,24 +345,24 @@ struct TechmapWorker
c->type = c->type.substr(1); c->type = c->type.substr(1);
for (auto &it2 : c->connections_) { for (auto &it2 : c->connections_) {
apply_prefix(cell->name.str(), it2.second, module); apply_prefix(cell->name, it2.second, module);
port_signal_map.apply(it2.second); port_signal_map.apply(it2.second);
} }
if (c->type == "$memrd" || c->type == "$memwr" || c->type == "$meminit") { if (c->type.in(ID($memrd), ID($memwr), ID($meminit))) {
IdString memid = c->getParam("\\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("\\MEMID", Const(memory_renames[memid].str())); c->setParam(ID(MEMID), Const(memory_renames[memid].str()));
} }
if (c->type == "$mem") { if (c->type == ID($mem)) {
string memid = c->getParam("\\MEMID").decode_string(); IdString memid = c->getParam(ID(MEMID)).decode_string();
apply_prefix(cell->name.str(), memid); apply_prefix(cell->name, memid);
c->setParam("\\MEMID", Const(memid)); c->setParam(ID(MEMID), Const(memid.c_str()));
} }
if (c->attributes.count("\\src")) if (c->attributes.count(ID(src)))
c->add_strpool_attribute("\\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("\\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("\\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("\\techmap_simplemap")) if (tpl->get_bool_attribute(ID(techmap_simplemap)))
extmapper_name = "simplemap"; extmapper_name = "simplemap";
if (tpl->get_bool_attribute("\\techmap_maccmap")) if (tpl->get_bool_attribute(ID(techmap_maccmap)))
extmapper_name = "maccmap"; extmapper_name = "maccmap";
if (tpl->attributes.count("\\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("\\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 == "\\Y" || w->name == "\\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;
@ -541,14 +541,14 @@ struct TechmapWorker
if (extmapper_name == "maccmap") { if (extmapper_name == "maccmap") {
log("Creating %s with maccmap.\n", log_id(extmapper_module)); log("Creating %s with maccmap.\n", log_id(extmapper_module));
if (extmapper_cell->type != "$macc") if (extmapper_cell->type != ID($macc))
log_error("The maccmap mapper can only map $macc (not %s) cells!\n", log_id(extmapper_cell->type)); log_error("The maccmap mapper can only map $macc (not %s) cells!\n", log_id(extmapper_cell->type));
maccmap(extmapper_module, extmapper_cell); maccmap(extmapper_module, extmapper_cell);
extmapper_module->remove(extmapper_cell); extmapper_module->remove(extmapper_cell);
} }
if (extmapper_name == "wrap") { if (extmapper_name == "wrap") {
std::string cmd_string = tpl->attributes.at("\\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);
@ -587,7 +587,7 @@ struct TechmapWorker
} }
if (extmapper_name == "maccmap") { if (extmapper_name == "maccmap") {
if (cell->type != "$macc") if (cell->type != ID($macc))
log_error("The maccmap mapper can only map $macc (not %s) cells!\n", log_id(cell->type)); log_error("The maccmap mapper can only map $macc (not %s) cells!\n", log_id(cell->type));
maccmap(module, cell); maccmap(module, cell);
} }
@ -616,8 +616,8 @@ struct TechmapWorker
continue; continue;
} }
if (tpl->avail_parameters.count("\\_TECHMAP_CELLTYPE_") != 0) if (tpl->avail_parameters.count(ID(_TECHMAP_CELLTYPE_)) != 0)
parameters["\\_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("\\_TECHMAP_BITS_CONNMAP_")) if (tpl->avail_parameters.count(ID(_TECHMAP_BITS_CONNMAP_)))
parameters["\\_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("\\techmap_celltype") && !it.second->attributes.at("\\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("\\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("\\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;

View file

@ -63,38 +63,38 @@ struct TribufWorker {
for (auto cell : module->selected_cells()) for (auto cell : module->selected_cells())
{ {
if (cell->type == "$tribuf") if (cell->type == ID($tribuf))
tribuf_cells[sigmap(cell->getPort("\\Y"))].push_back(cell); tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell);
if (cell->type == "$_TBUF_") if (cell->type == ID($_TBUF_))
tribuf_cells[sigmap(cell->getPort("\\Y"))].push_back(cell); tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell);
if (cell->type.in("$mux", "$_MUX_")) if (cell->type.in(ID($mux), ID($_MUX_)))
{ {
IdString en_port = cell->type == "$mux" ? "\\EN" : "\\E"; IdString en_port = cell->type == ID($mux) ? ID(EN) : ID(E);
IdString tri_type = cell->type == "$mux" ? "$tribuf" : "$_TBUF_"; IdString tri_type = cell->type == ID($mux) ? ID($tribuf) : ID($_TBUF_);
if (is_all_z(cell->getPort("\\A")) && is_all_z(cell->getPort("\\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("\\A"))) { if (is_all_z(cell->getPort(ID::A))) {
cell->setPort("\\A", cell->getPort("\\B")); cell->setPort(ID::A, cell->getPort(ID::B));
cell->setPort(en_port, cell->getPort("\\S")); cell->setPort(en_port, cell->getPort(ID(S)));
cell->unsetPort("\\B"); cell->unsetPort(ID::B);
cell->unsetPort("\\S"); cell->unsetPort(ID(S));
cell->type = tri_type; cell->type = tri_type;
tribuf_cells[sigmap(cell->getPort("\\Y"))].push_back(cell); tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell);
continue; continue;
} }
if (is_all_z(cell->getPort("\\B"))) { if (is_all_z(cell->getPort(ID::B))) {
cell->setPort(en_port, module->Not(NEW_ID, cell->getPort("\\S"))); cell->setPort(en_port, module->Not(NEW_ID, cell->getPort(ID(S))));
cell->unsetPort("\\B"); cell->unsetPort(ID::B);
cell->unsetPort("\\S"); cell->unsetPort(ID(S));
cell->type = tri_type; cell->type = tri_type;
tribuf_cells[sigmap(cell->getPort("\\Y"))].push_back(cell); tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell);
continue; continue;
} }
} }
@ -118,11 +118,11 @@ 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 == "$tribuf") if (cell->type == ID($tribuf))
pmux_s.append(cell->getPort("\\EN")); pmux_s.append(cell->getPort(ID(EN)));
else else
pmux_s.append(cell->getPort("\\E")); pmux_s.append(cell->getPort(ID(E)));
pmux_b.append(cell->getPort("\\A")); pmux_b.append(cell->getPort(ID::A));
module->remove(cell); module->remove(cell);
} }

View file

@ -62,12 +62,12 @@ struct ZinitPass : public Pass {
for (auto wire : module->selected_wires()) for (auto wire : module->selected_wires())
{ {
if (wire->attributes.count("\\init") == 0) if (wire->attributes.count(ID(init)) == 0)
continue; continue;
SigSpec wirebits = sigmap(wire); SigSpec wirebits = sigmap(wire);
Const initval = wire->attributes.at("\\init"); Const initval = wire->attributes.at(ID(init));
wire->attributes.erase("\\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++)
{ {
@ -90,12 +90,12 @@ struct ZinitPass : public Pass {
} }
pool<IdString> dff_types = { pool<IdString> dff_types = {
"$ff", "$dff", "$dffe", "$dffsr", "$adff", ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($adff),
"$_FF_", "$_DFFE_NN_", "$_DFFE_NP_", "$_DFFE_PN_", "$_DFFE_PP_", ID($_FF_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_),
"$_DFFSR_NNN_", "$_DFFSR_NNP_", "$_DFFSR_NPN_", "$_DFFSR_NPP_", ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_),
"$_DFFSR_PNN_", "$_DFFSR_PNP_", "$_DFFSR_PPN_", "$_DFFSR_PPP_", ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_),
"$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", ID($_DFF_N_), ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_),
"$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1_", "$_DFF_PP0_", "$_DFF_PP1_" ID($_DFF_P_), ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_)
}; };
for (auto cell : module->selected_cells()) for (auto cell : module->selected_cells())
@ -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("\\D")); SigSpec sig_d = sigmap(cell->getPort(ID(D)));
SigSpec sig_q = sigmap(cell->getPort("\\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["\\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["\\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("\\D", sig_d); cell->setPort(ID(D), sig_d);
cell->setPort("\\Q", initwire); cell->setPort(ID(Q), initwire);
} }
for (auto &it : initbits) for (auto &it : initbits)

View file

@ -43,7 +43,7 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type,
RTLIL::Cell *cell = module->addCell("\\UUT", cell_type); RTLIL::Cell *cell = module->addCell("\\UUT", cell_type);
RTLIL::Wire *wire; RTLIL::Wire *wire;
if (cell_type == "$mux" || cell_type == "$pmux") if (cell_type.in("$mux", "$pmux"))
{ {
int width = 1 + xorshift32(8); int width = 1 + xorshift32(8);
int swidth = cell_type == "$mux" ? 1 : 1 + xorshift32(8); int swidth = cell_type == "$mux" ? 1 : 1 + xorshift32(8);
@ -264,7 +264,7 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type,
cell->setPort("\\Y", wire); cell->setPort("\\Y", wire);
} }
if (muxdiv && (cell_type == "$div" || cell_type == "$mod")) { if (muxdiv && cell_type.in("$div", "$mod")) {
auto b_not_zero = module->ReduceBool(NEW_ID, cell->getPort("\\B")); auto b_not_zero = module->ReduceBool(NEW_ID, cell->getPort("\\B"));
auto div_out = module->addWire(NEW_ID, GetSize(cell->getPort("\\Y"))); auto div_out = module->addWire(NEW_ID, GetSize(cell->getPort("\\Y")));
module->addMux(NEW_ID, RTLIL::SigSpec(0, GetSize(div_out)), div_out, b_not_zero, cell->getPort("\\Y")); module->addMux(NEW_ID, RTLIL::SigSpec(0, GetSize(div_out)), div_out, b_not_zero, cell->getPort("\\Y"));

View file

@ -15,10 +15,13 @@ module L6MUX21 (input D0, D1, SD, output Z);
endmodule endmodule
// --------------------------------------- // ---------------------------------------
(* abc_box_id=1, abc_carry="CIN,COUT", lib_whitebox *) (* abc_box_id=1, lib_whitebox *)
module CCU2C(input CIN, A0, B0, C0, D0, A1, B1, C1, D1, module CCU2C(
output S0, S1, COUT); (* abc_carry *) input CIN,
input A0, B0, C0, D0, A1, B1, C1, D1,
output S0, S1,
(* abc_carry *) output COUT
);
parameter [15:0] INIT0 = 16'h0000; parameter [15:0] INIT0 = 16'h0000;
parameter [15:0] INIT1 = 16'h0000; parameter [15:0] INIT1 = 16'h0000;
parameter INJECT1_0 = "YES"; parameter INJECT1_0 = "YES";
@ -104,11 +107,12 @@ module PFUMX (input ALUT, BLUT, C0, output Z);
endmodule endmodule
// --------------------------------------- // ---------------------------------------
//(* abc_box_id=2, abc_scc_break="DI,WAD,WRE" *) //(* abc_box_id=2 *)
module TRELLIS_DPR16X4 ( module TRELLIS_DPR16X4 (
input [3:0] DI, (* abc_scc_break *) input [3:0] DI,
input [3:0] WAD, (* abc_scc_break *) input [3:0] WAD,
input WRE, WCK, (* abc_scc_break *) input WRE,
input WCK,
input [3:0] RAD, input [3:0] RAD,
output [3:0] DO output [3:0] DO
); );

View file

@ -4,7 +4,6 @@ OBJS += techlibs/ice40/ice40_braminit.o
OBJS += techlibs/ice40/ice40_ffssr.o OBJS += techlibs/ice40/ice40_ffssr.o
OBJS += techlibs/ice40/ice40_ffinit.o OBJS += techlibs/ice40/ice40_ffinit.o
OBJS += techlibs/ice40/ice40_opt.o OBJS += techlibs/ice40/ice40_opt.o
OBJS += techlibs/ice40/ice40_unlut.o
GENFILES += techlibs/ice40/brams_init1.vh GENFILES += techlibs/ice40/brams_init1.vh
GENFILES += techlibs/ice40/brams_init2.vh GENFILES += techlibs/ice40/brams_init2.vh

View file

@ -44,35 +44,21 @@ module _80_ice40_alu (A, B, CI, BI, X, Y, CO);
genvar i; genvar i;
generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice
`ifdef _ABC \$__ICE40_CARRY_WRAPPER #(
\$__ICE40_FULL_ADDER carry ( // A[0]: 1010 1010 1010 1010
// A[1]: 1100 1100 1100 1100
// A[2]: 1111 0000 1111 0000
// A[3]: 1111 1111 0000 0000
.LUT(16'b 0110_1001_1001_0110)
) fadd (
.A(AA[i]), .A(AA[i]),
.B(BB[i]), .B(BB[i]),
.CI(C[i]), .CI(C[i]),
.I0(1'b0),
.I3(C[i]),
.CO(CO[i]), .CO(CO[i]),
.O(Y[i]) .O(Y[i])
); );
`else
SB_CARRY carry (
.I0(AA[i]),
.I1(BB[i]),
.CI(C[i]),
.CO(CO[i])
);
SB_LUT4 #(
// I0: 1010 1010 1010 1010
// I1: 1100 1100 1100 1100
// I2: 1111 0000 1111 0000
// I3: 1111 1111 0000 0000
.LUT_INIT(16'b 0110_1001_1001_0110)
) adder (
.I0(1'b0),
.I1(AA[i]),
.I2(BB[i]),
.I3(C[i]),
.O(Y[i])
);
`endif
end endgenerate end endgenerate
assign X = AA ^ BB; assign X = AA ^ BB;

View file

@ -62,26 +62,21 @@ module \$lut (A, Y);
endmodule endmodule
`endif `endif
`ifdef _ABC `ifndef NO_ADDER
module \$__ICE40_FULL_ADDER (output CO, O, input A, B, CI); module \$__ICE40_CARRY_WRAPPER (output CO, O, input A, B, CI, I0, I3);
parameter LUT = 0;
SB_CARRY carry ( SB_CARRY carry (
.I0(A), .I0(A),
.I1(B), .I1(B),
.CI(CI), .CI(CI),
.CO(CO) .CO(CO)
); );
SB_LUT4 #( \$lut #(
// I0: 1010 1010 1010 1010 .WIDTH(4),
// I1: 1100 1100 1100 1100 .LUT(LUT)
// I2: 1111 0000 1111 0000 ) lut (
// I3: 1111 1111 0000 0000 .A({I0,A,B,I3}),
.LUT_INIT(16'b 0110_1001_1001_0110) .Y(O)
) adder (
.I0(1'b0),
.I1(A),
.I2(B),
.I3(CI),
.O(O)
); );
endmodule endmodule
`endif `endif

View file

@ -141,8 +141,14 @@ module SB_CARRY (output CO, input I0, I1, CI);
assign CO = (I0 && I1) || ((I0 || I1) && CI); assign CO = (I0 && I1) || ((I0 || I1) && CI);
endmodule endmodule
(* abc_box_id = 1, abc_carry="CI,CO", lib_whitebox *) (* abc_box_id = 1, lib_whitebox *)
module \$__ICE40_FULL_ADDER (output CO, O, input A, B, CI); module \$__ICE40_FULL_ADDER (
(* abc_carry *) output CO,
output O,
input A,
input B,
(* abc_carry *) input CI
);
SB_CARRY carry ( SB_CARRY carry (
.I0(A), .I0(A),
.I1(B), .I1(B),

View file

@ -1,106 +0,0 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "kernel/yosys.h"
#include "kernel/sigtools.h"
#include <stdlib.h>
#include <stdio.h>
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
static SigBit get_bit_or_zero(const SigSpec &sig)
{
if (GetSize(sig) == 0)
return State::S0;
return sig[0];
}
static void run_ice40_unlut(Module *module)
{
SigMap sigmap(module);
for (auto cell : module->selected_cells())
{
if (cell->type == "\\SB_LUT4")
{
SigSpec inbits;
inbits.append(get_bit_or_zero(cell->getPort("\\I0")));
inbits.append(get_bit_or_zero(cell->getPort("\\I1")));
inbits.append(get_bit_or_zero(cell->getPort("\\I2")));
inbits.append(get_bit_or_zero(cell->getPort("\\I3")));
sigmap.apply(inbits);
log("Mapping SB_LUT4 cell %s.%s to $lut.\n", log_id(module), log_id(cell));
cell->type ="$lut";
cell->setParam("\\WIDTH", 4);
cell->setParam("\\LUT", cell->getParam("\\LUT_INIT"));
cell->unsetParam("\\LUT_INIT");
cell->setPort("\\A", SigSpec({
get_bit_or_zero(cell->getPort("\\I0")),
get_bit_or_zero(cell->getPort("\\I1")),
get_bit_or_zero(cell->getPort("\\I2")),
get_bit_or_zero(cell->getPort("\\I3"))
}));
cell->setPort("\\Y", cell->getPort("\\O")[0]);
cell->unsetPort("\\I0");
cell->unsetPort("\\I1");
cell->unsetPort("\\I2");
cell->unsetPort("\\I3");
cell->unsetPort("\\O");
cell->check();
}
}
}
struct Ice40UnlutPass : public Pass {
Ice40UnlutPass() : Pass("ice40_unlut", "iCE40: transform SB_LUT4 cells to $lut cells") { }
void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" ice40_unlut [options] [selection]\n");
log("\n");
log("This command transforms all SB_LUT4 cells to generic $lut cells.\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing ICE40_UNLUT pass (convert SB_LUT4 to $lut).\n");
log_push();
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) {
// if (args[argidx] == "-???") {
// continue;
// }
break;
}
extra_args(args, argidx, design);
for (auto module : design->selected_modules())
run_ice40_unlut(module);
}
} Ice40UnlutPass;
PRIVATE_NAMESPACE_END

View file

@ -238,7 +238,7 @@ struct SynthIce40Pass : public ScriptPass
{ {
if (check_label("begin")) if (check_label("begin"))
{ {
run("read_verilog -icells -lib -D_ABC +/ice40/cells_sim.v"); run("read_verilog -icells -lib +/ice40/cells_sim.v");
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str())); run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
run("proc"); run("proc");
} }
@ -298,8 +298,10 @@ struct SynthIce40Pass : public ScriptPass
{ {
if (nocarry) if (nocarry)
run("techmap"); run("techmap");
else else {
run("techmap -map +/techmap.v -map +/ice40/arith_map.v" + std::string(abc == "abc9" ? " -D _ABC" : "")); run("ice40_wrapcarry");
run("techmap -map +/techmap.v -map +/ice40/arith_map.v");
}
if (retime || help_mode) if (retime || help_mode)
run(abc + " -dff", "(only if -retime)"); run(abc + " -dff", "(only if -retime)");
run("ice40_opt"); run("ice40_opt");
@ -314,7 +316,7 @@ struct SynthIce40Pass : public ScriptPass
run("opt_merge"); run("opt_merge");
run(stringf("dff2dffe -unmap-mince %d", min_ce_use)); run(stringf("dff2dffe -unmap-mince %d", min_ce_use));
} }
run("techmap -D NO_LUT -map +/ice40/cells_map.v"); run("techmap -D NO_LUT -D NO_ADDER -map +/ice40/cells_map.v");
run("opt_expr -mux_undef"); run("opt_expr -mux_undef");
run("simplemap"); run("simplemap");
run("ice40_ffinit"); run("ice40_ffinit");
@ -343,13 +345,12 @@ struct SynthIce40Pass : public ScriptPass
else else
wire_delay = 250; wire_delay = 250;
run(abc + stringf(" -W %d -lut +/ice40/abc_%s.lut -box +/ice40/abc_%s.box", wire_delay, device_opt.c_str(), device_opt.c_str()), "(skip if -noabc)"); run(abc + stringf(" -W %d -lut +/ice40/abc_%s.lut -box +/ice40/abc_%s.box", wire_delay, device_opt.c_str(), device_opt.c_str()), "(skip if -noabc)");
run("techmap -D NO_LUT -D _ABC -map +/ice40/cells_map.v");
} }
else else
run(abc + " -dress -lut 4", "(skip if -noabc)"); run(abc + " -dress -lut 4", "(skip if -noabc)");
} }
run("techmap -D NO_LUT -map +/ice40/cells_map.v");
run("clean"); run("clean");
run("ice40_unlut");
run("opt_lut -dlogic SB_CARRY:I0=2:I1=1:CI=0"); run("opt_lut -dlogic SB_CARRY:I0=2:I1=1:CI=0");
} }

View file

@ -1,6 +1,5 @@
read_verilog test_arith.v read_verilog test_arith.v
synth_ice40 synth_ice40
techmap -map ../cells_sim.v
rename test gate rename test gate
read_verilog test_arith.v read_verilog test_arith.v
@ -8,3 +7,11 @@ rename test gold
miter -equiv -flatten -make_outputs gold gate miter miter -equiv -flatten -make_outputs gold gate miter
sat -verify -prove trigger 0 -show-ports miter sat -verify -prove trigger 0 -show-ports miter
synth_ice40 -top gate
read_verilog test_arith.v
rename test gold
miter -equiv -flatten -make_outputs gold gate miter
sat -verify -prove trigger 0 -show-ports miter

View file

@ -5,20 +5,10 @@ $(eval $(call add_share_file,share/intel/common,techlibs/intel/common/m9k_bb.v))
$(eval $(call add_share_file,share/intel/common,techlibs/intel/common/altpll_bb.v)) $(eval $(call add_share_file,share/intel/common,techlibs/intel/common/altpll_bb.v))
$(eval $(call add_share_file,share/intel/common,techlibs/intel/common/brams_m9k.txt)) $(eval $(call add_share_file,share/intel/common,techlibs/intel/common/brams_m9k.txt))
$(eval $(call add_share_file,share/intel/common,techlibs/intel/common/brams_map_m9k.v)) $(eval $(call add_share_file,share/intel/common,techlibs/intel/common/brams_map_m9k.v))
$(eval $(call add_share_file,share/intel/max10,techlibs/intel/max10/cells_sim.v))
$(eval $(call add_share_file,share/intel/a10gx,techlibs/intel/a10gx/cells_sim.v)) # Add the cell models and mappings for the VQM backend
$(eval $(call add_share_file,share/intel/cyclonev,techlibs/intel/cyclonev/cells_sim.v)) families := max10 a10gx cyclonev cyclone10 cycloneiv cycloneive
$(eval $(call add_share_file,share/intel/cyclone10,techlibs/intel/cyclone10/cells_sim.v)) $(foreach family,$(families), $(eval $(call add_share_file,share/intel/$(family),techlibs/intel/$(family)/cells_sim.v)))
$(eval $(call add_share_file,share/intel/cycloneiv,techlibs/intel/cycloneiv/cells_sim.v)) $(foreach family,$(families), $(eval $(call add_share_file,share/intel/$(family),techlibs/intel/$(family)/cells_map.v)))
$(eval $(call add_share_file,share/intel/cycloneive,techlibs/intel/cycloneive/cells_sim.v))
$(eval $(call add_share_file,share/intel/max10,techlibs/intel/max10/cells_map.v))
$(eval $(call add_share_file,share/intel/a10gx,techlibs/intel/a10gx/cells_map.v))
$(eval $(call add_share_file,share/intel/cyclonev,techlibs/intel/cyclonev/cells_map.v))
$(eval $(call add_share_file,share/intel/cyclone10,techlibs/intel/cyclone10/cells_map.v))
$(eval $(call add_share_file,share/intel/cycloneiv,techlibs/intel/cycloneiv/cells_map.v))
$(eval $(call add_share_file,share/intel/cycloneive,techlibs/intel/cycloneive/cells_map.v))
#$(eval $(call add_share_file,share/intel/max10,techlibs/intel/max10/arith_map.v))
#$(eval $(call add_share_file,share/intel/a10gx,techlibs/intel/a10gx/arith_map.v))
#$(eval $(call add_share_file,share/intel/cycloneiv,techlibs/intel/cycloneiv/arith_map.v))
#$(eval $(call add_share_file,share/intel/cycloneive,techlibs/intel/cycloneive/arith_map.v)) #$(eval $(call add_share_file,share/intel/cycloneive,techlibs/intel/cycloneive/arith_map.v))

View file

@ -32,8 +32,8 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams_bb.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams.txt)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams.txt))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_bb.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_bb.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/drams.txt)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams.txt))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/drams_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/arith_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/arith_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/ff_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/ff_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut_map.v))

View file

@ -181,8 +181,14 @@ module XORCY(output O, input CI, LI);
assign O = CI ^ LI; assign O = CI ^ LI;
endmodule endmodule
(* abc_box_id = 4, abc_carry="CI,CO", lib_whitebox *) (* abc_box_id = 4, lib_whitebox *)
module CARRY4(output [3:0] CO, O, input CI, CYINIT, input [3:0] DI, S); module CARRY4(
(* abc_carry *) output [3:0] CO,
output [3:0] O,
(* abc_carry *) input CI,
input CYINIT,
input [3:0] DI, S
);
assign O = S ^ {CO[2:0], CI | CYINIT}; assign O = S ^ {CO[2:0], CI | CYINIT};
assign CO[0] = S[0] ? CI | CYINIT : DI[0]; assign CO[0] = S[0] ? CI | CYINIT : DI[0];
assign CO[1] = S[1] ? CO[0] : DI[1]; assign CO[1] = S[1] ? CO[0] : DI[1];
@ -289,10 +295,12 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE);
always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D; always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D;
endmodule endmodule
(* abc_box_id = 5, abc_scc_break="D,WE" *) (* abc_box_id = 5 *)
module RAM32X1D ( module RAM32X1D (
output DPO, SPO, output DPO, SPO,
input D, WCLK, WE, (* abc_scc_break *) input D,
input WCLK,
(* abc_scc_break *) input WE,
input A0, A1, A2, A3, A4, input A0, A1, A2, A3, A4,
input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4 input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
); );
@ -307,10 +315,12 @@ module RAM32X1D (
always @(posedge clk) if (WE) mem[a] <= D; always @(posedge clk) if (WE) mem[a] <= D;
endmodule endmodule
(* abc_box_id = 6, abc_scc_break="D,WE" *) (* abc_box_id = 6 *)
module RAM64X1D ( module RAM64X1D (
output DPO, SPO, output DPO, SPO,
input D, WCLK, WE, (* abc_scc_break *) input D,
input WCLK,
(* abc_scc_break *) input WE,
input A0, A1, A2, A3, A4, A5, input A0, A1, A2, A3, A4, A5,
input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5 input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
); );
@ -325,10 +335,12 @@ module RAM64X1D (
always @(posedge clk) if (WE) mem[a] <= D; always @(posedge clk) if (WE) mem[a] <= D;
endmodule endmodule
(* abc_box_id = 7, abc_scc_break="D,WE" *) (* abc_box_id = 7 *)
module RAM128X1D ( module RAM128X1D (
output DPO, SPO, output DPO, SPO,
input D, WCLK, WE, (* abc_scc_break *) input D,
input WCLK,
(* abc_scc_break *) input WE,
input [6:0] A, DPRA input [6:0] A, DPRA
); );
parameter INIT = 128'h0; parameter INIT = 128'h0;

View file

@ -64,13 +64,13 @@ struct SynthXilinxPass : public ScriptPass
log(" (this feature is experimental and incomplete)\n"); log(" (this feature is experimental and incomplete)\n");
log("\n"); log("\n");
log(" -nobram\n"); log(" -nobram\n");
log(" disable inference of block rams\n"); log(" do not use block RAM cells in output netlist\n");
log("\n"); log("\n");
log(" -nodram\n"); log(" -nolutram\n");
log(" disable inference of distributed rams\n"); log(" do not use distributed RAM cells in output netlist\n");
log("\n"); log("\n");
log(" -nosrl\n"); log(" -nosrl\n");
log(" disable inference of shift registers\n"); log(" do not use distributed SRL cells in output netlist\n");
log("\n"); log("\n");
log(" -nocarry\n"); log(" -nocarry\n");
log(" do not use XORCY/MUXCY/CARRY4 cells in output netlist\n"); log(" do not use XORCY/MUXCY/CARRY4 cells in output netlist\n");
@ -107,7 +107,7 @@ struct SynthXilinxPass : public ScriptPass
} }
std::string top_opt, edif_file, blif_file, family; std::string top_opt, edif_file, blif_file, family;
bool flatten, retime, vpr, nobram, nodram, nosrl, nocarry, nowidelut, nodsp, abc9; bool flatten, retime, vpr, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp, abc9;
int widemux; int widemux;
void clear_flags() YS_OVERRIDE void clear_flags() YS_OVERRIDE
@ -121,7 +121,7 @@ struct SynthXilinxPass : public ScriptPass
vpr = false; vpr = false;
nocarry = false; nocarry = false;
nobram = false; nobram = false;
nodram = false; nolutram = false;
nosrl = false; nosrl = false;
nocarry = false; nocarry = false;
nowidelut = false; nowidelut = false;
@ -190,8 +190,8 @@ struct SynthXilinxPass : public ScriptPass
nobram = true; nobram = true;
continue; continue;
} }
if (args[argidx] == "-nodram") { if (args[argidx] == "-nolutram" || /*deprecated alias*/ args[argidx] == "-nodram") {
nodram = true; nolutram = true;
continue; continue;
} }
if (args[argidx] == "-nosrl") { if (args[argidx] == "-nosrl") {
@ -306,7 +306,7 @@ struct SynthXilinxPass : public ScriptPass
run("opt_clean"); run("opt_clean");
} }
if (check_label("bram", "(skip if '-nobram')")) { if (check_label("map_bram", "(skip if '-nobram')")) {
if (help_mode) { if (help_mode) {
run("memory_bram -rules +/xilinx/{family}_brams.txt"); run("memory_bram -rules +/xilinx/{family}_brams.txt");
run("techmap -map +/xilinx/{family}_brams_map.v"); run("techmap -map +/xilinx/{family}_brams_map.v");
@ -323,20 +323,23 @@ struct SynthXilinxPass : public ScriptPass
} }
} }
if (check_label("dram", "(skip if '-nodram')")) { if (check_label("map_lutram", "(skip if '-nolutram')")) {
if (!nodram || help_mode) { if (!nolutram || help_mode) {
run("memory_bram -rules +/xilinx/drams.txt"); run("memory_bram -rules +/xilinx/lutrams.txt");
run("techmap -map +/xilinx/drams_map.v"); run("techmap -map +/xilinx/lutrams_map.v");
} }
} }
if (check_label("fine")) { if (check_label("map_ffram")) {
if (widemux > 0) if (widemux > 0)
run("opt -fast -mux_bool -undriven -fine"); // Necessary to omit -mux_undef otherwise muxcover run("opt -fast -mux_bool -undriven -fine"); // Necessary to omit -mux_undef otherwise muxcover
// performs less efficiently // performs less efficiently
else else
run("opt -fast -full"); run("opt -fast -full");
run("memory_map"); run("memory_map");
}
if (check_label("fine")) {
run("dffsr2dff"); run("dffsr2dff");
run("dff2dffe"); run("dff2dffe");
if (help_mode) { if (help_mode) {

View file

@ -6,7 +6,7 @@
set -e set -e
OPTIND=1 OPTIND=1
count=100 count=50
seed="" # default to no seed specified seed="" # default to no seed specified
while getopts "c:S:" opt while getopts "c:S:" opt
do do

View file

@ -1,21 +0,0 @@
module top(
input clk,
input rst,
input [2:0] a,
output [1:0] b
);
reg [2:0] b_reg;
initial begin
b_reg <= 3'b0;
end
assign b = b_reg[1:0];
always @(posedge clk or posedge rst) begin
if(rst) begin
b_reg <= 3'b0;
end else begin
b_reg <= a;
end
end
endmodule

View file

@ -1,3 +0,0 @@
read_verilog opt_ff.v
synth_ice40
ice40_unlut

View file

@ -1,4 +1,2 @@
read_verilog opt_lut.v read_verilog opt_lut.v
synth_ice40 equiv_opt -map +/ice40/cells_sim.v -assert synth_ice40
ice40_unlut
equiv_opt -map +/ice40/cells_sim.v -assert opt_lut -dlogic SB_CARRY:I0=1:I1=2:CI=3

View file

@ -19,8 +19,8 @@ hierarchy -top equiv
equiv_simple -undef equiv_simple -undef
equiv_status -assert equiv_status -assert
design -load gold #design -load gold
stat #stat
#
design -load gate #design -load gate
stat #stat

View file

@ -1,4 +1,4 @@
read_verilog opt_ff_sat.v read_verilog opt_rmdff_sat.v
prep -flatten prep -flatten
opt_rmdff -sat opt_rmdff -sat
synth synth

View file

@ -0,0 +1,10 @@
module opt_share_test(
input [15:0] a,
input [15:0] b,
input sel,
output [15:0] res,
);
assign res = {sel ? a + b : a - b};
endmodule

View file

@ -0,0 +1,13 @@
read_verilog opt_share_add_sub.v
proc;;
copy opt_share_test merged
alumacc merged
opt merged
opt_share merged
opt_clean merged
miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp opt_share_test merged miter
sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter
select -assert-count 1 -module merged t:$alu

15
tests/opt/opt_share_cat.v Normal file
View file

@ -0,0 +1,15 @@
module opt_share_test(
input [15:0] a,
input [15:0] b,
input [15:0] c,
input [15:0] d,
input sel,
output [63:0] res,
);
reg [31: 0] cat1 = {a+b, c+d};
reg [31: 0] cat2 = {a-b, c-d};
assign res = {b, sel ? cat1 : cat2, a};
endmodule

View file

@ -0,0 +1,13 @@
read_verilog opt_share_cat.v
proc;;
copy opt_share_test merged
alumacc merged
opt merged
opt_share merged
opt_clean merged
miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp opt_share_test merged miter
sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter
select -assert-count 2 -module merged t:$alu

Some files were not shown because too many files have changed in this diff Show more