3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-07-03 11:25:41 +00:00

Merge branch 'master' of github.com:YosysHQ/yosys into firrtl_backend_fileinfo

This commit is contained in:
Sahand Kashani 2020-04-08 23:50:37 +02:00
commit 9edf8869c1
228 changed files with 8971 additions and 6952 deletions

View file

@ -51,6 +51,10 @@ ifneq ($(wildcard Makefile.conf),)
include Makefile.conf
endif
ifeq ($(ENABLE_PYOSYS),1)
ENABLE_LIBYOSYS := 1
endif
BINDIR := $(PREFIX)/bin
LIBDIR := $(PREFIX)/lib
DATDIR := $(PREFIX)/share/yosys
@ -115,7 +119,7 @@ LDFLAGS += -rdynamic
LDLIBS += -lrt
endif
YOSYS_VER := 0.9+1706
YOSYS_VER := 0.9+2406
GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN)
OBJS = kernel/version_$(GIT_REV).o
@ -529,6 +533,7 @@ $(eval $(call add_include_file,kernel/register.h))
$(eval $(call add_include_file,kernel/celltypes.h))
$(eval $(call add_include_file,kernel/celledges.h))
$(eval $(call add_include_file,kernel/consteval.h))
$(eval $(call add_include_file,kernel/constids.inc))
$(eval $(call add_include_file,kernel/sigtools.h))
$(eval $(call add_include_file,kernel/modtools.h))
$(eval $(call add_include_file,kernel/macc.h))
@ -716,6 +721,7 @@ test: $(TARGETS) $(EXTRA_TARGETS)
+cd tests/memories && bash run-test.sh $(ABCOPT) $(SEEDOPT)
+cd tests/bram && bash run-test.sh $(SEEDOPT)
+cd tests/various && bash run-test.sh
+cd tests/select && bash run-test.sh
+cd tests/sat && bash run-test.sh
+cd tests/svinterfaces && bash run-test.sh $(SEEDOPT)
+cd tests/svtypes && bash run-test.sh $(SEEDOPT)

View file

@ -541,8 +541,6 @@ from SystemVerilog:
SystemVerilog files being read into the same design afterwards.
- typedefs are supported (including inside packages)
- type identifiers must currently be enclosed in (parentheses) when declaring
signals of that type (this is syntactically incorrect SystemVerilog)
- type casts are currently not supported
- enums are supported (including inside packages)

View file

@ -126,9 +126,9 @@ struct AigerWriter
for (auto wire : module->wires())
{
if (wire->attributes.count("\\init")) {
if (wire->attributes.count(ID::init)) {
SigSpec initsig = sigmap(wire);
Const initval = wire->attributes.at("\\init");
Const initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(wire) && i < GetSize(initval); i++)
if (initval[i] == State::S0 || initval[i] == State::S1)
init_map[initsig[i]] = initval[i] == State::S1;
@ -169,31 +169,31 @@ struct AigerWriter
for (auto cell : module->cells())
{
if (cell->type == "$_NOT_")
if (cell->type == ID($_NOT_))
{
SigBit A = sigmap(cell->getPort("\\A").as_bit());
SigBit Y = sigmap(cell->getPort("\\Y").as_bit());
SigBit A = sigmap(cell->getPort(ID::A).as_bit());
SigBit Y = sigmap(cell->getPort(ID::Y).as_bit());
unused_bits.erase(A);
undriven_bits.erase(Y);
not_map[Y] = A;
continue;
}
if (cell->type.in("$_FF_", "$_DFF_N_", "$_DFF_P_"))
if (cell->type.in(ID($_FF_), ID($_DFF_N_), ID($_DFF_P_)))
{
SigBit D = sigmap(cell->getPort("\\D").as_bit());
SigBit Q = sigmap(cell->getPort("\\Q").as_bit());
SigBit D = sigmap(cell->getPort(ID::D).as_bit());
SigBit Q = sigmap(cell->getPort(ID::Q).as_bit());
unused_bits.erase(D);
undriven_bits.erase(Q);
ff_map[Q] = D;
continue;
}
if (cell->type == "$_AND_")
if (cell->type == ID($_AND_))
{
SigBit A = sigmap(cell->getPort("\\A").as_bit());
SigBit B = sigmap(cell->getPort("\\B").as_bit());
SigBit Y = sigmap(cell->getPort("\\Y").as_bit());
SigBit A = sigmap(cell->getPort(ID::A).as_bit());
SigBit B = sigmap(cell->getPort(ID::B).as_bit());
SigBit Y = sigmap(cell->getPort(ID::Y).as_bit());
unused_bits.erase(A);
unused_bits.erase(B);
undriven_bits.erase(Y);
@ -201,66 +201,66 @@ struct AigerWriter
continue;
}
if (cell->type == "$initstate")
if (cell->type == ID($initstate))
{
SigBit Y = sigmap(cell->getPort("\\Y").as_bit());
SigBit Y = sigmap(cell->getPort(ID::Y).as_bit());
undriven_bits.erase(Y);
initstate_bits.insert(Y);
continue;
}
if (cell->type == "$assert")
if (cell->type == ID($assert))
{
SigBit A = sigmap(cell->getPort("\\A").as_bit());
SigBit EN = sigmap(cell->getPort("\\EN").as_bit());
SigBit A = sigmap(cell->getPort(ID::A).as_bit());
SigBit EN = sigmap(cell->getPort(ID::EN).as_bit());
unused_bits.erase(A);
unused_bits.erase(EN);
asserts.push_back(make_pair(A, EN));
continue;
}
if (cell->type == "$assume")
if (cell->type == ID($assume))
{
SigBit A = sigmap(cell->getPort("\\A").as_bit());
SigBit EN = sigmap(cell->getPort("\\EN").as_bit());
SigBit A = sigmap(cell->getPort(ID::A).as_bit());
SigBit EN = sigmap(cell->getPort(ID::EN).as_bit());
unused_bits.erase(A);
unused_bits.erase(EN);
assumes.push_back(make_pair(A, EN));
continue;
}
if (cell->type == "$live")
if (cell->type == ID($live))
{
SigBit A = sigmap(cell->getPort("\\A").as_bit());
SigBit EN = sigmap(cell->getPort("\\EN").as_bit());
SigBit A = sigmap(cell->getPort(ID::A).as_bit());
SigBit EN = sigmap(cell->getPort(ID::EN).as_bit());
unused_bits.erase(A);
unused_bits.erase(EN);
liveness.push_back(make_pair(A, EN));
continue;
}
if (cell->type == "$fair")
if (cell->type == ID($fair))
{
SigBit A = sigmap(cell->getPort("\\A").as_bit());
SigBit EN = sigmap(cell->getPort("\\EN").as_bit());
SigBit A = sigmap(cell->getPort(ID::A).as_bit());
SigBit EN = sigmap(cell->getPort(ID::EN).as_bit());
unused_bits.erase(A);
unused_bits.erase(EN);
fairness.push_back(make_pair(A, EN));
continue;
}
if (cell->type == "$anyconst")
if (cell->type == ID($anyconst))
{
for (auto bit : sigmap(cell->getPort("\\Y"))) {
for (auto bit : sigmap(cell->getPort(ID::Y))) {
undriven_bits.erase(bit);
ff_map[bit] = bit;
}
continue;
}
if (cell->type == "$anyseq")
if (cell->type == ID($anyseq))
{
for (auto bit : sigmap(cell->getPort("\\Y"))) {
for (auto bit : sigmap(cell->getPort(ID::Y))) {
undriven_bits.erase(bit);
input_bits.insert(bit);
}

View file

@ -174,7 +174,7 @@ struct XAigerWriter
undriven_bits.insert(bit);
unused_bits.insert(bit);
bool scc = wire->attributes.count(ID(abc9_scc));
bool scc = wire->attributes.count(ID::abc9_scc);
if (wire->port_input || scc)
input_bits.insert(bit);
@ -190,21 +190,21 @@ struct XAigerWriter
for (auto cell : module->cells()) {
if (!cell->has_keep_attr()) {
if (cell->type == "$_NOT_")
if (cell->type == ID($_NOT_))
{
SigBit A = sigmap(cell->getPort("\\A").as_bit());
SigBit Y = sigmap(cell->getPort("\\Y").as_bit());
SigBit A = sigmap(cell->getPort(ID::A).as_bit());
SigBit Y = sigmap(cell->getPort(ID::Y).as_bit());
unused_bits.erase(A);
undriven_bits.erase(Y);
not_map[Y] = A;
continue;
}
if (cell->type == "$_AND_")
if (cell->type == ID($_AND_))
{
SigBit A = sigmap(cell->getPort("\\A").as_bit());
SigBit B = sigmap(cell->getPort("\\B").as_bit());
SigBit Y = sigmap(cell->getPort("\\Y").as_bit());
SigBit A = sigmap(cell->getPort(ID::A).as_bit());
SigBit B = sigmap(cell->getPort(ID::B).as_bit());
SigBit Y = sigmap(cell->getPort(ID::Y).as_bit());
unused_bits.erase(A);
unused_bits.erase(B);
undriven_bits.erase(Y);
@ -212,13 +212,13 @@ struct XAigerWriter
continue;
}
if (cell->type == "$__ABC9_FF_" &&
if (cell->type == ID($__ABC9_FF_) &&
// The presence of an abc9_mergeability attribute indicates
// that we do want to pass this flop to ABC
cell->attributes.count("\\abc9_mergeability"))
cell->attributes.count(ID::abc9_mergeability))
{
SigBit D = sigmap(cell->getPort("\\D").as_bit());
SigBit Q = sigmap(cell->getPort("\\Q").as_bit());
SigBit D = sigmap(cell->getPort(ID::D).as_bit());
SigBit Q = sigmap(cell->getPort(ID::Q).as_bit());
unused_bits.erase(D);
undriven_bits.erase(Q);
alias_map[Q] = D;
@ -227,7 +227,7 @@ struct XAigerWriter
continue;
}
if (cell->type.in("$specify2", "$specify3", "$specrule"))
if (cell->type.in(ID($specify2), ID($specify3), ID($specrule)))
continue;
}
@ -239,7 +239,7 @@ struct XAigerWriter
bool abc9_flop = false;
if (!cell->has_keep_attr()) {
auto it = cell->attributes.find("\\abc9_box_seq");
auto it = cell->attributes.find(ID::abc9_box_seq);
if (it != cell->attributes.end()) {
int abc9_box_seq = it->second.as_int();
if (GetSize(box_list) <= abc9_box_seq)
@ -247,7 +247,7 @@ struct XAigerWriter
box_list[abc9_box_seq] = cell;
// Only flop boxes may have arrival times
// (all others are combinatorial)
abc9_flop = inst_module->get_bool_attribute("\\abc9_flop");
abc9_flop = inst_module->get_bool_attribute(ID::abc9_flop);
if (!abc9_flop)
continue;
}
@ -315,7 +315,7 @@ struct XAigerWriter
RTLIL::Module* box_module = module->design->module(cell->type);
log_assert(box_module);
log_assert(box_module->attributes.count("\\abc9_box_id") || box_module->get_bool_attribute("\\abc9_flop"));
log_assert(box_module->attributes.count(ID::abc9_box_id) || box_module->get_bool_attribute(ID::abc9_flop));
auto r = box_ports.insert(cell->type);
if (r.second) {
@ -325,7 +325,7 @@ struct XAigerWriter
for (const auto &port_name : box_module->ports) {
auto w = box_module->wire(port_name);
log_assert(w);
if (w->get_bool_attribute("\\abc9_carry")) {
if (w->get_bool_attribute(ID::abc9_carry)) {
if (w->port_input) {
if (carry_in != IdString())
log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(box_module));
@ -381,7 +381,7 @@ struct XAigerWriter
}
// Connect <cell>.abc9_ff.Q (inserted by abc9_map.v) as the last input to the flop box
if (box_module->get_bool_attribute("\\abc9_flop")) {
if (box_module->get_bool_attribute(ID::abc9_flop)) {
SigSpec rhs = module->wire(stringf("%s.abc9_ff.Q", cell->name.c_str()));
if (rhs.empty())
log_error("'%s.abc9_ff.Q' is not a wire present in module '%s'.\n", log_id(cell), log_id(module));
@ -437,7 +437,7 @@ struct XAigerWriter
for (const auto &i : ff_bits) {
const Cell *cell = i.second;
const SigBit &q = sigmap(cell->getPort("\\Q"));
const SigBit &q = sigmap(cell->getPort(ID::Q));
aig_m++, aig_i++;
log_assert(!aig_map.count(q));
aig_map[q] = 2*aig_m;
@ -608,12 +608,12 @@ struct XAigerWriter
// For flops only, create an extra 1-bit input that drives a new wire
// called "<cell>.abc9_ff.Q" that is used below
if (box_module->get_bool_attribute("\\abc9_flop"))
if (box_module->get_bool_attribute(ID::abc9_flop))
box_inputs++;
std::get<0>(v) = box_inputs;
std::get<1>(v) = box_outputs;
std::get<2>(v) = box_module->attributes.at("\\abc9_box_id").as_int();
std::get<2>(v) = box_module->attributes.at(ID::abc9_box_id).as_int();
}
write_h_buffer(std::get<0>(v));
@ -635,11 +635,11 @@ struct XAigerWriter
const SigBit &d = i.first;
const Cell *cell = i.second;
int mergeability = cell->attributes.at(ID(abc9_mergeability)).as_int();
int mergeability = cell->attributes.at(ID::abc9_mergeability).as_int();
log_assert(mergeability > 0);
write_r_buffer(mergeability);
Const init = cell->attributes.at(ID(abc9_init), State::Sx);
Const init = cell->attributes.at(ID::abc9_init, State::Sx);
log_assert(GetSize(init) == 1);
if (init == State::S1)
write_s_buffer(1);

View file

@ -69,9 +69,9 @@ struct BlifDumper
f(f), module(module), design(design), config(config), ct(design), sigmap(module)
{
for (Wire *wire : module->wires())
if (wire->attributes.count("\\init")) {
if (wire->attributes.count(ID::init)) {
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++)
switch (initval[i]) {
case State::S0:
@ -138,9 +138,9 @@ struct BlifDumper
{
if (!config->gates_mode)
return "subckt";
if (!design->modules_.count(RTLIL::escape_id(cell_type)))
if (design->module(RTLIL::escape_id(cell_type)) == nullptr)
return "gate";
if (design->modules_.at(RTLIL::escape_id(cell_type))->get_blackbox_attribute())
if (design->module(RTLIL::escape_id(cell_type))->get_blackbox_attribute())
return "gate";
return "subckt";
}
@ -148,7 +148,7 @@ struct BlifDumper
void dump_params(const char *command, dict<IdString, Const> &params)
{
for (auto &param : params) {
f << stringf("%s %s ", command, RTLIL::id2cstr(param.first));
f << stringf("%s %s ", command, log_id(param.first));
if (param.second.flags & RTLIL::CONST_FLAG_STRING) {
std::string str = param.second.decode_string();
f << stringf("\"");
@ -172,8 +172,7 @@ struct BlifDumper
std::map<int, RTLIL::Wire*> inputs, outputs;
for (auto &wire_it : module->wires_) {
RTLIL::Wire *wire = wire_it.second;
for (auto wire : module->wires()) {
if (wire->port_input)
inputs[wire->port_id] = wire;
if (wire->port_output)
@ -229,10 +228,8 @@ struct BlifDumper
f << stringf(".names $undef\n");
}
for (auto &cell_it : module->cells_)
for (auto cell : module->cells())
{
RTLIL::Cell *cell = cell_it.second;
if (config->unbuf_types.count(cell->type)) {
auto portnames = config->unbuf_types.at(cell->type);
f << stringf(".names %s %s\n1 1\n",
@ -240,142 +237,142 @@ struct BlifDumper
continue;
}
if (!config->icells_mode && cell->type == "$_NOT_") {
if (!config->icells_mode && cell->type == ID($_NOT_)) {
f << stringf(".names %s %s\n0 1\n",
cstr(cell->getPort("\\A")), cstr(cell->getPort("\\Y")));
cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_AND_") {
if (!config->icells_mode && cell->type == ID($_AND_)) {
f << stringf(".names %s %s %s\n11 1\n",
cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_OR_") {
if (!config->icells_mode && cell->type == ID($_OR_)) {
f << stringf(".names %s %s %s\n1- 1\n-1 1\n",
cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_XOR_") {
if (!config->icells_mode && cell->type == ID($_XOR_)) {
f << stringf(".names %s %s %s\n10 1\n01 1\n",
cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_NAND_") {
if (!config->icells_mode && cell->type == ID($_NAND_)) {
f << stringf(".names %s %s %s\n0- 1\n-0 1\n",
cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_NOR_") {
if (!config->icells_mode && cell->type == ID($_NOR_)) {
f << stringf(".names %s %s %s\n00 1\n",
cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_XNOR_") {
if (!config->icells_mode && cell->type == ID($_XNOR_)) {
f << stringf(".names %s %s %s\n11 1\n00 1\n",
cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_ANDNOT_") {
if (!config->icells_mode && cell->type == ID($_ANDNOT_)) {
f << stringf(".names %s %s %s\n10 1\n",
cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_ORNOT_") {
if (!config->icells_mode && cell->type == ID($_ORNOT_)) {
f << stringf(".names %s %s %s\n1- 1\n-0 1\n",
cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_AOI3_") {
if (!config->icells_mode && cell->type == ID($_AOI3_)) {
f << stringf(".names %s %s %s %s\n-00 1\n0-0 1\n",
cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\C")), cstr(cell->getPort("\\Y")));
cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::C)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_OAI3_") {
if (!config->icells_mode && cell->type == ID($_OAI3_)) {
f << stringf(".names %s %s %s %s\n00- 1\n--0 1\n",
cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\C")), cstr(cell->getPort("\\Y")));
cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::C)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_AOI4_") {
if (!config->icells_mode && cell->type == ID($_AOI4_)) {
f << stringf(".names %s %s %s %s %s\n-0-0 1\n-00- 1\n0--0 1\n0-0- 1\n",
cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")),
cstr(cell->getPort("\\C")), cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Y")));
cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)),
cstr(cell->getPort(ID::C)), cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_OAI4_") {
if (!config->icells_mode && cell->type == ID($_OAI4_)) {
f << stringf(".names %s %s %s %s %s\n00-- 1\n--00 1\n",
cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")),
cstr(cell->getPort("\\C")), cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Y")));
cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)),
cstr(cell->getPort(ID::C)), cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_MUX_") {
if (!config->icells_mode && cell->type == ID($_MUX_)) {
f << stringf(".names %s %s %s %s\n1-0 1\n-11 1\n",
cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")),
cstr(cell->getPort("\\S")), cstr(cell->getPort("\\Y")));
cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)),
cstr(cell->getPort(ID::S)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_NMUX_") {
if (!config->icells_mode && cell->type == ID($_NMUX_)) {
f << stringf(".names %s %s %s %s\n0-0 1\n-01 1\n",
cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")),
cstr(cell->getPort("\\S")), cstr(cell->getPort("\\Y")));
cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)),
cstr(cell->getPort(ID::S)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_FF_") {
f << stringf(".latch %s %s%s\n", cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")),
cstr_init(cell->getPort("\\Q")));
if (!config->icells_mode && cell->type == ID($_FF_)) {
f << stringf(".latch %s %s%s\n", cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Q)),
cstr_init(cell->getPort(ID::Q)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_DFF_N_") {
f << stringf(".latch %s %s fe %s%s\n", cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")),
cstr(cell->getPort("\\C")), cstr_init(cell->getPort("\\Q")));
if (!config->icells_mode && cell->type == ID($_DFF_N_)) {
f << stringf(".latch %s %s fe %s%s\n", cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Q)),
cstr(cell->getPort(ID::C)), cstr_init(cell->getPort(ID::Q)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_DFF_P_") {
f << stringf(".latch %s %s re %s%s\n", cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")),
cstr(cell->getPort("\\C")), cstr_init(cell->getPort("\\Q")));
if (!config->icells_mode && cell->type == ID($_DFF_P_)) {
f << stringf(".latch %s %s re %s%s\n", cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Q)),
cstr(cell->getPort(ID::C)), cstr_init(cell->getPort(ID::Q)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_DLATCH_N_") {
f << stringf(".latch %s %s al %s%s\n", cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")),
cstr(cell->getPort("\\E")), cstr_init(cell->getPort("\\Q")));
if (!config->icells_mode && cell->type == ID($_DLATCH_N_)) {
f << stringf(".latch %s %s al %s%s\n", cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Q)),
cstr(cell->getPort(ID::E)), cstr_init(cell->getPort(ID::Q)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$_DLATCH_P_") {
f << stringf(".latch %s %s ah %s%s\n", cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")),
cstr(cell->getPort("\\E")), cstr_init(cell->getPort("\\Q")));
if (!config->icells_mode && cell->type == ID($_DLATCH_P_)) {
f << stringf(".latch %s %s ah %s%s\n", cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Q)),
cstr(cell->getPort(ID::E)), cstr_init(cell->getPort(ID::Q)));
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$lut") {
if (!config->icells_mode && cell->type == ID($lut)) {
f << stringf(".names");
auto &inputs = cell->getPort("\\A");
auto width = cell->parameters.at("\\WIDTH").as_int();
auto &inputs = cell->getPort(ID::A);
auto width = cell->parameters.at(ID::WIDTH).as_int();
log_assert(inputs.size() == width);
for (int i = width-1; i >= 0; i--)
f << stringf(" %s", cstr(inputs.extract(i, 1)));
auto &output = cell->getPort("\\Y");
auto &output = cell->getPort(ID::Y);
log_assert(output.size() == 1);
f << stringf(" %s", cstr(output));
f << stringf("\n");
RTLIL::SigSpec mask = cell->parameters.at("\\LUT");
RTLIL::SigSpec mask = cell->parameters.at(ID::LUT);
for (int i = 0; i < (1 << width); i++)
if (mask[i] == State::S1) {
for (int j = width-1; j >= 0; j--) {
@ -386,18 +383,18 @@ struct BlifDumper
goto internal_cell;
}
if (!config->icells_mode && cell->type == "$sop") {
if (!config->icells_mode && cell->type == ID($sop)) {
f << stringf(".names");
auto &inputs = cell->getPort("\\A");
auto width = cell->parameters.at("\\WIDTH").as_int();
auto depth = cell->parameters.at("\\DEPTH").as_int();
vector<State> table = cell->parameters.at("\\TABLE").bits;
auto &inputs = cell->getPort(ID::A);
auto width = cell->parameters.at(ID::WIDTH).as_int();
auto depth = cell->parameters.at(ID::DEPTH).as_int();
vector<State> table = cell->parameters.at(ID::TABLE).bits;
while (GetSize(table) < 2*width*depth)
table.push_back(State::S0);
log_assert(inputs.size() == width);
for (int i = 0; i < width; i++)
f << stringf(" %s", cstr(inputs.extract(i, 1)));
auto &output = cell->getPort("\\Y");
auto &output = cell->getPort(ID::Y);
log_assert(output.size() == 1);
f << stringf(" %s", cstr(output));
f << stringf("\n");
@ -649,25 +646,24 @@ struct BlifBackend : public Backend {
extra_args(f, filename, args, argidx);
if (top_module_name.empty())
for (auto & mod_it:design->modules_)
if (mod_it.second->get_bool_attribute("\\top"))
top_module_name = mod_it.first.str();
for (auto module : design->modules())
if (module->get_bool_attribute(ID::top))
top_module_name = module->name.str();
*f << stringf("# Generated by %s\n", yosys_version_str);
std::vector<RTLIL::Module*> mod_list;
design->sort();
for (auto module_it : design->modules_)
for (auto module : design->modules())
{
RTLIL::Module *module = module_it.second;
if (module->get_blackbox_attribute() && !config.blackbox_mode)
continue;
if (module->processes.size() != 0)
log_error("Found unmapped processes in module %s: unmapped processes are not supported in BLIF backend!\n", RTLIL::id2cstr(module->name));
log_error("Found unmapped processes in module %s: unmapped processes are not supported in BLIF backend!\n", log_id(module->name));
if (module->memories.size() != 0)
log_error("Found unmapped memories in module %s: unmapped memories are not supported in BLIF backend!\n", RTLIL::id2cstr(module->name));
log_error("Found unmapped memories in module %s: unmapped memories are not supported in BLIF backend!\n", log_id(module->name));
if (module->name == RTLIL::escape_id(top_module_name)) {
BlifDumper::dump(*f, module, design, config);

View file

@ -39,6 +39,7 @@ struct BtorWorker
RTLIL::Module *module;
bool verbose;
bool single_bad;
bool cover_mode;
int next_nid = 1;
int initstate_nid = -1;
@ -71,7 +72,11 @@ struct BtorWorker
vector<int> bad_properties;
dict<SigBit, bool> initbits;
pool<Wire*> statewires;
string indent;
pool<string> srcsymbols;
string indent, info_filename;
vector<string> info_lines;
dict<int, int> info_clocks;
void btorf(const char *fmt, ...)
{
@ -81,6 +86,40 @@ struct BtorWorker
va_end(ap);
}
void infof(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
info_lines.push_back(vstringf(fmt, ap));
va_end(ap);
}
template<typename T>
string getinfo(T *obj, bool srcsym = false)
{
string infostr = log_id(obj);
if (obj->attributes.count(ID::src)) {
string src = obj->attributes.at(ID::src).decode_string().c_str();
if (srcsym && infostr[0] == '$') {
std::replace(src.begin(), src.end(), ' ', '_');
if (srcsymbols.count(src) || module->count_id("\\" + src)) {
for (int i = 1;; i++) {
string s = stringf("%s-%d", src.c_str(), i);
if (!srcsymbols.count(s) && !module->count_id("\\" + s)) {
src = s;
break;
}
}
}
srcsymbols.insert(src);
infostr = src;
} else {
infostr += " ; " + src;
}
}
return infostr;
}
void btorf_push(const string &id)
{
if (verbose) {
@ -144,40 +183,40 @@ struct BtorWorker
cell_recursion_guard.insert(cell);
btorf_push(log_id(cell));
if (cell->type.in("$add", "$sub", "$mul", "$and", "$or", "$xor", "$xnor", "$shl", "$sshl", "$shr", "$sshr", "$shift", "$shiftx",
"$concat", "$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_"))
if (cell->type.in(ID($add), ID($sub), ID($mul), ID($and), ID($or), ID($xor), ID($xnor), ID($shl), ID($sshl), ID($shr), ID($sshr), ID($shift), ID($shiftx),
ID($concat), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_)))
{
string btor_op;
if (cell->type == "$add") btor_op = "add";
if (cell->type == "$sub") btor_op = "sub";
if (cell->type == "$mul") btor_op = "mul";
if (cell->type.in("$shl", "$sshl")) btor_op = "sll";
if (cell->type == "$shr") btor_op = "srl";
if (cell->type == "$sshr") btor_op = "sra";
if (cell->type.in("$shift", "$shiftx")) btor_op = "shift";
if (cell->type.in("$and", "$_AND_")) btor_op = "and";
if (cell->type.in("$or", "$_OR_")) btor_op = "or";
if (cell->type.in("$xor", "$_XOR_")) btor_op = "xor";
if (cell->type == "$concat") btor_op = "concat";
if (cell->type == "$_NAND_") btor_op = "nand";
if (cell->type == "$_NOR_") btor_op = "nor";
if (cell->type.in("$xnor", "$_XNOR_")) btor_op = "xnor";
if (cell->type == ID($add)) btor_op = "add";
if (cell->type == ID($sub)) btor_op = "sub";
if (cell->type == ID($mul)) btor_op = "mul";
if (cell->type.in(ID($shl), ID($sshl))) btor_op = "sll";
if (cell->type == ID($shr)) btor_op = "srl";
if (cell->type == ID($sshr)) btor_op = "sra";
if (cell->type.in(ID($shift), ID($shiftx))) btor_op = "shift";
if (cell->type.in(ID($and), ID($_AND_))) btor_op = "and";
if (cell->type.in(ID($or), ID($_OR_))) btor_op = "or";
if (cell->type.in(ID($xor), ID($_XOR_))) btor_op = "xor";
if (cell->type == ID($concat)) btor_op = "concat";
if (cell->type == ID($_NAND_)) btor_op = "nand";
if (cell->type == ID($_NOR_)) btor_op = "nor";
if (cell->type.in(ID($xnor), ID($_XNOR_))) btor_op = "xnor";
log_assert(!btor_op.empty());
int width = GetSize(cell->getPort("\\Y"));
width = std::max(width, GetSize(cell->getPort("\\A")));
width = std::max(width, GetSize(cell->getPort("\\B")));
int width = GetSize(cell->getPort(ID::Y));
width = std::max(width, GetSize(cell->getPort(ID::A)));
width = std::max(width, GetSize(cell->getPort(ID::B)));
bool a_signed = cell->hasParam("\\A_SIGNED") ? cell->getParam("\\A_SIGNED").as_bool() : false;
bool b_signed = cell->hasParam("\\B_SIGNED") ? cell->getParam("\\B_SIGNED").as_bool() : false;
bool a_signed = cell->hasParam(ID::A_SIGNED) ? cell->getParam(ID::A_SIGNED).as_bool() : false;
bool b_signed = cell->hasParam(ID::B_SIGNED) ? cell->getParam(ID::B_SIGNED).as_bool() : false;
if (btor_op == "shift" && !b_signed)
btor_op = "srl";
if (cell->type.in("$shl", "$sshl", "$shr", "$sshr"))
if (cell->type.in(ID($shl), ID($sshl), ID($shr), ID($sshr)))
b_signed = false;
if (cell->type == "$sshr" && !a_signed)
if (cell->type == ID($sshr) && !a_signed)
btor_op = "srl";
int sid = get_bv_sid(width);
@ -185,8 +224,8 @@ struct BtorWorker
if (btor_op == "shift")
{
int nid_a = get_sig_nid(cell->getPort("\\A"), width, false);
int nid_b = get_sig_nid(cell->getPort("\\B"), width, b_signed);
int nid_a = get_sig_nid(cell->getPort(ID::A), width, false);
int nid_b = get_sig_nid(cell->getPort(ID::B), width, b_signed);
int nid_r = next_nid++;
btorf("%d srl %d %d %d\n", nid_r, sid, nid_a, nid_b);
@ -203,18 +242,18 @@ struct BtorWorker
btorf("%d slt %d %d %d\n", nid_b_ltz, sid_bit, nid_b, nid_zero);
nid = next_nid++;
btorf("%d ite %d %d %d %d\n", nid, sid, nid_b_ltz, nid_l, nid_r);
btorf("%d ite %d %d %d %d %s\n", nid, sid, nid_b_ltz, nid_l, nid_r, getinfo(cell).c_str());
}
else
{
int nid_a = get_sig_nid(cell->getPort("\\A"), width, a_signed);
int nid_b = get_sig_nid(cell->getPort("\\B"), width, b_signed);
int nid_a = get_sig_nid(cell->getPort(ID::A), width, a_signed);
int nid_b = get_sig_nid(cell->getPort(ID::B), width, b_signed);
nid = next_nid++;
btorf("%d %s %d %d %d\n", nid, btor_op.c_str(), sid, nid_a, nid_b);
btorf("%d %s %d %d %d %s\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
}
SigSpec sig = sigmap(cell->getPort("\\Y"));
SigSpec sig = sigmap(cell->getPort(ID::Y));
if (GetSize(sig) < width) {
int sid = get_bv_sid(GetSize(sig));
@ -227,28 +266,28 @@ struct BtorWorker
goto okay;
}
if (cell->type.in("$div", "$mod"))
if (cell->type.in(ID($div), ID($mod)))
{
string btor_op;
if (cell->type == "$div") btor_op = "div";
if (cell->type == "$mod") btor_op = "rem";
if (cell->type == ID($div)) btor_op = "div";
if (cell->type == ID($mod)) btor_op = "rem";
log_assert(!btor_op.empty());
int width = GetSize(cell->getPort("\\Y"));
width = std::max(width, GetSize(cell->getPort("\\A")));
width = std::max(width, GetSize(cell->getPort("\\B")));
int width = GetSize(cell->getPort(ID::Y));
width = std::max(width, GetSize(cell->getPort(ID::A)));
width = std::max(width, GetSize(cell->getPort(ID::B)));
bool a_signed = cell->hasParam("\\A_SIGNED") ? cell->getParam("\\A_SIGNED").as_bool() : false;
bool b_signed = cell->hasParam("\\B_SIGNED") ? cell->getParam("\\B_SIGNED").as_bool() : false;
bool a_signed = cell->hasParam(ID::A_SIGNED) ? cell->getParam(ID::A_SIGNED).as_bool() : false;
bool b_signed = cell->hasParam(ID::B_SIGNED) ? cell->getParam(ID::B_SIGNED).as_bool() : false;
int nid_a = get_sig_nid(cell->getPort("\\A"), width, a_signed);
int nid_b = get_sig_nid(cell->getPort("\\B"), width, b_signed);
int nid_a = get_sig_nid(cell->getPort(ID::A), width, a_signed);
int nid_b = get_sig_nid(cell->getPort(ID::B), width, b_signed);
int sid = get_bv_sid(width);
int nid = next_nid++;
btorf("%d %c%s %d %d %d\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b);
btorf("%d %c%s %d %d %d %s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
SigSpec sig = sigmap(cell->getPort("\\Y"));
SigSpec sig = sigmap(cell->getPort(ID::Y));
if (GetSize(sig) < width) {
int sid = get_bv_sid(GetSize(sig));
@ -261,120 +300,120 @@ struct BtorWorker
goto okay;
}
if (cell->type.in("$_ANDNOT_", "$_ORNOT_"))
if (cell->type.in(ID($_ANDNOT_), ID($_ORNOT_)))
{
int sid = get_bv_sid(1);
int nid_a = get_sig_nid(cell->getPort("\\A"));
int nid_b = get_sig_nid(cell->getPort("\\B"));
int nid_a = get_sig_nid(cell->getPort(ID::A));
int nid_b = get_sig_nid(cell->getPort(ID::B));
int nid1 = next_nid++;
int nid2 = next_nid++;
if (cell->type == "$_ANDNOT_") {
if (cell->type == ID($_ANDNOT_)) {
btorf("%d not %d %d\n", nid1, sid, nid_b);
btorf("%d and %d %d %d\n", nid2, sid, nid_a, nid1);
btorf("%d and %d %d %d %s\n", nid2, sid, nid_a, nid1, getinfo(cell).c_str());
}
if (cell->type == "$_ORNOT_") {
if (cell->type == ID($_ORNOT_)) {
btorf("%d not %d %d\n", nid1, sid, nid_b);
btorf("%d or %d %d %d\n", nid2, sid, nid_a, nid1);
btorf("%d or %d %d %d %s\n", nid2, sid, nid_a, nid1, getinfo(cell).c_str());
}
SigSpec sig = sigmap(cell->getPort("\\Y"));
SigSpec sig = sigmap(cell->getPort(ID::Y));
add_nid_sig(nid2, sig);
goto okay;
}
if (cell->type.in("$_OAI3_", "$_AOI3_"))
if (cell->type.in(ID($_OAI3_), ID($_AOI3_)))
{
int sid = get_bv_sid(1);
int nid_a = get_sig_nid(cell->getPort("\\A"));
int nid_b = get_sig_nid(cell->getPort("\\B"));
int nid_c = get_sig_nid(cell->getPort("\\C"));
int nid_a = get_sig_nid(cell->getPort(ID::A));
int nid_b = get_sig_nid(cell->getPort(ID::B));
int nid_c = get_sig_nid(cell->getPort(ID::C));
int nid1 = next_nid++;
int nid2 = next_nid++;
int nid3 = next_nid++;
if (cell->type == "$_OAI3_") {
if (cell->type == ID($_OAI3_)) {
btorf("%d or %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d and %d %d %d\n", nid2, sid, nid1, nid_c);
btorf("%d not %d %d\n", nid3, sid, nid2);
btorf("%d not %d %d %s\n", nid3, sid, nid2, getinfo(cell).c_str());
}
if (cell->type == "$_AOI3_") {
if (cell->type == ID($_AOI3_)) {
btorf("%d and %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d or %d %d %d\n", nid2, sid, nid1, nid_c);
btorf("%d not %d %d\n", nid3, sid, nid2);
btorf("%d not %d %d %s\n", nid3, sid, nid2, getinfo(cell).c_str());
}
SigSpec sig = sigmap(cell->getPort("\\Y"));
SigSpec sig = sigmap(cell->getPort(ID::Y));
add_nid_sig(nid3, sig);
goto okay;
}
if (cell->type.in("$_OAI4_", "$_AOI4_"))
if (cell->type.in(ID($_OAI4_), ID($_AOI4_)))
{
int sid = get_bv_sid(1);
int nid_a = get_sig_nid(cell->getPort("\\A"));
int nid_b = get_sig_nid(cell->getPort("\\B"));
int nid_c = get_sig_nid(cell->getPort("\\C"));
int nid_d = get_sig_nid(cell->getPort("\\D"));
int nid_a = get_sig_nid(cell->getPort(ID::A));
int nid_b = get_sig_nid(cell->getPort(ID::B));
int nid_c = get_sig_nid(cell->getPort(ID::C));
int nid_d = get_sig_nid(cell->getPort(ID::D));
int nid1 = next_nid++;
int nid2 = next_nid++;
int nid3 = next_nid++;
int nid4 = next_nid++;
if (cell->type == "$_OAI4_") {
if (cell->type == ID($_OAI4_)) {
btorf("%d or %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d or %d %d %d\n", nid2, sid, nid_c, nid_d);
btorf("%d and %d %d %d\n", nid3, sid, nid1, nid2);
btorf("%d not %d %d\n", nid4, sid, nid3);
btorf("%d not %d %d %s\n", nid4, sid, nid3, getinfo(cell).c_str());
}
if (cell->type == "$_AOI4_") {
if (cell->type == ID($_AOI4_)) {
btorf("%d and %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d and %d %d %d\n", nid2, sid, nid_c, nid_d);
btorf("%d or %d %d %d\n", nid3, sid, nid1, nid2);
btorf("%d not %d %d\n", nid4, sid, nid3);
btorf("%d not %d %d %s\n", nid4, sid, nid3, getinfo(cell).c_str());
}
SigSpec sig = sigmap(cell->getPort("\\Y"));
SigSpec sig = sigmap(cell->getPort(ID::Y));
add_nid_sig(nid4, sig);
goto okay;
}
if (cell->type.in("$lt", "$le", "$eq", "$eqx", "$ne", "$nex", "$ge", "$gt"))
if (cell->type.in(ID($lt), ID($le), ID($eq), ID($eqx), ID($ne), ID($nex), ID($ge), ID($gt)))
{
string btor_op;
if (cell->type == "$lt") btor_op = "lt";
if (cell->type == "$le") btor_op = "lte";
if (cell->type.in("$eq", "$eqx")) btor_op = "eq";
if (cell->type.in("$ne", "$nex")) btor_op = "neq";
if (cell->type == "$ge") btor_op = "gte";
if (cell->type == "$gt") btor_op = "gt";
if (cell->type == ID($lt)) btor_op = "lt";
if (cell->type == ID($le)) btor_op = "lte";
if (cell->type.in(ID($eq), ID($eqx))) btor_op = "eq";
if (cell->type.in(ID($ne), ID($nex))) btor_op = "neq";
if (cell->type == ID($ge)) btor_op = "gte";
if (cell->type == ID($gt)) btor_op = "gt";
log_assert(!btor_op.empty());
int width = 1;
width = std::max(width, GetSize(cell->getPort("\\A")));
width = std::max(width, GetSize(cell->getPort("\\B")));
width = std::max(width, GetSize(cell->getPort(ID::A)));
width = std::max(width, GetSize(cell->getPort(ID::B)));
bool a_signed = cell->hasParam("\\A_SIGNED") ? cell->getParam("\\A_SIGNED").as_bool() : false;
bool b_signed = cell->hasParam("\\B_SIGNED") ? cell->getParam("\\B_SIGNED").as_bool() : false;
bool a_signed = cell->hasParam(ID::A_SIGNED) ? cell->getParam(ID::A_SIGNED).as_bool() : false;
bool b_signed = cell->hasParam(ID::B_SIGNED) ? cell->getParam(ID::B_SIGNED).as_bool() : false;
int sid = get_bv_sid(1);
int nid_a = get_sig_nid(cell->getPort("\\A"), width, a_signed);
int nid_b = get_sig_nid(cell->getPort("\\B"), width, b_signed);
int nid_a = get_sig_nid(cell->getPort(ID::A), width, a_signed);
int nid_b = get_sig_nid(cell->getPort(ID::B), width, b_signed);
int nid = next_nid++;
if (cell->type.in("$lt", "$le", "$ge", "$gt")) {
btorf("%d %c%s %d %d %d\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b);
if (cell->type.in(ID($lt), ID($le), ID($ge), ID($gt))) {
btorf("%d %c%s %d %d %d %s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
} else {
btorf("%d %s %d %d %d\n", nid, btor_op.c_str(), sid, nid_a, nid_b);
btorf("%d %s %d %d %d %s\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
}
SigSpec sig = sigmap(cell->getPort("\\Y"));
SigSpec sig = sigmap(cell->getPort(ID::Y));
if (GetSize(sig) > 1) {
int sid = get_bv_sid(GetSize(sig));
@ -387,25 +426,24 @@ struct BtorWorker
goto okay;
}
if (cell->type.in("$not", "$neg", "$_NOT_"))
if (cell->type.in(ID($not), ID($neg), ID($_NOT_)))
{
string btor_op;
if (cell->type.in("$not", "$_NOT_")) btor_op = "not";
if (cell->type == "$neg") btor_op = "neg";
if (cell->type.in(ID($not), ID($_NOT_))) btor_op = "not";
if (cell->type == ID($neg)) btor_op = "neg";
log_assert(!btor_op.empty());
int width = GetSize(cell->getPort("\\Y"));
width = std::max(width, GetSize(cell->getPort("\\A")));
int width = std::max(GetSize(cell->getPort(ID::A)), GetSize(cell->getPort(ID::Y)));
bool a_signed = cell->hasParam("\\A_SIGNED") ? cell->getParam("\\A_SIGNED").as_bool() : false;
bool a_signed = cell->hasParam(ID::A_SIGNED) ? cell->getParam(ID::A_SIGNED).as_bool() : false;
int sid = get_bv_sid(width);
int nid_a = get_sig_nid(cell->getPort("\\A"), width, a_signed);
int nid_a = get_sig_nid(cell->getPort(ID::A), width, a_signed);
int nid = next_nid++;
btorf("%d %s %d %d\n", nid, btor_op.c_str(), sid, nid_a);
btorf("%d %s %d %d\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
SigSpec sig = sigmap(cell->getPort("\\Y"));
SigSpec sig = sigmap(cell->getPort(ID::Y));
if (GetSize(sig) < width) {
int sid = get_bv_sid(GetSize(sig));
@ -418,25 +456,25 @@ struct BtorWorker
goto okay;
}
if (cell->type.in("$logic_and", "$logic_or", "$logic_not"))
if (cell->type.in(ID($logic_and), ID($logic_or), ID($logic_not)))
{
string btor_op;
if (cell->type == "$logic_and") btor_op = "and";
if (cell->type == "$logic_or") btor_op = "or";
if (cell->type == "$logic_not") btor_op = "not";
if (cell->type == ID($logic_and)) btor_op = "and";
if (cell->type == ID($logic_or)) btor_op = "or";
if (cell->type == ID($logic_not)) btor_op = "not";
log_assert(!btor_op.empty());
int sid = get_bv_sid(1);
int nid_a = get_sig_nid(cell->getPort("\\A"));
int nid_b = btor_op != "not" ? get_sig_nid(cell->getPort("\\B")) : 0;
int nid_a = get_sig_nid(cell->getPort(ID::A));
int nid_b = btor_op != "not" ? get_sig_nid(cell->getPort(ID::B)) : 0;
if (GetSize(cell->getPort("\\A")) > 1) {
if (GetSize(cell->getPort(ID::A)) > 1) {
int nid_red_a = next_nid++;
btorf("%d redor %d %d\n", nid_red_a, sid, nid_a);
nid_a = nid_red_a;
}
if (btor_op != "not" && GetSize(cell->getPort("\\B")) > 1) {
if (btor_op != "not" && GetSize(cell->getPort(ID::B)) > 1) {
int nid_red_b = next_nid++;
btorf("%d redor %d %d\n", nid_red_b, sid, nid_b);
nid_b = nid_red_b;
@ -444,11 +482,11 @@ struct BtorWorker
int nid = next_nid++;
if (btor_op != "not")
btorf("%d %s %d %d %d\n", nid, btor_op.c_str(), sid, nid_a, nid_b);
btorf("%d %s %d %d %d\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
else
btorf("%d %s %d %d\n", nid, btor_op.c_str(), sid, nid_a);
btorf("%d %s %d %d\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
SigSpec sig = sigmap(cell->getPort("\\Y"));
SigSpec sig = sigmap(cell->getPort(ID::Y));
if (GetSize(sig) > 1) {
int sid = get_bv_sid(GetSize(sig));
@ -462,27 +500,29 @@ struct BtorWorker
goto okay;
}
if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_bool", "$reduce_xor", "$reduce_xnor"))
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool), ID($reduce_xor), ID($reduce_xnor)))
{
string btor_op;
if (cell->type == "$reduce_and") btor_op = "redand";
if (cell->type.in("$reduce_or", "$reduce_bool")) btor_op = "redor";
if (cell->type.in("$reduce_xor", "$reduce_xnor")) btor_op = "redxor";
if (cell->type == ID($reduce_and)) btor_op = "redand";
if (cell->type.in(ID($reduce_or), ID($reduce_bool))) btor_op = "redor";
if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) btor_op = "redxor";
log_assert(!btor_op.empty());
int sid = get_bv_sid(1);
int nid_a = get_sig_nid(cell->getPort("\\A"));
int nid_a = get_sig_nid(cell->getPort(ID::A));
int nid = next_nid++;
btorf("%d %s %d %d\n", nid, btor_op.c_str(), sid, nid_a);
if (cell->type == "$reduce_xnor") {
if (cell->type == ID($reduce_xnor)) {
int nid2 = next_nid++;
btorf("%d %s %d %d %s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
btorf("%d not %d %d %d\n", nid2, sid, nid);
nid = nid2;
} else {
btorf("%d %s %d %d %s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
}
SigSpec sig = sigmap(cell->getPort("\\Y"));
SigSpec sig = sigmap(cell->getPort(ID::Y));
if (GetSize(sig) > 1) {
int sid = get_bv_sid(GetSize(sig));
@ -496,12 +536,12 @@ struct BtorWorker
goto okay;
}
if (cell->type.in("$mux", "$_MUX_", "$_NMUX_"))
if (cell->type.in(ID($mux), ID($_MUX_), ID($_NMUX_)))
{
SigSpec sig_a = sigmap(cell->getPort("\\A"));
SigSpec sig_b = sigmap(cell->getPort("\\B"));
SigSpec sig_s = sigmap(cell->getPort("\\S"));
SigSpec sig_y = sigmap(cell->getPort("\\Y"));
SigSpec sig_a = sigmap(cell->getPort(ID::A));
SigSpec sig_b = sigmap(cell->getPort(ID::B));
SigSpec sig_s = sigmap(cell->getPort(ID::S));
SigSpec sig_y = sigmap(cell->getPort(ID::Y));
int nid_a = get_sig_nid(sig_a);
int nid_b = get_sig_nid(sig_b);
@ -509,24 +549,26 @@ struct BtorWorker
int sid = get_bv_sid(GetSize(sig_y));
int nid = next_nid++;
btorf("%d ite %d %d %d %d\n", nid, sid, nid_s, nid_b, nid_a);
if (cell->type == "$_NMUX_") {
if (cell->type == ID($_NMUX_)) {
int tmp = nid;
nid = next_nid++;
btorf("%d not %d %d\n", nid, sid, tmp);
btorf("%d ite %d %d %d %d\n", tmp, sid, nid_s, nid_b, nid_a);
btorf("%d not %d %d %s\n", nid, sid, tmp, getinfo(cell).c_str());
} else {
btorf("%d ite %d %d %d %d %s\n", nid, sid, nid_s, nid_b, nid_a, getinfo(cell).c_str());
}
add_nid_sig(nid, sig_y);
goto okay;
}
if (cell->type == "$pmux")
if (cell->type == ID($pmux))
{
SigSpec sig_a = sigmap(cell->getPort("\\A"));
SigSpec sig_b = sigmap(cell->getPort("\\B"));
SigSpec sig_s = sigmap(cell->getPort("\\S"));
SigSpec sig_y = sigmap(cell->getPort("\\Y"));
SigSpec sig_a = sigmap(cell->getPort(ID::A));
SigSpec sig_b = sigmap(cell->getPort(ID::B));
SigSpec sig_s = sigmap(cell->getPort(ID::S));
SigSpec sig_y = sigmap(cell->getPort(ID::Y));
int width = GetSize(sig_a);
int sid = get_bv_sid(width);
@ -536,7 +578,10 @@ struct BtorWorker
int nid_b = get_sig_nid(sig_b.extract(i*width, width));
int nid_s = get_sig_nid(sig_s.extract(i));
int nid2 = next_nid++;
btorf("%d ite %d %d %d %d\n", nid2, sid, nid_s, nid_b, nid);
if (i == GetSize(sig_s)-1)
btorf("%d ite %d %d %d %d %s\n", nid2, sid, nid_s, nid_b, nid, getinfo(cell).c_str());
else
btorf("%d ite %d %d %d %d\n", nid2, sid, nid_s, nid_b, nid);
nid = nid2;
}
@ -544,10 +589,25 @@ struct BtorWorker
goto okay;
}
if (cell->type.in("$dff", "$ff", "$_DFF_P_", "$_DFF_N", "$_FF_"))
if (cell->type.in(ID($dff), ID($ff), ID($_DFF_P_), ID($_DFF_N), ID($_FF_)))
{
SigSpec sig_d = sigmap(cell->getPort("\\D"));
SigSpec sig_q = sigmap(cell->getPort("\\Q"));
SigSpec sig_d = sigmap(cell->getPort(ID::D));
SigSpec sig_q = sigmap(cell->getPort(ID::Q));
if (!info_filename.empty() && cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_)))
{
SigSpec sig_c = sigmap(cell->getPort(cell->type == ID($dff) ? ID::CLK : ID::C));
int nid = get_sig_nid(sig_c);
bool negedge = false;
if (cell->type == ID($_DFF_N_))
negedge = true;
if (cell->type == ID($dff) && !cell->getParam(ID::CLK_POLARITY).as_bool())
negedge = true;
info_clocks[nid] |= negedge ? 2 : 1;
}
IdString symbol;
@ -591,16 +651,16 @@ struct BtorWorker
goto okay;
}
if (cell->type.in("$anyconst", "$anyseq"))
if (cell->type.in(ID($anyconst), ID($anyseq)))
{
SigSpec sig_y = sigmap(cell->getPort("\\Y"));
SigSpec sig_y = sigmap(cell->getPort(ID::Y));
int sid = get_bv_sid(GetSize(sig_y));
int nid = next_nid++;
btorf("%d state %d\n", nid, sid);
if (cell->type == "$anyconst") {
if (cell->type == ID($anyconst)) {
int nid2 = next_nid++;
btorf("%d next %d %d %d\n", nid2, sid, nid, nid);
}
@ -609,9 +669,9 @@ struct BtorWorker
goto okay;
}
if (cell->type == "$initstate")
if (cell->type == ID($initstate))
{
SigSpec sig_y = sigmap(cell->getPort("\\Y"));
SigSpec sig_y = sigmap(cell->getPort(ID::Y));
if (initstate_nid < 0)
{
@ -628,16 +688,16 @@ struct BtorWorker
goto okay;
}
if (cell->type == "$mem")
if (cell->type == ID($mem))
{
int abits = cell->getParam("\\ABITS").as_int();
int width = cell->getParam("\\WIDTH").as_int();
int nwords = cell->getParam("\\SIZE").as_int();
int rdports = cell->getParam("\\RD_PORTS").as_int();
int wrports = cell->getParam("\\WR_PORTS").as_int();
int abits = cell->getParam(ID::ABITS).as_int();
int width = cell->getParam(ID::WIDTH).as_int();
int nwords = cell->getParam(ID::SIZE).as_int();
int rdports = cell->getParam(ID::RD_PORTS).as_int();
int wrports = cell->getParam(ID::WR_PORTS).as_int();
Const wr_clk_en = cell->getParam("\\WR_CLK_ENABLE");
Const rd_clk_en = cell->getParam("\\RD_CLK_ENABLE");
Const wr_clk_en = cell->getParam(ID::WR_CLK_ENABLE);
Const rd_clk_en = cell->getParam(ID::RD_CLK_ENABLE);
bool asyncwr = wr_clk_en.is_fully_zero();
@ -649,18 +709,18 @@ struct BtorWorker
log_error("Memory %s.%s has sync read ports.\n",
log_id(module), log_id(cell));
SigSpec sig_rd_addr = sigmap(cell->getPort("\\RD_ADDR"));
SigSpec sig_rd_data = sigmap(cell->getPort("\\RD_DATA"));
SigSpec sig_rd_addr = sigmap(cell->getPort(ID::RD_ADDR));
SigSpec sig_rd_data = sigmap(cell->getPort(ID::RD_DATA));
SigSpec sig_wr_addr = sigmap(cell->getPort("\\WR_ADDR"));
SigSpec sig_wr_data = sigmap(cell->getPort("\\WR_DATA"));
SigSpec sig_wr_en = sigmap(cell->getPort("\\WR_EN"));
SigSpec sig_wr_addr = sigmap(cell->getPort(ID::WR_ADDR));
SigSpec sig_wr_data = sigmap(cell->getPort(ID::WR_DATA));
SigSpec sig_wr_en = sigmap(cell->getPort(ID::WR_EN));
int data_sid = get_bv_sid(width);
int bool_sid = get_bv_sid(1);
int sid = get_mem_sid(abits, width);
Const initdata = cell->getParam("\\INIT");
Const initdata = cell->getParam(ID::INIT);
initdata.exts(nwords*width);
int nid_init_val = -1;
@ -983,15 +1043,18 @@ struct BtorWorker
return nid;
}
BtorWorker(std::ostream &f, RTLIL::Module *module, bool verbose, bool single_bad) :
f(f), sigmap(module), module(module), verbose(verbose), single_bad(single_bad)
BtorWorker(std::ostream &f, RTLIL::Module *module, bool verbose, bool single_bad, bool cover_mode, string info_filename) :
f(f), sigmap(module), module(module), verbose(verbose), single_bad(single_bad), cover_mode(cover_mode), info_filename(info_filename)
{
if (!info_filename.empty())
infof("name %s\n", log_id(module));
btorf_push("inputs");
for (auto wire : module->wires())
{
if (wire->attributes.count("\\init")) {
Const attrval = wire->attributes.at("\\init");
if (wire->attributes.count(ID::init)) {
Const attrval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(wire) && i < GetSize(attrval); i++)
if (attrval[i] == State::S0 || attrval[i] == State::S1)
initbits[sigmap(SigBit(wire, i))] = (attrval[i] == State::S1);
@ -1004,7 +1067,7 @@ struct BtorWorker
int sid = get_bv_sid(GetSize(sig));
int nid = next_nid++;
btorf("%d input %d %s\n", nid, sid, log_id(wire));
btorf("%d input %d %s\n", nid, sid, getinfo(wire).c_str());
add_nid_sig(nid, sig);
}
@ -1028,20 +1091,20 @@ struct BtorWorker
btorf_push(stringf("output %s", log_id(wire)));
int nid = get_sig_nid(wire);
btorf("%d output %d %s\n", next_nid++, nid, log_id(wire));
btorf("%d output %d %s\n", next_nid++, nid, getinfo(wire).c_str());
btorf_pop(stringf("output %s", log_id(wire)));
}
for (auto cell : module->cells())
{
if (cell->type == "$assume")
if (cell->type == ID($assume))
{
btorf_push(log_id(cell));
int sid = get_bv_sid(1);
int nid_a = get_sig_nid(cell->getPort("\\A"));
int nid_en = get_sig_nid(cell->getPort("\\EN"));
int nid_a = get_sig_nid(cell->getPort(ID::A));
int nid_en = get_sig_nid(cell->getPort(ID::EN));
int nid_not_en = next_nid++;
int nid_a_or_not_en = next_nid++;
int nid = next_nid++;
@ -1053,29 +1116,49 @@ struct BtorWorker
btorf_pop(log_id(cell));
}
if (cell->type == "$assert")
if (cell->type == ID($assert))
{
btorf_push(log_id(cell));
int sid = get_bv_sid(1);
int nid_a = get_sig_nid(cell->getPort("\\A"));
int nid_en = get_sig_nid(cell->getPort("\\EN"));
int nid_a = get_sig_nid(cell->getPort(ID::A));
int nid_en = get_sig_nid(cell->getPort(ID::EN));
int nid_not_a = next_nid++;
int nid_en_and_not_a = next_nid++;
btorf("%d not %d %d\n", nid_not_a, sid, nid_a);
btorf("%d and %d %d %d\n", nid_en_and_not_a, sid, nid_en, nid_not_a);
if (single_bad) {
if (single_bad && !cover_mode) {
bad_properties.push_back(nid_en_and_not_a);
} else {
int nid = next_nid++;
string infostr = log_id(cell);
if (infostr[0] == '$' && cell->attributes.count("\\src")) {
infostr = cell->attributes.at("\\src").decode_string().c_str();
std::replace(infostr.begin(), infostr.end(), ' ', '_');
if (cover_mode) {
infof("bad %d %s\n", nid_en_and_not_a, getinfo(cell, true).c_str());
} else {
int nid = next_nid++;
btorf("%d bad %d %s\n", nid, nid_en_and_not_a, getinfo(cell, true).c_str());
}
btorf("%d bad %d %s\n", nid, nid_en_and_not_a, infostr.c_str());
}
btorf_pop(log_id(cell));
}
if (cell->type == ID($cover) && cover_mode)
{
btorf_push(log_id(cell));
int sid = get_bv_sid(1);
int nid_a = get_sig_nid(cell->getPort(ID::A));
int nid_en = get_sig_nid(cell->getPort(ID::EN));
int nid_en_and_a = next_nid++;
btorf("%d and %d %d %d\n", nid_en_and_a, sid, nid_en, nid_a);
if (single_bad) {
bad_properties.push_back(nid_en_and_a);
} else {
int nid = next_nid++;
btorf("%d bad %d %s\n", nid, nid_en_and_a, getinfo(cell, true).c_str());
}
btorf_pop(log_id(cell));
@ -1096,7 +1179,7 @@ struct BtorWorker
continue;
int this_nid = next_nid++;
btorf("%d uext %d %d %d %s\n", this_nid, sid, nid, 0, log_id(wire));
btorf("%d uext %d %d %d %s\n", this_nid, sid, nid, 0, getinfo(wire).c_str());
btorf_pop(stringf("wire %s", log_id(wire)));
continue;
@ -1114,15 +1197,15 @@ struct BtorWorker
btorf_push(stringf("next %s", log_id(cell)));
if (cell->type == "$mem")
if (cell->type == ID($mem))
{
int abits = cell->getParam("\\ABITS").as_int();
int width = cell->getParam("\\WIDTH").as_int();
int wrports = cell->getParam("\\WR_PORTS").as_int();
int abits = cell->getParam(ID::ABITS).as_int();
int width = cell->getParam(ID::WIDTH).as_int();
int wrports = cell->getParam(ID::WR_PORTS).as_int();
SigSpec sig_wr_addr = sigmap(cell->getPort("\\WR_ADDR"));
SigSpec sig_wr_data = sigmap(cell->getPort("\\WR_DATA"));
SigSpec sig_wr_en = sigmap(cell->getPort("\\WR_EN"));
SigSpec sig_wr_addr = sigmap(cell->getPort(ID::WR_ADDR));
SigSpec sig_wr_data = sigmap(cell->getPort(ID::WR_DATA));
SigSpec sig_wr_en = sigmap(cell->getPort(ID::WR_EN));
int data_sid = get_bv_sid(width);
int bool_sid = get_bv_sid(1);
@ -1167,14 +1250,14 @@ struct BtorWorker
}
int nid2 = next_nid++;
btorf("%d next %d %d %d\n", nid2, sid, nid, nid_head);
btorf("%d next %d %d %d %s\n", nid2, sid, nid, nid_head, getinfo(cell).c_str());
}
else
{
SigSpec sig = sigmap(cell->getPort("\\D"));
SigSpec sig = sigmap(cell->getPort(ID::D));
int nid_q = get_sig_nid(sig);
int sid = get_bv_sid(GetSize(sig));
btorf("%d next %d %d %d\n", next_nid++, sid, nid, nid_q);
btorf("%d next %d %d %d %s\n", next_nid++, sid, nid, nid_q, getinfo(cell).c_str());
}
btorf_pop(stringf("next %s", log_id(cell)));
@ -1210,6 +1293,35 @@ struct BtorWorker
btorf("%d bad %d\n", nid, todo[cursor]);
}
}
if (!info_filename.empty())
{
for (auto &it : info_clocks)
{
switch (it.second)
{
case 1:
infof("posedge %d\n", it.first);
break;
case 2:
infof("negedge %d\n", it.first);
break;
case 3:
infof("event %d\n", it.first);
break;
default:
log_abort();
}
}
std::ofstream f;
f.open(info_filename.c_str(), std::ofstream::trunc);
if (f.fail())
log_error("Can't open file `%s' for writing: %s\n", info_filename.c_str(), strerror(errno));
for (auto &it : info_lines)
f << it;
f.close();
}
}
};
@ -1229,10 +1341,17 @@ struct BtorBackend : public Backend {
log(" -s\n");
log(" Output only a single bad property for all asserts\n");
log("\n");
log(" -c\n");
log(" Output cover properties using 'bad' statements instead of asserts\n");
log("\n");
log(" -i <filename>\n");
log(" Create additional info file with auxiliary information\n");
log("\n");
}
void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
bool verbose = false, single_bad = false;
bool verbose = false, single_bad = false, cover_mode = false;
string info_filename;
log_header(design, "Executing BTOR backend.\n");
@ -1247,6 +1366,14 @@ struct BtorBackend : public Backend {
single_bad = true;
continue;
}
if (args[argidx] == "-c") {
cover_mode = true;
continue;
}
if (args[argidx] == "-i" && argidx+1 < args.size()) {
info_filename = args[++argidx];
continue;
}
break;
}
extra_args(f, filename, args, argidx);
@ -1259,7 +1386,7 @@ struct BtorBackend : public Backend {
*f << stringf("; BTOR description generated by %s for module %s.\n",
yosys_version_str, log_id(topmod));
BtorWorker(*f, topmod, verbose, single_bad);
BtorWorker(*f, topmod, verbose, single_bad, cover_mode, info_filename);
*f << stringf("; end of yosys output\n");
}

View file

@ -171,13 +171,12 @@ struct EdifBackend : public Backend {
extra_args(f, filename, args, argidx);
if (top_module_name.empty())
for (auto & mod_it:design->modules_)
if (mod_it.second->get_bool_attribute("\\top"))
top_module_name = mod_it.first.str();
for (auto module : design->modules())
if (module->get_bool_attribute(ID::top))
top_module_name = module->name.str();
for (auto module_it : design->modules_)
for (auto module : design->modules())
{
RTLIL::Module *module = module_it.second;
if (module->get_blackbox_attribute())
continue;
@ -185,14 +184,13 @@ struct EdifBackend : public Backend {
top_module_name = module->name.str();
if (module->processes.size() != 0)
log_error("Found unmapped processes in module %s: unmapped processes are not supported in EDIF backend!\n", RTLIL::id2cstr(module->name));
log_error("Found unmapped processes in module %s: unmapped processes are not supported in EDIF backend!\n", log_id(module->name));
if (module->memories.size() != 0)
log_error("Found unmapped memories in module %s: unmapped memories are not supported in EDIF backend!\n", RTLIL::id2cstr(module->name));
log_error("Found unmapped memories in module %s: unmapped memories are not supported in EDIF backend!\n", log_id(module->name));
for (auto cell_it : module->cells_)
for (auto cell : module->cells())
{
RTLIL::Cell *cell = cell_it.second;
if (!design->modules_.count(cell->type) || design->modules_.at(cell->type)->get_blackbox_attribute()) {
if (design->module(cell->type) == nullptr || design->module(cell->type)->get_blackbox_attribute()) {
lib_cell_ports[cell->type];
for (auto p : cell->connections())
lib_cell_ports[cell->type][p.first] = GetSize(p.second);
@ -277,11 +275,11 @@ struct EdifBackend : public Backend {
// extract module dependencies
std::map<RTLIL::Module*, std::set<RTLIL::Module*>> module_deps;
for (auto &mod_it : design->modules_) {
module_deps[mod_it.second] = std::set<RTLIL::Module*>();
for (auto &cell_it : mod_it.second->cells_)
if (design->modules_.count(cell_it.second->type) > 0)
module_deps[mod_it.second].insert(design->modules_.at(cell_it.second->type));
for (auto module : design->modules()) {
module_deps[module] = std::set<RTLIL::Module*>();
for (auto cell : module->cells())
if (design->module(cell->type) != nullptr)
module_deps[module].insert(design->module(cell->type));
}
// simple good-enough topological sort
@ -292,12 +290,12 @@ struct EdifBackend : public Backend {
for (auto &dep : it.second)
if (module_deps.count(dep) > 0)
goto not_ready_yet;
// log("Next in topological sort: %s\n", RTLIL::id2cstr(it.first->name));
// log("Next in topological sort: %s\n", log_id(it.first->name));
sorted_modules.push_back(it.first);
not_ready_yet:;
}
if (sorted_modules_idx == sorted_modules.size())
log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", RTLIL::id2cstr(module_deps.begin()->first->name));
log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", log_id(module_deps.begin()->first->name));
while (sorted_modules_idx < sorted_modules.size())
module_deps.erase(sorted_modules.at(sorted_modules_idx++));
}
@ -339,8 +337,7 @@ struct EdifBackend : public Backend {
*f << stringf(" (view VIEW_NETLIST\n");
*f << stringf(" (viewType NETLIST)\n");
*f << stringf(" (interface\n");
for (auto &wire_it : module->wires_) {
RTLIL::Wire *wire = wire_it.second;
for (auto wire : module->wires()) {
if (wire->port_id == 0)
continue;
const char *dir = "INOUT";
@ -378,8 +375,7 @@ struct EdifBackend : public Backend {
*f << stringf(" (instance GND (viewRef VIEW_NETLIST (cellRef GND (libraryRef LIB))))\n");
*f << stringf(" (instance VCC (viewRef VIEW_NETLIST (cellRef VCC (libraryRef LIB))))\n");
}
for (auto &cell_it : module->cells_) {
RTLIL::Cell *cell = cell_it.second;
for (auto cell : module->cells()) {
*f << stringf(" (instance %s\n", EDIF_DEF(cell->name));
*f << stringf(" (viewRef VIEW_NETLIST (cellRef %s%s))", EDIF_REF(cell->type),
lib_cell_ports.count(cell->type) > 0 ? " (libraryRef LIB)" : "");
@ -459,8 +455,7 @@ struct EdifBackend : public Backend {
add_prop(p.first, p.second);
*f << stringf("\n )\n");
}
for (auto &wire_it : module->wires_) {
RTLIL::Wire *wire = wire_it.second;
for (auto wire : module->wires()) {
if (!wire->get_bool_attribute(ID::keep))
continue;
for(int i = 0; i < wire->width; i++) {

View file

@ -208,7 +208,7 @@ struct FirrtlWorker
const char *atLine() {
if (srcLine == "") {
if (pCell) {
auto p = pCell->attributes.find("\\src");
auto p = pCell->attributes.find(ID::src);
srcLine = " at " + p->second.decode_string();
}
}
@ -414,9 +414,9 @@ struct FirrtlWorker
std::string wireFileinfo = getFileinfo(wire);
// If a wire has initial data, issue a warning since FIRRTL doesn't currently support it.
if (wire->attributes.count("\\init")) {
if (wire->attributes.count(ID::init)) {
log_warning("Initial value (%s) for (%s.%s) not supported\n",
wire->attributes.at("\\init").as_string().c_str(),
wire->attributes.at(ID::init).as_string().c_str(),
log_id(module), log_id(wire));
}
if (wire->port_id)
@ -444,11 +444,11 @@ struct FirrtlWorker
}
// Not a module instance. Set up cell properties
bool extract_y_bits = false; // Assume no extraction of final bits will be required.
int a_width = cell->parameters.at("\\A_WIDTH", ndef).as_int(); // The width of "A"
int b_width = cell->parameters.at("\\B_WIDTH", ndef).as_int(); // The width of "A"
const int y_width = cell->parameters.at("\\Y_WIDTH", ndef).as_int(); // The width of the result
const bool a_signed = cell->parameters.at("\\A_SIGNED", ndef).as_bool();
const bool b_signed = cell->parameters.at("\\B_SIGNED", ndef).as_bool();
int a_width = cell->parameters.at(ID::A_WIDTH, ndef).as_int(); // The width of "A"
int b_width = cell->parameters.at(ID::B_WIDTH, ndef).as_int(); // The width of "A"
const int y_width = cell->parameters.at(ID::Y_WIDTH, ndef).as_int(); // The width of the result
const bool a_signed = cell->parameters.at(ID::A_SIGNED, ndef).as_bool();
const bool b_signed = cell->parameters.at(ID::B_SIGNED, ndef).as_bool();
bool firrtl_is_signed = a_signed; // The result is signed (subsequent code may change this).
int firrtl_width = 0;
string primop;
@ -456,9 +456,9 @@ struct FirrtlWorker
string y_id = make_id(cell->name);
std::string cellFileinfo = getFileinfo(cell);
if (cell->type.in("$not", "$logic_not", "$neg", "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_bool", "$reduce_xnor"))
if (cell->type.in(ID($not), ID($logic_not), ID($neg), ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_bool), ID($reduce_xnor)))
{
string a_expr = make_expr(cell->getPort("\\A"));
string a_expr = make_expr(cell->getPort(ID::A));
wire_decls.push_back(stringf(" wire %s: UInt<%d> %s\n", y_id.c_str(), y_width, cellFileinfo.c_str()));
if (a_signed) {
@ -466,29 +466,29 @@ struct FirrtlWorker
}
// Don't use the results of logical operations (a single bit) to control padding
if (!(cell->type.in("$eq", "$eqx", "$gt", "$ge", "$lt", "$le", "$ne", "$nex", "$reduce_bool", "$logic_not") && y_width == 1) ) {
if (!(cell->type.in(ID($eq), ID($eqx), ID($gt), ID($ge), ID($lt), ID($le), ID($ne), ID($nex), ID($reduce_bool), ID($logic_not)) && y_width == 1) ) {
a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width);
}
// Assume the FIRRTL width is a single bit.
firrtl_width = 1;
if (cell->type == "$not") primop = "not";
else if (cell->type == "$neg") {
if (cell->type == ID($not)) primop = "not";
else if (cell->type == ID($neg)) {
primop = "neg";
firrtl_is_signed = true; // Result of "neg" is signed (an SInt).
firrtl_width = a_width;
} else if (cell->type == "$logic_not") {
} else if (cell->type == ID($logic_not)) {
primop = "eq";
a_expr = stringf("%s, UInt(0)", a_expr.c_str());
}
else if (cell->type == "$reduce_and") primop = "andr";
else if (cell->type == "$reduce_or") primop = "orr";
else if (cell->type == "$reduce_xor") primop = "xorr";
else if (cell->type == "$reduce_xnor") {
else if (cell->type == ID($reduce_and)) primop = "andr";
else if (cell->type == ID($reduce_or)) primop = "orr";
else if (cell->type == ID($reduce_xor)) primop = "xorr";
else if (cell->type == ID($reduce_xnor)) {
primop = "not";
a_expr = stringf("xorr(%s)", a_expr.c_str());
}
else if (cell->type == "$reduce_bool") {
else if (cell->type == ID($reduce_bool)) {
primop = "neq";
// Use the sign of the a_expr and its width as the type (UInt/SInt) and width of the comparand.
a_expr = stringf("%s, %cInt<%d>(0)", a_expr.c_str(), a_signed ? 'S' : 'U', a_width);
@ -500,16 +500,16 @@ struct FirrtlWorker
expr = stringf("asUInt(%s)", expr.c_str());
cell_exprs.push_back(stringf(" %s <= %s %s\n", y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
register_reverse_wire_map(y_id, cell->getPort("\\Y"));
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
}
if (cell->type.in("$add", "$sub", "$mul", "$div", "$mod", "$xor", "$xnor", "$and", "$or", "$eq", "$eqx",
"$gt", "$ge", "$lt", "$le", "$ne", "$nex", "$shr", "$sshr", "$sshl", "$shl",
"$logic_and", "$logic_or", "$pow"))
if (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($xor), ID($xnor), ID($and), ID($or), ID($eq), ID($eqx),
ID($gt), ID($ge), ID($lt), ID($le), ID($ne), ID($nex), ID($shr), ID($sshr), ID($sshl), ID($shl),
ID($logic_and), ID($logic_or), ID($pow)))
{
string a_expr = make_expr(cell->getPort("\\A"));
string b_expr = make_expr(cell->getPort("\\B"));
string a_expr = make_expr(cell->getPort(ID::A));
string b_expr = make_expr(cell->getPort(ID::B));
std::string cellFileinfo = getFileinfo(cell);
wire_decls.push_back(stringf(" wire %s: UInt<%d> %s\n", y_id.c_str(), y_width, cellFileinfo.c_str()));
@ -523,7 +523,7 @@ struct FirrtlWorker
}
// Shift amount is always unsigned, and needn't be padded to result width,
// otherwise, we need to cast the b_expr appropriately
if (b_signed && !cell->type.in("$shr", "$sshr", "$shl", "$sshl", "$pow")) {
if (b_signed && !cell->type.in(ID($shr), ID($sshr), ID($shl), ID($sshl), ID($pow))) {
b_expr = "asSInt(" + b_expr + ")";
// Expand the "B" operand to the result width
if (b_width < y_width) {
@ -534,7 +534,7 @@ struct FirrtlWorker
// For the arithmetic ops, expand operand widths to result widths befor performing the operation.
// This corresponds (according to iverilog) to what verilog compilers implement.
if (cell->type.in("$add", "$sub", "$mul", "$div", "$mod", "$xor", "$xnor", "$and", "$or"))
if (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($xor), ID($xnor), ID($and), ID($or)))
{
if (a_width < y_width) {
a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width);
@ -547,85 +547,85 @@ struct FirrtlWorker
}
// Assume the FIRRTL width is the width of "A"
firrtl_width = a_width;
auto a_sig = cell->getPort("\\A");
auto a_sig = cell->getPort(ID::A);
if (cell->type == "$add") {
if (cell->type == ID($add)) {
primop = "add";
firrtl_is_signed = a_signed | b_signed;
firrtl_width = max(a_width, b_width);
} else if (cell->type == "$sub") {
} else if (cell->type == ID($sub)) {
primop = "sub";
firrtl_is_signed = true;
int a_widthInc = (!a_signed && b_signed) ? 2 : (a_signed && !b_signed) ? 1 : 0;
int b_widthInc = (a_signed && !b_signed) ? 2 : (!a_signed && b_signed) ? 1 : 0;
firrtl_width = max(a_width + a_widthInc, b_width + b_widthInc);
} else if (cell->type == "$mul") {
} else if (cell->type == ID($mul)) {
primop = "mul";
firrtl_is_signed = a_signed | b_signed;
firrtl_width = a_width + b_width;
} else if (cell->type == "$div") {
} else if (cell->type == ID($div)) {
primop = "div";
firrtl_is_signed = a_signed | b_signed;
firrtl_width = a_width;
} else if (cell->type == "$mod") {
} else if (cell->type == ID($mod)) {
primop = "rem";
firrtl_width = min(a_width, b_width);
} else if (cell->type == "$and") {
} else if (cell->type == ID($and)) {
primop = "and";
always_uint = true;
firrtl_width = max(a_width, b_width);
}
else if (cell->type == "$or" ) {
else if (cell->type == ID($or) ) {
primop = "or";
always_uint = true;
firrtl_width = max(a_width, b_width);
}
else if (cell->type == "$xor") {
else if (cell->type == ID($xor)) {
primop = "xor";
always_uint = true;
firrtl_width = max(a_width, b_width);
}
else if (cell->type == "$xnor") {
else if (cell->type == ID($xnor)) {
primop = "xnor";
always_uint = true;
firrtl_width = max(a_width, b_width);
}
else if ((cell->type == "$eq") | (cell->type == "$eqx")) {
else if ((cell->type == ID($eq)) | (cell->type == ID($eqx))) {
primop = "eq";
always_uint = true;
firrtl_width = 1;
}
else if ((cell->type == "$ne") | (cell->type == "$nex")) {
}
else if ((cell->type == ID($ne)) | (cell->type == ID($nex))) {
primop = "neq";
always_uint = true;
firrtl_width = 1;
}
else if (cell->type == "$gt") {
else if (cell->type == ID($gt)) {
primop = "gt";
always_uint = true;
firrtl_width = 1;
}
else if (cell->type == "$ge") {
else if (cell->type == ID($ge)) {
primop = "geq";
always_uint = true;
firrtl_width = 1;
}
else if (cell->type == "$lt") {
else if (cell->type == ID($lt)) {
primop = "lt";
always_uint = true;
firrtl_width = 1;
}
else if (cell->type == "$le") {
else if (cell->type == ID($le)) {
primop = "leq";
always_uint = true;
firrtl_width = 1;
}
else if ((cell->type == "$shl") | (cell->type == "$sshl")) {
else if ((cell->type == ID($shl)) | (cell->type == ID($sshl))) {
// FIRRTL will widen the result (y) by the amount of the shift.
// We'll need to offset this by extracting the un-widened portion as Verilog would do.
extract_y_bits = true;
// Is the shift amount constant?
auto b_sig = cell->getPort("\\B");
auto b_sig = cell->getPort(ID::B);
if (b_sig.is_fully_const()) {
primop = "shl";
int shift_amount = b_sig.as_int();
@ -638,11 +638,11 @@ struct FirrtlWorker
firrtl_width = a_width + (1 << b_width) - 1;
}
}
else if ((cell->type == "$shr") | (cell->type == "$sshr")) {
else if ((cell->type == ID($shr)) | (cell->type == ID($sshr))) {
// We don't need to extract a specific range of bits.
extract_y_bits = false;
// Is the shift amount constant?
auto b_sig = cell->getPort("\\B");
auto b_sig = cell->getPort(ID::B);
if (b_sig.is_fully_const()) {
primop = "shr";
int shift_amount = b_sig.as_int();
@ -655,26 +655,26 @@ struct FirrtlWorker
// We'll need to do some special fixups if the source (and thus result) is signed.
if (firrtl_is_signed) {
// If this is a "logical" shift right, pretend the source is unsigned.
if (cell->type == "$shr") {
if (cell->type == ID($shr)) {
a_expr = "asUInt(" + a_expr + ")";
}
}
}
else if ((cell->type == "$logic_and")) {
else if ((cell->type == ID($logic_and))) {
primop = "and";
a_expr = "neq(" + a_expr + ", UInt(0))";
b_expr = "neq(" + b_expr + ", UInt(0))";
always_uint = true;
firrtl_width = 1;
}
else if ((cell->type == "$logic_or")) {
else if ((cell->type == ID($logic_or))) {
primop = "or";
a_expr = "neq(" + a_expr + ", UInt(0))";
b_expr = "neq(" + b_expr + ", UInt(0))";
always_uint = true;
firrtl_width = 1;
}
else if ((cell->type == "$pow")) {
else if ((cell->type == ID($pow))) {
if (a_sig.is_fully_const() && a_sig.as_int() == 2) {
// We'll convert this to a shift. To simplify things, change the a_expr to "1"
// so we can use b_expr directly as a shift amount.
@ -684,7 +684,7 @@ struct FirrtlWorker
a_expr = firrtl_is_signed ? "SInt(1)" : "UInt(1)";
extract_y_bits = true;
// Is the shift amount constant?
auto b_sig = cell->getPort("\\B");
auto b_sig = cell->getPort(ID::B);
if (b_sig.is_fully_const()) {
primop = "shl";
int shiftAmount = b_sig.as_int();
@ -704,7 +704,7 @@ struct FirrtlWorker
}
}
if (!cell->parameters.at("\\B_SIGNED").as_bool()) {
if (!cell->parameters.at(ID::B_SIGNED).as_bool()) {
b_expr = "asUInt(" + b_expr + ")";
}
@ -728,47 +728,47 @@ struct FirrtlWorker
expr = stringf("asUInt(%s)", expr.c_str());
cell_exprs.push_back(stringf(" %s <= %s %s\n", y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
register_reverse_wire_map(y_id, cell->getPort("\\Y"));
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
}
if (cell->type.in("$mux"))
if (cell->type.in(ID($mux)))
{
int width = cell->parameters.at("\\WIDTH").as_int();
string a_expr = make_expr(cell->getPort("\\A"));
string b_expr = make_expr(cell->getPort("\\B"));
string s_expr = make_expr(cell->getPort("\\S"));
int width = cell->parameters.at(ID::WIDTH).as_int();
string a_expr = make_expr(cell->getPort(ID::A));
string b_expr = make_expr(cell->getPort(ID::B));
string s_expr = make_expr(cell->getPort(ID::S));
wire_decls.push_back(stringf(" wire %s: UInt<%d> %s\n", y_id.c_str(), width, cellFileinfo.c_str()));
string expr = stringf("mux(%s, %s, %s)", s_expr.c_str(), b_expr.c_str(), a_expr.c_str());
cell_exprs.push_back(stringf(" %s <= %s %s\n", y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
register_reverse_wire_map(y_id, cell->getPort("\\Y"));
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
}
if (cell->type.in("$mem"))
if (cell->type.in(ID($mem)))
{
string mem_id = make_id(cell->name);
int abits = cell->parameters.at("\\ABITS").as_int();
int width = cell->parameters.at("\\WIDTH").as_int();
int size = cell->parameters.at("\\SIZE").as_int();
int abits = cell->parameters.at(ID::ABITS).as_int();
int width = cell->parameters.at(ID::WIDTH).as_int();
int size = cell->parameters.at(ID::SIZE).as_int();
memory m(cell, mem_id, abits, size, width);
int rd_ports = cell->parameters.at("\\RD_PORTS").as_int();
int wr_ports = cell->parameters.at("\\WR_PORTS").as_int();
int rd_ports = cell->parameters.at(ID::RD_PORTS).as_int();
int wr_ports = cell->parameters.at(ID::WR_PORTS).as_int();
Const initdata = cell->parameters.at("\\INIT");
Const initdata = cell->parameters.at(ID::INIT);
for (State bit : initdata.bits)
if (bit != State::Sx)
log_error("Memory with initialization data: %s.%s\n", log_id(module), log_id(cell));
Const rd_clk_enable = cell->parameters.at("\\RD_CLK_ENABLE");
Const wr_clk_enable = cell->parameters.at("\\WR_CLK_ENABLE");
Const wr_clk_polarity = cell->parameters.at("\\WR_CLK_POLARITY");
Const rd_clk_enable = cell->parameters.at(ID::RD_CLK_ENABLE);
Const wr_clk_enable = cell->parameters.at(ID::WR_CLK_ENABLE);
Const wr_clk_polarity = cell->parameters.at(ID::WR_CLK_POLARITY);
int offset = cell->parameters.at("\\OFFSET").as_int();
int offset = cell->parameters.at(ID::OFFSET).as_int();
if (offset != 0)
log_error("Memory with nonzero offset: %s.%s\n", log_id(module), log_id(cell));
@ -777,8 +777,8 @@ struct FirrtlWorker
if (rd_clk_enable[i] != State::S0)
log_error("Clocked read port %d on memory %s.%s.\n", i, log_id(module), log_id(cell));
SigSpec addr_sig = cell->getPort("\\RD_ADDR").extract(i*abits, abits);
SigSpec data_sig = cell->getPort("\\RD_DATA").extract(i*width, width);
SigSpec addr_sig = cell->getPort(ID::RD_ADDR).extract(i*abits, abits);
SigSpec data_sig = cell->getPort(ID::RD_DATA).extract(i*width, width);
string addr_expr = make_expr(addr_sig);
string name(stringf("%s.r%d", m.name.c_str(), i));
bool clk_enable = false;
@ -804,14 +804,14 @@ struct FirrtlWorker
bool clk_enable = true;
bool clk_parity = true;
bool transparency = false;
SigSpec addr_sig =cell->getPort("\\WR_ADDR").extract(i*abits, abits);
SigSpec addr_sig =cell->getPort(ID::WR_ADDR).extract(i*abits, abits);
string addr_expr = make_expr(addr_sig);
SigSpec data_sig =cell->getPort("\\WR_DATA").extract(i*width, width);
SigSpec data_sig =cell->getPort(ID::WR_DATA).extract(i*width, width);
string data_expr = make_expr(data_sig);
SigSpec clk_sig = cell->getPort("\\WR_CLK").extract(i);
SigSpec clk_sig = cell->getPort(ID::WR_CLK).extract(i);
string clk_expr = make_expr(clk_sig);
SigSpec wen_sig = cell->getPort("\\WR_EN").extract(i*width, width);
SigSpec wen_sig = cell->getPort(ID::WR_EN).extract(i*width, width);
string wen_expr = make_expr(wen_sig[0]);
for (int i = 1; i < GetSize(wen_sig); i++)
@ -828,23 +828,23 @@ struct FirrtlWorker
continue;
}
if (cell->type.in("$memwr", "$memrd", "$meminit"))
if (cell->type.in(ID($memwr), ID($memrd), ID($meminit)))
{
std::string cell_type = fid(cell->type);
std::string mem_id = make_id(cell->parameters["\\MEMID"].decode_string());
int abits = cell->parameters.at("\\ABITS").as_int();
int width = cell->parameters.at("\\WIDTH").as_int();
std::string mem_id = make_id(cell->parameters[ID::MEMID].decode_string());
int abits = cell->parameters.at(ID::ABITS).as_int();
int width = cell->parameters.at(ID::WIDTH).as_int();
memory *mp = nullptr;
if (cell->type == "$meminit" ) {
if (cell->type == ID($meminit) ) {
log_error("$meminit (%s.%s.%s) currently unsupported\n", log_id(module), log_id(cell), mem_id.c_str());
} else {
// It's a $memwr or $memrd. Remember the read/write port parameters for the eventual FIRRTL memory definition.
auto addrSig = cell->getPort("\\ADDR");
auto dataSig = cell->getPort("\\DATA");
auto enableSig = cell->getPort("\\EN");
auto clockSig = cell->getPort("\\CLK");
Const clk_enable = cell->parameters.at("\\CLK_ENABLE");
Const clk_polarity = cell->parameters.at("\\CLK_POLARITY");
auto addrSig = cell->getPort(ID::ADDR);
auto dataSig = cell->getPort(ID::DATA);
auto enableSig = cell->getPort(ID::EN);
auto clockSig = cell->getPort(ID::CLK);
Const clk_enable = cell->parameters.at(ID::CLK_ENABLE);
Const clk_polarity = cell->parameters.at(ID::CLK_POLARITY);
// Do we already have an entry for this memory?
if (memories.count(mem_id) == 0) {
@ -855,13 +855,13 @@ struct FirrtlWorker
int portNum = 0;
bool transparency = false;
string data_expr = make_expr(dataSig);
if (cell->type.in("$memwr")) {
if (cell->type.in(ID($memwr))) {
portNum = (int) mp->write_ports.size();
write_port wp(stringf("%s.w%d", mem_id.c_str(), portNum), clk_enable.as_bool(), clk_polarity.as_bool(), transparency, clockSig, enableSig, addrSig, dataSig);
mp->add_memory_write_port(wp);
cell_exprs.push_back(stringf("%s%s.data <= %s\n", indent.c_str(), wp.name.c_str(), data_expr.c_str()));
cell_exprs.push_back(wp.gen_write(indent.c_str()));
} else if (cell->type.in("$memrd")) {
} else if (cell->type.in(ID($memrd))) {
portNum = (int) mp->read_ports.size();
read_port rp(stringf("%s.r%d", mem_id.c_str(), portNum), clk_enable.as_bool(), clk_polarity.as_bool(), transparency, clockSig, enableSig, addrSig);
mp->add_memory_read_port(rp);
@ -872,20 +872,20 @@ struct FirrtlWorker
continue;
}
if (cell->type.in("$dff"))
if (cell->type.in(ID($dff)))
{
bool clkpol = cell->parameters.at("\\CLK_POLARITY").as_bool();
bool clkpol = cell->parameters.at(ID::CLK_POLARITY).as_bool();
if (clkpol == false)
log_error("Negative edge clock on FF %s.%s.\n", log_id(module), log_id(cell));
int width = cell->parameters.at("\\WIDTH").as_int();
string expr = make_expr(cell->getPort("\\D"));
string clk_expr = "asClock(" + make_expr(cell->getPort("\\CLK")) + ")";
int width = cell->parameters.at(ID::WIDTH).as_int();
string expr = make_expr(cell->getPort(ID::D));
string clk_expr = "asClock(" + make_expr(cell->getPort(ID::CLK)) + ")";
wire_decls.push_back(stringf(" reg %s: UInt<%d>, %s %s\n", y_id.c_str(), width, clk_expr.c_str(), cellFileinfo.c_str()));
cell_exprs.push_back(stringf(" %s <= %s %s\n", y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
register_reverse_wire_map(y_id, cell->getPort("\\Q"));
register_reverse_wire_map(y_id, cell->getPort(ID::Q));
continue;
}
@ -896,38 +896,38 @@ struct FirrtlWorker
process_instance(cell, wire_exprs);
continue;
}
if (cell->type == "$shiftx") {
if (cell->type == ID($shiftx)) {
// assign y = a[b +: y_width];
// We'll extract the correct bits as part of the primop.
string a_expr = make_expr(cell->getPort("\\A"));
string a_expr = make_expr(cell->getPort(ID::A));
// Get the initial bit selector
string b_expr = make_expr(cell->getPort("\\B"));
string b_expr = make_expr(cell->getPort(ID::B));
wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
if (cell->getParam("\\B_SIGNED").as_bool()) {
if (cell->getParam(ID::B_SIGNED).as_bool()) {
// Use validif to constrain the selection (test the sign bit)
auto b_string = b_expr.c_str();
int b_sign = cell->parameters.at("\\B_WIDTH").as_int() - 1;
int b_sign = cell->parameters.at(ID::B_WIDTH).as_int() - 1;
b_expr = stringf("validif(not(bits(%s, %d, %d)), %s)", b_string, b_sign, b_sign, b_string);
}
string expr = stringf("dshr(%s, %s)", a_expr.c_str(), b_expr.c_str());
cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str()));
register_reverse_wire_map(y_id, cell->getPort("\\Y"));
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
}
if (cell->type == "$shift") {
if (cell->type == ID($shift)) {
// assign y = a >> b;
// where b may be negative
string a_expr = make_expr(cell->getPort("\\A"));
string b_expr = make_expr(cell->getPort("\\B"));
string a_expr = make_expr(cell->getPort(ID::A));
string b_expr = make_expr(cell->getPort(ID::B));
auto b_string = b_expr.c_str();
string expr;
wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
if (cell->getParam("\\B_SIGNED").as_bool()) {
if (cell->getParam(ID::B_SIGNED).as_bool()) {
// We generate a left or right shift based on the sign of b.
std::string dshl = stringf("bits(dshl(%s, %s), 0, %d)", a_expr.c_str(), gen_dshl(b_expr, b_width).c_str(), y_width);
std::string dshr = stringf("dshr(%s, %s)", a_expr.c_str(), b_string);
@ -940,13 +940,13 @@ struct FirrtlWorker
expr = stringf("dshr(%s, %s)", a_expr.c_str(), b_string);
}
cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str()));
register_reverse_wire_map(y_id, cell->getPort("\\Y"));
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
}
if (cell->type == "$pos") {
if (cell->type == ID($pos)) {
// assign y = a;
// printCell(cell);
string a_expr = make_expr(cell->getPort("\\A"));
string a_expr = make_expr(cell->getPort(ID::A));
// Verilog appears to treat the result as signed, so if the result is wider than "A",
// we need to pad.
if (a_width < y_width) {
@ -954,7 +954,7 @@ struct FirrtlWorker
}
wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), a_expr.c_str()));
register_reverse_wire_map(y_id, cell->getPort("\\Y"));
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
}
log_error("Cell type not supported: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell));
@ -1134,7 +1134,7 @@ struct FirrtlBackend : public Backend {
for (auto module : design->modules()) {
make_id(module->name);
last = module;
if (top == nullptr && module->get_bool_attribute("\\top")) {
if (top == nullptr && module->get_bool_attribute(ID::top)) {
top = module;
}
for (auto wire : module->wires())

View file

@ -358,10 +358,10 @@ void ILANG_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool onl
if (!flag_m) {
int count_selected_mods = 0;
for (auto it = design->modules_.begin(); it != design->modules_.end(); ++it) {
if (design->selected_whole_module(it->first))
for (auto module : design->modules()) {
if (design->selected_whole_module(module->name))
flag_m = true;
if (design->selected(it->second))
if (design->selected(module))
count_selected_mods++;
}
if (count_selected_mods > 1)
@ -374,11 +374,11 @@ void ILANG_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool onl
f << stringf("autoidx %d\n", autoidx);
}
for (auto it = design->modules_.begin(); it != design->modules_.end(); ++it) {
if (!only_selected || design->selected(it->second)) {
for (auto module : design->modules()) {
if (!only_selected || design->selected(module)) {
if (only_selected)
f << stringf("\n");
dump_module(f, "", it->second, design, only_selected, flag_m, flag_n);
dump_module(f, "", module, design, only_selected, flag_m, flag_n);
}
}

View file

@ -122,70 +122,67 @@ struct IntersynthBackend : public Backend {
for (auto lib : libs)
ct.setup_design(lib);
for (auto module_it : design->modules_)
for (auto module : design->modules())
{
RTLIL::Module *module = module_it.second;
SigMap sigmap(module);
if (module->get_blackbox_attribute())
continue;
if (module->memories.size() == 0 && module->processes.size() == 0 && module->cells_.size() == 0)
if (module->memories.size() == 0 && module->processes.size() == 0 && module->cells().size() == 0)
continue;
if (selected && !design->selected_whole_module(module->name)) {
if (design->selected_module(module->name))
log_cmd_error("Can't handle partially selected module %s!\n", RTLIL::id2cstr(module->name));
log_cmd_error("Can't handle partially selected module %s!\n", log_id(module->name));
continue;
}
log("Generating netlist %s.\n", RTLIL::id2cstr(module->name));
log("Generating netlist %s.\n", log_id(module->name));
if (module->memories.size() != 0 || module->processes.size() != 0)
log_error("Can't generate a netlist for a module with unprocessed memories or processes!\n");
std::set<std::string> constcells_code;
netlists_code += stringf("# Netlist of module %s\n", RTLIL::id2cstr(module->name));
netlists_code += stringf("netlist %s\n", RTLIL::id2cstr(module->name));
netlists_code += stringf("# Netlist of module %s\n", log_id(module->name));
netlists_code += stringf("netlist %s\n", log_id(module->name));
// Module Ports: "std::set<string> celltypes_code" prevents duplicate top level ports
for (auto wire_it : module->wires_) {
RTLIL::Wire *wire = wire_it.second;
for (auto wire : module->wires()) {
if (wire->port_input || wire->port_output) {
celltypes_code.insert(stringf("celltype !%s b%d %sPORT\n" "%s %s %d %s PORT\n",
RTLIL::id2cstr(wire->name), wire->width, wire->port_input ? "*" : "",
wire->port_input ? "input" : "output", RTLIL::id2cstr(wire->name), wire->width, RTLIL::id2cstr(wire->name)));
netlists_code += stringf("node %s %s PORT %s\n", RTLIL::id2cstr(wire->name), RTLIL::id2cstr(wire->name),
log_id(wire->name), wire->width, wire->port_input ? "*" : "",
wire->port_input ? "input" : "output", log_id(wire->name), wire->width, log_id(wire->name)));
netlists_code += stringf("node %s %s PORT %s\n", log_id(wire->name), log_id(wire->name),
netname(conntypes_code, celltypes_code, constcells_code, sigmap(wire)).c_str());
}
}
// Submodules: "std::set<string> celltypes_code" prevents duplicate cell types
for (auto cell_it : module->cells_)
for (auto cell : module->cells())
{
RTLIL::Cell *cell = cell_it.second;
std::string celltype_code, node_code;
if (!ct.cell_known(cell->type))
log_error("Found unknown cell type %s in module!\n", RTLIL::id2cstr(cell->type));
log_error("Found unknown cell type %s in module!\n", log_id(cell->type));
celltype_code = stringf("celltype %s", RTLIL::id2cstr(cell->type));
node_code = stringf("node %s %s", RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
celltype_code = stringf("celltype %s", log_id(cell->type));
node_code = stringf("node %s %s", log_id(cell->name), log_id(cell->type));
for (auto &port : cell->connections()) {
RTLIL::SigSpec sig = sigmap(port.second);
if (sig.size() != 0) {
conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.size(), sig.size(), sig.size()));
celltype_code += stringf(" b%d %s%s", sig.size(), ct.cell_output(cell->type, port.first) ? "*" : "", RTLIL::id2cstr(port.first));
node_code += stringf(" %s %s", RTLIL::id2cstr(port.first), netname(conntypes_code, celltypes_code, constcells_code, sig).c_str());
celltype_code += stringf(" b%d %s%s", sig.size(), ct.cell_output(cell->type, port.first) ? "*" : "", log_id(port.first));
node_code += stringf(" %s %s", log_id(port.first), netname(conntypes_code, celltypes_code, constcells_code, sig).c_str());
}
}
for (auto &param : cell->parameters) {
celltype_code += stringf(" cfg:%d %s", int(param.second.bits.size()), RTLIL::id2cstr(param.first));
celltype_code += stringf(" cfg:%d %s", int(param.second.bits.size()), log_id(param.first));
if (param.second.bits.size() != 32) {
node_code += stringf(" %s '", RTLIL::id2cstr(param.first));
node_code += stringf(" %s '", log_id(param.first));
for (int i = param.second.bits.size()-1; i >= 0; i--)
node_code += param.second.bits[i] == State::S1 ? "1" : "0";
} else
node_code += stringf(" %s 0x%x", RTLIL::id2cstr(param.first), param.second.as_int());
node_code += stringf(" %s 0x%x", log_id(param.first), param.second.as_int());
}
celltypes_code.insert(celltype_code + "\n");

View file

@ -378,16 +378,16 @@ struct SimplecWorker
void eval_cell(HierDirtyFlags *work, Cell *cell)
{
if (cell->type.in("$_BUF_", "$_NOT_"))
if (cell->type.in(ID($_BUF_), ID($_NOT_)))
{
SigBit a = sigmaps.at(work->module)(cell->getPort("\\A"));
SigBit y = sigmaps.at(work->module)(cell->getPort("\\Y"));
SigBit a = sigmaps.at(work->module)(cell->getPort(ID::A));
SigBit y = sigmaps.at(work->module)(cell->getPort(ID::Y));
string a_expr = a.wire ? util_get_bit(work->prefix + cid(a.wire->name), a.wire->width, a.offset) : a.data ? "1" : "0";
string expr;
if (cell->type == "$_BUF_") expr = a_expr;
if (cell->type == "$_NOT_") expr = "!" + a_expr;
if (cell->type == ID($_BUF_)) expr = a_expr;
if (cell->type == ID($_NOT_)) expr = "!" + a_expr;
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
@ -397,24 +397,24 @@ struct SimplecWorker
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_)))
{
SigBit a = sigmaps.at(work->module)(cell->getPort("\\A"));
SigBit b = sigmaps.at(work->module)(cell->getPort("\\B"));
SigBit y = sigmaps.at(work->module)(cell->getPort("\\Y"));
SigBit a = sigmaps.at(work->module)(cell->getPort(ID::A));
SigBit b = sigmaps.at(work->module)(cell->getPort(ID::B));
SigBit y = sigmaps.at(work->module)(cell->getPort(ID::Y));
string a_expr = a.wire ? util_get_bit(work->prefix + cid(a.wire->name), a.wire->width, a.offset) : a.data ? "1" : "0";
string b_expr = b.wire ? util_get_bit(work->prefix + cid(b.wire->name), b.wire->width, b.offset) : b.data ? "1" : "0";
string expr;
if (cell->type == "$_AND_") expr = stringf("%s & %s", a_expr.c_str(), b_expr.c_str());
if (cell->type == "$_NAND_") expr = stringf("!(%s & %s)", a_expr.c_str(), b_expr.c_str());
if (cell->type == "$_OR_") expr = stringf("%s | %s", a_expr.c_str(), b_expr.c_str());
if (cell->type == "$_NOR_") expr = stringf("!(%s | %s)", a_expr.c_str(), b_expr.c_str());
if (cell->type == "$_XOR_") expr = stringf("%s ^ %s", a_expr.c_str(), b_expr.c_str());
if (cell->type == "$_XNOR_") expr = stringf("!(%s ^ %s)", a_expr.c_str(), b_expr.c_str());
if (cell->type == "$_ANDNOT_") expr = stringf("%s & (!%s)", a_expr.c_str(), b_expr.c_str());
if (cell->type == "$_ORNOT_") expr = stringf("%s | (!%s)", a_expr.c_str(), b_expr.c_str());
if (cell->type == ID($_AND_)) expr = stringf("%s & %s", a_expr.c_str(), b_expr.c_str());
if (cell->type == ID($_NAND_)) expr = stringf("!(%s & %s)", a_expr.c_str(), b_expr.c_str());
if (cell->type == ID($_OR_)) expr = stringf("%s | %s", a_expr.c_str(), b_expr.c_str());
if (cell->type == ID($_NOR_)) expr = stringf("!(%s | %s)", a_expr.c_str(), b_expr.c_str());
if (cell->type == ID($_XOR_)) expr = stringf("%s ^ %s", a_expr.c_str(), b_expr.c_str());
if (cell->type == ID($_XNOR_)) expr = stringf("!(%s ^ %s)", a_expr.c_str(), b_expr.c_str());
if (cell->type == ID($_ANDNOT_)) expr = stringf("%s & (!%s)", a_expr.c_str(), b_expr.c_str());
if (cell->type == ID($_ORNOT_)) expr = stringf("%s | (!%s)", a_expr.c_str(), b_expr.c_str());
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
@ -424,20 +424,20 @@ struct SimplecWorker
return;
}
if (cell->type.in("$_AOI3_", "$_OAI3_"))
if (cell->type.in(ID($_AOI3_), ID($_OAI3_)))
{
SigBit a = sigmaps.at(work->module)(cell->getPort("\\A"));
SigBit b = sigmaps.at(work->module)(cell->getPort("\\B"));
SigBit c = sigmaps.at(work->module)(cell->getPort("\\C"));
SigBit y = sigmaps.at(work->module)(cell->getPort("\\Y"));
SigBit a = sigmaps.at(work->module)(cell->getPort(ID::A));
SigBit b = sigmaps.at(work->module)(cell->getPort(ID::B));
SigBit c = sigmaps.at(work->module)(cell->getPort(ID::C));
SigBit y = sigmaps.at(work->module)(cell->getPort(ID::Y));
string a_expr = a.wire ? util_get_bit(work->prefix + cid(a.wire->name), a.wire->width, a.offset) : a.data ? "1" : "0";
string b_expr = b.wire ? util_get_bit(work->prefix + cid(b.wire->name), b.wire->width, b.offset) : b.data ? "1" : "0";
string c_expr = c.wire ? util_get_bit(work->prefix + cid(c.wire->name), c.wire->width, c.offset) : c.data ? "1" : "0";
string expr;
if (cell->type == "$_AOI3_") expr = stringf("!((%s & %s) | %s)", a_expr.c_str(), b_expr.c_str(), c_expr.c_str());
if (cell->type == "$_OAI3_") expr = stringf("!((%s | %s) & %s)", a_expr.c_str(), b_expr.c_str(), c_expr.c_str());
if (cell->type == ID($_AOI3_)) expr = stringf("!((%s & %s) | %s)", a_expr.c_str(), b_expr.c_str(), c_expr.c_str());
if (cell->type == ID($_OAI3_)) expr = stringf("!((%s | %s) & %s)", a_expr.c_str(), b_expr.c_str(), c_expr.c_str());
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
@ -447,13 +447,13 @@ struct SimplecWorker
return;
}
if (cell->type.in("$_AOI4_", "$_OAI4_"))
if (cell->type.in(ID($_AOI4_), ID($_OAI4_)))
{
SigBit a = sigmaps.at(work->module)(cell->getPort("\\A"));
SigBit b = sigmaps.at(work->module)(cell->getPort("\\B"));
SigBit c = sigmaps.at(work->module)(cell->getPort("\\C"));
SigBit d = sigmaps.at(work->module)(cell->getPort("\\D"));
SigBit y = sigmaps.at(work->module)(cell->getPort("\\Y"));
SigBit a = sigmaps.at(work->module)(cell->getPort(ID::A));
SigBit b = sigmaps.at(work->module)(cell->getPort(ID::B));
SigBit c = sigmaps.at(work->module)(cell->getPort(ID::C));
SigBit d = sigmaps.at(work->module)(cell->getPort(ID::D));
SigBit y = sigmaps.at(work->module)(cell->getPort(ID::Y));
string a_expr = a.wire ? util_get_bit(work->prefix + cid(a.wire->name), a.wire->width, a.offset) : a.data ? "1" : "0";
string b_expr = b.wire ? util_get_bit(work->prefix + cid(b.wire->name), b.wire->width, b.offset) : b.data ? "1" : "0";
@ -461,8 +461,8 @@ struct SimplecWorker
string d_expr = d.wire ? util_get_bit(work->prefix + cid(d.wire->name), d.wire->width, d.offset) : d.data ? "1" : "0";
string expr;
if (cell->type == "$_AOI4_") expr = stringf("!((%s & %s) | (%s & %s))", a_expr.c_str(), b_expr.c_str(), c_expr.c_str(), d_expr.c_str());
if (cell->type == "$_OAI4_") expr = stringf("!((%s | %s) & (%s | %s))", a_expr.c_str(), b_expr.c_str(), c_expr.c_str(), d_expr.c_str());
if (cell->type == ID($_AOI4_)) expr = stringf("!((%s & %s) | (%s & %s))", a_expr.c_str(), b_expr.c_str(), c_expr.c_str(), d_expr.c_str());
if (cell->type == ID($_OAI4_)) expr = stringf("!((%s | %s) & (%s | %s))", a_expr.c_str(), b_expr.c_str(), c_expr.c_str(), d_expr.c_str());
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
@ -472,12 +472,12 @@ struct SimplecWorker
return;
}
if (cell->type.in("$_MUX_", "$_NMUX_"))
if (cell->type.in(ID($_MUX_), ID($_NMUX_)))
{
SigBit a = sigmaps.at(work->module)(cell->getPort("\\A"));
SigBit b = sigmaps.at(work->module)(cell->getPort("\\B"));
SigBit s = sigmaps.at(work->module)(cell->getPort("\\S"));
SigBit y = sigmaps.at(work->module)(cell->getPort("\\Y"));
SigBit a = sigmaps.at(work->module)(cell->getPort(ID::A));
SigBit b = sigmaps.at(work->module)(cell->getPort(ID::B));
SigBit s = sigmaps.at(work->module)(cell->getPort(ID::S));
SigBit y = sigmaps.at(work->module)(cell->getPort(ID::Y));
string a_expr = a.wire ? util_get_bit(work->prefix + cid(a.wire->name), a.wire->width, a.offset) : a.data ? "1" : "0";
string b_expr = b.wire ? util_get_bit(work->prefix + cid(b.wire->name), b.wire->width, b.offset) : b.data ? "1" : "0";
@ -485,8 +485,8 @@ struct SimplecWorker
// casts to bool are a workaround for CBMC bug (https://github.com/diffblue/cbmc/issues/933)
string expr = stringf("%s ? %s(bool)%s : %s(bool)%s", s_expr.c_str(),
cell->type == "$_NMUX_" ? "!" : "", b_expr.c_str(),
cell->type == "$_NMUX_" ? "!" : "", a_expr.c_str());
cell->type == ID($_NMUX_) ? "!" : "", b_expr.c_str(),
cell->type == ID($_NMUX_) ? "!" : "", a_expr.c_str());
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
@ -653,10 +653,10 @@ struct SimplecWorker
for (Wire *w : module->wires())
{
if (w->attributes.count("\\init"))
if (w->attributes.count(ID::init))
{
SigSpec sig = sigmaps.at(module)(w);
Const val = w->attributes.at("\\init");
Const val = w->attributes.at(ID::init);
val.bits.resize(GetSize(sig), State::Sx);
for (int i = 0; i < GetSize(sig); i++)

View file

@ -135,7 +135,7 @@ struct Smt2Worker
log_error("Unsupported or unknown directionality on port %s of cell %s.%s (%s).\n",
log_id(conn.first), log_id(module), log_id(cell), log_id(cell->type));
if (cell->type.in("$mem") && conn.first.in("\\RD_CLK", "\\WR_CLK"))
if (cell->type.in(ID($mem)) && conn.first.in(ID::RD_CLK, ID::WR_CLK))
{
SigSpec clk = sigmap(conn.second);
for (int i = 0; i < GetSize(clk); i++)
@ -143,19 +143,19 @@ struct Smt2Worker
if (clk[i].wire == nullptr)
continue;
if (cell->getParam(conn.first == "\\RD_CLK" ? "\\RD_CLK_ENABLE" : "\\WR_CLK_ENABLE")[i] != State::S1)
if (cell->getParam(conn.first == ID::RD_CLK ? ID::RD_CLK_ENABLE : ID::WR_CLK_ENABLE)[i] != State::S1)
continue;
if (cell->getParam(conn.first == "\\RD_CLK" ? "\\RD_CLK_POLARITY" : "\\WR_CLK_POLARITY")[i] == State::S1)
if (cell->getParam(conn.first == ID::RD_CLK ? ID::RD_CLK_POLARITY : ID::WR_CLK_POLARITY)[i] == State::S1)
clock_posedge.insert(clk[i]);
else
clock_negedge.insert(clk[i]);
}
}
else
if (cell->type.in("$dff", "$_DFF_P_", "$_DFF_N_") && conn.first.in("\\CLK", "\\C"))
if (cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_)) && conn.first.in(ID::CLK, ID::C))
{
bool posedge = (cell->type == "$_DFF_N_") || (cell->type == "$dff" && cell->getParam("\\CLK_POLARITY").as_bool());
bool posedge = (cell->type == ID($_DFF_N_)) || (cell->type == ID($dff) && cell->getParam(ID::CLK_POLARITY).as_bool());
for (auto bit : sigmap(conn.second)) {
if (posedge)
clock_posedge.insert(bit);
@ -367,15 +367,15 @@ struct Smt2Worker
void export_gate(RTLIL::Cell *cell, std::string expr)
{
RTLIL::SigBit bit = sigmap(cell->getPort("\\Y").as_bit());
RTLIL::SigBit bit = sigmap(cell->getPort(ID::Y).as_bit());
std::string processed_expr;
for (char ch : expr) {
if (ch == 'A') processed_expr += get_bool(cell->getPort("\\A"));
else if (ch == 'B') processed_expr += get_bool(cell->getPort("\\B"));
else if (ch == 'C') processed_expr += get_bool(cell->getPort("\\C"));
else if (ch == 'D') processed_expr += get_bool(cell->getPort("\\D"));
else if (ch == 'S') processed_expr += get_bool(cell->getPort("\\S"));
if (ch == 'A') processed_expr += get_bool(cell->getPort(ID::A));
else if (ch == 'B') processed_expr += get_bool(cell->getPort(ID::B));
else if (ch == 'C') processed_expr += get_bool(cell->getPort(ID::C));
else if (ch == 'D') processed_expr += get_bool(cell->getPort(ID::D));
else if (ch == 'S') processed_expr += get_bool(cell->getPort(ID::S));
else processed_expr += ch;
}
@ -391,23 +391,23 @@ struct Smt2Worker
void export_bvop(RTLIL::Cell *cell, std::string expr, char type = 0)
{
RTLIL::SigSpec sig_a, sig_b;
RTLIL::SigSpec sig_y = sigmap(cell->getPort("\\Y"));
bool is_signed = cell->getParam("\\A_SIGNED").as_bool();
RTLIL::SigSpec sig_y = sigmap(cell->getPort(ID::Y));
bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
int width = GetSize(sig_y);
if (type == 's' || type == 'd' || type == 'b') {
width = max(width, GetSize(cell->getPort("\\A")));
if (cell->hasPort("\\B"))
width = max(width, GetSize(cell->getPort("\\B")));
width = max(width, GetSize(cell->getPort(ID::A)));
if (cell->hasPort(ID::B))
width = max(width, GetSize(cell->getPort(ID::B)));
}
if (cell->hasPort("\\A")) {
sig_a = cell->getPort("\\A");
if (cell->hasPort(ID::A)) {
sig_a = cell->getPort(ID::A);
sig_a.extend_u0(width, is_signed);
}
if (cell->hasPort("\\B")) {
sig_b = cell->getPort("\\B");
if (cell->hasPort(ID::B)) {
sig_b = cell->getPort(ID::B);
sig_b.extend_u0(width, is_signed && !(type == 's'));
}
@ -416,7 +416,7 @@ struct Smt2Worker
for (char ch : expr) {
if (ch == 'A') processed_expr += get_bv(sig_a);
else if (ch == 'B') processed_expr += get_bv(sig_b);
else if (ch == 'P') processed_expr += get_bv(cell->getPort("\\B"));
else if (ch == 'P') processed_expr += get_bv(cell->getPort(ID::B));
else if (ch == 'L') processed_expr += is_signed ? "a" : "l";
else if (ch == 'U') processed_expr += is_signed ? "s" : "u";
else processed_expr += ch;
@ -443,7 +443,7 @@ struct Smt2Worker
void export_reduce(RTLIL::Cell *cell, std::string expr, bool identity_val)
{
RTLIL::SigSpec sig_y = sigmap(cell->getPort("\\Y"));
RTLIL::SigSpec sig_y = sigmap(cell->getPort(ID::Y));
std::string processed_expr;
for (char ch : expr)
@ -480,9 +480,9 @@ struct Smt2Worker
exported_cells.insert(cell);
recursive_cells.insert(cell);
if (cell->type == "$initstate")
if (cell->type == ID($initstate))
{
SigBit bit = sigmap(cell->getPort("\\Y").as_bit());
SigBit bit = sigmap(cell->getPort(ID::Y).as_bit());
decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) Bool (|%s_is| state)) ; %s\n",
get_id(module), idcounter, get_id(module), get_id(module), log_signal(bit)));
register_bool(bit, idcounter++);
@ -490,132 +490,132 @@ struct Smt2Worker
return;
}
if (cell->type.in("$_FF_", "$_DFF_P_", "$_DFF_N_"))
if (cell->type.in(ID($_FF_), ID($_DFF_P_), ID($_DFF_N_)))
{
registers.insert(cell);
makebits(stringf("%s#%d", get_id(module), idcounter), 0, log_signal(cell->getPort("\\Q")));
register_bool(cell->getPort("\\Q"), idcounter++);
makebits(stringf("%s#%d", get_id(module), idcounter), 0, log_signal(cell->getPort(ID::Q)));
register_bool(cell->getPort(ID::Q), idcounter++);
recursive_cells.erase(cell);
return;
}
if (cell->type == "$_BUF_") return export_gate(cell, "A");
if (cell->type == "$_NOT_") return export_gate(cell, "(not A)");
if (cell->type == "$_AND_") return export_gate(cell, "(and A B)");
if (cell->type == "$_NAND_") return export_gate(cell, "(not (and A B))");
if (cell->type == "$_OR_") return export_gate(cell, "(or A B)");
if (cell->type == "$_NOR_") return export_gate(cell, "(not (or A B))");
if (cell->type == "$_XOR_") return export_gate(cell, "(xor A B)");
if (cell->type == "$_XNOR_") return export_gate(cell, "(not (xor A B))");
if (cell->type == "$_ANDNOT_") return export_gate(cell, "(and A (not B))");
if (cell->type == "$_ORNOT_") return export_gate(cell, "(or A (not B))");
if (cell->type == "$_MUX_") return export_gate(cell, "(ite S B A)");
if (cell->type == "$_NMUX_") return export_gate(cell, "(not (ite S B A))");
if (cell->type == "$_AOI3_") return export_gate(cell, "(not (or (and A B) C))");
if (cell->type == "$_OAI3_") return export_gate(cell, "(not (and (or A B) C))");
if (cell->type == "$_AOI4_") return export_gate(cell, "(not (or (and A B) (and C D)))");
if (cell->type == "$_OAI4_") return export_gate(cell, "(not (and (or A B) (or C D)))");
if (cell->type == ID($_BUF_)) return export_gate(cell, "A");
if (cell->type == ID($_NOT_)) return export_gate(cell, "(not A)");
if (cell->type == ID($_AND_)) return export_gate(cell, "(and A B)");
if (cell->type == ID($_NAND_)) return export_gate(cell, "(not (and A B))");
if (cell->type == ID($_OR_)) return export_gate(cell, "(or A B)");
if (cell->type == ID($_NOR_)) return export_gate(cell, "(not (or A B))");
if (cell->type == ID($_XOR_)) return export_gate(cell, "(xor A B)");
if (cell->type == ID($_XNOR_)) return export_gate(cell, "(not (xor A B))");
if (cell->type == ID($_ANDNOT_)) return export_gate(cell, "(and A (not B))");
if (cell->type == ID($_ORNOT_)) return export_gate(cell, "(or A (not B))");
if (cell->type == ID($_MUX_)) return export_gate(cell, "(ite S B A)");
if (cell->type == ID($_NMUX_)) return export_gate(cell, "(not (ite S B A))");
if (cell->type == ID($_AOI3_)) return export_gate(cell, "(not (or (and A B) C))");
if (cell->type == ID($_OAI3_)) return export_gate(cell, "(not (and (or A B) C))");
if (cell->type == ID($_AOI4_)) return export_gate(cell, "(not (or (and A B) (and C D)))");
if (cell->type == ID($_OAI4_)) return export_gate(cell, "(not (and (or A B) (or C D)))");
// FIXME: $lut
if (bvmode)
{
if (cell->type.in("$ff", "$dff"))
if (cell->type.in(ID($ff), ID($dff)))
{
registers.insert(cell);
makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort("\\Q")), log_signal(cell->getPort("\\Q")));
register_bv(cell->getPort("\\Q"), idcounter++);
makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort(ID::Q)), log_signal(cell->getPort(ID::Q)));
register_bv(cell->getPort(ID::Q), idcounter++);
recursive_cells.erase(cell);
return;
}
if (cell->type.in("$anyconst", "$anyseq", "$allconst", "$allseq"))
if (cell->type.in(ID($anyconst), ID($anyseq), ID($allconst), ID($allseq)))
{
registers.insert(cell);
string infostr = cell->attributes.count("\\src") ? cell->attributes.at("\\src").decode_string().c_str() : get_id(cell);
if (cell->attributes.count("\\reg"))
infostr += " " + cell->attributes.at("\\reg").decode_string();
decls.push_back(stringf("; yosys-smt2-%s %s#%d %d %s\n", cell->type.c_str() + 1, get_id(module), idcounter, GetSize(cell->getPort("\\Y")), infostr.c_str()));
if (cell->getPort("\\Y").is_wire() && cell->getPort("\\Y").as_wire()->get_bool_attribute("\\maximize")){
string infostr = cell->attributes.count(ID::src) ? cell->attributes.at(ID::src).decode_string().c_str() : get_id(cell);
if (cell->attributes.count(ID::reg))
infostr += " " + cell->attributes.at(ID::reg).decode_string();
decls.push_back(stringf("; yosys-smt2-%s %s#%d %d %s\n", cell->type.c_str() + 1, get_id(module), idcounter, GetSize(cell->getPort(ID::Y)), infostr.c_str()));
if (cell->getPort(ID::Y).is_wire() && cell->getPort(ID::Y).as_wire()->get_bool_attribute(ID::maximize)){
decls.push_back(stringf("; yosys-smt2-maximize %s#%d\n", get_id(module), idcounter));
log("Wire %s is maximized\n", cell->getPort("\\Y").as_wire()->name.str().c_str());
log("Wire %s is maximized\n", cell->getPort(ID::Y).as_wire()->name.str().c_str());
}
else if (cell->getPort("\\Y").is_wire() && cell->getPort("\\Y").as_wire()->get_bool_attribute("\\minimize")){
else if (cell->getPort(ID::Y).is_wire() && cell->getPort(ID::Y).as_wire()->get_bool_attribute(ID::minimize)){
decls.push_back(stringf("; yosys-smt2-minimize %s#%d\n", get_id(module), idcounter));
log("Wire %s is minimized\n", cell->getPort("\\Y").as_wire()->name.str().c_str());
log("Wire %s is minimized\n", cell->getPort(ID::Y).as_wire()->name.str().c_str());
}
makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort("\\Y")), log_signal(cell->getPort("\\Y")));
if (cell->type == "$anyseq")
makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort(ID::Y)), log_signal(cell->getPort(ID::Y)));
if (cell->type == ID($anyseq))
ex_input_eq.push_back(stringf(" (= (|%s#%d| state) (|%s#%d| other_state))", get_id(module), idcounter, get_id(module), idcounter));
register_bv(cell->getPort("\\Y"), idcounter++);
register_bv(cell->getPort(ID::Y), idcounter++);
recursive_cells.erase(cell);
return;
}
if (cell->type == "$and") return export_bvop(cell, "(bvand A B)");
if (cell->type == "$or") return export_bvop(cell, "(bvor A B)");
if (cell->type == "$xor") return export_bvop(cell, "(bvxor A B)");
if (cell->type == "$xnor") return export_bvop(cell, "(bvxnor A B)");
if (cell->type == ID($and)) return export_bvop(cell, "(bvand A B)");
if (cell->type == ID($or)) return export_bvop(cell, "(bvor A B)");
if (cell->type == ID($xor)) return export_bvop(cell, "(bvxor A B)");
if (cell->type == ID($xnor)) return export_bvop(cell, "(bvxnor A B)");
if (cell->type == "$shl") return export_bvop(cell, "(bvshl A B)", 's');
if (cell->type == "$shr") return export_bvop(cell, "(bvlshr A B)", 's');
if (cell->type == "$sshl") return export_bvop(cell, "(bvshl A B)", 's');
if (cell->type == "$sshr") return export_bvop(cell, "(bvLshr A B)", 's');
if (cell->type == ID($shl)) return export_bvop(cell, "(bvshl A B)", 's');
if (cell->type == ID($shr)) return export_bvop(cell, "(bvlshr A B)", 's');
if (cell->type == ID($sshl)) return export_bvop(cell, "(bvshl A B)", 's');
if (cell->type == ID($sshr)) return export_bvop(cell, "(bvLshr A B)", 's');
if (cell->type.in("$shift", "$shiftx")) {
if (cell->getParam("\\B_SIGNED").as_bool()) {
if (cell->type.in(ID($shift), ID($shiftx))) {
if (cell->getParam(ID::B_SIGNED).as_bool()) {
return export_bvop(cell, stringf("(ite (bvsge P #b%0*d) "
"(bvlshr A B) (bvlshr A (bvneg B)))",
GetSize(cell->getPort("\\B")), 0), 's');
GetSize(cell->getPort(ID::B)), 0), 's');
} else {
return export_bvop(cell, "(bvlshr A B)", 's');
}
}
if (cell->type == "$lt") return export_bvop(cell, "(bvUlt A B)", 'b');
if (cell->type == "$le") return export_bvop(cell, "(bvUle A B)", 'b');
if (cell->type == "$ge") return export_bvop(cell, "(bvUge A B)", 'b');
if (cell->type == "$gt") return export_bvop(cell, "(bvUgt A B)", 'b');
if (cell->type == ID($lt)) return export_bvop(cell, "(bvUlt A B)", 'b');
if (cell->type == ID($le)) return export_bvop(cell, "(bvUle A B)", 'b');
if (cell->type == ID($ge)) return export_bvop(cell, "(bvUge A B)", 'b');
if (cell->type == ID($gt)) return export_bvop(cell, "(bvUgt A B)", 'b');
if (cell->type == "$ne") return export_bvop(cell, "(distinct A B)", 'b');
if (cell->type == "$nex") return export_bvop(cell, "(distinct A B)", 'b');
if (cell->type == "$eq") return export_bvop(cell, "(= A B)", 'b');
if (cell->type == "$eqx") return export_bvop(cell, "(= A B)", 'b');
if (cell->type == ID($ne)) return export_bvop(cell, "(distinct A B)", 'b');
if (cell->type == ID($nex)) return export_bvop(cell, "(distinct A B)", 'b');
if (cell->type == ID($eq)) return export_bvop(cell, "(= A B)", 'b');
if (cell->type == ID($eqx)) return export_bvop(cell, "(= A B)", 'b');
if (cell->type == "$not") return export_bvop(cell, "(bvnot A)");
if (cell->type == "$pos") return export_bvop(cell, "A");
if (cell->type == "$neg") return export_bvop(cell, "(bvneg A)");
if (cell->type == ID($not)) return export_bvop(cell, "(bvnot A)");
if (cell->type == ID($pos)) return export_bvop(cell, "A");
if (cell->type == ID($neg)) return export_bvop(cell, "(bvneg A)");
if (cell->type == "$add") return export_bvop(cell, "(bvadd A B)");
if (cell->type == "$sub") return export_bvop(cell, "(bvsub A B)");
if (cell->type == "$mul") return export_bvop(cell, "(bvmul A B)");
if (cell->type == "$div") return export_bvop(cell, "(bvUdiv A B)", 'd');
if (cell->type == "$mod") return export_bvop(cell, "(bvUrem A B)", 'd');
if (cell->type == ID($add)) return export_bvop(cell, "(bvadd A B)");
if (cell->type == ID($sub)) return export_bvop(cell, "(bvsub A B)");
if (cell->type == ID($mul)) return export_bvop(cell, "(bvmul A B)");
if (cell->type == ID($div)) return export_bvop(cell, "(bvUdiv A B)", 'd');
if (cell->type == ID($mod)) return export_bvop(cell, "(bvUrem A B)", 'd');
if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_bool") &&
2*GetSize(cell->getPort("\\A").chunks()) < GetSize(cell->getPort("\\A"))) {
bool is_and = cell->type == "$reduce_and";
string bits(GetSize(cell->getPort("\\A")), is_and ? '1' : '0');
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool)) &&
2*GetSize(cell->getPort(ID::A).chunks()) < GetSize(cell->getPort(ID::A))) {
bool is_and = cell->type == ID($reduce_and);
string bits(GetSize(cell->getPort(ID::A)), is_and ? '1' : '0');
return export_bvop(cell, stringf("(%s A #b%s)", is_and ? "=" : "distinct", bits.c_str()), 'b');
}
if (cell->type == "$reduce_and") return export_reduce(cell, "(and A)", true);
if (cell->type == "$reduce_or") return export_reduce(cell, "(or A)", false);
if (cell->type == "$reduce_xor") return export_reduce(cell, "(xor A)", false);
if (cell->type == "$reduce_xnor") return export_reduce(cell, "(not (xor A))", false);
if (cell->type == "$reduce_bool") return export_reduce(cell, "(or A)", false);
if (cell->type == ID($reduce_and)) return export_reduce(cell, "(and A)", true);
if (cell->type == ID($reduce_or)) return export_reduce(cell, "(or A)", false);
if (cell->type == ID($reduce_xor)) return export_reduce(cell, "(xor A)", false);
if (cell->type == ID($reduce_xnor)) return export_reduce(cell, "(not (xor A))", false);
if (cell->type == ID($reduce_bool)) return export_reduce(cell, "(or A)", false);
if (cell->type == "$logic_not") return export_reduce(cell, "(not (or A))", false);
if (cell->type == "$logic_and") return export_reduce(cell, "(and (or A) (or B))", false);
if (cell->type == "$logic_or") return export_reduce(cell, "(or A B)", false);
if (cell->type == ID($logic_not)) return export_reduce(cell, "(not (or A))", false);
if (cell->type == ID($logic_and)) return export_reduce(cell, "(and (or A) (or B))", false);
if (cell->type == ID($logic_or)) return export_reduce(cell, "(or A B)", false);
if (cell->type.in("$mux", "$pmux"))
if (cell->type.in(ID($mux), ID($pmux)))
{
int width = GetSize(cell->getPort("\\Y"));
std::string processed_expr = get_bv(cell->getPort("\\A"));
int width = GetSize(cell->getPort(ID::Y));
std::string processed_expr = get_bv(cell->getPort(ID::A));
RTLIL::SigSpec sig_b = cell->getPort("\\B");
RTLIL::SigSpec sig_s = cell->getPort("\\S");
RTLIL::SigSpec sig_b = cell->getPort(ID::B);
RTLIL::SigSpec sig_s = cell->getPort(ID::S);
get_bv(sig_b);
get_bv(sig_s);
@ -626,7 +626,7 @@ struct Smt2Worker
if (verbose)
log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", log_id(cell));
RTLIL::SigSpec sig = sigmap(cell->getPort("\\Y"));
RTLIL::SigSpec sig = sigmap(cell->getPort(ID::Y));
decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n",
get_id(module), idcounter, get_id(module), width, processed_expr.c_str(), log_signal(sig)));
register_bv(sig, idcounter++);
@ -637,19 +637,19 @@ struct Smt2Worker
// FIXME: $slice $concat
}
if (memmode && cell->type == "$mem")
if (memmode && cell->type == ID($mem))
{
int arrayid = idcounter++;
memarrays[cell] = arrayid;
int abits = cell->getParam("\\ABITS").as_int();
int width = cell->getParam("\\WIDTH").as_int();
int rd_ports = cell->getParam("\\RD_PORTS").as_int();
int wr_ports = cell->getParam("\\WR_PORTS").as_int();
int abits = cell->getParam(ID::ABITS).as_int();
int width = cell->getParam(ID::WIDTH).as_int();
int rd_ports = cell->getParam(ID::RD_PORTS).as_int();
int wr_ports = cell->getParam(ID::WR_PORTS).as_int();
bool async_read = false;
if (!cell->getParam("\\WR_CLK_ENABLE").is_fully_ones()) {
if (!cell->getParam("\\WR_CLK_ENABLE").is_fully_zero())
if (!cell->getParam(ID::WR_CLK_ENABLE).is_fully_ones()) {
if (!cell->getParam(ID::WR_CLK_ENABLE).is_fully_zero())
log_error("Memory %s.%s has mixed clocked/nonclocked write ports. This is not supported by \"write_smt2\".\n", log_id(cell), log_id(module));
async_read = true;
}
@ -665,8 +665,8 @@ struct Smt2Worker
if (statebv)
{
int mem_size = cell->getParam("\\SIZE").as_int();
int mem_offset = cell->getParam("\\OFFSET").as_int();
int mem_size = cell->getParam(ID::SIZE).as_int();
int mem_offset = cell->getParam(ID::OFFSET).as_int();
makebits(memstate, width*mem_size, get_id(cell));
decls.push_back(stringf("(define-fun |%s_m %s| ((state |%s_s|)) (_ BitVec %d) (|%s| state))\n",
@ -674,11 +674,11 @@ struct Smt2Worker
for (int i = 0; i < rd_ports; i++)
{
SigSpec addr_sig = cell->getPort("\\RD_ADDR").extract(abits*i, abits);
SigSpec data_sig = cell->getPort("\\RD_DATA").extract(width*i, width);
SigSpec addr_sig = cell->getPort(ID::RD_ADDR).extract(abits*i, abits);
SigSpec data_sig = cell->getPort(ID::RD_DATA).extract(width*i, width);
std::string addr = get_bv(addr_sig);
if (cell->getParam("\\RD_CLK_ENABLE").extract(i).as_bool())
if (cell->getParam(ID::RD_CLK_ENABLE).extract(i).as_bool())
log_error("Read port %d (%s) of memory %s.%s is clocked. This is not supported by \"write_smt2\"! "
"Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(data_sig), log_id(cell), log_id(module));
@ -717,11 +717,11 @@ struct Smt2Worker
for (int i = 0; i < rd_ports; i++)
{
SigSpec addr_sig = cell->getPort("\\RD_ADDR").extract(abits*i, abits);
SigSpec data_sig = cell->getPort("\\RD_DATA").extract(width*i, width);
SigSpec addr_sig = cell->getPort(ID::RD_ADDR).extract(abits*i, abits);
SigSpec data_sig = cell->getPort(ID::RD_DATA).extract(width*i, width);
std::string addr = get_bv(addr_sig);
if (cell->getParam("\\RD_CLK_ENABLE").extract(i).as_bool())
if (cell->getParam(ID::RD_CLK_ENABLE).extract(i).as_bool())
log_error("Read port %d (%s) of memory %s.%s is clocked. This is not supported by \"write_smt2\"! "
"Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(data_sig), log_id(cell), log_id(module));
@ -801,9 +801,9 @@ struct Smt2Worker
pool<SigBit> reg_bits;
for (auto cell : module->cells())
if (cell->type.in("$ff", "$dff", "$_FF_", "$_DFF_P_", "$_DFF_N_")) {
if (cell->type.in(ID($ff), ID($dff), ID($_FF_), ID($_DFF_P_), ID($_DFF_N_))) {
// not using sigmap -- we want the net directly at the dff output
for (auto bit : cell->getPort("\\Q"))
for (auto bit : cell->getPort(ID::Q))
reg_bits.insert(bit);
}
@ -812,7 +812,7 @@ struct Smt2Worker
for (auto bit : SigSpec(wire))
if (reg_bits.count(bit))
is_register = true;
if (wire->port_id || is_register || wire->get_bool_attribute("\\keep") || (wiresmode && wire->name[0] == '\\')) {
if (wire->port_id || is_register || wire->get_bool_attribute(ID::keep) || (wiresmode && wire->name[0] == '\\')) {
RTLIL::SigSpec sig = sigmap(wire);
if (wire->port_input)
decls.push_back(stringf("; yosys-smt2-input %s %d\n", get_id(wire), wire->width));
@ -820,7 +820,7 @@ struct Smt2Worker
decls.push_back(stringf("; yosys-smt2-output %s %d\n", get_id(wire), wire->width));
if (is_register)
decls.push_back(stringf("; yosys-smt2-register %s %d\n", get_id(wire), wire->width));
if (wire->get_bool_attribute("\\keep") || (wiresmode && wire->name[0] == '\\'))
if (wire->get_bool_attribute(ID::keep) || (wiresmode && wire->name[0] == '\\'))
decls.push_back(stringf("; yosys-smt2-wire %s %d\n", get_id(wire), wire->width));
if (GetSize(wire) == 1 && (clock_posedge.count(sig) || clock_negedge.count(sig)))
decls.push_back(stringf("; yosys-smt2-clock %s%s%s\n", get_id(wire),
@ -854,9 +854,9 @@ struct Smt2Worker
vector<string> init_list;
for (auto wire : module->wires())
if (wire->attributes.count("\\init")) {
if (wire->attributes.count(ID::init)) {
RTLIL::SigSpec sig = sigmap(wire);
Const val = wire->attributes.at("\\init");
Const val = wire->attributes.at(ID::init);
val.bits.resize(GetSize(sig), State::Sx);
if (bvmode && GetSize(sig) > 1) {
Const mask(State::S1, GetSize(sig));
@ -885,31 +885,31 @@ struct Smt2Worker
for (auto cell : module->cells())
{
if (cell->type.in("$assert", "$assume", "$cover"))
if (cell->type.in(ID($assert), ID($assume), ID($cover)))
{
int &id = cell->type == "$assert" ? assert_id :
cell->type == "$assume" ? assume_id :
cell->type == "$cover" ? cover_id : *(int*)nullptr;
int &id = cell->type == ID($assert) ? assert_id :
cell->type == ID($assume) ? assume_id :
cell->type == ID($cover) ? cover_id : *(int*)nullptr;
char postfix = cell->type == "$assert" ? 'a' :
cell->type == "$assume" ? 'u' :
cell->type == "$cover" ? 'c' : 0;
char postfix = cell->type == ID($assert) ? 'a' :
cell->type == ID($assume) ? 'u' :
cell->type == ID($cover) ? 'c' : 0;
string name_a = get_bool(cell->getPort("\\A"));
string name_en = get_bool(cell->getPort("\\EN"));
string infostr = (cell->name[0] == '$' && cell->attributes.count("\\src")) ? cell->attributes.at("\\src").decode_string() : get_id(cell);
string name_a = get_bool(cell->getPort(ID::A));
string name_en = get_bool(cell->getPort(ID::EN));
string infostr = (cell->name[0] == '$' && cell->attributes.count(ID::src)) ? cell->attributes.at(ID::src).decode_string() : get_id(cell);
decls.push_back(stringf("; yosys-smt2-%s %d %s\n", cell->type.c_str() + 1, id, infostr.c_str()));
if (cell->type == "$cover")
if (cell->type == ID($cover))
decls.push_back(stringf("(define-fun |%s_%c %d| ((state |%s_s|)) Bool (and %s %s)) ; %s\n",
get_id(module), postfix, id, get_id(module), name_a.c_str(), name_en.c_str(), get_id(cell)));
else
decls.push_back(stringf("(define-fun |%s_%c %d| ((state |%s_s|)) Bool (or %s (not %s))) ; %s\n",
get_id(module), postfix, id, get_id(module), name_a.c_str(), name_en.c_str(), get_id(cell)));
if (cell->type == "$assert")
if (cell->type == ID($assert))
assert_list.push_back(stringf("(|%s_a %d| state)", get_id(module), id));
else if (cell->type == "$assume")
else if (cell->type == ID($assume))
assume_list.push_back(stringf("(|%s_u %d| state)", get_id(module), id));
id++;
@ -965,44 +965,44 @@ struct Smt2Worker
for (auto cell : this_regs)
{
if (cell->type.in("$_FF_", "$_DFF_P_", "$_DFF_N_"))
if (cell->type.in(ID($_FF_), ID($_DFF_P_), ID($_DFF_N_)))
{
std::string expr_d = get_bool(cell->getPort("\\D"));
std::string expr_q = get_bool(cell->getPort("\\Q"), "next_state");
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort("\\Q"))));
ex_state_eq.push_back(stringf("(= %s %s)", get_bool(cell->getPort("\\Q")).c_str(), get_bool(cell->getPort("\\Q"), "other_state").c_str()));
std::string expr_d = get_bool(cell->getPort(ID::D));
std::string expr_q = get_bool(cell->getPort(ID::Q), "next_state");
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort(ID::Q))));
ex_state_eq.push_back(stringf("(= %s %s)", get_bool(cell->getPort(ID::Q)).c_str(), get_bool(cell->getPort(ID::Q), "other_state").c_str()));
}
if (cell->type.in("$ff", "$dff"))
if (cell->type.in(ID($ff), ID($dff)))
{
std::string expr_d = get_bv(cell->getPort("\\D"));
std::string expr_q = get_bv(cell->getPort("\\Q"), "next_state");
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort("\\Q"))));
ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort("\\Q")).c_str(), get_bv(cell->getPort("\\Q"), "other_state").c_str()));
std::string expr_d = get_bv(cell->getPort(ID::D));
std::string expr_q = get_bv(cell->getPort(ID::Q), "next_state");
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort(ID::Q))));
ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort(ID::Q)).c_str(), get_bv(cell->getPort(ID::Q), "other_state").c_str()));
}
if (cell->type.in("$anyconst", "$allconst"))
if (cell->type.in(ID($anyconst), ID($allconst)))
{
std::string expr_d = get_bv(cell->getPort("\\Y"));
std::string expr_q = get_bv(cell->getPort("\\Y"), "next_state");
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort("\\Y"))));
if (cell->type == "$anyconst")
ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort("\\Y")).c_str(), get_bv(cell->getPort("\\Y"), "other_state").c_str()));
std::string expr_d = get_bv(cell->getPort(ID::Y));
std::string expr_q = get_bv(cell->getPort(ID::Y), "next_state");
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort(ID::Y))));
if (cell->type == ID($anyconst))
ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort(ID::Y)).c_str(), get_bv(cell->getPort(ID::Y), "other_state").c_str()));
}
if (cell->type == "$mem")
if (cell->type == ID($mem))
{
int arrayid = memarrays.at(cell);
int abits = cell->getParam("\\ABITS").as_int();
int width = cell->getParam("\\WIDTH").as_int();
int wr_ports = cell->getParam("\\WR_PORTS").as_int();
int abits = cell->getParam(ID::ABITS).as_int();
int width = cell->getParam(ID::WIDTH).as_int();
int wr_ports = cell->getParam(ID::WR_PORTS).as_int();
bool async_read = false;
string initial_memstate, final_memstate;
if (!cell->getParam("\\WR_CLK_ENABLE").is_fully_ones()) {
log_assert(cell->getParam("\\WR_CLK_ENABLE").is_fully_zero());
if (!cell->getParam(ID::WR_CLK_ENABLE).is_fully_ones()) {
log_assert(cell->getParam(ID::WR_CLK_ENABLE).is_fully_zero());
async_read = true;
initial_memstate = stringf("%s#%d#0", get_id(module), arrayid);
final_memstate = stringf("%s#%d#final", get_id(module), arrayid);
@ -1010,8 +1010,8 @@ struct Smt2Worker
if (statebv)
{
int mem_size = cell->getParam("\\SIZE").as_int();
int mem_offset = cell->getParam("\\OFFSET").as_int();
int mem_size = cell->getParam(ID::SIZE).as_int();
int mem_offset = cell->getParam(ID::OFFSET).as_int();
if (async_read) {
makebits(final_memstate, width*mem_size, get_id(cell));
@ -1019,9 +1019,9 @@ struct Smt2Worker
for (int i = 0; i < wr_ports; i++)
{
SigSpec addr_sig = cell->getPort("\\WR_ADDR").extract(abits*i, abits);
SigSpec data_sig = cell->getPort("\\WR_DATA").extract(width*i, width);
SigSpec mask_sig = cell->getPort("\\WR_EN").extract(width*i, width);
SigSpec addr_sig = cell->getPort(ID::WR_ADDR).extract(abits*i, abits);
SigSpec data_sig = cell->getPort(ID::WR_DATA).extract(width*i, width);
SigSpec mask_sig = cell->getPort(ID::WR_EN).extract(width*i, width);
std::string addr = get_bv(addr_sig);
std::string data = get_bv(data_sig);
@ -1066,9 +1066,9 @@ struct Smt2Worker
for (int i = 0; i < wr_ports; i++)
{
SigSpec addr_sig = cell->getPort("\\WR_ADDR").extract(abits*i, abits);
SigSpec data_sig = cell->getPort("\\WR_DATA").extract(width*i, width);
SigSpec mask_sig = cell->getPort("\\WR_EN").extract(width*i, width);
SigSpec addr_sig = cell->getPort(ID::WR_ADDR).extract(abits*i, abits);
SigSpec data_sig = cell->getPort(ID::WR_DATA).extract(width*i, width);
SigSpec mask_sig = cell->getPort(ID::WR_EN).extract(width*i, width);
std::string addr = get_bv(addr_sig);
std::string data = get_bv(data_sig);
@ -1104,8 +1104,8 @@ struct Smt2Worker
if (async_read)
hier.push_back(stringf(" (= %s (|%s| state)) ; %s\n", expr_d.c_str(), final_memstate.c_str(), get_id(cell)));
Const init_data = cell->getParam("\\INIT");
int memsize = cell->getParam("\\SIZE").as_int();
Const init_data = cell->getParam(ID::INIT);
int memsize = cell->getParam(ID::SIZE).as_int();
for (int i = 0; i < memsize; i++)
{
@ -1394,7 +1394,7 @@ struct Smt2Backend : public Backend {
log("\n");
log("For this proof we create the following template (test.tpl).\n");
log("\n");
log(" ; we need QF_UFBV for this poof\n");
log(" ; we need QF_UFBV for this proof\n");
log(" (set-logic QF_UFBV)\n");
log("\n");
log(" ; insert the auto-generated code here\n");
@ -1523,12 +1523,12 @@ struct Smt2Backend : public Backend {
for (auto &dep : it.second)
if (module_deps.count(dep) > 0)
goto not_ready_yet;
// log("Next in topological sort: %s\n", RTLIL::id2cstr(it.first->name));
// log("Next in topological sort: %s\n", log_id(it.first->name));
sorted_modules.push_back(it.first);
not_ready_yet:;
}
if (sorted_modules_idx == sorted_modules.size())
log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", RTLIL::id2cstr(module_deps.begin()->first->name));
log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", log_id(module_deps.begin()->first->name));
while (sorted_modules_idx < sorted_modules.size())
module_deps.erase(sorted_modules.at(sorted_modules_idx++));
}
@ -1540,7 +1540,7 @@ struct Smt2Backend : public Backend {
for (auto module : sorted_modules)
for (auto cell : module->cells())
if (cell->type.in("$allconst", "$allseq"))
if (cell->type.in(ID($allconst), ID($allseq)))
goto found_forall;
if (0) {
found_forall:

View file

@ -704,8 +704,12 @@ class SmtIo:
if msg is not None:
print("%s waiting for solver (%s)" % (self.timestamp(), msg), flush=True)
result = ""
while result not in ["sat", "unsat"]:
if self.forall:
result = self.read()
while result not in ["sat", "unsat", "unknown"]:
print("%s %s: %s" % (self.timestamp(), self.solver, result))
result = self.read()
else:
result = self.read()
if self.debug_file:

View file

@ -219,30 +219,30 @@ struct SmvWorker
if (wire->port_input)
inputvars.push_back(stringf("%s : unsigned word[%d]; -- %s", cid(wire->name), wire->width, log_id(wire)));
if (wire->attributes.count("\\init"))
assignments.push_back(stringf("init(%s) := %s;", lvalue(wire), rvalue(wire->attributes.at("\\init"))));
if (wire->attributes.count(ID::init))
assignments.push_back(stringf("init(%s) := %s;", lvalue(wire), rvalue(wire->attributes.at(ID::init))));
}
for (auto cell : module->cells())
{
// FIXME: $slice, $concat, $mem
if (cell->type.in("$assert"))
if (cell->type.in(ID($assert)))
{
SigSpec sig_a = cell->getPort("\\A");
SigSpec sig_en = cell->getPort("\\EN");
SigSpec sig_a = cell->getPort(ID::A);
SigSpec sig_en = cell->getPort(ID::EN);
invarspecs.push_back(stringf("!bool(%s) | bool(%s);", rvalue(sig_en), rvalue(sig_a)));
continue;
}
if (cell->type.in("$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx"))
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)))
{
SigSpec sig_a = cell->getPort("\\A");
SigSpec sig_b = cell->getPort("\\B");
SigSpec sig_a = cell->getPort(ID::A);
SigSpec sig_b = cell->getPort(ID::B);
int width_y = GetSize(cell->getPort("\\Y"));
int width_y = GetSize(cell->getPort(ID::Y));
int shift_b_width = GetSize(sig_b);
int width_ay = max(GetSize(sig_a), width_y);
int width = width_ay;
@ -254,12 +254,12 @@ struct SmvWorker
break;
}
bool signed_a = cell->getParam("\\A_SIGNED").as_bool();
bool signed_b = cell->getParam("\\B_SIGNED").as_bool();
string op = cell->type.in("$shl", "$sshl") ? "<<" : ">>";
bool signed_a = cell->getParam(ID::A_SIGNED).as_bool();
bool signed_b = cell->getParam(ID::B_SIGNED).as_bool();
string op = cell->type.in(ID($shl), ID($sshl)) ? "<<" : ">>";
string expr, expr_a;
if (cell->type == "$sshr" && signed_a)
if (cell->type == ID($sshr) && signed_a)
{
expr_a = rvalue_s(sig_a, width);
expr = stringf("resize(unsigned(%s %s %s), %d)", expr_a.c_str(), op.c_str(), rvalue(sig_b.extract(0, shift_b_width)), width_y);
@ -268,7 +268,7 @@ struct SmvWorker
rvalue(sig_b.extract(shift_b_width, GetSize(sig_b) - shift_b_width)), GetSize(sig_b) - shift_b_width,
rvalue(sig_a[GetSize(sig_a)-1]), width_y, width_y, expr.c_str());
}
else if (cell->type.in("$shift", "$shiftx") && signed_b)
else if (cell->type.in(ID($shift), ID($shiftx)) && signed_b)
{
expr_a = rvalue_u(sig_a, width);
@ -292,7 +292,7 @@ struct SmvWorker
}
else
{
if (cell->type.in("$shift", "$shiftx") || !signed_a)
if (cell->type.in(ID($shift), ID($shiftx)) || !signed_a)
expr_a = rvalue_u(sig_a, width);
else
expr_a = stringf("resize(unsigned(%s), %d)", rvalue_s(sig_a, width_ay), width);
@ -303,272 +303,272 @@ struct SmvWorker
GetSize(sig_b)-shift_b_width, width_y, expr.c_str());
}
definitions.push_back(stringf("%s := %s;", lvalue(cell->getPort("\\Y")), expr.c_str()));
definitions.push_back(stringf("%s := %s;", lvalue(cell->getPort(ID::Y)), expr.c_str()));
continue;
}
if (cell->type.in("$not", "$pos", "$neg"))
if (cell->type.in(ID($not), ID($pos), ID($neg)))
{
int width = GetSize(cell->getPort("\\Y"));
int width = GetSize(cell->getPort(ID::Y));
string expr_a, op;
if (cell->type == "$not") op = "!";
if (cell->type == "$pos") op = "";
if (cell->type == "$neg") op = "-";
if (cell->type == ID($not)) op = "!";
if (cell->type == ID($pos)) op = "";
if (cell->type == ID($neg)) op = "-";
if (cell->getParam("\\A_SIGNED").as_bool())
if (cell->getParam(ID::A_SIGNED).as_bool())
{
definitions.push_back(stringf("%s := unsigned(%s%s);", lvalue(cell->getPort("\\Y")),
op.c_str(), rvalue_s(cell->getPort("\\A"), width)));
definitions.push_back(stringf("%s := unsigned(%s%s);", lvalue(cell->getPort(ID::Y)),
op.c_str(), rvalue_s(cell->getPort(ID::A), width)));
}
else
{
definitions.push_back(stringf("%s := %s%s;", lvalue(cell->getPort("\\Y")),
op.c_str(), rvalue_u(cell->getPort("\\A"), width)));
definitions.push_back(stringf("%s := %s%s;", lvalue(cell->getPort(ID::Y)),
op.c_str(), rvalue_u(cell->getPort(ID::A), width)));
}
continue;
}
if (cell->type.in("$add", "$sub", "$mul", "$and", "$or", "$xor", "$xnor"))
if (cell->type.in(ID($add), ID($sub), ID($mul), ID($and), ID($or), ID($xor), ID($xnor)))
{
int width = GetSize(cell->getPort("\\Y"));
int width = GetSize(cell->getPort(ID::Y));
string expr_a, expr_b, op;
if (cell->type == "$add") op = "+";
if (cell->type == "$sub") op = "-";
if (cell->type == "$mul") op = "*";
if (cell->type == "$and") op = "&";
if (cell->type == "$or") op = "|";
if (cell->type == "$xor") op = "xor";
if (cell->type == "$xnor") op = "xnor";
if (cell->type == ID($add)) op = "+";
if (cell->type == ID($sub)) op = "-";
if (cell->type == ID($mul)) op = "*";
if (cell->type == ID($and)) op = "&";
if (cell->type == ID($or)) op = "|";
if (cell->type == ID($xor)) op = "xor";
if (cell->type == ID($xnor)) op = "xnor";
if (cell->getParam("\\A_SIGNED").as_bool())
if (cell->getParam(ID::A_SIGNED).as_bool())
{
definitions.push_back(stringf("%s := unsigned(%s %s %s);", lvalue(cell->getPort("\\Y")),
rvalue_s(cell->getPort("\\A"), width), op.c_str(), rvalue_s(cell->getPort("\\B"), width)));
definitions.push_back(stringf("%s := unsigned(%s %s %s);", lvalue(cell->getPort(ID::Y)),
rvalue_s(cell->getPort(ID::A), width), op.c_str(), rvalue_s(cell->getPort(ID::B), width)));
}
else
{
definitions.push_back(stringf("%s := %s %s %s;", lvalue(cell->getPort("\\Y")),
rvalue_u(cell->getPort("\\A"), width), op.c_str(), rvalue_u(cell->getPort("\\B"), width)));
definitions.push_back(stringf("%s := %s %s %s;", lvalue(cell->getPort(ID::Y)),
rvalue_u(cell->getPort(ID::A), width), op.c_str(), rvalue_u(cell->getPort(ID::B), width)));
}
continue;
}
if (cell->type.in("$div", "$mod"))
if (cell->type.in(ID($div), ID($mod)))
{
int width_y = GetSize(cell->getPort("\\Y"));
int width = max(width_y, GetSize(cell->getPort("\\A")));
width = max(width, GetSize(cell->getPort("\\B")));
int width_y = GetSize(cell->getPort(ID::Y));
int width = max(width_y, GetSize(cell->getPort(ID::A)));
width = max(width, GetSize(cell->getPort(ID::B)));
string expr_a, expr_b, op;
if (cell->type == "$div") op = "/";
if (cell->type == "$mod") op = "mod";
if (cell->type == ID($div)) op = "/";
if (cell->type == ID($mod)) op = "mod";
if (cell->getParam("\\A_SIGNED").as_bool())
if (cell->getParam(ID::A_SIGNED).as_bool())
{
definitions.push_back(stringf("%s := resize(unsigned(%s %s %s), %d);", lvalue(cell->getPort("\\Y")),
rvalue_s(cell->getPort("\\A"), width), op.c_str(), rvalue_s(cell->getPort("\\B"), width), width_y));
definitions.push_back(stringf("%s := resize(unsigned(%s %s %s), %d);", lvalue(cell->getPort(ID::Y)),
rvalue_s(cell->getPort(ID::A), width), op.c_str(), rvalue_s(cell->getPort(ID::B), width), width_y));
}
else
{
definitions.push_back(stringf("%s := resize(%s %s %s, %d);", lvalue(cell->getPort("\\Y")),
rvalue_u(cell->getPort("\\A"), width), op.c_str(), rvalue_u(cell->getPort("\\B"), width), width_y));
definitions.push_back(stringf("%s := resize(%s %s %s, %d);", lvalue(cell->getPort(ID::Y)),
rvalue_u(cell->getPort(ID::A), width), op.c_str(), rvalue_u(cell->getPort(ID::B), width), width_y));
}
continue;
}
if (cell->type.in("$eq", "$ne", "$eqx", "$nex", "$lt", "$le", "$ge", "$gt"))
if (cell->type.in(ID($eq), ID($ne), ID($eqx), ID($nex), ID($lt), ID($le), ID($ge), ID($gt)))
{
int width = max(GetSize(cell->getPort("\\A")), GetSize(cell->getPort("\\B")));
int width = max(GetSize(cell->getPort(ID::A)), GetSize(cell->getPort(ID::B)));
string expr_a, expr_b, op;
if (cell->type == "$eq") op = "=";
if (cell->type == "$ne") op = "!=";
if (cell->type == "$eqx") op = "=";
if (cell->type == "$nex") op = "!=";
if (cell->type == "$lt") op = "<";
if (cell->type == "$le") op = "<=";
if (cell->type == "$ge") op = ">=";
if (cell->type == "$gt") op = ">";
if (cell->type == ID($eq)) op = "=";
if (cell->type == ID($ne)) op = "!=";
if (cell->type == ID($eqx)) op = "=";
if (cell->type == ID($nex)) op = "!=";
if (cell->type == ID($lt)) op = "<";
if (cell->type == ID($le)) op = "<=";
if (cell->type == ID($ge)) op = ">=";
if (cell->type == ID($gt)) op = ">";
if (cell->getParam("\\A_SIGNED").as_bool())
if (cell->getParam(ID::A_SIGNED).as_bool())
{
expr_a = stringf("resize(signed(%s), %d)", rvalue(cell->getPort("\\A")), width);
expr_b = stringf("resize(signed(%s), %d)", rvalue(cell->getPort("\\B")), width);
expr_a = stringf("resize(signed(%s), %d)", rvalue(cell->getPort(ID::A)), width);
expr_b = stringf("resize(signed(%s), %d)", rvalue(cell->getPort(ID::B)), width);
}
else
{
expr_a = stringf("resize(%s, %d)", rvalue(cell->getPort("\\A")), width);
expr_b = stringf("resize(%s, %d)", rvalue(cell->getPort("\\B")), width);
expr_a = stringf("resize(%s, %d)", rvalue(cell->getPort(ID::A)), width);
expr_b = stringf("resize(%s, %d)", rvalue(cell->getPort(ID::B)), width);
}
definitions.push_back(stringf("%s := resize(word1(%s %s %s), %d);", lvalue(cell->getPort("\\Y")),
expr_a.c_str(), op.c_str(), expr_b.c_str(), GetSize(cell->getPort("\\Y"))));
definitions.push_back(stringf("%s := resize(word1(%s %s %s), %d);", lvalue(cell->getPort(ID::Y)),
expr_a.c_str(), op.c_str(), expr_b.c_str(), GetSize(cell->getPort(ID::Y))));
continue;
}
if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_bool"))
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool)))
{
int width_a = GetSize(cell->getPort("\\A"));
int width_y = GetSize(cell->getPort("\\Y"));
const char *expr_a = rvalue(cell->getPort("\\A"));
const char *expr_y = lvalue(cell->getPort("\\Y"));
int width_a = GetSize(cell->getPort(ID::A));
int width_y = GetSize(cell->getPort(ID::Y));
const char *expr_a = rvalue(cell->getPort(ID::A));
const char *expr_y = lvalue(cell->getPort(ID::Y));
string expr;
if (cell->type == "$reduce_and") expr = stringf("%s = !0ub%d_0", expr_a, width_a);
if (cell->type == "$reduce_or") expr = stringf("%s != 0ub%d_0", expr_a, width_a);
if (cell->type == "$reduce_bool") expr = stringf("%s != 0ub%d_0", expr_a, width_a);
if (cell->type == ID($reduce_and)) expr = stringf("%s = !0ub%d_0", expr_a, width_a);
if (cell->type == ID($reduce_or)) expr = stringf("%s != 0ub%d_0", expr_a, width_a);
if (cell->type == ID($reduce_bool)) expr = stringf("%s != 0ub%d_0", expr_a, width_a);
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr.c_str(), width_y));
continue;
}
if (cell->type.in("$reduce_xor", "$reduce_xnor"))
if (cell->type.in(ID($reduce_xor), ID($reduce_xnor)))
{
int width_y = GetSize(cell->getPort("\\Y"));
const char *expr_y = lvalue(cell->getPort("\\Y"));
int width_y = GetSize(cell->getPort(ID::Y));
const char *expr_y = lvalue(cell->getPort(ID::Y));
string expr;
for (auto bit : cell->getPort("\\A")) {
for (auto bit : cell->getPort(ID::A)) {
if (!expr.empty())
expr += " xor ";
expr += rvalue(bit);
}
if (cell->type == "$reduce_xnor")
if (cell->type == ID($reduce_xnor))
expr = "!(" + expr + ")";
definitions.push_back(stringf("%s := resize(%s, %d);", expr_y, expr.c_str(), width_y));
continue;
}
if (cell->type.in("$logic_and", "$logic_or"))
if (cell->type.in(ID($logic_and), ID($logic_or)))
{
int width_a = GetSize(cell->getPort("\\A"));
int width_b = GetSize(cell->getPort("\\B"));
int width_y = GetSize(cell->getPort("\\Y"));
int width_a = GetSize(cell->getPort(ID::A));
int width_b = GetSize(cell->getPort(ID::B));
int width_y = GetSize(cell->getPort(ID::Y));
string expr_a = stringf("(%s != 0ub%d_0)", rvalue(cell->getPort("\\A")), width_a);
string expr_b = stringf("(%s != 0ub%d_0)", rvalue(cell->getPort("\\B")), width_b);
const char *expr_y = lvalue(cell->getPort("\\Y"));
string expr_a = stringf("(%s != 0ub%d_0)", rvalue(cell->getPort(ID::A)), width_a);
string expr_b = stringf("(%s != 0ub%d_0)", rvalue(cell->getPort(ID::B)), width_b);
const char *expr_y = lvalue(cell->getPort(ID::Y));
string expr;
if (cell->type == "$logic_and") expr = expr_a + " & " + expr_b;
if (cell->type == "$logic_or") expr = expr_a + " | " + expr_b;
if (cell->type == ID($logic_and)) expr = expr_a + " & " + expr_b;
if (cell->type == ID($logic_or)) expr = expr_a + " | " + expr_b;
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr.c_str(), width_y));
continue;
}
if (cell->type.in("$logic_not"))
if (cell->type.in(ID($logic_not)))
{
int width_a = GetSize(cell->getPort("\\A"));
int width_y = GetSize(cell->getPort("\\Y"));
int width_a = GetSize(cell->getPort(ID::A));
int width_y = GetSize(cell->getPort(ID::Y));
string expr_a = stringf("(%s = 0ub%d_0)", rvalue(cell->getPort("\\A")), width_a);
const char *expr_y = lvalue(cell->getPort("\\Y"));
string expr_a = stringf("(%s = 0ub%d_0)", rvalue(cell->getPort(ID::A)), width_a);
const char *expr_y = lvalue(cell->getPort(ID::Y));
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr_a.c_str(), width_y));
continue;
}
if (cell->type.in("$mux", "$pmux"))
if (cell->type.in(ID($mux), ID($pmux)))
{
int width = GetSize(cell->getPort("\\Y"));
SigSpec sig_a = cell->getPort("\\A");
SigSpec sig_b = cell->getPort("\\B");
SigSpec sig_s = cell->getPort("\\S");
int width = GetSize(cell->getPort(ID::Y));
SigSpec sig_a = cell->getPort(ID::A);
SigSpec sig_b = cell->getPort(ID::B);
SigSpec sig_s = cell->getPort(ID::S);
string expr;
for (int i = 0; i < GetSize(sig_s); i++)
expr += stringf("bool(%s) ? %s : ", rvalue(sig_s[i]), rvalue(sig_b.extract(i*width, width)));
expr += rvalue(sig_a);
definitions.push_back(stringf("%s := %s;", lvalue(cell->getPort("\\Y")), expr.c_str()));
definitions.push_back(stringf("%s := %s;", lvalue(cell->getPort(ID::Y)), expr.c_str()));
continue;
}
if (cell->type == "$dff")
if (cell->type == ID($dff))
{
vars.push_back(stringf("%s : unsigned word[%d]; -- %s", lvalue(cell->getPort("\\Q")), GetSize(cell->getPort("\\Q")), log_signal(cell->getPort("\\Q"))));
assignments.push_back(stringf("next(%s) := %s;", lvalue(cell->getPort("\\Q")), rvalue(cell->getPort("\\D"))));
vars.push_back(stringf("%s : unsigned word[%d]; -- %s", lvalue(cell->getPort(ID::Q)), GetSize(cell->getPort(ID::Q)), log_signal(cell->getPort(ID::Q))));
assignments.push_back(stringf("next(%s) := %s;", lvalue(cell->getPort(ID::Q)), rvalue(cell->getPort(ID::D))));
continue;
}
if (cell->type.in("$_BUF_", "$_NOT_"))
if (cell->type.in(ID($_BUF_), ID($_NOT_)))
{
string op = cell->type == "$_NOT_" ? "!" : "";
definitions.push_back(stringf("%s := %s%s;", lvalue(cell->getPort("\\Y")), op.c_str(), rvalue(cell->getPort("\\A"))));
string op = cell->type == ID($_NOT_) ? "!" : "";
definitions.push_back(stringf("%s := %s%s;", lvalue(cell->getPort(ID::Y)), op.c_str(), rvalue(cell->getPort(ID::A))));
continue;
}
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_)))
{
string op;
if (cell->type.in("$_AND_", "$_NAND_", "$_ANDNOT_")) op = "&";
if (cell->type.in("$_OR_", "$_NOR_", "$_ORNOT_")) op = "|";
if (cell->type.in("$_XOR_")) op = "xor";
if (cell->type.in("$_XNOR_")) op = "xnor";
if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_ANDNOT_))) op = "&";
if (cell->type.in(ID($_OR_), ID($_NOR_), ID($_ORNOT_))) op = "|";
if (cell->type.in(ID($_XOR_))) op = "xor";
if (cell->type.in(ID($_XNOR_))) op = "xnor";
if (cell->type.in("$_ANDNOT_", "$_ORNOT_"))
definitions.push_back(stringf("%s := %s %s (!%s);", lvalue(cell->getPort("\\Y")),
rvalue(cell->getPort("\\A")), op.c_str(), rvalue(cell->getPort("\\B"))));
if (cell->type.in(ID($_ANDNOT_), ID($_ORNOT_)))
definitions.push_back(stringf("%s := %s %s (!%s);", lvalue(cell->getPort(ID::Y)),
rvalue(cell->getPort(ID::A)), op.c_str(), rvalue(cell->getPort(ID::B))));
else
if (cell->type.in("$_NAND_", "$_NOR_"))
definitions.push_back(stringf("%s := !(%s %s %s);", lvalue(cell->getPort("\\Y")),
rvalue(cell->getPort("\\A")), op.c_str(), rvalue(cell->getPort("\\B"))));
if (cell->type.in(ID($_NAND_), ID($_NOR_)))
definitions.push_back(stringf("%s := !(%s %s %s);", lvalue(cell->getPort(ID::Y)),
rvalue(cell->getPort(ID::A)), op.c_str(), rvalue(cell->getPort(ID::B))));
else
definitions.push_back(stringf("%s := %s %s %s;", lvalue(cell->getPort("\\Y")),
rvalue(cell->getPort("\\A")), op.c_str(), rvalue(cell->getPort("\\B"))));
definitions.push_back(stringf("%s := %s %s %s;", lvalue(cell->getPort(ID::Y)),
rvalue(cell->getPort(ID::A)), op.c_str(), rvalue(cell->getPort(ID::B))));
continue;
}
if (cell->type == "$_MUX_")
if (cell->type == ID($_MUX_))
{
definitions.push_back(stringf("%s := bool(%s) ? %s : %s;", lvalue(cell->getPort("\\Y")),
rvalue(cell->getPort("\\S")), rvalue(cell->getPort("\\B")), rvalue(cell->getPort("\\A"))));
definitions.push_back(stringf("%s := bool(%s) ? %s : %s;", lvalue(cell->getPort(ID::Y)),
rvalue(cell->getPort(ID::S)), rvalue(cell->getPort(ID::B)), rvalue(cell->getPort(ID::A))));
continue;
}
if (cell->type == "$_NMUX_")
if (cell->type == ID($_NMUX_))
{
definitions.push_back(stringf("%s := !(bool(%s) ? %s : %s);", lvalue(cell->getPort("\\Y")),
rvalue(cell->getPort("\\S")), rvalue(cell->getPort("\\B")), rvalue(cell->getPort("\\A"))));
definitions.push_back(stringf("%s := !(bool(%s) ? %s : %s);", lvalue(cell->getPort(ID::Y)),
rvalue(cell->getPort(ID::S)), rvalue(cell->getPort(ID::B)), rvalue(cell->getPort(ID::A))));
continue;
}
if (cell->type == "$_AOI3_")
if (cell->type == ID($_AOI3_))
{
definitions.push_back(stringf("%s := !((%s & %s) | %s);", lvalue(cell->getPort("\\Y")),
rvalue(cell->getPort("\\A")), rvalue(cell->getPort("\\B")), rvalue(cell->getPort("\\C"))));
definitions.push_back(stringf("%s := !((%s & %s) | %s);", lvalue(cell->getPort(ID::Y)),
rvalue(cell->getPort(ID::A)), rvalue(cell->getPort(ID::B)), rvalue(cell->getPort(ID::C))));
continue;
}
if (cell->type == "$_OAI3_")
if (cell->type == ID($_OAI3_))
{
definitions.push_back(stringf("%s := !((%s | %s) & %s);", lvalue(cell->getPort("\\Y")),
rvalue(cell->getPort("\\A")), rvalue(cell->getPort("\\B")), rvalue(cell->getPort("\\C"))));
definitions.push_back(stringf("%s := !((%s | %s) & %s);", lvalue(cell->getPort(ID::Y)),
rvalue(cell->getPort(ID::A)), rvalue(cell->getPort(ID::B)), rvalue(cell->getPort(ID::C))));
continue;
}
if (cell->type == "$_AOI4_")
if (cell->type == ID($_AOI4_))
{
definitions.push_back(stringf("%s := !((%s & %s) | (%s & %s));", lvalue(cell->getPort("\\Y")),
rvalue(cell->getPort("\\A")), rvalue(cell->getPort("\\B")), rvalue(cell->getPort("\\C")), rvalue(cell->getPort("\\D"))));
definitions.push_back(stringf("%s := !((%s & %s) | (%s & %s));", lvalue(cell->getPort(ID::Y)),
rvalue(cell->getPort(ID::A)), rvalue(cell->getPort(ID::B)), rvalue(cell->getPort(ID::C)), rvalue(cell->getPort(ID::D))));
continue;
}
if (cell->type == "$_OAI4_")
if (cell->type == ID($_OAI4_))
{
definitions.push_back(stringf("%s := !((%s | %s) & (%s | %s));", lvalue(cell->getPort("\\Y")),
rvalue(cell->getPort("\\A")), rvalue(cell->getPort("\\B")), rvalue(cell->getPort("\\C")), rvalue(cell->getPort("\\D"))));
definitions.push_back(stringf("%s := !((%s | %s) & (%s | %s));", lvalue(cell->getPort(ID::Y)),
rvalue(cell->getPort(ID::A)), rvalue(cell->getPort(ID::B)), rvalue(cell->getPort(ID::C)), rvalue(cell->getPort(ID::D))));
continue;
}

View file

@ -70,14 +70,13 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De
idict<IdString, 1> inums;
int cell_counter = 0, conn_counter = 0, nc_counter = 0;
for (auto &cell_it : module->cells_)
for (auto cell : module->cells())
{
RTLIL::Cell *cell = cell_it.second;
f << stringf("X%d", cell_counter++);
std::vector<RTLIL::SigSpec> port_sigs;
if (design->modules_.count(cell->type) == 0)
if (design->module(cell->type) == nullptr)
{
log_warning("no (blackbox) module for cell type `%s' (%s.%s) found! Guessing order of ports.\n",
log_id(cell->type), log_id(module), log_id(cell));
@ -88,11 +87,10 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De
}
else
{
RTLIL::Module *mod = design->modules_.at(cell->type);
RTLIL::Module *mod = design->module(cell->type);
std::vector<RTLIL::Wire*> ports;
for (auto wire_it : mod->wires_) {
RTLIL::Wire *wire = wire_it.second;
for (auto wire : mod->wires()) {
if (wire->port_id == 0)
continue;
while (int(ports.size()) < wire->port_id)
@ -202,16 +200,15 @@ struct SpiceBackend : public Backend {
extra_args(f, filename, args, argidx);
if (top_module_name.empty())
for (auto & mod_it:design->modules_)
if (mod_it.second->get_bool_attribute("\\top"))
top_module_name = mod_it.first.str();
for (auto module : design->modules())
if (module->get_bool_attribute(ID::top))
top_module_name = module->name.str();
*f << stringf("* SPICE netlist generated by %s\n", yosys_version_str);
*f << stringf("\n");
for (auto module_it : design->modules_)
for (auto module : design->modules())
{
RTLIL::Module *module = module_it.second;
if (module->get_blackbox_attribute())
continue;
@ -226,8 +223,7 @@ struct SpiceBackend : public Backend {
}
std::vector<RTLIL::Wire*> ports;
for (auto wire_it : module->wires_) {
RTLIL::Wire *wire = wire_it.second;
for (auto wire : module->wires()) {
if (wire->port_id == 0)
continue;
while (int(ports.size()) < wire->port_id)

File diff suppressed because it is too large Load diff

View file

@ -29,8 +29,8 @@ struct EvalDemoPass : public Pass
if (module == nullptr)
log_error("No top module found!\n");
Wire *wire_a = module->wire("\\A");
Wire *wire_y = module->wire("\\Y");
Wire *wire_a = module->wire(ID::A);
Wire *wire_y = module->wire(ID::Y);
if (wire_a == nullptr)
log_error("No wire A found!\n");

View file

@ -30,7 +30,9 @@
#include <libkern/OSByteOrder.h>
#define __builtin_bswap32 OSSwapInt32
#endif
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#include <inttypes.h>
#include "kernel/yosys.h"
@ -117,7 +119,7 @@ struct ConstEvalAig
sig2deps[output].insert(output);
RTLIL::Cell *cell = sig2driver.at(output);
RTLIL::SigBit sig_a = cell->getPort("\\A");
RTLIL::SigBit sig_a = cell->getPort(ID::A);
sig2deps[sig_a].reserve(sig2deps[sig_a].size() + sig2deps[output].size()); // Reserve so that any invalidation
// that may occur does so here, and
// not mid insertion (below)
@ -125,8 +127,8 @@ struct ConstEvalAig
if (!inputs.count(sig_a))
compute_deps(sig_a, inputs);
if (cell->type == "$_AND_") {
RTLIL::SigSpec sig_b = cell->getPort("\\B");
if (cell->type == ID($_AND_)) {
RTLIL::SigSpec sig_b = cell->getPort(ID::B);
sig2deps[sig_b].reserve(sig2deps[sig_b].size() + sig2deps[output].size()); // Reserve so that any invalidation
// that may occur does so here, and
// not mid insertion (below)
@ -135,34 +137,34 @@ struct ConstEvalAig
if (!inputs.count(sig_b))
compute_deps(sig_b, inputs);
}
else if (cell->type == "$_NOT_") {
else if (cell->type == ID($_NOT_)) {
}
else log_abort();
}
bool eval(RTLIL::Cell *cell)
{
RTLIL::SigBit sig_y = cell->getPort("\\Y");
RTLIL::SigBit sig_y = cell->getPort(ID::Y);
if (values_map.count(sig_y))
return true;
RTLIL::SigBit sig_a = cell->getPort("\\A");
RTLIL::SigBit sig_a = cell->getPort(ID::A);
if (!eval(sig_a))
return false;
RTLIL::State eval_ret = RTLIL::Sx;
if (cell->type == "$_NOT_") {
if (cell->type == ID($_NOT_)) {
if (sig_a == State::S0) eval_ret = State::S1;
else if (sig_a == State::S1) eval_ret = State::S0;
}
else if (cell->type == "$_AND_") {
else if (cell->type == ID($_AND_)) {
if (sig_a == State::S0) {
eval_ret = State::S0;
goto eval_end;
}
{
RTLIL::SigBit sig_b = cell->getPort("\\B");
RTLIL::SigBit sig_b = cell->getPort(ID::B);
if (!eval(sig_b))
return false;
if (sig_b == State::S0) {
@ -444,7 +446,7 @@ void AigerReader::parse_xaiger()
}
}
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);
log_debug("flopNum = %u\n", flopNum);
log_assert(dataSize == (flopNum+1) * sizeof(uint32_t));
@ -478,9 +480,9 @@ void AigerReader::parse_xaiger()
log_assert(boxUniqueId > 0);
uint32_t oldBoxNum = parse_xaiger_literal(f);
RTLIL::Cell* cell = module->addCell(stringf("$box%u", oldBoxNum), stringf("$__boxid%u", boxUniqueId));
cell->setPort("\\i", SigSpec(State::S0, boxInputs));
cell->setPort("\\o", SigSpec(State::S0, boxOutputs));
cell->attributes["\\abc9_box_seq"] = oldBoxNum;
cell->setPort(ID(i), SigSpec(State::S0, boxInputs));
cell->setPort(ID(o), SigSpec(State::S0, boxOutputs));
cell->attributes[ID::abc9_box_seq] = oldBoxNum;
boxes.emplace_back(cell);
}
}
@ -548,18 +550,18 @@ void AigerReader::parse_aiger_ascii()
log_error("Line %u cannot be interpreted as a latch!\n", line_count);
if (l3 == 0)
q_wire->attributes["\\init"] = State::S0;
q_wire->attributes[ID::init] = State::S0;
else if (l3 == 1)
q_wire->attributes["\\init"] = State::S1;
q_wire->attributes[ID::init] = State::S1;
else if (l3 == l1) {
//q_wire->attributes["\\init"] = RTLIL::Sx;
//q_wire->attributes[ID::init] = RTLIL::Sx;
}
else
log_error("Line %u has invalid reset literal for latch!\n", line_count);
}
else {
// AIGER latches are assumed to be initialized to zero
q_wire->attributes["\\init"] = State::S0;
q_wire->attributes[ID::init] = State::S0;
}
latches.push_back(q_wire);
}
@ -673,18 +675,18 @@ void AigerReader::parse_aiger_binary()
log_error("Line %u cannot be interpreted as a latch!\n", line_count);
if (l3 == 0)
q_wire->attributes["\\init"] = State::S0;
q_wire->attributes[ID::init] = State::S0;
else if (l3 == 1)
q_wire->attributes["\\init"] = State::S1;
q_wire->attributes[ID::init] = State::S1;
else if (l3 == l1) {
//q_wire->attributes["\\init"] = RTLIL::Sx;
//q_wire->attributes[ID::init] = RTLIL::Sx;
}
else
log_error("Line %u has invalid reset literal for latch!\n", line_count);
}
else {
// AIGER latches are assumed to be initialized to zero
q_wire->attributes["\\init"] = State::S0;
q_wire->attributes[ID::init] = State::S0;
}
latches.push_back(q_wire);
}
@ -747,7 +749,7 @@ void AigerReader::post_process()
{
unsigned ci_count = 0, co_count = 0;
for (auto cell : boxes) {
for (auto &bit : cell->connections_.at("\\i")) {
for (auto &bit : cell->connections_.at(ID(i))) {
log_assert(bit == State::S0);
log_assert(co_count < outputs.size());
bit = outputs[co_count++];
@ -755,7 +757,7 @@ void AigerReader::post_process()
log_assert(bit.wire->port_output);
bit.wire->port_output = false;
}
for (auto &bit : cell->connections_.at("\\o")) {
for (auto &bit : cell->connections_.at(ID(o))) {
log_assert(bit == State::S0);
log_assert((piNum + ci_count) < inputs.size());
bit = inputs[piNum + ci_count++];
@ -776,10 +778,10 @@ void AigerReader::post_process()
log_assert(q->port_input);
q->port_input = false;
auto ff = module->addCell(NEW_ID, "$__ABC9_FF_");
ff->setPort("\\D", d);
ff->setPort("\\Q", q);
ff->attributes["\\abc9_mergeability"] = mergeability[i];
auto ff = module->addCell(NEW_ID, ID($__ABC9_FF_));
ff->setPort(ID::D, d);
ff->setPort(ID::Q, q);
ff->attributes[ID::abc9_mergeability] = mergeability[i];
}
dict<RTLIL::IdString, int> wideports_cache;
@ -866,7 +868,7 @@ void AigerReader::post_process()
int init;
mf >> init;
if (init < 2)
wire->attributes["\\init"] = init;
wire->attributes[ID::init] = init;
}
else if (type == "box") {
RTLIL::Cell* cell = module->cell(stringf("$box%d", variable));
@ -929,8 +931,8 @@ void AigerReader::post_process()
design->add(module);
for (auto cell : module->cells().to_vector()) {
if (cell->type != "$lut") continue;
auto y_port = cell->getPort("\\Y").as_bit();
if (cell->type != ID($lut)) continue;
auto y_port = cell->getPort(ID::Y).as_bit();
if (y_port.wire->width == 1)
module->rename(cell, stringf("$lut%s", y_port.wire->name.c_str()));
else

View file

@ -952,9 +952,9 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
current_module = new AstModule;
current_module->ast = NULL;
current_module->name = ast->str;
current_module->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line,
current_module->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line,
ast->location.first_column, ast->location.last_line, ast->location.last_column);
current_module->set_bool_attribute("\\cells_not_processed");
current_module->set_bool_attribute(ID::cells_not_processed);
current_ast_mod = ast;
AstNode *ast_before_simplify;
@ -1007,61 +1007,61 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
log("--- END OF AST DUMP ---\n");
}
if (flag_nowb && ast->attributes.count("\\whitebox")) {
delete ast->attributes.at("\\whitebox");
ast->attributes.erase("\\whitebox");
if (flag_nowb && ast->attributes.count(ID::whitebox)) {
delete ast->attributes.at(ID::whitebox);
ast->attributes.erase(ID::whitebox);
}
if (ast->attributes.count("\\lib_whitebox")) {
if (ast->attributes.count(ID::lib_whitebox)) {
if (!flag_lib || flag_nowb) {
delete ast->attributes.at("\\lib_whitebox");
ast->attributes.erase("\\lib_whitebox");
delete ast->attributes.at(ID::lib_whitebox);
ast->attributes.erase(ID::lib_whitebox);
} else {
if (ast->attributes.count("\\whitebox")) {
delete ast->attributes.at("\\whitebox");
ast->attributes.erase("\\whitebox");
if (ast->attributes.count(ID::whitebox)) {
delete ast->attributes.at(ID::whitebox);
ast->attributes.erase(ID::whitebox);
}
AstNode *n = ast->attributes.at("\\lib_whitebox");
ast->attributes["\\whitebox"] = n;
ast->attributes.erase("\\lib_whitebox");
AstNode *n = ast->attributes.at(ID::lib_whitebox);
ast->attributes[ID::whitebox] = n;
ast->attributes.erase(ID::lib_whitebox);
}
}
if (!blackbox_module && ast->attributes.count("\\blackbox")) {
AstNode *n = ast->attributes.at("\\blackbox");
if (!blackbox_module && ast->attributes.count(ID::blackbox)) {
AstNode *n = ast->attributes.at(ID::blackbox);
if (n->type != AST_CONSTANT)
log_file_error(ast->filename, ast->location.first_line, "Got blackbox attribute with non-constant value!\n");
blackbox_module = n->asBool();
}
if (blackbox_module && ast->attributes.count("\\whitebox")) {
AstNode *n = ast->attributes.at("\\whitebox");
if (blackbox_module && ast->attributes.count(ID::whitebox)) {
AstNode *n = ast->attributes.at(ID::whitebox);
if (n->type != AST_CONSTANT)
log_file_error(ast->filename, ast->location.first_line, "Got whitebox attribute with non-constant value!\n");
blackbox_module = !n->asBool();
}
if (ast->attributes.count("\\noblackbox")) {
if (ast->attributes.count(ID::noblackbox)) {
if (blackbox_module) {
AstNode *n = ast->attributes.at("\\noblackbox");
AstNode *n = ast->attributes.at(ID::noblackbox);
if (n->type != AST_CONSTANT)
log_file_error(ast->filename, ast->location.first_line, "Got noblackbox attribute with non-constant value!\n");
blackbox_module = !n->asBool();
}
delete ast->attributes.at("\\noblackbox");
ast->attributes.erase("\\noblackbox");
delete ast->attributes.at(ID::noblackbox);
ast->attributes.erase(ID::noblackbox);
}
if (blackbox_module)
{
if (ast->attributes.count("\\whitebox")) {
delete ast->attributes.at("\\whitebox");
ast->attributes.erase("\\whitebox");
if (ast->attributes.count(ID::whitebox)) {
delete ast->attributes.at(ID::whitebox);
ast->attributes.erase(ID::whitebox);
}
if (ast->attributes.count("\\lib_whitebox")) {
delete ast->attributes.at("\\lib_whitebox");
ast->attributes.erase("\\lib_whitebox");
if (ast->attributes.count(ID::lib_whitebox)) {
delete ast->attributes.at(ID::lib_whitebox);
ast->attributes.erase(ID::lib_whitebox);
}
std::vector<AstNode*> new_children;
@ -1082,8 +1082,8 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
ast->children.swap(new_children);
if (ast->attributes.count("\\blackbox") == 0) {
ast->attributes["\\blackbox"] = AstNode::mkconst_int(1, false);
if (ast->attributes.count(ID::blackbox) == 0) {
ast->attributes[ID::blackbox] = AstNode::mkconst_int(1, false);
}
}
@ -1124,7 +1124,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
}
if (ast->type == AST_INTERFACE)
current_module->set_bool_attribute("\\is_interface");
current_module->set_bool_attribute(ID::is_interface);
current_module->ast = ast_before_simplify;
current_module->nolatches = flag_nolatches;
current_module->nomeminit = flag_nomeminit;
@ -1179,12 +1179,13 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump
for (auto n : design->verilog_globals)
(*it)->children.push_back(n->clone());
for (auto n : design->verilog_packages){
for (auto o : n->children) {
// append nodes from previous packages using package-qualified names
for (auto &n : design->verilog_packages) {
for (auto &o : n->children) {
AstNode *cloned_node = o->clone();
log("cloned node %s\n", type2str(cloned_node->type).c_str());
if (cloned_node->type == AST_ENUM){
for (auto e : cloned_node->children){
// log("cloned node %s\n", type2str(cloned_node->type).c_str());
if (cloned_node->type == AST_ENUM) {
for (auto &e : cloned_node->children) {
log_assert(e->type == AST_ENUM_ITEM);
e->str = n->str + std::string("::") + e->str.substr(1);
}
@ -1211,7 +1212,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump
continue;
} else {
log("Replacing existing%s module `%s' at %s:%d.%d-%d.%d.\n",
existing_mod->get_bool_attribute("\\blackbox") ? " blackbox" : "",
existing_mod->get_bool_attribute(ID::blackbox) ? " blackbox" : "",
(*it)->str.c_str(), (*it)->filename.c_str(), (*it)->location.first_line, (*it)->location.first_column, (*it)->location.last_line, (*it)->location.last_column);
design->remove(existing_mod);
}
@ -1220,6 +1221,8 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump
design->add(process_module(*it, defer));
}
else if ((*it)->type == AST_PACKAGE) {
// process enum/other declarations
(*it)->simplify(true, false, false, 1, -1, false, false);
design->verilog_packages.push_back((*it)->clone());
}
else {
@ -1281,9 +1284,9 @@ AstNode * AST::find_modport(AstNode *intf, std::string name)
// Iterate over all wires in an interface and add them as wires in the AST module:
void AST::explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule, std::string intfname, AstNode *modport)
{
for (auto &wire_it : intfmodule->wires_){
AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, AstNode::mkconst_int(wire_it.second->width -1, true), AstNode::mkconst_int(0, true)));
std::string origname = log_id(wire_it.first);
for (auto w : intfmodule->wires()){
AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, AstNode::mkconst_int(w->width -1, true), AstNode::mkconst_int(0, true)));
std::string origname = log_id(w->name);
std::string newname = intfname + "." + origname;
wire->str = newname;
if (modport != NULL) {
@ -1317,7 +1320,7 @@ void AST::explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule
// When an interface instance is found in a module, the whole RTLIL for the module will be rederived again
// from AST. The interface members are copied into the AST module with the prefix of the interface.
void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module*> local_interfaces)
void AstModule::reprocess_module(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module*> &local_interfaces)
{
loadconfig();
@ -1326,9 +1329,9 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT
for (auto &intf : local_interfaces) {
std::string intfname = intf.first.str();
RTLIL::Module *intfmodule = intf.second;
for (auto &wire_it : intfmodule->wires_){
AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, AstNode::mkconst_int(wire_it.second->width -1, true), AstNode::mkconst_int(0, true)));
std::string newname = log_id(wire_it.first);
for (auto w : intfmodule->wires()){
AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, AstNode::mkconst_int(w->width -1, true), AstNode::mkconst_int(0, true)));
std::string newname = log_id(w->name);
newname = intfname + "." + newname;
wire->str = newname;
new_ast->children.push_back(wire);
@ -1352,7 +1355,7 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT
std::pair<std::string,std::string> res = split_modport_from_type(ch->str);
std::string interface_type = res.first;
std::string interface_modport = res.second; // Is "", if no modport
if (design->modules_.count(interface_type) > 0) {
if (design->module(interface_type) != nullptr) {
// Add a cell to the module corresponding to the interface port such that
// it can further propagated down if needed:
AstNode *celltype_for_intf = new AstNode(AST_CELLTYPE);
@ -1362,7 +1365,7 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT
new_ast->children.push_back(cell_for_intf);
// Get all members of this non-overridden dummy interface instance:
RTLIL::Module *intfmodule = design->modules_[interface_type]; // All interfaces should at this point in time (assuming
RTLIL::Module *intfmodule = design->module(interface_type); // All interfaces should at this point in time (assuming
// reprocess_module is called from the hierarchy pass) be
// present in design->modules_
AstModule *ast_module_of_interface = (AstModule*)intfmodule;
@ -1382,12 +1385,12 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT
std::string original_name = this->name.str();
std::string changed_name = original_name + "_before_replacing_local_interfaces";
design->rename(this, changed_name);
this->set_bool_attribute("\\to_delete");
this->set_bool_attribute(ID::to_delete);
// Check if the module was the top module. If it was, we need to remove the top attribute and put it on the
// new module.
if (this->get_bool_attribute("\\initial_top")) {
this->attributes.erase("\\initial_top");
if (this->get_bool_attribute(ID::initial_top)) {
this->attributes.erase(ID::initial_top);
is_top = true;
}
@ -1397,15 +1400,15 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT
design->add(newmod);
RTLIL::Module* mod = design->module(original_name);
if (is_top)
mod->set_bool_attribute("\\top");
mod->set_bool_attribute(ID::top);
// Set the attribute "interfaces_replaced_in_module" so that it does not happen again.
mod->set_bool_attribute("\\interfaces_replaced_in_module");
mod->set_bool_attribute(ID::interfaces_replaced_in_module);
}
// create a new parametric module (when needed) and return the name of the generated module - WITH support for interfaces
// This method is used to explode the interface when the interface is a port of the module (not instantiated inside)
RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool /*mayfail*/)
RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool /*mayfail*/)
{
AstNode *new_ast = NULL;
std::string modname = derive_common(design, parameters, &new_ast);
@ -1457,13 +1460,20 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R
// Now that the interfaces have been exploded, we can delete the dummy port related to every interface.
for(auto &intf : interfaces) {
if(mod->wires_.count(intf.first)) {
mod->wires_.erase(intf.first);
if(mod->wire(intf.first) != nullptr) {
// Normally, removing wires would be batched together as it's an
// expensive operation, however, in this case doing so would mean
// that a cell with the same name cannot be created (below)...
// Since we won't expect many interfaces to exist in a module,
// we can let this slide...
pool<RTLIL::Wire*> to_remove;
to_remove.insert(mod->wire(intf.first));
mod->remove(to_remove);
mod->fixup_ports();
// We copy the cell of the interface to the sub-module such that it can further be found if it is propagated
// down to sub-sub-modules etc.
RTLIL::Cell * new_subcell = mod->addCell(intf.first, intf.second->name);
new_subcell->set_bool_attribute("\\is_interface");
// We copy the cell of the interface to the sub-module such that it
// can further be found if it is propagated down to sub-sub-modules etc.
RTLIL::Cell *new_subcell = mod->addCell(intf.first, intf.second->name);
new_subcell->set_bool_attribute(ID::is_interface);
}
else {
log_error("No port with matching name found (%s) in %s. Stopping\n", log_id(intf.first), modname.c_str());
@ -1472,7 +1482,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R
// If any interfaces were replaced, set the attribute 'interfaces_replaced_in_module':
if (interfaces.size() > 0) {
mod->set_bool_attribute("\\interfaces_replaced_in_module");
mod->set_bool_attribute(ID::interfaces_replaced_in_module);
}
} else {
@ -1484,9 +1494,9 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R
}
// create a new parametric module (when needed) and return the name of the generated module - without support for interfaces
RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool /*mayfail*/)
RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool /*mayfail*/)
{
bool quiet = lib || attributes.count(ID(blackbox)) || attributes.count(ID(whitebox));
bool quiet = lib || attributes.count(ID::blackbox) || attributes.count(ID::whitebox);
AstNode *new_ast = NULL;
std::string modname = derive_common(design, parameters, &new_ast, quiet);
@ -1504,7 +1514,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R
}
// create a new parametric module (when needed) and return the name of the generated module
std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out, bool quiet)
std::string AstModule::derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, AstNode **new_ast_out, bool quiet)
{
std::string stripped_name = name.str();
@ -1518,18 +1528,18 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString
if (child->type != AST_PARAMETER)
continue;
para_counter++;
std::string para_id = child->str;
if (parameters.count(para_id) > 0) {
auto it = parameters.find(child->str);
if (it != parameters.end()) {
if (!quiet)
log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str])));
para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
log("Parameter %s = %s\n", child->str.c_str(), log_signal(it->second));
para_info += stringf("%s=%s", child->str.c_str(), log_signal(it->second));
continue;
}
para_id = stringf("$%d", para_counter);
if (parameters.count(para_id) > 0) {
it = parameters.find(stringf("$%d", para_counter));
if (it != parameters.end()) {
if (!quiet)
log("Parameter %d (%s) = %s\n", para_counter, 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])));
log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(it->second));
para_info += stringf("%s=%s", child->str.c_str(), log_signal(it->second));
continue;
}
}
@ -1549,46 +1559,52 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString
log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str());
loadconfig();
pool<IdString> rewritten;
rewritten.reserve(GetSize(parameters));
AstNode *new_ast = ast->clone();
para_counter = 0;
for (auto child : new_ast->children) {
if (child->type != AST_PARAMETER)
continue;
para_counter++;
std::string para_id = child->str;
if (parameters.count(para_id) > 0) {
auto it = parameters.find(child->str);
if (it != parameters.end()) {
if (!quiet)
log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str])));
log("Parameter %s = %s\n", child->str.c_str(), log_signal(it->second));
goto rewrite_parameter;
}
para_id = stringf("$%d", para_counter);
if (parameters.count(para_id) > 0) {
it = parameters.find(stringf("$%d", para_counter));
if (it != parameters.end()) {
if (!quiet)
log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(it->second));
goto rewrite_parameter;
}
continue;
rewrite_parameter:
delete child->children.at(0);
if ((parameters[para_id].flags & RTLIL::CONST_FLAG_REAL) != 0) {
if ((it->second.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]->realvalue = std::stod(it->second.decode_string());
} else if ((it->second.flags & RTLIL::CONST_FLAG_STRING) != 0)
child->children[0] = AstNode::mkconst_str(it->second.decode_string());
else
child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, (parameters[para_id].flags & RTLIL::CONST_FLAG_SIGNED) != 0);
parameters.erase(para_id);
child->children[0] = AstNode::mkconst_bits(it->second.bits, (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0);
rewritten.insert(it->first);
}
for (auto param : parameters) {
AstNode *defparam = new AstNode(AST_DEFPARAM, new AstNode(AST_IDENTIFIER));
defparam->children[0]->str = param.first.str();
if ((param.second.flags & RTLIL::CONST_FLAG_STRING) != 0)
defparam->children.push_back(AstNode::mkconst_str(param.second.decode_string()));
else
defparam->children.push_back(AstNode::mkconst_bits(param.second.bits, (param.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0));
new_ast->children.push_back(defparam);
}
if (GetSize(rewritten) < GetSize(parameters))
for (const auto &param : parameters) {
if (rewritten.count(param.first))
continue;
AstNode *defparam = new AstNode(AST_DEFPARAM, new AstNode(AST_IDENTIFIER));
defparam->children[0]->str = param.first.str();
if ((param.second.flags & RTLIL::CONST_FLAG_STRING) != 0)
defparam->children.push_back(AstNode::mkconst_str(param.second.decode_string()));
else
defparam->children.push_back(AstNode::mkconst_bits(param.second.bits, (param.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0));
new_ast->children.push_back(defparam);
}
(*new_ast_out) = new_ast;
return modname;

View file

@ -312,10 +312,10 @@ namespace AST
AstNode *ast;
bool nolatches, nomeminit, nomem2reg, mem2reg, noblackbox, lib, nowb, noopt, icells, pwires, autowire;
~AstModule() YS_OVERRIDE;
RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail) YS_OVERRIDE;
RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail) YS_OVERRIDE;
std::string derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out, bool quiet = false);
void reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module *> local_interfaces) YS_OVERRIDE;
RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool mayfail) YS_OVERRIDE;
RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail) YS_OVERRIDE;
std::string derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, AstNode **new_ast_out, bool quiet = false);
void reprocess_module(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces) YS_OVERRIDE;
RTLIL::Module *clone() const YS_OVERRIDE;
void loadconfig() const;
};

View file

@ -41,16 +41,14 @@ using namespace AST;
using namespace AST_INTERNAL;
// helper function for creating RTLIL code for unary operations
static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_width, const RTLIL::SigSpec &arg, bool gen_attributes = true)
static RTLIL::SigSpec uniop2rtlil(AstNode *that, IdString type, int result_width, const RTLIL::SigSpec &arg, bool gen_attributes = true)
{
std::stringstream sstr;
sstr << type << "$" << that->filename << ":" << that->location.first_line << "$" << (autoidx++);
RTLIL::Cell *cell = current_module->addCell(sstr.str(), type);
cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
IdString name = stringf("%s$%s:%d$%d", type.c_str(), that->filename.c_str(), that->location.first_line, autoidx++);
RTLIL::Cell *cell = current_module->addCell(name, type);
cell->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width);
wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
wire->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
if (gen_attributes)
for (auto &attr : that->attributes) {
@ -59,12 +57,12 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi
cell->attributes[attr.first] = attr.second->asAttrConst();
}
cell->parameters["\\A_SIGNED"] = RTLIL::Const(that->children[0]->is_signed);
cell->parameters["\\A_WIDTH"] = RTLIL::Const(arg.size());
cell->setPort("\\A", arg);
cell->parameters[ID::A_SIGNED] = RTLIL::Const(that->children[0]->is_signed);
cell->parameters[ID::A_WIDTH] = RTLIL::Const(arg.size());
cell->setPort(ID::A, arg);
cell->parameters["\\Y_WIDTH"] = result_width;
cell->setPort("\\Y", wire);
cell->parameters[ID::Y_WIDTH] = result_width;
cell->setPort(ID::Y, wire);
return wire;
}
@ -76,14 +74,12 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s
return;
}
std::stringstream sstr;
sstr << "$extend" << "$" << that->filename << ":" << that->location.first_line << "$" << (autoidx++);
RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$pos");
cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
IdString name = stringf("$extend$%s:%d$%d", that->filename.c_str(), that->location.first_line, autoidx++);
RTLIL::Cell *cell = current_module->addCell(name, ID($pos));
cell->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", width);
wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
wire->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
if (that != NULL)
for (auto &attr : that->attributes) {
@ -92,26 +88,24 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s
cell->attributes[attr.first] = attr.second->asAttrConst();
}
cell->parameters["\\A_SIGNED"] = RTLIL::Const(is_signed);
cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.size());
cell->setPort("\\A", sig);
cell->parameters[ID::A_SIGNED] = RTLIL::Const(is_signed);
cell->parameters[ID::A_WIDTH] = RTLIL::Const(sig.size());
cell->setPort(ID::A, sig);
cell->parameters["\\Y_WIDTH"] = width;
cell->setPort("\\Y", wire);
cell->parameters[ID::Y_WIDTH] = width;
cell->setPort(ID::Y, wire);
sig = wire;
}
// helper function for creating RTLIL code for binary operations
static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_width, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
static RTLIL::SigSpec binop2rtlil(AstNode *that, IdString type, int result_width, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
{
std::stringstream sstr;
sstr << type << "$" << that->filename << ":" << that->location.first_line << "$" << (autoidx++);
RTLIL::Cell *cell = current_module->addCell(sstr.str(), type);
cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
IdString name = stringf("%s$%s:%d$%d", type.c_str(), that->filename.c_str(), that->location.first_line, autoidx++);
RTLIL::Cell *cell = current_module->addCell(name, type);
cell->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width);
wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
wire->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
for (auto &attr : that->attributes) {
if (attr.second->type != AST_CONSTANT)
@ -119,17 +113,17 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi
cell->attributes[attr.first] = attr.second->asAttrConst();
}
cell->parameters["\\A_SIGNED"] = RTLIL::Const(that->children[0]->is_signed);
cell->parameters["\\B_SIGNED"] = RTLIL::Const(that->children[1]->is_signed);
cell->parameters[ID::A_SIGNED] = RTLIL::Const(that->children[0]->is_signed);
cell->parameters[ID::B_SIGNED] = RTLIL::Const(that->children[1]->is_signed);
cell->parameters["\\A_WIDTH"] = RTLIL::Const(left.size());
cell->parameters["\\B_WIDTH"] = RTLIL::Const(right.size());
cell->parameters[ID::A_WIDTH] = RTLIL::Const(left.size());
cell->parameters[ID::B_WIDTH] = RTLIL::Const(right.size());
cell->setPort("\\A", left);
cell->setPort("\\B", right);
cell->setPort(ID::A, left);
cell->setPort(ID::B, right);
cell->parameters["\\Y_WIDTH"] = result_width;
cell->setPort("\\Y", wire);
cell->parameters[ID::Y_WIDTH] = result_width;
cell->setPort(ID::Y, wire);
return wire;
}
@ -141,11 +135,11 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const
std::stringstream sstr;
sstr << "$ternary$" << that->filename << ":" << that->location.first_line << "$" << (autoidx++);
RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$mux");
cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($mux));
cell->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", left.size());
wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
wire->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
for (auto &attr : that->attributes) {
if (attr.second->type != AST_CONSTANT)
@ -153,12 +147,12 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const
cell->attributes[attr.first] = attr.second->asAttrConst();
}
cell->parameters["\\WIDTH"] = RTLIL::Const(left.size());
cell->parameters[ID::WIDTH] = RTLIL::Const(left.size());
cell->setPort("\\A", right);
cell->setPort("\\B", left);
cell->setPort("\\S", cond);
cell->setPort("\\Y", wire);
cell->setPort(ID::A, right);
cell->setPort(ID::B, left);
cell->setPort(ID::S, cond);
cell->setPort(ID::Y, wire);
return wire;
}
@ -199,7 +193,7 @@ struct AST_INTERNAL::ProcessGenerator
{
// generate process and simple root case
proc = new RTLIL::Process;
proc->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", always->filename.c_str(), always->location.first_line, always->location.first_column, always->location.last_line, always->location.last_column);
proc->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", always->filename.c_str(), always->location.first_line, always->location.first_column, always->location.last_line, always->location.last_column);
proc->name = stringf("$proc$%s:%d$%d", always->filename.c_str(), always->location.first_line, autoidx++);
for (auto &attr : always->attributes) {
if (attr.second->type != AST_CONSTANT)
@ -221,7 +215,7 @@ struct AST_INTERNAL::ProcessGenerator
for (auto child : always->children)
{
if ((child->type == AST_POSEDGE || child->type == AST_NEGEDGE) && GetSize(child->children) == 1 && child->children.at(0)->type == AST_IDENTIFIER &&
child->children.at(0)->id2ast && child->children.at(0)->id2ast->type == AST_WIRE && child->children.at(0)->id2ast->get_bool_attribute("\\gclk")) {
child->children.at(0)->id2ast && child->children.at(0)->id2ast->type == AST_WIRE && child->children.at(0)->id2ast->get_bool_attribute(ID::gclk)) {
found_global_syncs = true;
}
if (child->type == AST_EDGE) {
@ -245,7 +239,7 @@ struct AST_INTERNAL::ProcessGenerator
for (auto child : always->children)
if (child->type == AST_POSEDGE || child->type == AST_NEGEDGE) {
if (GetSize(child->children) == 1 && child->children.at(0)->type == AST_IDENTIFIER && child->children.at(0)->id2ast &&
child->children.at(0)->id2ast->type == AST_WIRE && child->children.at(0)->id2ast->get_bool_attribute("\\gclk"))
child->children.at(0)->id2ast->type == AST_WIRE && child->children.at(0)->id2ast->get_bool_attribute(ID::gclk))
continue;
found_clocked_sync = true;
if (found_global_syncs || found_anyedge_syncs)
@ -267,7 +261,7 @@ struct AST_INTERNAL::ProcessGenerator
}
// create initial assignments for the temporary signals
if ((flag_nolatches || always->get_bool_attribute("\\nolatches") || current_module->get_bool_attribute("\\nolatches")) && !found_clocked_sync) {
if ((flag_nolatches || always->get_bool_attribute(ID::nolatches) || current_module->get_bool_attribute(ID::nolatches)) && !found_clocked_sync) {
subst_rvalue_map = subst_lvalue_from.to_sigbit_dict(RTLIL::SigSpec(RTLIL::State::Sx, GetSize(subst_lvalue_from)));
} else {
addChunkActions(current_case->actions, subst_lvalue_to, subst_lvalue_from);
@ -335,7 +329,7 @@ struct AST_INTERNAL::ProcessGenerator
} while (current_module->wires_.count(wire_name) > 0);
RTLIL::Wire *wire = current_module->addWire(wire_name, chunk.width);
wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", always->filename.c_str(), always->location.first_line, always->location.first_column, always->location.last_line, always->location.last_column);
wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", always->filename.c_str(), always->location.first_line, always->location.first_column, always->location.last_line, always->location.last_column);
chunk.wire = wire;
chunk.offset = 0;
@ -420,7 +414,7 @@ struct AST_INTERNAL::ProcessGenerator
for (auto &lvalue_c : lvalue.chunks()) {
RTLIL::SigSpec lhs = lvalue_c;
RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue_c.width);
if (inSyncRule && lvalue_c.wire && lvalue_c.wire->get_bool_attribute("\\nosync"))
if (inSyncRule && lvalue_c.wire && lvalue_c.wire->get_bool_attribute(ID::nosync))
rhs = RTLIL::SigSpec(RTLIL::State::Sx, rhs.size());
remove_unwanted_lvalue_bits(lhs, rhs);
actions.push_back(RTLIL::SigSig(lhs, rhs));
@ -470,7 +464,7 @@ struct AST_INTERNAL::ProcessGenerator
case AST_CASE:
{
RTLIL::SwitchRule *sw = new RTLIL::SwitchRule;
sw->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line, ast->location.first_column, ast->location.last_line, ast->location.last_column);
sw->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line, ast->location.first_column, ast->location.last_line, ast->location.last_column);
sw->signal = ast->children[0]->genWidthRTLIL(-1, &subst_rvalue_map.stdmap());
current_case->switches.push_back(sw);
@ -504,7 +498,7 @@ struct AST_INTERNAL::ProcessGenerator
RTLIL::CaseRule *backup_case = current_case;
current_case = new RTLIL::CaseRule;
current_case->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", child->filename.c_str(), child->location.first_line, child->location.first_column, child->location.last_line, child->location.last_column);
current_case->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", child->filename.c_str(), child->location.first_line, child->location.first_column, child->location.last_line, child->location.last_column);
last_generated_case = current_case;
addChunkActions(current_case->actions, this_case_eq_ltemp, this_case_eq_rvalue);
for (auto node : child->children) {
@ -525,7 +519,7 @@ struct AST_INTERNAL::ProcessGenerator
subst_rvalue_map.restore();
}
if (last_generated_case != NULL && ast->get_bool_attribute("\\full_case") && default_case == NULL) {
if (last_generated_case != NULL && ast->get_bool_attribute(ID::full_case) && default_case == NULL) {
#if 0
// this is a valid transformation, but as optimization it is premature.
// better: add a default case that assigns 'x' to everything, and let later
@ -842,7 +836,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
// Clifford's Device (http://www.clifford.at/cfun/cliffdev/). In this
// cases this variable is used to hold the type of the cell that should
// be instantiated for this type of AST node.
std::string type_name;
IdString type_name;
current_filename = filename;
@ -873,19 +867,19 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
// This is used by the hierarchy pass to know when it can replace interface connection with the individual
// signals.
RTLIL::Wire *wire = current_module->addWire(str, 1);
wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
wire->start_offset = 0;
wire->port_id = port_id;
wire->port_input = true;
wire->port_output = true;
wire->set_bool_attribute("\\is_interface");
wire->set_bool_attribute(ID::is_interface);
if (children.size() > 0) {
for(size_t i=0; i<children.size();i++) {
if(children[i]->type == AST_INTERFACEPORTTYPE) {
std::pair<std::string,std::string> res = AST::split_modport_from_type(children[i]->str);
wire->attributes["\\interface_type"] = res.first;
wire->attributes[ID::interface_type] = res.first;
if (res.second != "")
wire->attributes["\\interface_modport"] = res.second;
wire->attributes[ID::interface_modport] = res.second;
break;
}
}
@ -910,8 +904,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
RTLIL::Wire *wire = current_module->addWire(str, GetSize(val));
current_module->connect(wire, val);
wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
wire->attributes[type == AST_PARAMETER ? "\\parameter" : "\\localparam"] = 1;
wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
wire->attributes[type == AST_PARAMETER ? ID::parameter : ID::localparam] = 1;
for (auto &attr : attributes) {
if (attr.second->type != AST_CONSTANT)
@ -932,7 +926,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
log_file_error(filename, location.first_line, "Signal `%s' with invalid width range %d!\n", str.c_str(), range_left - range_right + 1);
RTLIL::Wire *wire = current_module->addWire(str, range_left - range_right + 1);
wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
wire->start_offset = range_right;
wire->port_id = port_id;
wire->port_input = is_input;
@ -945,8 +939,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
wire->attributes[attr.first] = attr.second->asAttrConst();
}
if (is_wand) wire->set_bool_attribute("\\wand");
if (is_wor) wire->set_bool_attribute("\\wor");
if (is_wand) wire->set_bool_attribute(ID::wand);
if (is_wor) wire->set_bool_attribute(ID::wor);
}
break;
@ -963,7 +957,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
log_file_error(filename, location.first_line, "Memory `%s' with non-constant width or size!\n", str.c_str());
RTLIL::Memory *memory = new RTLIL::Memory;
memory->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
memory->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
memory->name = str;
memory->width = children[0]->range_left - children[0]->range_right + 1;
if (children[1]->range_right < children[1]->range_left) {
@ -1018,7 +1012,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
if (id2ast && id2ast->type == AST_AUTOWIRE && current_module->wires_.count(str) == 0) {
RTLIL::Wire *wire = current_module->addWire(str);
wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
wire->name = str;
if (flag_autowire)
log_file_warning(filename, location.first_line, "Identifier `%s' is implicitly declared.\n", str.c_str());
@ -1033,7 +1027,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
else if (id2ast && (id2ast->type == AST_WIRE || id2ast->type == AST_AUTOWIRE || id2ast->type == AST_MEMORY) && current_module->wires_.count(str) != 0) {
RTLIL::Wire *current_wire = current_module->wire(str);
if (current_wire->get_bool_attribute("\\is_interface"))
if (current_wire->get_bool_attribute(ID::is_interface))
is_interface = true;
// Ignore
}
@ -1052,16 +1046,13 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
// This makes it possible for the hierarchy pass to see what are interface connections and then replace them
// with the individual signals:
if (is_interface) {
RTLIL::Wire *dummy_wire;
std::string dummy_wire_name = "$dummywireforinterface" + str;
if (current_module->wires_.count(dummy_wire_name))
dummy_wire = current_module->wires_[dummy_wire_name];
else {
IdString dummy_wire_name = stringf("$dummywireforinterface%s", str.c_str());
RTLIL::Wire *dummy_wire = current_module->wire(dummy_wire_name);
if (!dummy_wire) {
dummy_wire = current_module->addWire(dummy_wire_name);
dummy_wire->set_bool_attribute("\\is_interface");
dummy_wire->set_bool_attribute(ID::is_interface);
}
RTLIL::SigSpec tmp = RTLIL::SigSpec(dummy_wire);
return tmp;
return dummy_wire;
}
wire = current_module->wires_[str];
@ -1097,7 +1088,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
if (GetSize(shift_val) >= 32)
fake_ast->children[1]->is_signed = true;
RTLIL::SigSpec sig = binop2rtlil(fake_ast, "$shiftx", width, fake_ast->children[0]->genRTLIL(), shift_val);
RTLIL::SigSpec sig = binop2rtlil(fake_ast, ID($shiftx), width, fake_ast->children[0]->genRTLIL(), shift_val);
delete left_at_zero_ast;
delete right_at_zero_ast;
delete fake_ast;
@ -1181,9 +1172,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
// generate cells for unary operations: $not, $pos, $neg
if (0) { case AST_BIT_NOT: type_name = "$not"; }
if (0) { case AST_POS: type_name = "$pos"; }
if (0) { case AST_NEG: type_name = "$neg"; }
if (0) { case AST_BIT_NOT: type_name = ID($not); }
if (0) { case AST_POS: type_name = ID($pos); }
if (0) { case AST_NEG: type_name = ID($neg); }
{
RTLIL::SigSpec arg = children[0]->genRTLIL(width_hint, sign_hint);
is_signed = children[0]->is_signed;
@ -1196,10 +1187,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
// generate cells for binary operations: $and, $or, $xor, $xnor
if (0) { case AST_BIT_AND: type_name = "$and"; }
if (0) { case AST_BIT_OR: type_name = "$or"; }
if (0) { case AST_BIT_XOR: type_name = "$xor"; }
if (0) { case AST_BIT_XNOR: type_name = "$xnor"; }
if (0) { case AST_BIT_AND: type_name = ID($and); }
if (0) { case AST_BIT_OR: type_name = ID($or); }
if (0) { case AST_BIT_XOR: type_name = ID($xor); }
if (0) { case AST_BIT_XNOR: type_name = ID($xnor); }
{
if (width_hint < 0)
detectSignWidth(width_hint, sign_hint);
@ -1213,10 +1204,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
// generate cells for unary operations: $reduce_and, $reduce_or, $reduce_xor, $reduce_xnor
if (0) { case AST_REDUCE_AND: type_name = "$reduce_and"; }
if (0) { case AST_REDUCE_OR: type_name = "$reduce_or"; }
if (0) { case AST_REDUCE_XOR: type_name = "$reduce_xor"; }
if (0) { case AST_REDUCE_XNOR: type_name = "$reduce_xnor"; }
if (0) { case AST_REDUCE_AND: type_name = ID($reduce_and); }
if (0) { case AST_REDUCE_OR: type_name = ID($reduce_or); }
if (0) { case AST_REDUCE_XOR: type_name = ID($reduce_xor); }
if (0) { case AST_REDUCE_XNOR: type_name = ID($reduce_xnor); }
{
RTLIL::SigSpec arg = children[0]->genRTLIL();
RTLIL::SigSpec sig = uniop2rtlil(this, type_name, max(width_hint, 1), arg);
@ -1225,7 +1216,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
// generate cells for unary operations: $reduce_bool
// (this is actually just an $reduce_or, but for clarity a different cell type is used)
if (0) { case AST_REDUCE_BOOL: type_name = "$reduce_bool"; }
if (0) { case AST_REDUCE_BOOL: type_name = ID($reduce_bool); }
{
RTLIL::SigSpec arg = children[0]->genRTLIL();
RTLIL::SigSpec sig = arg.size() > 1 ? uniop2rtlil(this, type_name, max(width_hint, 1), arg) : arg;
@ -1233,10 +1224,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
// generate cells for binary operations: $shl, $shr, $sshl, $sshr
if (0) { case AST_SHIFT_LEFT: type_name = "$shl"; }
if (0) { case AST_SHIFT_RIGHT: type_name = "$shr"; }
if (0) { case AST_SHIFT_SLEFT: type_name = "$sshl"; }
if (0) { case AST_SHIFT_SRIGHT: type_name = "$sshr"; }
if (0) { case AST_SHIFT_LEFT: type_name = ID($shl); }
if (0) { case AST_SHIFT_RIGHT: type_name = ID($shr); }
if (0) { case AST_SHIFT_SLEFT: type_name = ID($sshl); }
if (0) { case AST_SHIFT_SRIGHT: type_name = ID($sshr); }
{
if (width_hint < 0)
detectSignWidth(width_hint, sign_hint);
@ -1260,19 +1251,19 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
int width = width_hint > 0 ? width_hint : left.size();
is_signed = children[0]->is_signed;
if (!flag_noopt && left.is_fully_const() && left.as_int() == 2 && !right_signed)
return binop2rtlil(this, "$shl", width, RTLIL::SigSpec(1, left.size()), right);
return binop2rtlil(this, "$pow", width, left, right);
return binop2rtlil(this, ID($shl), width, RTLIL::SigSpec(1, left.size()), right);
return binop2rtlil(this, ID($pow), width, left, right);
}
// generate cells for binary operations: $lt, $le, $eq, $ne, $ge, $gt
if (0) { case AST_LT: type_name = "$lt"; }
if (0) { case AST_LE: type_name = "$le"; }
if (0) { case AST_EQ: type_name = "$eq"; }
if (0) { case AST_NE: type_name = "$ne"; }
if (0) { case AST_EQX: type_name = "$eqx"; }
if (0) { case AST_NEX: type_name = "$nex"; }
if (0) { case AST_GE: type_name = "$ge"; }
if (0) { case AST_GT: type_name = "$gt"; }
if (0) { case AST_LT: type_name = ID($lt); }
if (0) { case AST_LE: type_name = ID($le); }
if (0) { case AST_EQ: type_name = ID($eq); }
if (0) { case AST_NE: type_name = ID($ne); }
if (0) { case AST_EQX: type_name = ID($eqx); }
if (0) { case AST_NEX: type_name = ID($nex); }
if (0) { case AST_GE: type_name = ID($ge); }
if (0) { case AST_GT: type_name = ID($gt); }
{
int width = max(width_hint, 1);
width_hint = -1, sign_hint = true;
@ -1285,11 +1276,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
// generate cells for binary operations: $add, $sub, $mul, $div, $mod
if (0) { case AST_ADD: type_name = "$add"; }
if (0) { case AST_SUB: type_name = "$sub"; }
if (0) { case AST_MUL: type_name = "$mul"; }
if (0) { case AST_DIV: type_name = "$div"; }
if (0) { case AST_MOD: type_name = "$mod"; }
if (0) { case AST_ADD: type_name = ID($add); }
if (0) { case AST_SUB: type_name = ID($sub); }
if (0) { case AST_MUL: type_name = ID($mul); }
if (0) { case AST_DIV: type_name = ID($div); }
if (0) { case AST_MOD: type_name = ID($mod); }
{
if (width_hint < 0)
detectSignWidth(width_hint, sign_hint);
@ -1315,8 +1306,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
// generate cells for binary operations: $logic_and, $logic_or
if (0) { case AST_LOGIC_AND: type_name = "$logic_and"; }
if (0) { case AST_LOGIC_OR: type_name = "$logic_or"; }
if (0) { case AST_LOGIC_AND: type_name = ID($logic_and); }
if (0) { case AST_LOGIC_OR: type_name = ID($logic_or); }
{
RTLIL::SigSpec left = children[0]->genRTLIL();
RTLIL::SigSpec right = children[1]->genRTLIL();
@ -1327,7 +1318,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
case AST_LOGIC_NOT:
{
RTLIL::SigSpec arg = children[0]->genRTLIL();
return uniop2rtlil(this, "$logic_not", max(width_hint, 1), arg);
return uniop2rtlil(this, ID($logic_not), max(width_hint, 1), arg);
}
// generate multiplexer for ternary operator (aka ?:-operator)
@ -1353,7 +1344,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
RTLIL::SigSpec val2 = children[2]->genRTLIL(width_hint, sign_hint);
if (cond.size() > 1)
cond = uniop2rtlil(this, "$reduce_bool", 1, cond, false);
cond = uniop2rtlil(this, ID($reduce_bool), 1, cond, false);
int width = max(val1.size(), val2.size());
is_signed = children[1]->is_signed && children[2]->is_signed;
@ -1374,11 +1365,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
std::stringstream sstr;
sstr << "$memrd$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++);
RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$memrd");
cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), location.first_line);
RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($memrd));
cell->attributes[ID::src] = stringf("%s:%d", filename.c_str(), location.first_line);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_DATA", current_module->memories[str]->width);
wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), location.first_line);
wire->attributes[ID::src] = stringf("%s:%d", filename.c_str(), location.first_line);
int mem_width, mem_size, addr_bits;
is_signed = id2ast->is_signed;
@ -1386,18 +1377,18 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
RTLIL::SigSpec addr_sig = children[0]->genRTLIL();
cell->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1));
cell->setPort("\\EN", RTLIL::SigSpec(RTLIL::State::Sx, 1));
cell->setPort("\\ADDR", addr_sig);
cell->setPort("\\DATA", RTLIL::SigSpec(wire));
cell->setPort(ID::CLK, RTLIL::SigSpec(RTLIL::State::Sx, 1));
cell->setPort(ID::EN, RTLIL::SigSpec(RTLIL::State::Sx, 1));
cell->setPort(ID::ADDR, addr_sig);
cell->setPort(ID::DATA, RTLIL::SigSpec(wire));
cell->parameters["\\MEMID"] = RTLIL::Const(str);
cell->parameters["\\ABITS"] = RTLIL::Const(GetSize(addr_sig));
cell->parameters["\\WIDTH"] = RTLIL::Const(wire->width);
cell->parameters[ID::MEMID] = RTLIL::Const(str);
cell->parameters[ID::ABITS] = RTLIL::Const(GetSize(addr_sig));
cell->parameters[ID::WIDTH] = RTLIL::Const(wire->width);
cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(0);
cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(0);
cell->parameters["\\TRANSPARENT"] = RTLIL::Const(0);
cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(0);
cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(0);
cell->parameters[ID::TRANSPARENT] = RTLIL::Const(0);
if (!sign_hint)
is_signed = false;
@ -1412,8 +1403,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
std::stringstream sstr;
sstr << (type == AST_MEMWR ? "$memwr$" : "$meminit$") << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++);
RTLIL::Cell *cell = current_module->addCell(sstr.str(), type == AST_MEMWR ? "$memwr" : "$meminit");
cell->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
RTLIL::Cell *cell = current_module->addCell(sstr.str(), type == AST_MEMWR ? ID($memwr) : ID($meminit));
cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
int mem_width, mem_size, addr_bits;
id2ast->meminfo(mem_width, mem_size, addr_bits);
@ -1423,26 +1414,26 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
if (children[2]->type != AST_CONSTANT)
log_file_error(filename, location.first_line, "Memory init with non-constant word count!\n");
num_words = int(children[2]->asInt(false));
cell->parameters["\\WORDS"] = RTLIL::Const(num_words);
cell->parameters[ID::WORDS] = RTLIL::Const(num_words);
}
SigSpec addr_sig = children[0]->genRTLIL();
cell->setPort("\\ADDR", addr_sig);
cell->setPort("\\DATA", children[1]->genWidthRTLIL(current_module->memories[str]->width * num_words));
cell->setPort(ID::ADDR, addr_sig);
cell->setPort(ID::DATA, children[1]->genWidthRTLIL(current_module->memories[str]->width * num_words));
cell->parameters["\\MEMID"] = RTLIL::Const(str);
cell->parameters["\\ABITS"] = RTLIL::Const(GetSize(addr_sig));
cell->parameters["\\WIDTH"] = RTLIL::Const(current_module->memories[str]->width);
cell->parameters[ID::MEMID] = RTLIL::Const(str);
cell->parameters[ID::ABITS] = RTLIL::Const(GetSize(addr_sig));
cell->parameters[ID::WIDTH] = RTLIL::Const(current_module->memories[str]->width);
if (type == AST_MEMWR) {
cell->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1));
cell->setPort("\\EN", children[2]->genRTLIL());
cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(0);
cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(0);
cell->setPort(ID::CLK, RTLIL::SigSpec(RTLIL::State::Sx, 1));
cell->setPort(ID::EN, children[2]->genRTLIL());
cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(0);
cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(0);
}
cell->parameters["\\PRIORITY"] = RTLIL::Const(autoidx-1);
cell->parameters[ID::PRIORITY] = RTLIL::Const(autoidx-1);
}
break;
@ -1453,12 +1444,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
case AST_FAIR:
case AST_COVER:
{
const char *celltype = nullptr;
if (type == AST_ASSERT) celltype = "$assert";
if (type == AST_ASSUME) celltype = "$assume";
if (type == AST_LIVE) celltype = "$live";
if (type == AST_FAIR) celltype = "$fair";
if (type == AST_COVER) celltype = "$cover";
IdString celltype;
if (type == AST_ASSERT) celltype = ID($assert);
if (type == AST_ASSUME) celltype = ID($assume);
if (type == AST_LIVE) celltype = ID($live);
if (type == AST_FAIR) celltype = ID($fair);
if (type == AST_COVER) celltype = ID($cover);
log_assert(children.size() == 2);
@ -1471,16 +1462,13 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
en = current_module->ReduceBool(NEW_ID, en);
IdString cellname;
if (str.empty()) {
std::stringstream sstr;
sstr << celltype << "$" << filename << ":" << location.first_line << "$" << (autoidx++);
cellname = sstr.str();
} else {
if (str.empty())
cellname = stringf("%s$%s:%d$%d", celltype.c_str(), filename.c_str(), location.first_line, autoidx++);
else
cellname = str;
}
RTLIL::Cell *cell = current_module->addCell(cellname, celltype);
cell->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
for (auto &attr : attributes) {
if (attr.second->type != AST_CONSTANT)
@ -1488,8 +1476,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
cell->attributes[attr.first] = attr.second->asAttrConst();
}
cell->setPort("\\A", check);
cell->setPort("\\EN", en);
cell->setPort(ID::A, check);
cell->setPort(ID::EN, en);
}
break;
@ -1525,9 +1513,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
log_file_error(filename, location.first_line, "Re-definition of cell `%s'!\n", str.c_str());
RTLIL::Cell *cell = current_module->addCell(str, "");
cell->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
// Set attribute 'module_not_derived' which will be cleared again after the hierarchy pass
cell->set_bool_attribute("\\module_not_derived");
cell->set_bool_attribute(ID::module_not_derived);
for (auto it = children.begin(); it != children.end(); it++) {
AstNode *child = *it;
@ -1575,29 +1563,29 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value.\n", attr.first.c_str());
cell->attributes[attr.first] = attr.second->asAttrConst();
}
if (cell->type == "$specify2") {
int src_width = GetSize(cell->getPort("\\SRC"));
int dst_width = GetSize(cell->getPort("\\DST"));
bool full = cell->getParam("\\FULL").as_bool();
if (cell->type == ID($specify2)) {
int src_width = GetSize(cell->getPort(ID::SRC));
int dst_width = GetSize(cell->getPort(ID::DST));
bool full = cell->getParam(ID::FULL).as_bool();
if (!full && src_width != dst_width)
log_file_error(filename, location.first_line, "Parallel specify SRC width does not match DST width.\n");
cell->setParam("\\SRC_WIDTH", Const(src_width));
cell->setParam("\\DST_WIDTH", Const(dst_width));
cell->setParam(ID::SRC_WIDTH, Const(src_width));
cell->setParam(ID::DST_WIDTH, Const(dst_width));
}
else if (cell->type == "$specify3") {
int dat_width = GetSize(cell->getPort("\\DAT"));
int dst_width = GetSize(cell->getPort("\\DST"));
else if (cell->type == ID($specify3)) {
int dat_width = GetSize(cell->getPort(ID::DAT));
int dst_width = GetSize(cell->getPort(ID::DST));
if (dat_width != dst_width)
log_file_error(filename, location.first_line, "Specify DAT width does not match DST width.\n");
int src_width = GetSize(cell->getPort("\\SRC"));
cell->setParam("\\SRC_WIDTH", Const(src_width));
cell->setParam("\\DST_WIDTH", Const(dst_width));
int src_width = GetSize(cell->getPort(ID::SRC));
cell->setParam(ID::SRC_WIDTH, Const(src_width));
cell->setParam(ID::DST_WIDTH, Const(dst_width));
}
else if (cell->type == "$specrule") {
int src_width = GetSize(cell->getPort("\\SRC"));
int dst_width = GetSize(cell->getPort("\\DST"));
cell->setParam("\\SRC_WIDTH", Const(src_width));
cell->setParam("\\DST_WIDTH", Const(dst_width));
else if (cell->type == ID($specrule)) {
int src_width = GetSize(cell->getPort(ID::SRC));
int dst_width = GetSize(cell->getPort(ID::DST));
cell->setParam(ID::SRC_WIDTH, Const(src_width));
cell->setParam(ID::DST_WIDTH, Const(dst_width));
}
}
break;
@ -1668,19 +1656,19 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
log_file_error(filename, location.first_line, "Failed to detect width of %s!\n", RTLIL::unescape_id(str).c_str());
Cell *cell = current_module->addCell(myid, str.substr(1));
cell->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
cell->parameters["\\WIDTH"] = width;
cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
cell->parameters[ID::WIDTH] = width;
if (attributes.count("\\reg")) {
auto &attr = attributes.at("\\reg");
if (attributes.count(ID::reg)) {
auto &attr = attributes.at(ID::reg);
if (attr->type != AST_CONSTANT)
log_file_error(filename, location.first_line, "Attribute `reg' with non-constant value!\n");
cell->attributes["\\reg"] = attr->asAttrConst();
cell->attributes[ID::reg] = attr->asAttrConst();
}
Wire *wire = current_module->addWire(myid + "_wire", width);
wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
cell->setPort("\\Y", wire);
wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
cell->setPort(ID::Y, wire);
is_signed = sign_hint;
return SigSpec(wire);

View file

@ -172,7 +172,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
deep_recursion_warning = true;
while (simplify(const_fold, at_zero, in_lvalue, 1, width_hint, sign_hint, in_param)) { }
if (!flag_nomem2reg && !get_bool_attribute("\\nomem2reg"))
if (!flag_nomem2reg && !get_bool_attribute(ID::nomem2reg))
{
dict<AstNode*, pool<std::string>> mem2reg_places;
dict<AstNode*, uint32_t> mem2reg_candidates, dummy_proc_flags;
@ -187,10 +187,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
bool this_nomeminit = flag_nomeminit;
log_assert((memflags & ~0x00ffff00) == 0);
if (mem->get_bool_attribute("\\nomem2reg"))
if (mem->get_bool_attribute(ID::nomem2reg))
continue;
if (mem->get_bool_attribute("\\nomeminit") || get_bool_attribute("\\nomeminit"))
if (mem->get_bool_attribute(ID::nomeminit) || get_bool_attribute(ID::nomeminit))
this_nomeminit = true;
if (memflags & AstNode::MEM2REG_FL_FORCED)
@ -248,7 +248,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
reg->is_reg = true;
reg->is_signed = node->is_signed;
for (auto &it : node->attributes)
if (it.first != ID(mem2reg))
if (it.first != ID::mem2reg)
reg->attributes.emplace(it.first, it.second->clone());
reg->filename = node->filename;
reg->location = node->location;
@ -345,9 +345,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (node->children.size() == 1 && node->children[0]->type == AST_RANGE) {
for (auto c : node->children[0]->children) {
if (!c->is_simple_const_expr()) {
if (attributes.count("\\dynports"))
delete attributes.at("\\dynports");
attributes["\\dynports"] = AstNode::mkconst_int(1, true);
if (attributes.count(ID::dynports))
delete attributes.at(ID::dynports);
attributes[ID::dynports] = AstNode::mkconst_int(1, true);
}
}
}
@ -432,7 +432,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM))
did_something = true;
if (node->type == AST_ENUM) {
for (auto enode : node->children){
for (auto enode YS_ATTRIBUTE(unused) : node->children){
log_assert(enode->type==AST_ENUM_ITEM);
while (node->simplify(true, false, false, 1, -1, false, in_param))
did_something = true;
@ -1219,7 +1219,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(data_range_left, true), mkconst_int(data_range_right, true)));
wire->str = wire_id;
if (current_block)
wire->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
wire->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
current_ast_mod->children.push_back(wire);
while (wire->simplify(true, false, false, 1, -1, false, false)) { }
@ -1727,13 +1727,14 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
}
did_something = true;
newNode = new AstNode(AST_CASE, shift_expr);
for (int i = 0; i <= source_width-result_width; i++) {
for (int i = 0; i < source_width; i++) {
int start_bit = children[0]->id2ast->range_right + i;
AstNode *cond = new AstNode(AST_COND, mkconst_int(start_bit, true));
AstNode *lvalue = children[0]->clone();
lvalue->delete_children();
int end_bit = std::min(start_bit+result_width,source_width) - 1;
lvalue->children.push_back(new AstNode(AST_RANGE,
mkconst_int(start_bit+result_width-1, true), mkconst_int(start_bit, true)));
mkconst_int(end_bit, true), mkconst_int(start_bit, true)));
cond->children.push_back(new AstNode(AST_BLOCK, new AstNode(type, lvalue, children[1]->clone())));
newNode->children.push_back(cond);
}
@ -1811,6 +1812,7 @@ skip_dynamic_range_lvalue_expansion:;
newNode->children.push_back(assign_en);
AstNode *assertnode = new AstNode(type);
assertnode->location = location;
assertnode->str = str;
assertnode->children.push_back(new AstNode(AST_IDENTIFIER));
assertnode->children.push_back(new AstNode(AST_IDENTIFIER));
@ -1855,7 +1857,7 @@ skip_dynamic_range_lvalue_expansion:;
wire_tmp->str = stringf("$splitcmplxassign$%s:%d$%d", filename.c_str(), location.first_line, autoidx++);
current_ast_mod->children.push_back(wire_tmp);
current_scope[wire_tmp->str] = wire_tmp;
wire_tmp->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
wire_tmp->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
while (wire_tmp->simplify(true, false, false, 1, -1, false, false)) { }
wire_tmp->is_logic = true;
@ -1897,6 +1899,9 @@ skip_dynamic_range_lvalue_expansion:;
bool mem_signed = children[0]->id2ast->is_signed;
children[0]->id2ast->meminfo(mem_width, mem_size, addr_bits);
newNode = new AstNode(AST_BLOCK);
AstNode *defNode = new AstNode(AST_BLOCK);
int data_range_left = children[0]->id2ast->children[0]->range_left;
int data_range_right = children[0]->id2ast->children[0]->range_right;
int mem_data_range_offset = std::min(data_range_left, data_range_right);
@ -1906,31 +1911,6 @@ skip_dynamic_range_lvalue_expansion:;
children[0]->children[0]->children[0]->detectSignWidthWorker(addr_width_hint, addr_sign_hint);
addr_bits = std::max(addr_bits, addr_width_hint);
AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));
wire_addr->str = id_addr;
wire_addr->was_checked = true;
current_ast_mod->children.push_back(wire_addr);
current_scope[wire_addr->str] = wire_addr;
while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { }
AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
wire_data->str = id_data;
wire_data->was_checked = true;
wire_data->is_signed = mem_signed;
current_ast_mod->children.push_back(wire_data);
current_scope[wire_data->str] = wire_data;
while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
AstNode *wire_en = nullptr;
if (current_always->type != AST_INITIAL) {
wire_en = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
wire_en->str = id_en;
wire_en->was_checked = true;
current_ast_mod->children.push_back(wire_en);
current_scope[wire_en->str] = wire_en;
while (wire_en->simplify(true, false, false, 1, -1, false, false)) { }
}
std::vector<RTLIL::State> x_bits_addr, x_bits_data, set_bits_en;
for (int i = 0; i < addr_bits; i++)
x_bits_addr.push_back(RTLIL::State::Sx);
@ -1939,32 +1919,79 @@ skip_dynamic_range_lvalue_expansion:;
for (int i = 0; i < mem_width; i++)
set_bits_en.push_back(RTLIL::State::S1);
AstNode *assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_addr, false));
assign_addr->children[0]->str = id_addr;
assign_addr->children[0]->was_checked = true;
AstNode *node_addr = nullptr;
if (children[0]->children[0]->children[0]->isConst()) {
node_addr = children[0]->children[0]->children[0]->clone();
} else {
AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));
wire_addr->str = id_addr;
wire_addr->was_checked = true;
current_ast_mod->children.push_back(wire_addr);
current_scope[wire_addr->str] = wire_addr;
while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { }
AstNode *assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_data, false));
assign_data->children[0]->str = id_data;
assign_data->children[0]->was_checked = true;
AstNode *assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_addr, false));
assign_addr->children[0]->str = id_addr;
assign_addr->children[0]->was_checked = true;
defNode->children.push_back(assign_addr);
AstNode *assign_en = nullptr;
if (current_always->type != AST_INITIAL) {
assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, mem_width));
assign_en->children[0]->str = id_en;
assign_en->children[0]->was_checked = true;
assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone());
assign_addr->children[0]->str = id_addr;
assign_addr->children[0]->was_checked = true;
newNode->children.push_back(assign_addr);
node_addr = new AstNode(AST_IDENTIFIER);
node_addr->str = id_addr;
}
AstNode *default_signals = new AstNode(AST_BLOCK);
default_signals->children.push_back(assign_addr);
default_signals->children.push_back(assign_data);
if (current_always->type != AST_INITIAL)
default_signals->children.push_back(assign_en);
current_top_block->children.insert(current_top_block->children.begin(), default_signals);
AstNode *node_data = nullptr;
if (children[0]->children.size() == 1 && children[1]->isConst()) {
node_data = children[1]->clone();
} else {
AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
wire_data->str = id_data;
wire_data->was_checked = true;
wire_data->is_signed = mem_signed;
current_ast_mod->children.push_back(wire_data);
current_scope[wire_data->str] = wire_data;
while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone());
assign_addr->children[0]->str = id_addr;
assign_addr->children[0]->was_checked = true;
AstNode *assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_data, false));
assign_data->children[0]->str = id_data;
assign_data->children[0]->was_checked = true;
defNode->children.push_back(assign_data);
node_data = new AstNode(AST_IDENTIFIER);
node_data->str = id_data;
}
AstNode *node_en = nullptr;
if (current_always->type == AST_INITIAL) {
node_en = AstNode::mkconst_int(1, false);
} else {
AstNode *wire_en = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
wire_en->str = id_en;
wire_en->was_checked = true;
current_ast_mod->children.push_back(wire_en);
current_scope[wire_en->str] = wire_en;
while (wire_en->simplify(true, false, false, 1, -1, false, false)) { }
AstNode *assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, mem_width));
assign_en->children[0]->str = id_en;
assign_en->children[0]->was_checked = true;
defNode->children.push_back(assign_en);
node_en = new AstNode(AST_IDENTIFIER);
node_en->str = id_en;
}
if (!defNode->children.empty())
current_top_block->children.insert(current_top_block->children.begin(), defNode);
else
delete defNode;
AstNode *assign_data = nullptr;
AstNode *assign_en = nullptr;
if (children[0]->children.size() == 2)
{
if (children[0]->children[1]->range_valid)
@ -2025,9 +2052,11 @@ skip_dynamic_range_lvalue_expansion:;
}
else
{
assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[1]->clone());
assign_data->children[0]->str = id_data;
assign_data->children[0]->was_checked = true;
if (!(children[0]->children.size() == 1 && children[1]->isConst())) {
assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[1]->clone());
assign_data->children[0]->str = id_data;
assign_data->children[0]->was_checked = true;
}
if (current_always->type != AST_INITIAL) {
assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false));
@ -2035,28 +2064,20 @@ skip_dynamic_range_lvalue_expansion:;
assign_en->children[0]->was_checked = true;
}
}
newNode = new AstNode(AST_BLOCK);
newNode->children.push_back(assign_addr);
newNode->children.push_back(assign_data);
if (current_always->type != AST_INITIAL)
if (assign_data)
newNode->children.push_back(assign_data);
if (assign_en)
newNode->children.push_back(assign_en);
AstNode *wrnode = new AstNode(current_always->type == AST_INITIAL ? AST_MEMINIT : AST_MEMWR);
wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
if (current_always->type != AST_INITIAL)
wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
else
wrnode->children.push_back(AstNode::mkconst_int(1, false));
AstNode *wrnode = new AstNode(current_always->type == AST_INITIAL ? AST_MEMINIT : AST_MEMWR, node_addr, node_data, node_en);
wrnode->str = children[0]->str;
wrnode->id2ast = children[0]->id2ast;
wrnode->children[0]->str = id_addr;
wrnode->children[1]->str = id_data;
if (current_always->type != AST_INITIAL)
wrnode->children[2]->str = id_en;
current_ast_mod->children.push_back(wrnode);
if (newNode->children.empty()) {
delete newNode;
newNode = new AstNode();
}
goto apply_newNode;
}
@ -2656,7 +2677,7 @@ skip_dynamic_range_lvalue_expansion:;
wire->is_input = false;
wire->is_output = false;
wire->is_reg = true;
wire->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
wire->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
if (child->type == AST_ENUM_ITEM)
wire->attributes["\\enum_base_type"] = child->attributes["\\enum_base_type"];
@ -3344,10 +3365,10 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg
}
// also activate if requested, either by using mem2reg attribute or by declaring array as 'wire' instead of 'reg'
if (type == AST_MEMORY && (get_bool_attribute("\\mem2reg") || (flags & AstNode::MEM2REG_FL_ALL) || !is_reg))
if (type == AST_MEMORY && (get_bool_attribute(ID::mem2reg) || (flags & AstNode::MEM2REG_FL_ALL) || !is_reg))
mem2reg_candidates[this] |= AstNode::MEM2REG_FL_FORCED;
if (type == AST_MODULE && get_bool_attribute("\\mem2reg"))
if (type == AST_MODULE && get_bool_attribute(ID::mem2reg))
children_flags |= AstNode::MEM2REG_FL_ALL;
dict<AstNode*, uint32_t> *proc_flags_p = NULL;
@ -3510,7 +3531,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
wire_addr->str = id_addr;
wire_addr->is_reg = true;
wire_addr->was_checked = true;
wire_addr->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
wire_addr->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
mod->children.push_back(wire_addr);
while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { }
@ -3519,7 +3540,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
wire_data->is_reg = true;
wire_data->was_checked = true;
wire_data->is_signed = mem_signed;
wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
wire_data->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
mod->children.push_back(wire_data);
while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
@ -3590,7 +3611,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
wire_addr->is_reg = true;
wire_addr->was_checked = true;
if (block)
wire_addr->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
wire_addr->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
mod->children.push_back(wire_addr);
while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { }
@ -3600,7 +3621,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
wire_data->was_checked = true;
wire_data->is_signed = mem_signed;
if (block)
wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
wire_data->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
mod->children.push_back(wire_data);
while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }

View file

@ -176,7 +176,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
if (!strcmp(cmd, ".blackbox"))
{
module->attributes["\\blackbox"] = RTLIL::Const(1);
module->attributes[ID::blackbox] = RTLIL::Const(1);
continue;
}
@ -215,17 +215,17 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
vector<Cell*> remove_cells;
for (auto cell : module->cells())
if (cell->type == "$lut" && cell->getParam("\\LUT") == buffer_lut) {
module->connect(cell->getPort("\\Y"), cell->getPort("\\A"));
if (cell->type == ID($lut) && cell->getParam(ID::LUT) == buffer_lut) {
module->connect(cell->getPort(ID::Y), cell->getPort(ID::A));
remove_cells.push_back(cell);
}
for (auto cell : remove_cells)
module->remove(cell);
Wire *true_wire = module->wire("$true");
Wire *false_wire = module->wire("$false");
Wire *undef_wire = module->wire("$undef");
Wire *true_wire = module->wire(ID($true));
Wire *false_wire = module->wire(ID($false));
Wire *undef_wire = module->wire(ID($undef));
if (true_wire != nullptr)
module->rename(true_wire, stringf("$true$%d", ++blif_maxnum));
@ -337,7 +337,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
}
if (init != nullptr && (init[0] == '0' || init[0] == '1'))
blif_wire(q)->attributes["\\init"] = Const(init[0] == '1' ? 1 : 0, 1);
blif_wire(q)->attributes[ID::init] = Const(init[0] == '1' ? 1 : 0, 1);
if (clock == nullptr)
goto no_latch_clock;
@ -356,8 +356,8 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
cell = module->addFf(NEW_ID, blif_wire(d), blif_wire(q));
} else {
cell = module->addCell(NEW_ID, dff_name);
cell->setPort("\\D", blif_wire(d));
cell->setPort("\\Q", blif_wire(q));
cell->setPort(ID::D, blif_wire(d));
cell->setPort(ID::Q, blif_wire(q));
}
}
@ -476,7 +476,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
finished_parsing_constval:
if (state == RTLIL::State::Sa)
state = RTLIL::State::S0;
if (output_sig.as_wire()->name == "$undef")
if (output_sig.as_wire()->name == ID($undef))
state = RTLIL::State::Sx;
module->connect(RTLIL::SigSig(output_sig, state));
goto continue_without_read;
@ -484,23 +484,23 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
if (sop_mode)
{
sopcell = module->addCell(NEW_ID, "$sop");
sopcell->parameters["\\WIDTH"] = RTLIL::Const(input_sig.size());
sopcell->parameters["\\DEPTH"] = 0;
sopcell->parameters["\\TABLE"] = RTLIL::Const();
sopcell->setPort("\\A", input_sig);
sopcell->setPort("\\Y", output_sig);
sopcell = module->addCell(NEW_ID, ID($sop));
sopcell->parameters[ID::WIDTH] = RTLIL::Const(input_sig.size());
sopcell->parameters[ID::DEPTH] = 0;
sopcell->parameters[ID::TABLE] = RTLIL::Const();
sopcell->setPort(ID::A, input_sig);
sopcell->setPort(ID::Y, output_sig);
sopmode = -1;
lastcell = sopcell;
}
else
{
RTLIL::Cell *cell = module->addCell(NEW_ID, "$lut");
cell->parameters["\\WIDTH"] = RTLIL::Const(input_sig.size());
cell->parameters["\\LUT"] = RTLIL::Const(RTLIL::State::Sx, 1 << input_sig.size());
cell->setPort("\\A", input_sig);
cell->setPort("\\Y", output_sig);
lutptr = &cell->parameters.at("\\LUT");
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($lut));
cell->parameters[ID::WIDTH] = RTLIL::Const(input_sig.size());
cell->parameters[ID::LUT] = RTLIL::Const(RTLIL::State::Sx, 1 << input_sig.size());
cell->setPort(ID::A, input_sig);
cell->setPort(ID::Y, output_sig);
lutptr = &cell->parameters.at(ID::LUT);
lut_default_state = RTLIL::State::Sx;
lastcell = cell;
}
@ -523,32 +523,32 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
if (sopcell)
{
log_assert(sopcell->parameters["\\WIDTH"].as_int() == input_len);
sopcell->parameters["\\DEPTH"] = sopcell->parameters["\\DEPTH"].as_int() + 1;
log_assert(sopcell->parameters[ID::WIDTH].as_int() == input_len);
sopcell->parameters[ID::DEPTH] = sopcell->parameters[ID::DEPTH].as_int() + 1;
for (int i = 0; i < input_len; i++)
switch (input[i]) {
case '0':
sopcell->parameters["\\TABLE"].bits.push_back(State::S1);
sopcell->parameters["\\TABLE"].bits.push_back(State::S0);
sopcell->parameters[ID::TABLE].bits.push_back(State::S1);
sopcell->parameters[ID::TABLE].bits.push_back(State::S0);
break;
case '1':
sopcell->parameters["\\TABLE"].bits.push_back(State::S0);
sopcell->parameters["\\TABLE"].bits.push_back(State::S1);
sopcell->parameters[ID::TABLE].bits.push_back(State::S0);
sopcell->parameters[ID::TABLE].bits.push_back(State::S1);
break;
default:
sopcell->parameters["\\TABLE"].bits.push_back(State::S0);
sopcell->parameters["\\TABLE"].bits.push_back(State::S0);
sopcell->parameters[ID::TABLE].bits.push_back(State::S0);
sopcell->parameters[ID::TABLE].bits.push_back(State::S0);
break;
}
if (sopmode == -1) {
sopmode = (*output == '1');
if (!sopmode) {
SigSpec outnet = sopcell->getPort("\\Y");
SigSpec outnet = sopcell->getPort(ID::Y);
SigSpec tempnet = module->addWire(NEW_ID);
module->addNotGate(NEW_ID, tempnet, outnet);
sopcell->setPort("\\Y", tempnet);
sopcell->setPort(ID::Y, tempnet);
}
} else
log_assert(sopmode == (*output == '1'));

View file

@ -55,37 +55,37 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *&
static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A)
{
RTLIL::Cell *cell = module->addCell(NEW_ID, "$_NOT_");
cell->setPort("\\A", A);
cell->setPort("\\Y", module->addWire(NEW_ID));
return cell->getPort("\\Y");
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_NOT_));
cell->setPort(ID::A, A);
cell->setPort(ID::Y, module->addWire(NEW_ID));
return cell->getPort(ID::Y);
}
static RTLIL::SigSpec create_xor_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B)
{
RTLIL::Cell *cell = module->addCell(NEW_ID, "$_XOR_");
cell->setPort("\\A", A);
cell->setPort("\\B", B);
cell->setPort("\\Y", module->addWire(NEW_ID));
return cell->getPort("\\Y");
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_XOR_));
cell->setPort(ID::A, A);
cell->setPort(ID::B, B);
cell->setPort(ID::Y, module->addWire(NEW_ID));
return cell->getPort(ID::Y);
}
static RTLIL::SigSpec create_and_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B)
{
RTLIL::Cell *cell = module->addCell(NEW_ID, "$_AND_");
cell->setPort("\\A", A);
cell->setPort("\\B", B);
cell->setPort("\\Y", module->addWire(NEW_ID));
return cell->getPort("\\Y");
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_AND_));
cell->setPort(ID::A, A);
cell->setPort(ID::B, B);
cell->setPort(ID::Y, module->addWire(NEW_ID));
return cell->getPort(ID::Y);
}
static RTLIL::SigSpec create_or_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B)
{
RTLIL::Cell *cell = module->addCell(NEW_ID, "$_OR_");
cell->setPort("\\A", A);
cell->setPort("\\B", B);
cell->setPort("\\Y", module->addWire(NEW_ID));
return cell->getPort("\\Y");
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_OR_));
cell->setPort(ID::A, A);
cell->setPort(ID::B, B);
cell->setPort(ID::Y, module->addWire(NEW_ID));
return cell->getPort(ID::Y);
}
static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack, token_t next_token)
@ -241,32 +241,32 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node)
rerun_invert_rollback = false;
for (auto &it : module->cells_) {
if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == clk_sig) {
clk_sig = it.second->getPort("\\A");
if (it.second->type == ID($_NOT_) && it.second->getPort(ID::Y) == clk_sig) {
clk_sig = it.second->getPort(ID::A);
clk_polarity = !clk_polarity;
rerun_invert_rollback = true;
}
if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == clear_sig) {
clear_sig = it.second->getPort("\\A");
if (it.second->type == ID($_NOT_) && it.second->getPort(ID::Y) == clear_sig) {
clear_sig = it.second->getPort(ID::A);
clear_polarity = !clear_polarity;
rerun_invert_rollback = true;
}
if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == preset_sig) {
preset_sig = it.second->getPort("\\A");
if (it.second->type == ID($_NOT_) && it.second->getPort(ID::Y) == preset_sig) {
preset_sig = it.second->getPort(ID::A);
preset_polarity = !preset_polarity;
rerun_invert_rollback = true;
}
}
}
RTLIL::Cell *cell = module->addCell(NEW_ID, "$_NOT_");
cell->setPort("\\A", iq_sig);
cell->setPort("\\Y", iqn_sig);
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_NOT_));
cell->setPort(ID::A, iq_sig);
cell->setPort(ID::Y, iqn_sig);
cell = module->addCell(NEW_ID, "");
cell->setPort("\\D", data_sig);
cell->setPort("\\Q", iq_sig);
cell->setPort("\\C", clk_sig);
cell->setPort(ID::D, data_sig);
cell->setPort(ID::Q, iq_sig);
cell->setPort(ID::C, clk_sig);
if (clear_sig.size() == 0 && preset_sig.size() == 0) {
cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N');
@ -274,18 +274,18 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node)
if (clear_sig.size() == 1 && preset_sig.size() == 0) {
cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N');
cell->setPort("\\R", clear_sig);
cell->setPort(ID::R, clear_sig);
}
if (clear_sig.size() == 0 && preset_sig.size() == 1) {
cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N');
cell->setPort("\\R", preset_sig);
cell->setPort(ID::R, preset_sig);
}
if (clear_sig.size() == 1 && preset_sig.size() == 1) {
cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N');
cell->setPort("\\S", preset_sig);
cell->setPort("\\R", clear_sig);
cell->setPort(ID::S, preset_sig);
cell->setPort(ID::R, clear_sig);
}
log_assert(!cell->type.empty());
@ -324,27 +324,27 @@ static bool create_latch(RTLIL::Module *module, LibertyAst *node, bool flag_igno
rerun_invert_rollback = false;
for (auto &it : module->cells_) {
if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == enable_sig) {
enable_sig = it.second->getPort("\\A");
if (it.second->type == ID($_NOT_) && it.second->getPort(ID::Y) == enable_sig) {
enable_sig = it.second->getPort(ID::A);
enable_polarity = !enable_polarity;
rerun_invert_rollback = true;
}
if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == clear_sig) {
clear_sig = it.second->getPort("\\A");
if (it.second->type == ID($_NOT_) && it.second->getPort(ID::Y) == clear_sig) {
clear_sig = it.second->getPort(ID::A);
clear_polarity = !clear_polarity;
rerun_invert_rollback = true;
}
if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == preset_sig) {
preset_sig = it.second->getPort("\\A");
if (it.second->type == ID($_NOT_) && it.second->getPort(ID::Y) == preset_sig) {
preset_sig = it.second->getPort(ID::A);
preset_polarity = !preset_polarity;
rerun_invert_rollback = true;
}
}
}
RTLIL::Cell *cell = module->addCell(NEW_ID, "$_NOT_");
cell->setPort("\\A", iq_sig);
cell->setPort("\\Y", iqn_sig);
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_NOT_));
cell->setPort(ID::A, iq_sig);
cell->setPort(ID::Y, iqn_sig);
if (clear_sig.size() == 1)
{
@ -353,25 +353,25 @@ static bool create_latch(RTLIL::Module *module, LibertyAst *node, bool flag_igno
if (clear_polarity == true || clear_polarity != enable_polarity)
{
RTLIL::Cell *inv = module->addCell(NEW_ID, "$_NOT_");
inv->setPort("\\A", clear_sig);
inv->setPort("\\Y", module->addWire(NEW_ID));
RTLIL::Cell *inv = module->addCell(NEW_ID, ID($_NOT_));
inv->setPort(ID::A, clear_sig);
inv->setPort(ID::Y, module->addWire(NEW_ID));
if (clear_polarity == true)
clear_negative = inv->getPort("\\Y");
clear_negative = inv->getPort(ID::Y);
if (clear_polarity != enable_polarity)
clear_enable = inv->getPort("\\Y");
clear_enable = inv->getPort(ID::Y);
}
RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_AND_");
data_gate->setPort("\\A", data_sig);
data_gate->setPort("\\B", clear_negative);
data_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID));
RTLIL::Cell *data_gate = module->addCell(NEW_ID, ID($_AND_));
data_gate->setPort(ID::A, data_sig);
data_gate->setPort(ID::B, clear_negative);
data_gate->setPort(ID::Y, data_sig = module->addWire(NEW_ID));
RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_");
enable_gate->setPort("\\A", enable_sig);
enable_gate->setPort("\\B", clear_enable);
enable_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID));
RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? ID($_OR_) : ID($_AND_));
enable_gate->setPort(ID::A, enable_sig);
enable_gate->setPort(ID::B, clear_enable);
enable_gate->setPort(ID::Y, data_sig = module->addWire(NEW_ID));
}
if (preset_sig.size() == 1)
@ -381,31 +381,31 @@ static bool create_latch(RTLIL::Module *module, LibertyAst *node, bool flag_igno
if (preset_polarity == false || preset_polarity != enable_polarity)
{
RTLIL::Cell *inv = module->addCell(NEW_ID, "$_NOT_");
inv->setPort("\\A", preset_sig);
inv->setPort("\\Y", module->addWire(NEW_ID));
RTLIL::Cell *inv = module->addCell(NEW_ID, ID($_NOT_));
inv->setPort(ID::A, preset_sig);
inv->setPort(ID::Y, module->addWire(NEW_ID));
if (preset_polarity == false)
preset_positive = inv->getPort("\\Y");
preset_positive = inv->getPort(ID::Y);
if (preset_polarity != enable_polarity)
preset_enable = inv->getPort("\\Y");
preset_enable = inv->getPort(ID::Y);
}
RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_OR_");
data_gate->setPort("\\A", data_sig);
data_gate->setPort("\\B", preset_positive);
data_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID));
RTLIL::Cell *data_gate = module->addCell(NEW_ID, ID($_OR_));
data_gate->setPort(ID::A, data_sig);
data_gate->setPort(ID::B, preset_positive);
data_gate->setPort(ID::Y, data_sig = module->addWire(NEW_ID));
RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_");
enable_gate->setPort("\\A", enable_sig);
enable_gate->setPort("\\B", preset_enable);
enable_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID));
RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? ID($_OR_) : ID($_AND_));
enable_gate->setPort(ID::A, enable_sig);
enable_gate->setPort(ID::B, preset_enable);
enable_gate->setPort(ID::Y, data_sig = module->addWire(NEW_ID));
}
cell = module->addCell(NEW_ID, stringf("$_DLATCH_%c_", enable_polarity ? 'P' : 'N'));
cell->setPort("\\D", data_sig);
cell->setPort("\\Q", iq_sig);
cell->setPort("\\E", enable_sig);
cell->setPort(ID::D, data_sig);
cell->setPort(ID::Q, iq_sig);
cell->setPort(ID::E, enable_sig);
return true;
}
@ -550,13 +550,13 @@ struct LibertyFrontend : public Frontend {
if (design->has(cell_name)) {
Module *existing_mod = design->module(cell_name);
if (!flag_nooverwrite && !flag_overwrite && !existing_mod->get_bool_attribute("\\blackbox")) {
if (!flag_nooverwrite && !flag_overwrite && !existing_mod->get_bool_attribute(ID::blackbox)) {
log_error("Re-definition of cell/module %s!\n", log_id(cell_name));
} else if (flag_nooverwrite) {
log("Ignoring re-definition of module %s.\n", log_id(cell_name));
continue;
} else {
log("Replacing existing%s module %s.\n", existing_mod->get_bool_attribute("\\blackbox") ? " blackbox" : "", log_id(cell_name));
log("Replacing existing%s module %s.\n", existing_mod->get_bool_attribute(ID::blackbox) ? " blackbox" : "", log_id(cell_name));
design->remove(existing_mod);
}
}
@ -570,7 +570,7 @@ struct LibertyFrontend : public Frontend {
module->name = cell_name;
if (flag_lib)
module->set_bool_attribute("\\blackbox");
module->set_bool_attribute(ID::blackbox);
for (auto &attr : attributes)
module->attributes[attr] = 1;

View file

@ -157,7 +157,7 @@ struct RpcServer {
struct RpcModule : RTLIL::Module {
std::shared_ptr<RpcServer> server;
RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool /*mayfail*/) YS_OVERRIDE {
RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool /*mayfail*/) YS_OVERRIDE {
std::string stripped_name = name.str();
if (stripped_name.compare(0, 9, "$abstract") == 0)
stripped_name = stripped_name.substr(9);
@ -216,7 +216,7 @@ struct RpcModule : RTLIL::Module {
module.second->name = mangled_name;
module.second->design = design;
module.second->attributes.erase("\\top");
module.second->attributes.erase(ID::top);
design->modules_[mangled_name] = module.second;
derived_design->modules_.erase(module.first);
}

View file

@ -155,7 +155,7 @@ void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &att
Att *attr;
if (obj->Linefile())
attributes["\\src"] = stringf("%s:%d", LineFile::GetFileName(obj->Linefile()), LineFile::GetLineNo(obj->Linefile()));
attributes[ID::src] = stringf("%s:%d", LineFile::GetFileName(obj->Linefile()), LineFile::GetLineNo(obj->Linefile()));
// FIXME: Parse numeric attributes
FOREACH_ATTRIBUTE(obj, mi, attr) {
@ -738,7 +738,7 @@ void VerificImporter::merge_past_ffs_clock(pool<RTLIL::Cell*> &candidates, SigBi
SigSpec dbits;
for (auto cell : candidates) {
SigBit bit = sigmap(cell->getPort("\\D"));
SigBit bit = sigmap(cell->getPort(ID::D));
dbits_db[bit].insert(cell);
dbits.append(bit);
}
@ -764,7 +764,7 @@ void VerificImporter::merge_past_ffs_clock(pool<RTLIL::Cell*> &candidates, SigBi
if (verific_verbose)
log(" replacing old ff %s on bit %d.\n", log_id(old_ff), i);
SigBit old_q = old_ff->getPort("\\Q");
SigBit old_q = old_ff->getPort(ID::Q);
SigBit new_q = sig_q[i];
sigmap.add(old_q, new_q);
@ -783,8 +783,8 @@ void VerificImporter::merge_past_ffs(pool<RTLIL::Cell*> &candidates)
for (auto cell : candidates)
{
SigBit clock = cell->getPort("\\CLK");
bool clock_pol = cell->getParam("\\CLK_POLARITY").as_bool();
SigBit clock = cell->getPort(ID::CLK);
bool clock_pol = cell->getParam(ID::CLK_POLARITY).as_bool();
database[make_pair(clock, int(clock_pol))].insert(cell);
}
@ -822,7 +822,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
if (is_blackbox(nl)) {
log("Importing blackbox module %s.\n", RTLIL::id2cstr(module->name));
module->set_bool_attribute("\\blackbox");
module->set_bool_attribute(ID::blackbox);
} else {
log("Importing module %s.\n", RTLIL::id2cstr(module->name));
}
@ -952,17 +952,17 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
ascii_initdata++;
}
if (initval_valid) {
RTLIL::Cell *cell = module->addCell(new_verific_id(net), "$meminit");
cell->parameters["\\WORDS"] = 1;
RTLIL::Cell *cell = module->addCell(new_verific_id(net), ID($meminit));
cell->parameters[ID::WORDS] = 1;
if (net->GetOrigTypeRange()->LeftRangeBound() < net->GetOrigTypeRange()->RightRangeBound())
cell->setPort("\\ADDR", word_idx);
cell->setPort(ID::ADDR, word_idx);
else
cell->setPort("\\ADDR", memory->size - word_idx - 1);
cell->setPort("\\DATA", initval);
cell->parameters["\\MEMID"] = RTLIL::Const(memory->name.str());
cell->parameters["\\ABITS"] = 32;
cell->parameters["\\WIDTH"] = memory->width;
cell->parameters["\\PRIORITY"] = RTLIL::Const(autoidx-1);
cell->setPort(ID::ADDR, memory->size - word_idx - 1);
cell->setPort(ID::DATA, initval);
cell->parameters[ID::MEMID] = RTLIL::Const(memory->name.str());
cell->parameters[ID::ABITS] = 32;
cell->parameters[ID::WIDTH] = memory->width;
cell->parameters[ID::PRIORITY] = RTLIL::Const(autoidx-1);
}
}
}
@ -1079,7 +1079,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
}
if (initval_valid)
wire->attributes["\\init"] = initval;
wire->attributes[ID::init] = initval;
}
else
{
@ -1133,8 +1133,8 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
SigBit bit = net_map_at(it.first);
log_assert(bit.wire);
if (bit.wire->attributes.count("\\init"))
initval = bit.wire->attributes.at("\\init");
if (bit.wire->attributes.count(ID::init))
initval = bit.wire->attributes.at(ID::init);
while (GetSize(initval) < GetSize(bit.wire))
initval.bits.push_back(State::Sx);
@ -1144,7 +1144,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
if (it.second == '1')
initval.bits.at(bit.offset) = State::S1;
bit.wire->attributes["\\init"] = initval;
bit.wire->attributes[ID::init] = initval;
}
for (auto net : anyconst_nets)
@ -1212,17 +1212,17 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
RTLIL::SigSpec data = operatorOutput(inst).extract(i * memory->width, memory->width);
RTLIL::Cell *cell = module->addCell(numchunks == 1 ? inst_name :
RTLIL::IdString(stringf("%s_%d", inst_name.c_str(), i)), "$memrd");
cell->parameters["\\MEMID"] = memory->name.str();
cell->parameters["\\CLK_ENABLE"] = false;
cell->parameters["\\CLK_POLARITY"] = true;
cell->parameters["\\TRANSPARENT"] = false;
cell->parameters["\\ABITS"] = GetSize(addr);
cell->parameters["\\WIDTH"] = GetSize(data);
cell->setPort("\\CLK", RTLIL::State::Sx);
cell->setPort("\\EN", RTLIL::State::Sx);
cell->setPort("\\ADDR", addr);
cell->setPort("\\DATA", data);
RTLIL::IdString(stringf("%s_%d", inst_name.c_str(), i)), ID($memrd));
cell->parameters[ID::MEMID] = memory->name.str();
cell->parameters[ID::CLK_ENABLE] = false;
cell->parameters[ID::CLK_POLARITY] = true;
cell->parameters[ID::TRANSPARENT] = false;
cell->parameters[ID::ABITS] = GetSize(addr);
cell->parameters[ID::WIDTH] = GetSize(data);
cell->setPort(ID::CLK, RTLIL::State::Sx);
cell->setPort(ID::EN, RTLIL::State::Sx);
cell->setPort(ID::ADDR, addr);
cell->setPort(ID::DATA, data);
}
continue;
}
@ -1242,21 +1242,21 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
RTLIL::SigSpec data = operatorInput2(inst).extract(i * memory->width, memory->width);
RTLIL::Cell *cell = module->addCell(numchunks == 1 ? inst_name :
RTLIL::IdString(stringf("%s_%d", inst_name.c_str(), i)), "$memwr");
cell->parameters["\\MEMID"] = memory->name.str();
cell->parameters["\\CLK_ENABLE"] = false;
cell->parameters["\\CLK_POLARITY"] = true;
cell->parameters["\\PRIORITY"] = 0;
cell->parameters["\\ABITS"] = GetSize(addr);
cell->parameters["\\WIDTH"] = GetSize(data);
cell->setPort("\\EN", RTLIL::SigSpec(net_map_at(inst->GetControl())).repeat(GetSize(data)));
cell->setPort("\\CLK", RTLIL::State::S0);
cell->setPort("\\ADDR", addr);
cell->setPort("\\DATA", data);
RTLIL::IdString(stringf("%s_%d", inst_name.c_str(), i)), ID($memwr));
cell->parameters[ID::MEMID] = memory->name.str();
cell->parameters[ID::CLK_ENABLE] = false;
cell->parameters[ID::CLK_POLARITY] = true;
cell->parameters[ID::PRIORITY] = 0;
cell->parameters[ID::ABITS] = GetSize(addr);
cell->parameters[ID::WIDTH] = GetSize(data);
cell->setPort(ID::EN, RTLIL::SigSpec(net_map_at(inst->GetControl())).repeat(GetSize(data)));
cell->setPort(ID::CLK, RTLIL::State::S0);
cell->setPort(ID::ADDR, addr);
cell->setPort(ID::DATA, data);
if (inst->Type() == OPER_CLOCKED_WRITE_PORT) {
cell->parameters["\\CLK_ENABLE"] = true;
cell->setPort("\\CLK", net_map_at(inst->GetClock()));
cell->parameters[ID::CLK_ENABLE] = true;
cell->setPort(ID::CLK, net_map_at(inst->GetClock()));
}
}
continue;
@ -1431,7 +1431,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
RTLIL::Cell *cell = module->addCell(inst_name, inst_type);
if (inst->IsPrimitive() && mode_keep)
cell->attributes["\\keep"] = 1;
cell->attributes[ID::keep] = 1;
dict<IdString, vector<SigBit>> cell_port_conns;
@ -1514,10 +1514,10 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
for (auto wire : module->wires())
{
if (!wire->attributes.count("\\init"))
if (!wire->attributes.count(ID::init))
continue;
Const &initval = wire->attributes.at("\\init");
Const &initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(initval); i++)
{
if (initval[i] != State::S0 && initval[i] != State::S1)
@ -1528,7 +1528,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
}
if (initval.is_fully_undef())
wire->attributes.erase("\\init");
wire->attributes.erase(ID::init);
}
}
}
@ -1652,10 +1652,10 @@ Cell *VerificClocking::addDff(IdString name, SigSpec sig_d, SigSpec sig_q, Const
if (GetSize(init_value) != 0) {
log_assert(GetSize(sig_q) == GetSize(init_value));
if (sig_q.is_wire()) {
sig_q.as_wire()->attributes["\\init"] = init_value;
sig_q.as_wire()->attributes[ID::init] = init_value;
} else {
Wire *w = module->addWire(NEW_ID, GetSize(sig_q));
w->attributes["\\init"] = init_value;
w->attributes[ID::init] = init_value;
module->connect(sig_q, w);
sig_q = w;
}

View file

@ -10,7 +10,7 @@ frontends/verilog/verilog_parser.tab.cc: frontends/verilog/verilog_parser.y
frontends/verilog/verilog_parser.tab.hh: frontends/verilog/verilog_parser.tab.cc
frontends/verilog/verilog_lexer.cc: frontends/verilog/verilog_lexer.l
frontends/verilog/verilog_lexer.cc: frontends/verilog/verilog_lexer.l frontends/verilog/verilog_parser.tab.cc
$(Q) mkdir -p $(dir $@)
$(P) flex -o frontends/verilog/verilog_lexer.cc $<

View file

@ -139,6 +139,9 @@ static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int le
data.resize(len_in_bits, msb);
}
if (len_in_bits == 0)
log_file_error(current_filename, get_line_num(), "Illegal integer constant size of zero (IEEE 1800-2012, 5.7).\n");
if (len > len_in_bits)
log_warning("Literal has a width of %d bit, but value requires %d bit. (%s:%d)\n",
len_in_bits, len, current_filename.c_str(), get_line_num());

View file

@ -32,8 +32,10 @@
*
*/
#include "preproc.h"
#include "verilog_frontend.h"
#include "kernel/log.h"
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
@ -199,6 +201,175 @@ static std::string next_token(bool pass_newline = false)
return token;
}
struct macro_arg_t
{
macro_arg_t(const std::string &name_, const char *default_value_)
: name(name_),
has_default(default_value_ != nullptr),
default_value(default_value_ ? default_value_ : "")
{}
std::string name;
bool has_default;
std::string default_value;
};
static bool all_white(const std::string &str)
{
for (char c : str)
if (!isspace(c))
return false;
return true;
}
struct arg_map_t
{
arg_map_t()
{}
void add_arg(const std::string &name, const char *default_value)
{
if (find(name)) {
log_error("Duplicate macro arguments with name `%s'.\n", name.c_str());
}
name_to_pos[name] = args.size();
args.push_back(macro_arg_t(name, default_value));
}
// Find an argument by name; return nullptr if it doesn't exist. If pos is not null, write
// the argument's position to it on success.
const macro_arg_t *find(const std::string &name, int *pos = nullptr) const
{
auto it = name_to_pos.find(name);
if (it == name_to_pos.end())
return nullptr;
if (pos) *pos = it->second;
return &args[it->second];
}
// Construct the name for the local macro definition we use for the given argument
// (something like macro_foobar_arg2). This doesn't include the leading backtick.
static std::string str_token(const std::string &macro_name, int pos)
{
return stringf("macro_%s_arg%d", macro_name.c_str(), pos);
}
// Return definitions for the macro arguments (so that substituting in the macro body and
// then performing macro expansion will do argument substitution properly).
std::vector<std::pair<std::string, std::string>>
get_vals(const std::string &macro_name, const std::vector<std::string> &arg_vals) const
{
std::vector<std::pair<std::string, std::string>> ret;
for (int i = 0; i < GetSize(args); ++ i) {
// The SystemVerilog rules are:
//
// - If the call site specifies an argument and it's not whitespace, use
// it.
//
// - Otherwise, if the argument has a default value, use it.
//
// - Otherwise, if the call site specified whitespace, use that.
//
// - Otherwise, error.
const std::string *dflt = nullptr;
if (args[i].has_default)
dflt = &args[i].default_value;
const std::string *given = nullptr;
if (i < GetSize(arg_vals))
given = &arg_vals[i];
const std::string *val = nullptr;
if (given && (! (dflt && all_white(*given))))
val = given;
else if (dflt)
val = dflt;
else if (given)
val = given;
else
log_error("Cannot expand macro `%s by giving only %d argument%s "
"(argument %d has no default).\n",
macro_name.c_str(), GetSize(arg_vals),
(GetSize(arg_vals) == 1 ? "" : "s"), i + 1);
assert(val);
ret.push_back(std::make_pair(str_token(macro_name, i), * val));
}
return ret;
}
std::vector<macro_arg_t> args;
std::map<std::string, int> name_to_pos;
};
struct define_body_t
{
define_body_t(const std::string &body, const arg_map_t *args = nullptr)
: body(body),
has_args(args != nullptr),
args(args ? *args : arg_map_t())
{}
std::string body;
bool has_args;
arg_map_t args;
};
define_map_t::define_map_t()
{
add("YOSYS", "1");
add(formal_mode ? "FORMAL" : "SYNTHESIS", "1");
}
// We must define this destructor here (rather than relying on the default), because we need to
// define it somewhere we've got a complete definition of define_body_t.
define_map_t::~define_map_t()
{}
void
define_map_t::add(const std::string &name, const std::string &txt, const arg_map_t *args)
{
defines[name] = std::unique_ptr<define_body_t>(new define_body_t(txt, args));
}
void define_map_t::merge(const define_map_t &map)
{
for (const auto &pr : map.defines) {
// These contortions are so that we take a copy of each definition body in
// map.defines.
defines[pr.first] = std::unique_ptr<define_body_t>(new define_body_t(*pr.second));
}
}
const define_body_t *define_map_t::find(const std::string &name) const
{
auto it = defines.find(name);
return (it == defines.end()) ? nullptr : it->second.get();
}
void define_map_t::erase(const std::string &name)
{
defines.erase(name);
}
void define_map_t::clear()
{
defines.clear();
}
void define_map_t::log() const
{
for (auto &it : defines) {
const std::string &name = it.first;
const define_body_t &body = *it.second;
Yosys::log("`define %s%s %s\n",
name.c_str(), body.has_args ? "()" : "", body.body.c_str());
}
}
static void input_file(std::istream &f, std::string filename)
{
char buffer[513];
@ -215,11 +386,59 @@ static void input_file(std::istream &f, std::string filename)
input_buffer.insert(it, "\n`file_pop\n");
}
// Read tokens to get one argument (either a macro argument at a callsite or a default argument in a
// macro definition). Writes the argument to dest. Returns true if we finished with ')' (the end of
// the argument list); false if we finished with ','.
static bool read_argument(std::string &dest)
{
std::vector<char> openers;
for (;;) {
skip_spaces();
std::string tok = next_token(true);
if (tok == ")") {
if (openers.empty())
return true;
if (openers.back() != '(')
log_error("Mismatched brackets in macro argument: %c and %c.\n",
openers.back(), tok[0]);
static bool try_expand_macro(std::set<std::string> &defines_with_args,
std::map<std::string, std::string> &defines_map,
std::string &tok
)
openers.pop_back();
dest += tok;
continue;
}
if (tok == "]") {
char opener = openers.empty() ? '(' : openers.back();
if (opener != '[')
log_error("Mismatched brackets in macro argument: %c and %c.\n",
opener, tok[0]);
openers.pop_back();
dest += tok;
continue;
}
if (tok == "}") {
char opener = openers.empty() ? '(' : openers.back();
if (opener != '{')
log_error("Mismatched brackets in macro argument: %c and %c.\n",
opener, tok[0]);
openers.pop_back();
dest += tok;
continue;
}
if (tok == "," && openers.empty()) {
return false;
}
if (tok == "(" || tok == "[" || tok == "{")
openers.push_back(tok[0]);
dest += tok;
}
}
static bool try_expand_macro(define_map_t &defines, std::string &tok)
{
if (tok == "`\"") {
std::string literal("\"");
@ -229,54 +448,272 @@ static bool try_expand_macro(std::set<std::string> &defines_with_args,
if (ntok == "`\"") {
insert_input(literal+"\"");
return true;
} else if (!try_expand_macro(defines_with_args, defines_map, ntok)) {
} else if (!try_expand_macro(defines, ntok)) {
literal += ntok;
}
}
return false; // error - unmatched `"
} else if (tok.size() > 1 && tok[0] == '`' && defines_map.count(tok.substr(1)) > 0) {
std::string name = tok.substr(1);
// printf("expand: >>%s<< -> >>%s<<\n", name.c_str(), defines_map[name].c_str());
std::string skipped_spaces = skip_spaces();
tok = next_token(false);
if (tok == "(" && defines_with_args.count(name) > 0) {
int level = 1;
std::vector<std::string> args;
args.push_back(std::string());
while (1)
{
skip_spaces();
tok = next_token(true);
if (tok == ")" || tok == "}" || tok == "]")
level--;
if (level == 0)
break;
if (level == 1 && tok == ",")
args.push_back(std::string());
else
args.back() += tok;
if (tok == "(" || tok == "{" || tok == "[")
level++;
}
for (int i = 0; i < GetSize(args); i++)
defines_map[stringf("macro_%s_arg%d", name.c_str(), i+1)] = args[i];
} else {
insert_input(tok);
insert_input(skipped_spaces);
}
insert_input(defines_map[name]);
return true;
} else if (tok == "``") {
}
if (tok == "``") {
// Swallow `` in macro expansion
return true;
} else return false;
}
if (tok.size() <= 1 || tok[0] != '`')
return false;
// This token looks like a macro name (`foo).
std::string macro_name = tok.substr(1);
const define_body_t *body = defines.find(tok.substr(1));
if (! body) {
// Apparently not a name we know.
return false;
}
std::string name = tok.substr(1);
std::string skipped_spaces = skip_spaces();
tok = next_token(false);
if (tok == "(" && body->has_args) {
std::vector<std::string> args;
bool done = false;
while (!done) {
std::string arg;
done = read_argument(arg);
args.push_back(arg);
}
for (const auto &pr : body->args.get_vals(name, args)) {
defines.add(pr.first, pr.second);
}
} else {
insert_input(tok);
insert_input(skipped_spaces);
}
insert_input(body->body);
return true;
}
std::string frontend_verilog_preproc(std::istream &f, std::string filename, const std::map<std::string, std::string> &pre_defines_map,
dict<std::string, std::pair<std::string, bool>> &global_defines_cache, const std::list<std::string> &include_dirs)
// Read the arguments for a `define preprocessor directive with formal arguments. This is called
// just after reading the token containing "(". Returns the number of newlines to emit afterwards to
// keep line numbers in sync, together with the map from argument name to data (pos and default
// value).
static std::pair<int, arg_map_t>
read_define_args()
{
std::set<std::string> defines_with_args;
std::map<std::string, std::string> defines_map(pre_defines_map);
// Each argument looks like one of the following:
//
// identifier
// identifier = default_text
// identifier =
//
// The first example is an argument with no default value. The second is an argument whose
// default value is default_text. The third is an argument with default value the empty
// string.
int newline_count = 0;
arg_map_t args;
// FSM state.
//
// 0: At start of identifier
// 1: After identifier (stored in arg_name)
// 2: After closing paren
int state = 0;
std::string arg_name, default_val;
skip_spaces();
for (;;) {
if (state == 2)
// We've read the closing paren.
break;
std::string tok = next_token();
// Cope with escaped EOLs
if (tok == "\\") {
char ch = next_char();
if (ch == '\n') {
// Eat the \, the \n and any trailing space and keep going.
skip_spaces();
continue;
} else {
// There aren't any other situations where a backslash makes sense.
log_error("Backslash in macro arguments (not at end of line).\n");
}
}
switch (state) {
case 0:
// At start of argument. If the token is ')', we've presumably just seen
// something like "`define foo() ...". Set state to 2 to finish. Otherwise,
// the token should be a valid simple identifier, but we'll allow anything
// here.
if (tok == ")") {
state = 2;
} else {
arg_name = tok;
state = 1;
}
skip_spaces();
break;
case 1:
// After argument. The token should either be an equals sign or a comma or
// closing paren.
if (tok == "=") {
std::string default_val;
//Read an argument into default_val and set state to 2 if we're at
// the end; 0 if we hit a comma.
state = read_argument(default_val) ? 2 : 0;
args.add_arg(arg_name, default_val.c_str());
skip_spaces();
break;
}
if (tok == ",") {
// Take the identifier as an argument with no default value.
args.add_arg(arg_name, nullptr);
state = 0;
skip_spaces();
break;
}
if (tok == ")") {
// As with comma, but set state to 2 (end of args)
args.add_arg(arg_name, nullptr);
state = 2;
skip_spaces();
break;
}
log_error("Trailing contents after identifier in macro argument `%s': "
"expected '=', ',' or ')'.\n",
arg_name.c_str());
default:
// The only FSM states are 0-2 and we dealt with 2 at the start of the loop.
__builtin_unreachable();
}
}
return std::make_pair(newline_count, args);
}
// Read a `define preprocessor directive. This is called just after reading the token containing
// "`define".
static void
read_define(const std::string &filename,
define_map_t &defines_map,
define_map_t &global_defines_cache)
{
std::string name, value;
arg_map_t args;
skip_spaces();
name = next_token(true);
bool here_doc_mode = false;
int newline_count = 0;
// The FSM state starts at 0. If it sees space (or enters here_doc_mode), it assumes this is
// a macro without formal arguments and jumps to state 1.
//
// In state 0, if it sees an opening parenthesis, it assumes this is a macro with formal
// arguments. It reads the arguments with read_define_args() and then jumps to state 2.
//
// In states 1 or 2, the FSM reads tokens to the end of line (or end of here_doc): this is
// the body of the macro definition.
int state = 0;
if (skip_spaces() != "")
state = 1;
for (;;) {
std::string tok = next_token();
if (tok.empty())
break;
// printf("define-tok: >>%s<<\n", tok != "\n" ? tok.c_str() : "NEWLINE");
if (tok == "\"\"\"") {
here_doc_mode = !here_doc_mode;
continue;
}
if (state == 0 && tok == "(") {
auto pr = read_define_args();
newline_count += pr.first;
args = pr.second;
state = 2;
continue;
}
// This token isn't an opening parenthesis immediately following the macro name, so
// it's presumably at or after the start of the macro body. If state isn't already 2
// (which would mean we'd parsed an argument list), set it to 1.
if (state == 0) {
state = 1;
}
if (tok == "\n") {
if (here_doc_mode) {
value += " ";
newline_count++;
} else {
return_char('\n');
break;
}
continue;
}
if (tok == "\\") {
char ch = next_char();
if (ch == '\n') {
value += " ";
newline_count++;
} else {
value += std::string("\\");
return_char(ch);
}
continue;
}
// Is this token the name of a macro argument? If so, replace it with a magic symbol
// that we'll replace with the argument value.
int arg_pos;
if (args.find(tok, &arg_pos)) {
value += '`' + args.str_token(name, arg_pos);
continue;
}
// This token is nothing special. Insert it verbatim into the macro body.
value += tok;
}
// Append some newlines so that we don't mess up line counts in error messages.
while (newline_count-- > 0)
return_char('\n');
if (strchr("abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ$0123456789", name[0])) {
// printf("define: >>%s<< -> >>%s<<\n", name.c_str(), value.c_str());
defines_map.add(name, value, (state == 2) ? &args : nullptr);
global_defines_cache.add(name, value, (state == 2) ? &args : nullptr);
} else {
log_file_error(filename, 0, "Invalid name for macro definition: >>%s<<.\n", name.c_str());
}
}
std::string
frontend_verilog_preproc(std::istream &f,
std::string filename,
const define_map_t &pre_defines,
define_map_t &global_defines_cache,
const std::list<std::string> &include_dirs)
{
define_map_t defines;
defines.merge(pre_defines);
defines.merge(global_defines_cache);
std::vector<std::string> filename_stack;
int ifdef_fail_level = 0;
bool in_elseif = false;
@ -287,18 +724,6 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
input_file(f, filename);
defines_map["YOSYS"] = "1";
defines_map[formal_mode ? "FORMAL" : "SYNTHESIS"] = "1";
for (auto &it : pre_defines_map)
defines_map[it.first] = it.second;
for (auto &it : global_defines_cache) {
if (it.second.second)
defines_with_args.insert(it.first);
defines_map[it.first] = it.second.first;
}
while (!input_buffer.empty())
{
std::string tok = next_token();
@ -325,7 +750,7 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
std::string name = next_token(true);
if (ifdef_fail_level == 0)
ifdef_fail_level = 1, in_elseif = true;
else if (ifdef_fail_level == 1 && defines_map.count(name) != 0)
else if (ifdef_fail_level == 1 && defines.find(name))
ifdef_fail_level = 0, in_elseif = true;
continue;
}
@ -333,7 +758,7 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
if (tok == "`ifdef") {
skip_spaces();
std::string name = next_token(true);
if (ifdef_fail_level > 0 || defines_map.count(name) == 0)
if (ifdef_fail_level > 0 || !defines.find(name))
ifdef_fail_level++;
continue;
}
@ -341,7 +766,7 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
if (tok == "`ifndef") {
skip_spaces();
std::string name = next_token(true);
if (ifdef_fail_level > 0 || defines_map.count(name) != 0)
if (ifdef_fail_level > 0 || defines.find(name))
ifdef_fail_level++;
continue;
}
@ -355,7 +780,7 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
if (tok == "`include") {
skip_spaces();
std::string fn = next_token(true);
while (try_expand_macro(defines_with_args, defines_map, fn)) {
while (try_expand_macro(defines, fn)) {
fn = next_token();
}
while (1) {
@ -433,74 +858,7 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
}
if (tok == "`define") {
std::string name, value;
std::map<std::string, int> args;
skip_spaces();
name = next_token(true);
bool here_doc_mode = false;
int newline_count = 0;
int state = 0;
if (skip_spaces() != "")
state = 3;
while (!tok.empty()) {
tok = next_token();
if (tok == "\"\"\"") {
here_doc_mode = !here_doc_mode;
continue;
}
if (state == 0 && tok == "(") {
state = 1;
skip_spaces();
} else
if (state == 1) {
if (tok == ")")
state = 2;
else if (tok != ",") {
int arg_idx = args.size()+1;
args[tok] = arg_idx;
}
skip_spaces();
} else {
if (state != 2)
state = 3;
if (tok == "\n") {
if (here_doc_mode) {
value += " ";
newline_count++;
} else {
return_char('\n');
break;
}
} else
if (tok == "\\") {
char ch = next_char();
if (ch == '\n') {
value += " ";
newline_count++;
} else {
value += std::string("\\");
return_char(ch);
}
} else
if (args.count(tok) > 0)
value += stringf("`macro_%s_arg%d", name.c_str(), args.at(tok));
else
value += tok;
}
}
while (newline_count-- > 0)
return_char('\n');
if (strchr("abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ$0123456789", name[0])) {
// printf("define: >>%s<< -> >>%s<<\n", name.c_str(), value.c_str());
defines_map[name] = value;
if (state == 2)
defines_with_args.insert(name);
else
defines_with_args.erase(name);
global_defines_cache[name] = std::pair<std::string, bool>(value, state == 2);
} else {
log_file_error(filename, 0, "Invalid name for macro definition: >>%s<<.\n", name.c_str());
}
read_define(filename, defines, global_defines_cache);
continue;
}
@ -509,8 +867,7 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
skip_spaces();
name = next_token(true);
// printf("undef: >>%s<<\n", name.c_str());
defines_map.erase(name);
defines_with_args.erase(name);
defines.erase(name);
global_defines_cache.erase(name);
continue;
}
@ -525,13 +882,12 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
}
if (tok == "`resetall") {
defines_map.clear();
defines_with_args.clear();
defines.clear();
global_defines_cache.clear();
continue;
}
if (try_expand_macro(defines_with_args, defines_map, tok))
if (try_expand_macro(defines, tok))
continue;
output_code.push_back(tok);

View file

@ -0,0 +1,77 @@
/*
* 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.
*
* ---
*
* The Verilog preprocessor.
*
*/
#ifndef VERILOG_PREPROC_H
#define VERILOG_PREPROC_H
#include "kernel/yosys.h"
#include <iosfwd>
#include <list>
#include <memory>
#include <string>
YOSYS_NAMESPACE_BEGIN
struct define_body_t;
struct arg_map_t;
struct define_map_t
{
define_map_t();
~ define_map_t();
// Add a definition, overwriting any existing definition for name.
void add(const std::string &name, const std::string &txt, const arg_map_t *args = nullptr);
// Merge in another map of definitions (which take precedence
// over anything currently defined).
void merge(const define_map_t &map);
// Find a definition by name. If no match, returns null.
const define_body_t *find(const std::string &name) const;
// Erase a definition by name (no effect if not defined).
void erase(const std::string &name);
// Clear any existing definitions
void clear();
// Print a list of definitions, using the log function
void log() const;
std::map<std::string, std::unique_ptr<define_body_t>> defines;
};
struct define_map_t;
std::string
frontend_verilog_preproc(std::istream &f,
std::string filename,
const define_map_t &pre_defines,
define_map_t &global_defines_cache,
const std::list<std::string> &include_dirs);
YOSYS_NAMESPACE_END
#endif

View file

@ -27,6 +27,7 @@
*/
#include "verilog_frontend.h"
#include "preproc.h"
#include "kernel/yosys.h"
#include "libs/sha1/sha1.h"
#include <stdarg.h>
@ -47,6 +48,23 @@ static void error_on_dpi_function(AST::AstNode *node)
error_on_dpi_function(child);
}
static void add_package_types(std::map<std::string, AST::AstNode *> &user_types, std::vector<AST::AstNode *> &package_list)
{
// prime the parser's user type lookup table with the package qualified names
// of typedefed names in the packages seen so far.
for (const auto &pkg : package_list) {
log_assert(pkg->type==AST::AST_PACKAGE);
for (const auto &node: pkg->children) {
if (node->type == AST::AST_TYPEDEF) {
std::string s = pkg->str + "::" + node->str.substr(1);
user_types[s] = node;
}
}
}
user_type_stack.clear();
user_type_stack.push_back(new UserTypeMap());
}
struct VerilogFrontend : public Frontend {
VerilogFrontend() : Frontend("verilog", "read modules from Verilog file") { }
void help() YS_OVERRIDE
@ -237,7 +255,8 @@ struct VerilogFrontend : public Frontend {
bool flag_defer = false;
bool flag_noblackbox = false;
bool flag_nowb = false;
std::map<std::string, std::string> defines_map;
define_map_t defines_map;
std::list<std::string> include_dirs;
std::list<std::string> attributes;
@ -353,7 +372,7 @@ struct VerilogFrontend : public Frontend {
}
if (arg == "-lib") {
lib_mode = true;
defines_map["BLACKBOX"] = string();
defines_map.add("BLACKBOX", "");
continue;
}
if (arg == "-nowb") {
@ -405,7 +424,7 @@ struct VerilogFrontend : public Frontend {
value = name.substr(equal+1);
name = name.substr(0, equal);
}
defines_map[name] = value;
defines_map.add(name, value);
continue;
}
if (arg.compare(0, 2, "-D") == 0) {
@ -414,7 +433,7 @@ struct VerilogFrontend : public Frontend {
std::string value;
if (equal != std::string::npos)
value = arg.substr(equal+1);
defines_map[name] = value;
defines_map.add(name, value);
continue;
}
if (arg == "-I" && argidx+1 < args.size()) {
@ -444,12 +463,15 @@ struct VerilogFrontend : public Frontend {
std::string code_after_preproc;
if (!flag_nopp) {
code_after_preproc = frontend_verilog_preproc(*f, filename, defines_map, design->verilog_defines, include_dirs);
code_after_preproc = frontend_verilog_preproc(*f, filename, defines_map, *design->verilog_defines, include_dirs);
if (flag_ppdump)
log("-- Verilog code after preprocessor --\n%s-- END OF DUMP --\n", code_after_preproc.c_str());
lexin = new std::istringstream(code_after_preproc);
}
// make package typedefs available to parser
add_package_types(pkg_user_types, design->verilog_packages);
frontend_verilog_yyset_lineno(1);
frontend_verilog_yyrestart(NULL);
frontend_verilog_yyparse();
@ -468,6 +490,7 @@ struct VerilogFrontend : public Frontend {
AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_vlog1, flag_dump_vlog2, flag_dump_rtlil, flag_nolatches,
flag_nomeminit, flag_nomem2reg, flag_mem2reg, flag_noblackbox, lib_mode, flag_nowb, flag_noopt, flag_icells, flag_pwires, flag_nooverwrite, flag_overwrite, flag_defer, default_nettype_wire);
if (!flag_nopp)
delete lexin;
@ -572,7 +595,7 @@ struct VerilogDefines : public Pass {
value = name.substr(equal+1);
name = name.substr(0, equal);
}
design->verilog_defines[name] = std::pair<std::string, bool>(value, false);
design->verilog_defines->add(name, value);
continue;
}
if (arg.compare(0, 2, "-D") == 0) {
@ -581,27 +604,25 @@ struct VerilogDefines : public Pass {
std::string value;
if (equal != std::string::npos)
value = arg.substr(equal+1);
design->verilog_defines[name] = std::pair<std::string, bool>(value, false);
design->verilog_defines->add(name, value);
continue;
}
if (arg == "-U" && argidx+1 < args.size()) {
std::string name = args[++argidx];
design->verilog_defines.erase(name);
design->verilog_defines->erase(name);
continue;
}
if (arg.compare(0, 2, "-U") == 0) {
std::string name = arg.substr(2);
design->verilog_defines.erase(name);
design->verilog_defines->erase(name);
continue;
}
if (arg == "-reset") {
design->verilog_defines.clear();
design->verilog_defines->clear();
continue;
}
if (arg == "-list") {
for (auto &it : design->verilog_defines) {
log("`define %s%s %s\n", it.first.c_str(), it.second.second ? "()" : "", it.second.first.c_str());
}
design->verilog_defines->log();
continue;
}
break;

View file

@ -45,6 +45,13 @@ namespace VERILOG_FRONTEND
// this function converts a Verilog constant to an AST_CONSTANT node
AST::AstNode *const2ast(std::string code, char case_type = 0, bool warn_z = false);
// names of locally typedef'ed types in a stack
typedef std::map<std::string, AST::AstNode*> UserTypeMap;
extern std::vector<UserTypeMap *> user_type_stack;
// names of package typedef'ed types
extern std::map<std::string, AST::AstNode*> pkg_user_types;
// state of `default_nettype
extern bool default_nettype_wire;
@ -79,10 +86,6 @@ namespace VERILOG_FRONTEND
extern std::istream *lexin;
}
// the pre-processor
std::string frontend_verilog_preproc(std::istream &f, std::string filename, const std::map<std::string, std::string> &pre_defines_map,
dict<std::string, std::pair<std::string, bool>> &global_defines_cache, const std::list<std::string> &include_dirs);
YOSYS_NAMESPACE_END
// the usual bison/flex stuff

View file

@ -99,6 +99,18 @@ YYLTYPE old_location;
#define YY_BUF_SIZE 65536
extern int frontend_verilog_yylex(YYSTYPE *yylval_param, YYLTYPE *yyloc_param);
static bool isUserType(std::string &s)
{
// check current scope then outer scopes for a name
for (auto it = user_type_stack.rbegin(); it != user_type_stack.rend(); ++it) {
if ((*it)->count(s) > 0) {
return true;
}
}
return false;
}
%}
%option yylineno
@ -372,9 +384,34 @@ supply1 { return TOK_SUPPLY1; }
"$signed" { return TOK_TO_SIGNED; }
"$unsigned" { return TOK_TO_UNSIGNED; }
[a-zA-Z_][a-zA-Z0-9_]*::[a-zA-Z_$][a-zA-Z0-9_$]* {
// package qualifier
auto s = std::string("\\") + yytext;
if (pkg_user_types.count(s) > 0) {
// package qualified typedefed name
yylval->string = new std::string(s);
return TOK_PKG_USER_TYPE;
}
else {
// backup before :: just return first part
size_t len = strchr(yytext, ':') - yytext;
yyless(len);
yylval->string = new std::string(std::string("\\") + yytext);
return TOK_ID;
}
}
[a-zA-Z_$][a-zA-Z0-9_$]* {
yylval->string = new std::string(std::string("\\") + yytext);
return TOK_ID;
auto s = std::string("\\") + yytext;
if (isUserType(s)) {
// previously typedefed name
yylval->string = new std::string(s);
return TOK_USER_TYPE;
}
else {
yylval->string = new std::string(std::string("\\") + yytext);
return TOK_ID;
}
}
[a-zA-Z_$][a-zA-Z0-9_$\.]* {

View file

@ -54,6 +54,8 @@ namespace VERILOG_FRONTEND {
std::map<std::string, AstNode*> *attr_list, default_attr_list;
std::stack<std::map<std::string, AstNode*> *> attr_list_stack;
std::map<std::string, AstNode*> *albuf;
std::vector<UserTypeMap*> user_type_stack;
std::map<std::string, AstNode*> pkg_user_types;
std::vector<AstNode*> ast_stack;
struct AstNode *astbuf1, *astbuf2, *astbuf3;
struct AstNode *current_function_or_task;
@ -125,6 +127,40 @@ struct specify_rise_fall {
specify_triple fall;
};
static void addTypedefNode(std::string *name, AstNode *node)
{
log_assert(node);
auto *tnode = new AstNode(AST_TYPEDEF, node);
tnode->str = *name;
auto user_types = user_type_stack.back();
(*user_types)[*name] = tnode;
if (current_ast_mod && current_ast_mod->type == AST_PACKAGE) {
// typedef inside a package so we need the qualified name
auto qname = current_ast_mod->str + "::" + (*name).substr(1);
pkg_user_types[qname] = tnode;
}
delete name;
ast_stack.back()->children.push_back(tnode);
}
static void enterTypeScope()
{
auto user_types = new UserTypeMap();
user_type_stack.push_back(user_types);
}
static void exitTypeScope()
{
user_type_stack.pop_back();
}
static bool isInLocalScope(const std::string *name)
{
// tests if a name was declared in the current block scope
auto user_types = user_type_stack.back();
return (user_types->count(*name) > 0);
}
static AstNode *makeRange(int msb = 31, int lsb = 0, bool isSigned = true)
{
auto range = new AstNode(AST_RANGE);
@ -167,6 +203,7 @@ static void addRange(AstNode *parent, int msb = 31, int lsb = 0, bool isSigned =
%token <string> TOK_STRING TOK_ID TOK_CONSTVAL TOK_REALVAL TOK_PRIMITIVE
%token <string> TOK_SVA_LABEL TOK_SPECIFY_OPER TOK_MSG_TASKS
%token <string> TOK_BASE TOK_BASED_CONSTVAL TOK_UNBASED_UNSIZED_CONSTVAL
%token <string> TOK_USER_TYPE TOK_PKG_USER_TYPE
%token TOK_ASSERT TOK_ASSUME TOK_RESTRICT TOK_COVER TOK_FINAL
%token ATTR_BEGIN ATTR_END DEFATTR_BEGIN DEFATTR_END
%token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM
@ -190,6 +227,7 @@ static void addRange(AstNode *parent, int msb = 31, int lsb = 0, bool isSigned =
%type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int
%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list
%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id integral_number
%type <string> type_name
%type <ast> opt_enum_init
%type <boolean> opt_signed opt_property unique_case_attr always_comb_or_latch always_or_always_ff
%type <al> attr case_attr
@ -330,10 +368,15 @@ hierarchical_id:
};
hierarchical_type_id:
'(' hierarchical_id ')' { $$ = $2; };
TOK_USER_TYPE
| TOK_PKG_USER_TYPE // package qualified type name
| '(' TOK_USER_TYPE ')' { $$ = $2; } // non-standard grammar
;
module:
attr TOK_MODULE TOK_ID {
attr TOK_MODULE {
enterTypeScope();
} TOK_ID {
do_not_require_port_stubs = false;
AstNode *mod = new AstNode(AST_MODULE);
ast_stack.back()->children.push_back(mod);
@ -341,9 +384,9 @@ module:
current_ast_mod = mod;
port_stubs.clear();
port_counter = 0;
mod->str = *$3;
mod->str = *$4;
append_attr(mod, $1);
delete $3;
delete $4;
} module_para_opt module_args_opt ';' module_body TOK_ENDMODULE {
if (port_stubs.size() != 0)
frontend_verilog_yyerror("Missing details for module port `%s'.",
@ -352,6 +395,7 @@ module:
ast_stack.pop_back();
log_assert(ast_stack.size() == 1);
current_ast_mod = NULL;
exitTypeScope();
};
module_para_opt:
@ -392,9 +436,9 @@ module_arg_opt_assignment:
wire->str = ast_stack.back()->children.back()->str;
if (ast_stack.back()->children.back()->is_input) {
AstNode *n = ast_stack.back()->children.back();
if (n->attributes.count("\\defaultvalue"))
delete n->attributes.at("\\defaultvalue");
n->attributes["\\defaultvalue"] = $2;
if (n->attributes.count(ID::defaultvalue))
delete n->attributes.at(ID::defaultvalue);
n->attributes[ID::defaultvalue] = $2;
} else
if (ast_stack.back()->children.back()->is_reg || ast_stack.back()->children.back()->is_logic)
ast_stack.back()->children.push_back(new AstNode(AST_INITIAL, new AstNode(AST_BLOCK, new AstNode(AST_ASSIGN_LE, wire, $2))));
@ -455,16 +499,19 @@ module_arg:
};
package:
attr TOK_PACKAGE TOK_ID {
attr TOK_PACKAGE {
enterTypeScope();
} TOK_ID {
AstNode *mod = new AstNode(AST_PACKAGE);
ast_stack.back()->children.push_back(mod);
ast_stack.push_back(mod);
current_ast_mod = mod;
mod->str = *$3;
mod->str = *$4;
append_attr(mod, $1);
} ';' package_body TOK_ENDPACKAGE {
ast_stack.pop_back();
current_ast_mod = NULL;
exitTypeScope();
};
package_body:
@ -477,7 +524,9 @@ package_body_stmt:
localparam_decl;
interface:
TOK_INTERFACE TOK_ID {
TOK_INTERFACE {
enterTypeScope();
} TOK_ID {
do_not_require_port_stubs = false;
AstNode *intf = new AstNode(AST_INTERFACE);
ast_stack.back()->children.push_back(intf);
@ -485,8 +534,8 @@ interface:
current_ast_mod = intf;
port_stubs.clear();
port_counter = 0;
intf->str = *$2;
delete $2;
intf->str = *$3;
delete $3;
} module_para_opt module_args_opt ';' interface_body TOK_ENDINTERFACE {
if (port_stubs.size() != 0)
frontend_verilog_yyerror("Missing details for module port `%s'.",
@ -494,6 +543,7 @@ interface:
ast_stack.pop_back();
log_assert(ast_stack.size() == 1);
current_ast_mod = NULL;
exitTypeScope();
};
interface_body:
@ -1461,24 +1511,24 @@ wire_name_and_opt_assign:
bool attr_anyseq = false;
bool attr_allconst = false;
bool attr_allseq = false;
if (ast_stack.back()->children.back()->get_bool_attribute("\\anyconst")) {
delete ast_stack.back()->children.back()->attributes.at("\\anyconst");
ast_stack.back()->children.back()->attributes.erase("\\anyconst");
if (ast_stack.back()->children.back()->get_bool_attribute(ID::anyconst)) {
delete ast_stack.back()->children.back()->attributes.at(ID::anyconst);
ast_stack.back()->children.back()->attributes.erase(ID::anyconst);
attr_anyconst = true;
}
if (ast_stack.back()->children.back()->get_bool_attribute("\\anyseq")) {
delete ast_stack.back()->children.back()->attributes.at("\\anyseq");
ast_stack.back()->children.back()->attributes.erase("\\anyseq");
if (ast_stack.back()->children.back()->get_bool_attribute(ID::anyseq)) {
delete ast_stack.back()->children.back()->attributes.at(ID::anyseq);
ast_stack.back()->children.back()->attributes.erase(ID::anyseq);
attr_anyseq = true;
}
if (ast_stack.back()->children.back()->get_bool_attribute("\\allconst")) {
delete ast_stack.back()->children.back()->attributes.at("\\allconst");
ast_stack.back()->children.back()->attributes.erase("\\allconst");
if (ast_stack.back()->children.back()->get_bool_attribute(ID::allconst)) {
delete ast_stack.back()->children.back()->attributes.at(ID::allconst);
ast_stack.back()->children.back()->attributes.erase(ID::allconst);
attr_allconst = true;
}
if (ast_stack.back()->children.back()->get_bool_attribute("\\allseq")) {
delete ast_stack.back()->children.back()->attributes.at("\\allseq");
ast_stack.back()->children.back()->attributes.erase("\\allseq");
if (ast_stack.back()->children.back()->get_bool_attribute(ID::allseq)) {
delete ast_stack.back()->children.back()->attributes.at(ID::allseq);
ast_stack.back()->children.back()->attributes.erase(ID::allseq);
attr_allseq = true;
}
if (current_wire_rand || attr_anyconst || attr_anyseq || attr_allconst || attr_allseq) {
@ -1494,7 +1544,7 @@ wire_name_and_opt_assign:
fcall->str = "\\$allconst";
if (attr_allseq)
fcall->str = "\\$allseq";
fcall->attributes["\\reg"] = AstNode::mkconst_str(RTLIL::unescape_id(wire->str));
fcall->attributes[ID::reg] = AstNode::mkconst_str(RTLIL::unescape_id(wire->str));
ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, wire, fcall));
}
} |
@ -1502,9 +1552,9 @@ wire_name_and_opt_assign:
AstNode *wire = new AstNode(AST_IDENTIFIER);
wire->str = ast_stack.back()->children.back()->str;
if (astbuf1->is_input) {
if (astbuf1->attributes.count("\\defaultvalue"))
delete astbuf1->attributes.at("\\defaultvalue");
astbuf1->attributes["\\defaultvalue"] = $3;
if (astbuf1->attributes.count(ID::defaultvalue))
delete astbuf1->attributes.at(ID::defaultvalue);
astbuf1->attributes[ID::defaultvalue] = $3;
}
else if (astbuf1->is_reg || astbuf1->is_logic){
AstNode *assign = new AstNode(AST_ASSIGN_LE, wire, $3);
@ -1591,8 +1641,12 @@ assign_expr:
ast_stack.back()->children.push_back(node);
};
type_name: TOK_ID // first time seen
| TOK_USER_TYPE { if (isInLocalScope($1)) frontend_verilog_yyerror("Duplicate declaration of TYPEDEF '%s'", $1->c_str()+1); }
;
typedef_decl:
TOK_TYPEDEF wire_type range TOK_ID range_or_multirange ';' {
TOK_TYPEDEF wire_type range type_name range_or_multirange ';' {
astbuf1 = $2;
astbuf2 = $3;
if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) {
@ -1625,13 +1679,10 @@ typedef_decl:
}
astbuf1->children.push_back(rangeNode);
}
ast_stack.back()->children.push_back(new AstNode(AST_TYPEDEF, astbuf1));
ast_stack.back()->children.back()->str = *$4;
addTypedefNode($4, astbuf1);
} |
TOK_TYPEDEF enum_type TOK_ID ';' {
ast_stack.back()->children.push_back(new AstNode(AST_TYPEDEF, astbuf1));
ast_stack.back()->children.back()->str = *$3;
TOK_TYPEDEF enum_type type_name ';' {
addTypedefNode($3, astbuf1);
}
;
@ -1788,7 +1839,7 @@ cell_port:
attr TOK_WILDCARD_CONNECT {
if (!sv_mode)
frontend_verilog_yyerror("Wildcard port connections are only supported in SystemVerilog mode.");
astbuf2->attributes[ID(wildcard_port_conns)] = AstNode::mkconst_int(1, false);
astbuf2->attributes[ID::wildcard_port_conns] = AstNode::mkconst_int(1, false);
};
always_comb_or_latch:
@ -1812,7 +1863,7 @@ always_stmt:
AstNode *node = new AstNode(AST_ALWAYS);
append_attr(node, $1);
if ($2)
node->attributes[ID(always_ff)] = AstNode::mkconst_int(1, false);
node->attributes[ID::always_ff] = AstNode::mkconst_int(1, false);
ast_stack.back()->children.push_back(node);
ast_stack.push_back(node);
} always_cond {
@ -1832,9 +1883,9 @@ always_stmt:
AstNode *node = new AstNode(AST_ALWAYS);
append_attr(node, $1);
if ($2)
node->attributes[ID(always_latch)] = AstNode::mkconst_int(1, false);
node->attributes[ID::always_latch] = AstNode::mkconst_int(1, false);
else
node->attributes[ID(always_comb)] = AstNode::mkconst_int(1, false);
node->attributes[ID::always_comb] = AstNode::mkconst_int(1, false);
ast_stack.back()->children.push_back(node);
ast_stack.push_back(node);
AstNode *block = new AstNode(AST_BLOCK);
@ -1955,6 +2006,7 @@ assert:
delete $5;
} else {
AstNode *node = new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $5);
SET_AST_NODE_LOC(node, @1, @6);
if ($1 != nullptr)
node->str = *$1;
ast_stack.back()->children.push_back(node);
@ -1967,6 +2019,7 @@ assert:
delete $5;
} else {
AstNode *node = new AstNode(assert_assumes_mode ? AST_ASSERT : AST_ASSUME, $5);
SET_AST_NODE_LOC(node, @1, @6);
if ($1 != nullptr)
node->str = *$1;
ast_stack.back()->children.push_back(node);
@ -1979,6 +2032,7 @@ assert:
delete $6;
} else {
AstNode *node = new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $6);
SET_AST_NODE_LOC(node, @1, @7);
if ($1 != nullptr)
node->str = *$1;
ast_stack.back()->children.push_back(node);
@ -1991,6 +2045,7 @@ assert:
delete $6;
} else {
AstNode *node = new AstNode(assert_assumes_mode ? AST_LIVE : AST_FAIR, $6);
SET_AST_NODE_LOC(node, @1, @7);
if ($1 != nullptr)
node->str = *$1;
ast_stack.back()->children.push_back(node);
@ -2000,6 +2055,7 @@ assert:
} |
opt_sva_label TOK_COVER opt_property '(' expr ')' ';' {
AstNode *node = new AstNode(AST_COVER, $5);
SET_AST_NODE_LOC(node, @1, @6);
if ($1 != nullptr) {
node->str = *$1;
delete $1;
@ -2008,6 +2064,7 @@ assert:
} |
opt_sva_label TOK_COVER opt_property '(' ')' ';' {
AstNode *node = new AstNode(AST_COVER, AstNode::mkconst_int(1, false));
SET_AST_NODE_LOC(node, @1, @5);
if ($1 != nullptr) {
node->str = *$1;
delete $1;
@ -2016,6 +2073,7 @@ assert:
} |
opt_sva_label TOK_COVER ';' {
AstNode *node = new AstNode(AST_COVER, AstNode::mkconst_int(1, false));
SET_AST_NODE_LOC(node, @1, @2);
if ($1 != nullptr) {
node->str = *$1;
delete $1;
@ -2027,6 +2085,7 @@ assert:
delete $5;
} else {
AstNode *node = new AstNode(AST_ASSUME, $5);
SET_AST_NODE_LOC(node, @1, @6);
if ($1 != nullptr)
node->str = *$1;
ast_stack.back()->children.push_back(node);
@ -2041,6 +2100,7 @@ assert:
delete $6;
} else {
AstNode *node = new AstNode(AST_FAIR, $6);
SET_AST_NODE_LOC(node, @1, @7);
if ($1 != nullptr)
node->str = *$1;
ast_stack.back()->children.push_back(node);
@ -2053,35 +2113,45 @@ assert:
assert_property:
opt_sva_label TOK_ASSERT TOK_PROPERTY '(' expr ')' ';' {
ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $5));
AstNode *node = new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $5);
SET_AST_NODE_LOC(node, @1, @6);
ast_stack.back()->children.push_back(node);
if ($1 != nullptr) {
ast_stack.back()->children.back()->str = *$1;
delete $1;
}
} |
opt_sva_label TOK_ASSUME TOK_PROPERTY '(' expr ')' ';' {
ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $5));
AstNode *node = new AstNode(AST_ASSUME, $5);
SET_AST_NODE_LOC(node, @1, @6);
ast_stack.back()->children.push_back(node);
if ($1 != nullptr) {
ast_stack.back()->children.back()->str = *$1;
delete $1;
}
} |
opt_sva_label TOK_ASSERT TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' {
ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $6));
AstNode *node = new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $6);
SET_AST_NODE_LOC(node, @1, @7);
ast_stack.back()->children.push_back(node);
if ($1 != nullptr) {
ast_stack.back()->children.back()->str = *$1;
delete $1;
}
} |
opt_sva_label TOK_ASSUME TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' {
ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $6));
AstNode *node = new AstNode(AST_FAIR, $6);
SET_AST_NODE_LOC(node, @1, @7);
ast_stack.back()->children.push_back(node);
if ($1 != nullptr) {
ast_stack.back()->children.back()->str = *$1;
delete $1;
}
} |
opt_sva_label TOK_COVER TOK_PROPERTY '(' expr ')' ';' {
ast_stack.back()->children.push_back(new AstNode(AST_COVER, $5));
AstNode *node = new AstNode(AST_COVER, $5);
SET_AST_NODE_LOC(node, @1, @6);
ast_stack.back()->children.push_back(node);
if ($1 != nullptr) {
ast_stack.back()->children.back()->str = *$1;
delete $1;
@ -2091,7 +2161,9 @@ assert_property:
if (norestrict_mode) {
delete $5;
} else {
ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $5));
AstNode *node = new AstNode(AST_ASSUME, $5);
SET_AST_NODE_LOC(node, @1, @6);
ast_stack.back()->children.push_back(node);
if ($1 != nullptr) {
ast_stack.back()->children.back()->str = *$1;
delete $1;
@ -2102,7 +2174,9 @@ assert_property:
if (norestrict_mode) {
delete $6;
} else {
ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $6));
AstNode *node = new AstNode(AST_FAIR, $6);
SET_AST_NODE_LOC(node, @1, @7);
ast_stack.back()->children.push_back(node);
if ($1 != nullptr) {
ast_stack.back()->children.back()->str = *$1;
delete $1;
@ -2157,20 +2231,21 @@ behavioral_stmt:
} opt_arg_list ';'{
ast_stack.pop_back();
} |
attr TOK_BEGIN opt_label {
attr TOK_BEGIN {
enterTypeScope();
} opt_label {
AstNode *node = new AstNode(AST_BLOCK);
ast_stack.back()->children.push_back(node);
ast_stack.push_back(node);
append_attr(node, $1);
if ($3 != NULL)
node->str = *$3;
if ($4 != NULL)
node->str = *$4;
} behavioral_stmt_list TOK_END opt_label {
if ($3 != NULL && $7 != NULL && *$3 != *$7)
frontend_verilog_yyerror("Begin label (%s) and end label (%s) don't match.", $3->c_str()+1, $7->c_str()+1);
if ($3 != NULL)
delete $3;
if ($7 != NULL)
delete $7;
exitTypeScope();
if ($4 != NULL && $8 != NULL && *$4 != *$8)
frontend_verilog_yyerror("Begin label (%s) and end label (%s) don't match.", $4->c_str()+1, $8->c_str()+1);
delete $4;
delete $8;
ast_stack.pop_back();
} |
attr TOK_FOR '(' {
@ -2248,6 +2323,8 @@ behavioral_stmt:
ast_stack.pop_back();
};
;
unique_case_attr:
/* empty */ {
$$ = false;
@ -2278,12 +2355,12 @@ case_type:
opt_synopsys_attr:
opt_synopsys_attr TOK_SYNOPSYS_FULL_CASE {
if (ast_stack.back()->attributes.count("\\full_case") == 0)
ast_stack.back()->attributes["\\full_case"] = AstNode::mkconst_int(1, false);
if (ast_stack.back()->attributes.count(ID::full_case) == 0)
ast_stack.back()->attributes[ID::full_case] = AstNode::mkconst_int(1, false);
} |
opt_synopsys_attr TOK_SYNOPSYS_PARALLEL_CASE {
if (ast_stack.back()->attributes.count("\\parallel_case") == 0)
ast_stack.back()->attributes["\\parallel_case"] = AstNode::mkconst_int(1, false);
if (ast_stack.back()->attributes.count(ID::parallel_case) == 0)
ast_stack.back()->attributes[ID::parallel_case] = AstNode::mkconst_int(1, false);
} |
/* empty */;
@ -2445,6 +2522,7 @@ gen_stmt:
} simple_behavioral_stmt ';' expr {
ast_stack.back()->children.push_back($6);
} ';' simple_behavioral_stmt ')' gen_stmt_block {
SET_AST_NODE_LOC(ast_stack.back(), @1, @11);
ast_stack.pop_back();
} |
TOK_IF '(' expr ')' {
@ -2453,6 +2531,7 @@ gen_stmt:
ast_stack.push_back(node);
ast_stack.back()->children.push_back($3);
} gen_stmt_block opt_gen_else {
SET_AST_NODE_LOC(ast_stack.back(), @1, @7);
ast_stack.pop_back();
} |
case_type '(' expr ')' {
@ -2461,18 +2540,21 @@ gen_stmt:
ast_stack.push_back(node);
} gen_case_body TOK_ENDCASE {
case_type_stack.pop_back();
SET_AST_NODE_LOC(ast_stack.back(), @1, @7);
ast_stack.pop_back();
} |
TOK_BEGIN opt_label {
TOK_BEGIN {
enterTypeScope();
} opt_label {
AstNode *node = new AstNode(AST_GENBLOCK);
node->str = $2 ? *$2 : std::string();
node->str = $3 ? *$3 : std::string();
ast_stack.back()->children.push_back(node);
ast_stack.push_back(node);
} module_gen_body TOK_END opt_label {
if ($2 != NULL)
delete $2;
if ($6 != NULL)
delete $6;
exitTypeScope();
delete $3;
delete $7;
SET_AST_NODE_LOC(ast_stack.back(), @1, @7);
ast_stack.pop_back();
} |
TOK_MSG_TASKS {
@ -2482,6 +2564,7 @@ gen_stmt:
ast_stack.back()->children.push_back(node);
ast_stack.push_back(node);
} opt_arg_list ';'{
SET_AST_NODE_LOC(ast_stack.back(), @1, @3);
ast_stack.pop_back();
};
@ -2491,6 +2574,7 @@ gen_stmt_block:
ast_stack.back()->children.push_back(node);
ast_stack.push_back(node);
} gen_stmt_or_module_body_stmt {
SET_AST_NODE_LOC(ast_stack.back(), @2, @2);
ast_stack.pop_back();
};

View file

@ -268,9 +268,9 @@ Aig::Aig(Cell *cell)
cell->parameters.sort();
for (auto p : cell->parameters)
{
if (p.first == ID(A_WIDTH) && mkname_a_signed) {
if (p.first == ID::A_WIDTH && mkname_a_signed) {
name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U');
} else if (p.first == ID(B_WIDTH) && mkname_b_signed) {
} else if (p.first == ID::B_WIDTH && mkname_b_signed) {
name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U');
} else {
mkname_last = name;
@ -280,11 +280,11 @@ Aig::Aig(Cell *cell)
mkname_a_signed = false;
mkname_b_signed = false;
mkname_is_signed = false;
if (p.first == ID(A_SIGNED)) {
if (p.first == ID::A_SIGNED) {
mkname_a_signed = true;
mkname_is_signed = p.second.as_bool();
}
if (p.first == ID(B_SIGNED)) {
if (p.first == ID::B_SIGNED) {
mkname_b_signed = true;
mkname_is_signed = p.second.as_bool();
}
@ -320,7 +320,7 @@ Aig::Aig(Cell *cell)
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++) {
int A = mk.inport(ID::A, i);
int B = mk.inport(ID::B, i);
@ -390,8 +390,8 @@ Aig::Aig(Cell *cell)
int width = GetSize(cell->getPort(ID::Y));
vector<int> A = mk.inport_vec(ID::A, width);
vector<int> B = mk.inport_vec(ID::B, width);
int carry = mk.inport(ID(CI));
int binv = mk.inport(ID(BI));
int carry = mk.inport(ID::CI);
int binv = mk.inport(ID::BI);
for (auto &n : B)
n = mk.xor_gate(n, binv);
vector<int> X(width), CO(width);
@ -399,8 +399,8 @@ Aig::Aig(Cell *cell)
for (int i = 0; i < width; i++)
X[i] = mk.xor_gate(A[i], B[i]);
mk.outport_vec(Y, ID::Y);
mk.outport_vec(X, ID(X));
mk.outport_vec(CO, ID(CO));
mk.outport_vec(X, ID::X);
mk.outport_vec(CO, ID::CO);
goto optimize;
}
@ -422,7 +422,7 @@ Aig::Aig(Cell *cell)
{
int A = mk.inport(ID::A);
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);
mk.outport(Y, ID::Y);
goto optimize;
@ -432,7 +432,7 @@ Aig::Aig(Cell *cell)
{
int A = mk.inport(ID::A);
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);
mk.outport(Y, ID::Y);
goto optimize;
@ -442,8 +442,8 @@ Aig::Aig(Cell *cell)
{
int A = mk.inport(ID::A);
int B = mk.inport(ID::B);
int C = mk.inport(ID(C));
int D = mk.inport(ID(D));
int C = mk.inport(ID::C);
int D = mk.inport(ID::D);
int Y = mk.nor_gate(mk.and_gate(A, B), mk.and_gate(C, D));
mk.outport(Y, ID::Y);
goto optimize;
@ -453,8 +453,8 @@ Aig::Aig(Cell *cell)
{
int A = mk.inport(ID::A);
int B = mk.inport(ID::B);
int C = mk.inport(ID(C));
int D = mk.inport(ID(D));
int C = mk.inport(ID::C);
int D = mk.inport(ID::D);
int Y = mk.nand_gate(mk.or_gate(A, B), mk.or_gate(C, D));
mk.outport(Y, ID::Y);
goto optimize;

View file

@ -24,29 +24,25 @@ PRIVATE_NAMESPACE_BEGIN
void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
IdString A = ID::A, Y = ID::Y;
bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
int a_width = GetSize(cell->getPort(A));
int y_width = GetSize(cell->getPort(Y));
bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
int a_width = GetSize(cell->getPort(ID::A));
int y_width = GetSize(cell->getPort(ID::Y));
for (int i = 0; i < y_width; i++)
{
if (i < a_width)
db->add_edge(cell, A, i, Y, i, -1);
db->add_edge(cell, ID::A, i, ID::Y, i, -1);
else if (is_signed && a_width > 0)
db->add_edge(cell, A, a_width-1, Y, i, -1);
db->add_edge(cell, ID::A, a_width-1, ID::Y, i, -1);
}
}
void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
IdString A = ID::A, B = ID::B, Y = ID::Y;
bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
int a_width = GetSize(cell->getPort(A));
int b_width = GetSize(cell->getPort(B));
int y_width = GetSize(cell->getPort(Y));
bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
int a_width = GetSize(cell->getPort(ID::A));
int b_width = GetSize(cell->getPort(ID::B));
int y_width = GetSize(cell->getPort(ID::Y));
if (cell->type == ID($and) && !is_signed) {
if (a_width > b_width)
@ -58,41 +54,37 @@ void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
for (int i = 0; i < y_width; i++)
{
if (i < a_width)
db->add_edge(cell, A, i, Y, i, -1);
db->add_edge(cell, ID::A, i, ID::Y, i, -1);
else if (is_signed && a_width > 0)
db->add_edge(cell, A, a_width-1, Y, i, -1);
db->add_edge(cell, ID::A, a_width-1, ID::Y, i, -1);
if (i < b_width)
db->add_edge(cell, B, i, Y, i, -1);
db->add_edge(cell, ID::B, i, ID::Y, i, -1);
else if (is_signed && b_width > 0)
db->add_edge(cell, B, b_width-1, Y, i, -1);
db->add_edge(cell, ID::B, b_width-1, ID::Y, i, -1);
}
}
void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
IdString A = ID::A, Y = ID::Y;
bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
int a_width = GetSize(cell->getPort(A));
int y_width = GetSize(cell->getPort(Y));
bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
int a_width = GetSize(cell->getPort(ID::A));
int y_width = GetSize(cell->getPort(ID::Y));
if (is_signed && a_width == 1)
y_width = std::min(y_width, 1);
for (int i = 0; i < y_width; i++)
for (int k = 0; k <= i && k < a_width; k++)
db->add_edge(cell, A, k, Y, i, -1);
db->add_edge(cell, ID::A, k, ID::Y, i, -1);
}
void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
IdString A = ID::A, B = ID::B, Y = ID::Y;
bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
int a_width = GetSize(cell->getPort(A));
int b_width = GetSize(cell->getPort(B));
int y_width = GetSize(cell->getPort(Y));
bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
int a_width = GetSize(cell->getPort(ID::A));
int b_width = GetSize(cell->getPort(ID::B));
int y_width = GetSize(cell->getPort(ID::Y));
if (!is_signed && cell->type != ID($sub)) {
int ab_width = std::max(a_width, b_width);
@ -104,55 +96,49 @@ void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
for (int k = 0; k <= i; k++)
{
if (k < a_width)
db->add_edge(cell, A, k, Y, i, -1);
db->add_edge(cell, ID::A, k, ID::Y, i, -1);
if (k < b_width)
db->add_edge(cell, B, k, Y, i, -1);
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
}
}
}
void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
IdString A = ID::A, Y = ID::Y;
int a_width = GetSize(cell->getPort(A));
int a_width = GetSize(cell->getPort(ID::A));
for (int i = 0; i < a_width; i++)
db->add_edge(cell, A, i, Y, 0, -1);
db->add_edge(cell, ID::A, i, ID::Y, 0, -1);
}
void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
IdString A = ID::A, B = ID::B, Y = ID::Y;
int a_width = GetSize(cell->getPort(A));
int b_width = GetSize(cell->getPort(B));
int a_width = GetSize(cell->getPort(ID::A));
int b_width = GetSize(cell->getPort(ID::B));
for (int i = 0; i < a_width; i++)
db->add_edge(cell, A, i, Y, 0, -1);
db->add_edge(cell, ID::A, i, ID::Y, 0, -1);
for (int i = 0; i < b_width; i++)
db->add_edge(cell, B, i, Y, 0, -1);
db->add_edge(cell, ID::B, i, ID::Y, 0, -1);
}
void mux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
IdString A = ID::A, B = ID::B, S = ID(S), Y = ID::Y;
int a_width = GetSize(cell->getPort(A));
int b_width = GetSize(cell->getPort(B));
int s_width = GetSize(cell->getPort(S));
int a_width = GetSize(cell->getPort(ID::A));
int b_width = GetSize(cell->getPort(ID::B));
int s_width = GetSize(cell->getPort(ID::S));
for (int i = 0; i < a_width; i++)
{
db->add_edge(cell, A, i, Y, i, -1);
db->add_edge(cell, ID::A, i, ID::Y, i, -1);
for (int k = i; k < b_width; k += a_width)
db->add_edge(cell, B, k, Y, i, -1);
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
for (int k = 0; k < s_width; k++)
db->add_edge(cell, S, k, Y, i, -1);
db->add_edge(cell, ID::S, k, ID::Y, i, -1);
}
}

View file

@ -84,26 +84,22 @@ struct CellTypes
{
setup_internals_eval();
IdString A = ID::A, B = ID::B, EN = ID(EN), Y = ID::Y;
IdString SRC = ID(SRC), DST = ID(DST), DAT = ID(DAT);
IdString EN_SRC = ID(EN_SRC), EN_DST = ID(EN_DST);
setup_type(ID($tribuf), {ID::A, ID::EN}, {ID::Y}, true);
setup_type(ID($tribuf), {A, EN}, {Y}, true);
setup_type(ID($assert), {A, EN}, pool<RTLIL::IdString>(), true);
setup_type(ID($assume), {A, EN}, pool<RTLIL::IdString>(), true);
setup_type(ID($live), {A, EN}, pool<RTLIL::IdString>(), true);
setup_type(ID($fair), {A, EN}, pool<RTLIL::IdString>(), true);
setup_type(ID($cover), {A, EN}, pool<RTLIL::IdString>(), true);
setup_type(ID($initstate), pool<RTLIL::IdString>(), {Y}, true);
setup_type(ID($anyconst), pool<RTLIL::IdString>(), {Y}, true);
setup_type(ID($anyseq), pool<RTLIL::IdString>(), {Y}, true);
setup_type(ID($allconst), pool<RTLIL::IdString>(), {Y}, true);
setup_type(ID($allseq), pool<RTLIL::IdString>(), {Y}, true);
setup_type(ID($equiv), {A, B}, {Y}, true);
setup_type(ID($specify2), {EN, SRC, DST}, pool<RTLIL::IdString>(), true);
setup_type(ID($specify3), {EN, SRC, DST, DAT}, pool<RTLIL::IdString>(), true);
setup_type(ID($specrule), {EN_SRC, EN_DST, SRC, DST}, pool<RTLIL::IdString>(), true);
setup_type(ID($assert), {ID::A, ID::EN}, pool<RTLIL::IdString>(), true);
setup_type(ID($assume), {ID::A, ID::EN}, pool<RTLIL::IdString>(), true);
setup_type(ID($live), {ID::A, ID::EN}, pool<RTLIL::IdString>(), true);
setup_type(ID($fair), {ID::A, ID::EN}, pool<RTLIL::IdString>(), true);
setup_type(ID($cover), {ID::A, ID::EN}, pool<RTLIL::IdString>(), true);
setup_type(ID($initstate), pool<RTLIL::IdString>(), {ID::Y}, true);
setup_type(ID($anyconst), pool<RTLIL::IdString>(), {ID::Y}, true);
setup_type(ID($anyseq), pool<RTLIL::IdString>(), {ID::Y}, true);
setup_type(ID($allconst), pool<RTLIL::IdString>(), {ID::Y}, true);
setup_type(ID($allseq), pool<RTLIL::IdString>(), {ID::Y}, true);
setup_type(ID($equiv), {ID::A, ID::B}, {ID::Y}, true);
setup_type(ID($specify2), {ID::EN, ID::SRC, ID::DST}, pool<RTLIL::IdString>(), true);
setup_type(ID($specify3), {ID::EN, ID::SRC, ID::DST, ID::DAT}, pool<RTLIL::IdString>(), true);
setup_type(ID($specrule), {ID::EN_SRC, ID::EN_DST, ID::SRC, ID::DST}, pool<RTLIL::IdString>(), true);
}
void setup_internals_eval()
@ -121,134 +117,109 @@ struct CellTypes
ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow),
ID($logic_and), ID($logic_or), ID($concat), ID($macc)
};
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 BI = ID(BI), CI = ID(CI), CO = ID(CO), EN = ID(EN);
for (auto type : unary_ops)
setup_type(type, {A}, {Y}, true);
setup_type(type, {ID::A}, {ID::Y}, true);
for (auto type : binary_ops)
setup_type(type, {A, B}, {Y}, true);
setup_type(type, {ID::A, ID::B}, {ID::Y}, true);
for (auto type : std::vector<RTLIL::IdString>({ID($mux), ID($pmux)}))
setup_type(type, {A, B, S}, {Y}, true);
setup_type(type, {ID::A, ID::B, ID::S}, {ID::Y}, true);
setup_type(ID($lcu), {P, G, CI}, {CO}, true);
setup_type(ID($alu), {A, B, CI, BI}, {X, Y, CO}, true);
setup_type(ID($fa), {A, B, C}, {X, Y}, true);
setup_type(ID($lcu), {ID::P, ID::G, ID::CI}, {ID::CO}, true);
setup_type(ID($alu), {ID::A, ID::B, ID::CI, ID::BI}, {ID::X, ID::Y, ID::CO}, true);
setup_type(ID($fa), {ID::A, ID::B, ID::C}, {ID::X, ID::Y}, true);
}
void setup_internals_ff()
{
IdString SET = ID(SET), CLR = ID(CLR), CLK = ID(CLK), ARST = ID(ARST), EN = ID(EN);
IdString Q = ID(Q), D = ID(D);
setup_type(ID($sr), {SET, CLR}, {Q});
setup_type(ID($ff), {D}, {Q});
setup_type(ID($dff), {CLK, D}, {Q});
setup_type(ID($dffe), {CLK, EN, D}, {Q});
setup_type(ID($dffsr), {CLK, SET, CLR, D}, {Q});
setup_type(ID($adff), {CLK, ARST, D}, {Q});
setup_type(ID($dlatch), {EN, D}, {Q});
setup_type(ID($dlatchsr), {EN, SET, CLR, D}, {Q});
setup_type(ID($sr), {ID::SET, ID::CLR}, {ID::Q});
setup_type(ID($ff), {ID::D}, {ID::Q});
setup_type(ID($dff), {ID::CLK, ID::D}, {ID::Q});
setup_type(ID($dffe), {ID::CLK, ID::EN, ID::D}, {ID::Q});
setup_type(ID($dffsr), {ID::CLK, ID::SET, ID::CLR, ID::D}, {ID::Q});
setup_type(ID($adff), {ID::CLK, ID::ARST, ID::D}, {ID::Q});
setup_type(ID($dlatch), {ID::EN, ID::D}, {ID::Q});
setup_type(ID($dlatchsr), {ID::EN, ID::SET, ID::CLR, ID::D}, {ID::Q});
}
void setup_internals_mem()
{
setup_internals_ff();
IdString CLK = ID(CLK), ARST = ID(ARST), EN = ID(EN);
IdString ADDR = ID(ADDR), DATA = ID(DATA), RD_EN = ID(RD_EN);
IdString RD_CLK = ID(RD_CLK), RD_ADDR = ID(RD_ADDR), WR_CLK = ID(WR_CLK), WR_EN = ID(WR_EN);
IdString WR_ADDR = ID(WR_ADDR), WR_DATA = ID(WR_DATA), RD_DATA = ID(RD_DATA);
IdString CTRL_IN = ID(CTRL_IN), CTRL_OUT = ID(CTRL_OUT);
setup_type(ID($memrd), {ID::CLK, ID::EN, ID::ADDR}, {ID::DATA});
setup_type(ID($memwr), {ID::CLK, ID::EN, ID::ADDR, ID::DATA}, pool<RTLIL::IdString>());
setup_type(ID($meminit), {ID::ADDR, ID::DATA}, pool<RTLIL::IdString>());
setup_type(ID($mem), {ID::RD_CLK, ID::RD_EN, ID::RD_ADDR, ID::WR_CLK, ID::WR_EN, ID::WR_ADDR, ID::WR_DATA}, {ID::RD_DATA});
setup_type(ID($memrd), {CLK, EN, ADDR}, {DATA});
setup_type(ID($memwr), {CLK, EN, ADDR, DATA}, pool<RTLIL::IdString>());
setup_type(ID($meminit), {ADDR, DATA}, pool<RTLIL::IdString>());
setup_type(ID($mem), {RD_CLK, RD_EN, RD_ADDR, WR_CLK, WR_EN, WR_ADDR, WR_DATA}, {RD_DATA});
setup_type(ID($fsm), {CLK, ARST, CTRL_IN}, {CTRL_OUT});
setup_type(ID($fsm), {ID::CLK, ID::ARST, ID::CTRL_IN}, {ID::CTRL_OUT});
}
void setup_stdcells()
{
setup_stdcells_eval();
IdString A = ID::A, E = ID(E), Y = ID::Y;
setup_type(ID($_TBUF_), {A, E}, {Y}, true);
setup_type(ID($_TBUF_), {ID::A, ID::E}, {ID::Y}, true);
}
void setup_stdcells_eval()
{
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 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 S = ID(S), T = ID(T), U = ID(U), V = ID(V);
IdString Y = ID::Y;
setup_type(ID($_BUF_), {A}, {Y}, true);
setup_type(ID($_NOT_), {A}, {Y}, true);
setup_type(ID($_AND_), {A, B}, {Y}, true);
setup_type(ID($_NAND_), {A, B}, {Y}, true);
setup_type(ID($_OR_), {A, B}, {Y}, true);
setup_type(ID($_NOR_), {A, B}, {Y}, true);
setup_type(ID($_XOR_), {A, B}, {Y}, true);
setup_type(ID($_XNOR_), {A, B}, {Y}, true);
setup_type(ID($_ANDNOT_), {A, B}, {Y}, true);
setup_type(ID($_ORNOT_), {A, B}, {Y}, true);
setup_type(ID($_MUX_), {A, B, S}, {Y}, true);
setup_type(ID($_NMUX_), {A, B, S}, {Y}, true);
setup_type(ID($_MUX4_), {A, B, C, D, S, T}, {Y}, true);
setup_type(ID($_MUX8_), {A, B, C, D, E, F, G, H, S, T, U}, {Y}, true);
setup_type(ID($_MUX16_), {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V}, {Y}, true);
setup_type(ID($_AOI3_), {A, B, C}, {Y}, true);
setup_type(ID($_OAI3_), {A, B, C}, {Y}, true);
setup_type(ID($_AOI4_), {A, B, C, D}, {Y}, true);
setup_type(ID($_OAI4_), {A, B, C, D}, {Y}, true);
setup_type(ID($_BUF_), {ID::A}, {ID::Y}, true);
setup_type(ID($_NOT_), {ID::A}, {ID::Y}, true);
setup_type(ID($_AND_), {ID::A, ID::B}, {ID::Y}, true);
setup_type(ID($_NAND_), {ID::A, ID::B}, {ID::Y}, true);
setup_type(ID($_OR_), {ID::A, ID::B}, {ID::Y}, true);
setup_type(ID($_NOR_), {ID::A, ID::B}, {ID::Y}, true);
setup_type(ID($_XOR_), {ID::A, ID::B}, {ID::Y}, true);
setup_type(ID($_XNOR_), {ID::A, ID::B}, {ID::Y}, true);
setup_type(ID($_ANDNOT_), {ID::A, ID::B}, {ID::Y}, true);
setup_type(ID($_ORNOT_), {ID::A, ID::B}, {ID::Y}, true);
setup_type(ID($_MUX_), {ID::A, ID::B, ID::S}, {ID::Y}, true);
setup_type(ID($_NMUX_), {ID::A, ID::B, ID::S}, {ID::Y}, true);
setup_type(ID($_MUX4_), {ID::A, ID::B, ID::C, ID::D, ID::S, ID::T}, {ID::Y}, true);
setup_type(ID($_MUX8_), {ID::A, ID::B, ID::C, ID::D, ID::E, ID::F, ID::G, ID::H, ID::S, ID::T, ID::U}, {ID::Y}, true);
setup_type(ID($_MUX16_), {ID::A, ID::B, ID::C, ID::D, ID::E, ID::F, ID::G, ID::H, ID::I, ID::J, ID::K, ID::L, ID::M, ID::N, ID::O, ID::P, ID::S, ID::T, ID::U, ID::V}, {ID::Y}, true);
setup_type(ID($_AOI3_), {ID::A, ID::B, ID::C}, {ID::Y}, true);
setup_type(ID($_OAI3_), {ID::A, ID::B, ID::C}, {ID::Y}, true);
setup_type(ID($_AOI4_), {ID::A, ID::B, ID::C, ID::D}, {ID::Y}, true);
setup_type(ID($_OAI4_), {ID::A, ID::B, ID::C, ID::D}, {ID::Y}, true);
}
void setup_stdcells_mem()
{
IdString S = ID(S), R = ID(R), C = ID(C);
IdString D = ID(D), Q = ID(Q), E = ID(E);
std::vector<char> list_np = {'N', 'P'}, list_01 = {'0', '1'};
for (auto c1 : list_np)
for (auto c2 : list_np)
setup_type(stringf("$_SR_%c%c_", c1, c2), {S, R}, {Q});
setup_type(stringf("$_SR_%c%c_", c1, c2), {ID::S, ID::R}, {ID::Q});
setup_type(ID($_FF_), {D}, {Q});
setup_type(ID($_FF_), {ID::D}, {ID::Q});
for (auto c1 : list_np)
setup_type(stringf("$_DFF_%c_", c1), {C, D}, {Q});
setup_type(stringf("$_DFF_%c_", c1), {ID::C, ID::D}, {ID::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
setup_type(stringf("$_DFFE_%c%c_", c1, c2), {C, D, E}, {Q});
setup_type(stringf("$_DFFE_%c%c_", c1, c2), {ID::C, ID::D, ID::E}, {ID::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_01)
setup_type(stringf("$_DFF_%c%c%c_", c1, c2, c3), {C, R, D}, {Q});
setup_type(stringf("$_DFF_%c%c%c_", c1, c2, c3), {ID::C, ID::R, ID::D}, {ID::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_np)
setup_type(stringf("$_DFFSR_%c%c%c_", c1, c2, c3), {C, S, R, D}, {Q});
setup_type(stringf("$_DFFSR_%c%c%c_", c1, c2, c3), {ID::C, ID::S, ID::R, ID::D}, {ID::Q});
for (auto c1 : list_np)
setup_type(stringf("$_DLATCH_%c_", c1), {E, D}, {Q});
setup_type(stringf("$_DLATCH_%c_", c1), {ID::E, ID::D}, {ID::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_np)
setup_type(stringf("$_DLATCHSR_%c%c%c_", c1, c2, c3), {E, S, R, D}, {Q});
setup_type(stringf("$_DLATCHSR_%c%c%c_", c1, c2, c3), {ID::E, ID::S, ID::R, ID::D}, {ID::Q});
}
void clear()
@ -300,7 +271,7 @@ struct CellTypes
signed1 = false, signed2 = false;
}
#define HANDLE_CELL_TYPE(_t) if (type == "$" #_t) return const_ ## _t(arg1, arg2, signed1, signed2, result_len);
#define HANDLE_CELL_TYPE(_t) if (type == ID($##_t)) return const_ ## _t(arg1, arg2, signed1, signed2, result_len);
HANDLE_CELL_TYPE(not)
HANDLE_CELL_TYPE(and)
HANDLE_CELL_TYPE(or)
@ -371,8 +342,8 @@ struct CellTypes
{
if (cell->type == ID($slice)) {
RTLIL::Const ret;
int width = cell->parameters.at(ID(Y_WIDTH)).as_int();
int offset = cell->parameters.at(ID(OFFSET)).as_int();
int width = cell->parameters.at(ID::Y_WIDTH).as_int();
int offset = cell->parameters.at(ID::OFFSET).as_int();
ret.bits.insert(ret.bits.end(), arg1.bits.begin()+offset, arg1.bits.begin()+offset+width);
return ret;
}
@ -385,9 +356,9 @@ struct CellTypes
if (cell->type == ID($lut))
{
int width = cell->parameters.at(ID(WIDTH)).as_int();
int width = cell->parameters.at(ID::WIDTH).as_int();
std::vector<RTLIL::State> t = cell->parameters.at(ID(LUT)).bits;
std::vector<RTLIL::State> t = cell->parameters.at(ID::LUT).bits;
while (GetSize(t) < (1 << width))
t.push_back(State::S0);
t.resize(1 << width);
@ -411,9 +382,9 @@ struct CellTypes
if (cell->type == ID($sop))
{
int width = cell->parameters.at(ID(WIDTH)).as_int();
int depth = cell->parameters.at(ID(DEPTH)).as_int();
std::vector<RTLIL::State> t = cell->parameters.at(ID(TABLE)).bits;
int width = cell->parameters.at(ID::WIDTH).as_int();
int depth = cell->parameters.at(ID::DEPTH).as_int();
std::vector<RTLIL::State> t = cell->parameters.at(ID::TABLE).bits;
while (GetSize(t) < width*depth*2)
t.push_back(State::S0);
@ -447,9 +418,9 @@ struct CellTypes
return default_ret;
}
bool signed_a = cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters[ID(A_SIGNED)].as_bool();
bool signed_b = cell->parameters.count(ID(B_SIGNED)) > 0 && cell->parameters[ID(B_SIGNED)].as_bool();
int result_len = cell->parameters.count(ID(Y_WIDTH)) > 0 ? cell->parameters[ID(Y_WIDTH)].as_int() : -1;
bool signed_a = cell->parameters.count(ID::A_SIGNED) > 0 && cell->parameters[ID::A_SIGNED].as_bool();
bool signed_b = cell->parameters.count(ID::B_SIGNED) > 0 && cell->parameters[ID::B_SIGNED].as_bool();
int result_len = cell->parameters.count(ID::Y_WIDTH) > 0 ? cell->parameters[ID::Y_WIDTH].as_int() : -1;
return eval(cell->type, arg1, arg2, signed_a, signed_b, result_len, errp);
}

View file

@ -91,10 +91,10 @@ struct ConstEval
{
if (cell->type == ID($lcu))
{
RTLIL::SigSpec sig_p = cell->getPort(ID(P));
RTLIL::SigSpec sig_g = cell->getPort(ID(G));
RTLIL::SigSpec sig_ci = cell->getPort(ID(CI));
RTLIL::SigSpec sig_co = values_map(assign_map(cell->getPort(ID(CO))));
RTLIL::SigSpec sig_p = cell->getPort(ID::P);
RTLIL::SigSpec sig_g = cell->getPort(ID::G);
RTLIL::SigSpec sig_ci = cell->getPort(ID::CI);
RTLIL::SigSpec sig_co = values_map(assign_map(cell->getPort(ID::CO)));
if (sig_co.is_fully_const())
return true;
@ -133,8 +133,8 @@ struct ConstEval
if (sig_y.is_fully_const())
return true;
if (cell->hasPort(ID(S))) {
sig_s = cell->getPort(ID(S));
if (cell->hasPort(ID::S)) {
sig_s = cell->getPort(ID::S);
if (!eval(sig_s, undef, cell))
return false;
}
@ -200,8 +200,8 @@ struct ConstEval
}
else if (cell->type == ID($fa))
{
RTLIL::SigSpec sig_c = cell->getPort(ID(C));
RTLIL::SigSpec sig_x = cell->getPort(ID(X));
RTLIL::SigSpec sig_c = cell->getPort(ID::C);
RTLIL::SigSpec sig_x = cell->getPort(ID::X);
int width = GetSize(sig_c);
if (!eval(sig_a, undef, cell))
@ -229,11 +229,11 @@ struct ConstEval
}
else if (cell->type == ID($alu))
{
bool signed_a = cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters[ID(A_SIGNED)].as_bool();
bool signed_b = cell->parameters.count(ID(B_SIGNED)) > 0 && cell->parameters[ID(B_SIGNED)].as_bool();
bool signed_a = cell->parameters.count(ID::A_SIGNED) > 0 && cell->parameters[ID::A_SIGNED].as_bool();
bool signed_b = cell->parameters.count(ID::B_SIGNED) > 0 && cell->parameters[ID::B_SIGNED].as_bool();
RTLIL::SigSpec sig_ci = cell->getPort(ID(CI));
RTLIL::SigSpec sig_bi = cell->getPort(ID(BI));
RTLIL::SigSpec sig_ci = cell->getPort(ID::CI);
RTLIL::SigSpec sig_bi = cell->getPort(ID::BI);
if (!eval(sig_a, undef, cell))
return false;
@ -247,8 +247,8 @@ struct ConstEval
if (!eval(sig_bi, undef, cell))
return false;
RTLIL::SigSpec sig_x = cell->getPort(ID(X));
RTLIL::SigSpec sig_co = cell->getPort(ID(CO));
RTLIL::SigSpec sig_x = cell->getPort(ID::X);
RTLIL::SigSpec sig_co = cell->getPort(ID::CO);
bool any_input_undef = !(sig_a.is_fully_def() && sig_b.is_fully_def() && sig_ci.is_fully_def() && sig_bi.is_fully_def());
sig_a.extend_u0(GetSize(sig_y), signed_a);
@ -309,10 +309,10 @@ struct ConstEval
RTLIL::SigSpec sig_c, sig_d;
if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) {
if (cell->hasPort(ID(C)))
sig_c = cell->getPort(ID(C));
if (cell->hasPort(ID(D)))
sig_d = cell->getPort(ID(D));
if (cell->hasPort(ID::C))
sig_c = cell->getPort(ID::C);
if (cell->hasPort(ID::D))
sig_d = cell->getPort(ID::D);
}
if (sig_a.size() > 0 && !eval(sig_a, undef, cell))

213
kernel/constids.inc Normal file
View file

@ -0,0 +1,213 @@
X(A)
X(abc9_box)
X(abc9_box_id)
X(abc9_box_seq)
X(abc9_carry)
X(abc9_flop)
X(abc9_holes)
X(abc9_init)
X(abc9_lut)
X(abc9_mergeability)
X(abc9_scc)
X(abc9_scc_id)
X(abcgroup)
X(ABITS)
X(ADDR)
X(allconst)
X(allseq)
X(always_comb)
X(always_ff)
X(always_latch)
X(anyconst)
X(anyseq)
X(ARST)
X(ARST_POLARITY)
X(ARST_VALUE)
X(A_SIGNED)
X(A_WIDTH)
X(B)
X(BI)
X(blackbox)
X(B_SIGNED)
X(B_WIDTH)
X(C)
X(cells_not_processed)
X(CFG_ABITS)
X(CFG_DBITS)
X(CFG_INIT)
X(CI)
X(CLK)
X(clkbuf_driver)
X(clkbuf_inhibit)
X(clkbuf_inv)
X(clkbuf_sink)
X(CLK_ENABLE)
X(CLK_POLARITY)
X(CLR)
X(CLR_POLARITY)
X(CO)
X(CONFIG)
X(CONFIG_WIDTH)
X(CTRL_IN)
X(CTRL_IN_WIDTH)
X(CTRL_OUT)
X(CTRL_OUT_WIDTH)
X(D)
X(DAT)
X(DATA)
X(DAT_DST_PEN)
X(DAT_DST_POL)
X(defaultvalue)
X(DELAY)
X(DEPTH)
X(DST)
X(DST_EN)
X(DST_PEN)
X(DST_POL)
X(DST_WIDTH)
X(dynports)
X(E)
X(EDGE_EN)
X(EDGE_POL)
X(EN)
X(EN_DST)
X(EN_POLARITY)
X(EN_SRC)
X(equiv_merged)
X(equiv_region)
X(extract_order)
X(F)
X(fsm_encoding)
X(fsm_export)
X(FULL)
X(full_case)
X(G)
X(gclk)
X(gentb_clock)
X(gentb_constant)
X(gentb_skip)
X(H)
X(hdlname)
X(hierconn)
X(I)
X(INIT)
X(init)
X(initial_top)
X(interface_modport)
X(interfaces_replaced_in_module)
X(interface_type)
X(invertible_pin)
X(iopad_external_pin)
X(is_interface)
X(J)
X(K)
X(keep)
X(keep_hierarchy)
X(L)
X(lib_whitebox)
X(localparam)
X(LUT)
X(lut_keep)
X(M)
X(maximize)
X(mem2reg)
X(MEMID)
X(minimize)
X(module_not_derived)
X(N)
X(NAME)
X(noblackbox)
X(nolatches)
X(nomem2init)
X(nomem2reg)
X(nomeminit)
X(nosync)
X(O)
X(OFFSET)
X(onehot)
X(P)
X(parallel_case)
X(parameter)
X(PRIORITY)
X(Q)
X(qwp_position)
X(R)
X(RD_ADDR)
X(RD_CLK)
X(RD_CLK_ENABLE)
X(RD_CLK_POLARITY)
X(RD_DATA)
X(RD_EN)
X(RD_PORTS)
X(RD_TRANSPARENT)
X(reg)
X(S)
X(SET)
X(SET_POLARITY)
X(SIZE)
X(SRC)
X(src)
X(SRC_DST_PEN)
X(SRC_DST_POL)
X(SRC_EN)
X(SRC_PEN)
X(SRC_POL)
X(SRC_WIDTH)
X(STATE_BITS)
X(STATE_NUM)
X(STATE_NUM_LOG2)
X(STATE_RST)
X(STATE_TABLE)
X(submod)
X(S_WIDTH)
X(T)
X(TABLE)
X(techmap_autopurge)
X(_TECHMAP_BITS_CONNMAP_)
X(_TECHMAP_CELLTYPE_)
X(techmap_celltype)
X(techmap_maccmap)
X(_TECHMAP_REPLACE_)
X(techmap_simplemap)
X(_techmap_special_)
X(techmap_wrap)
X(T_FALL_MAX)
X(T_FALL_MIN)
X(T_FALL_TYP)
X(T_LIMIT)
X(T_LIMIT2)
X(T_LIMIT2_MAX)
X(T_LIMIT2_MIN)
X(T_LIMIT2_TYP)
X(T_LIMIT_MAX)
X(T_LIMIT_MIN)
X(T_LIMIT_TYP)
X(to_delete)
X(top)
X(TRANS_NUM)
X(TRANSPARENT)
X(TRANS_TABLE)
X(T_RISE_MAX)
X(T_RISE_MIN)
X(T_RISE_TYP)
X(TYPE)
X(U)
X(unique)
X(unused_bits)
X(V)
X(wand)
X(whitebox)
X(WIDTH)
X(wildcard_port_conns)
X(wor)
X(WORDS)
X(WR_ADDR)
X(WR_CLK)
X(WR_CLK_ENABLE)
X(WR_CLK_POLARITY)
X(WR_DATA)
X(WR_EN)
X(WR_PORTS)
X(X)
X(Y)
X(Y_WIDTH)

View file

@ -104,11 +104,11 @@ struct Macc
ports.clear();
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;
#ifndef NDEBUG
int config_width = cell->getParam(ID(CONFIG_WIDTH)).as_int();
int config_width = cell->getParam(ID::CONFIG_WIDTH).as_int();
log_assert(GetSize(config_bits) >= config_width);
#endif
@ -193,10 +193,10 @@ struct Macc
cell->setPort(ID::A, port_a);
cell->setPort(ID::B, bit_ports);
cell->setParam(ID(CONFIG), config_bits);
cell->setParam(ID(CONFIG_WIDTH), GetSize(config_bits));
cell->setParam(ID(A_WIDTH), GetSize(port_a));
cell->setParam(ID(B_WIDTH), GetSize(bit_ports));
cell->setParam(ID::CONFIG, config_bits);
cell->setParam(ID::CONFIG_WIDTH, GetSize(config_bits));
cell->setParam(ID::A_WIDTH, GetSize(port_a));
cell->setParam(ID::B_WIDTH, GetSize(bit_ports));
}
bool eval(RTLIL::Const &result) const

View file

@ -158,7 +158,7 @@ struct ModIndex : public RTLIL::Monitor
#endif
}
void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) YS_OVERRIDE
void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) YS_OVERRIDE
{
log_assert(module == cell->module);
@ -380,22 +380,15 @@ struct ModWalker
}
}
ModWalker() : design(NULL), module(NULL)
ModWalker(RTLIL::Design *design) : design(design), module(NULL)
{
ct.setup(design);
}
ModWalker(RTLIL::Design *design, RTLIL::Module *module, CellTypes *filter_ct = NULL)
void setup(RTLIL::Module *module, CellTypes *filter_ct = NULL)
{
setup(design, module, filter_ct);
}
void setup(RTLIL::Design *design, RTLIL::Module *module, CellTypes *filter_ct = NULL)
{
this->design = design;
this->module = module;
ct.clear();
ct.setup(design);
sigmap.set(module);
signal_drivers.clear();

File diff suppressed because it is too large Load diff

View file

@ -235,7 +235,10 @@ namespace RTLIL
return;
log_assert(refcount == 0);
free_reference(idx);
}
static inline void free_reference(int idx)
{
if (yosys_xtrace) {
log("#X# Removed IdString '%s' with index %d.\n", global_id_storage_.at(idx), idx);
log_backtrace("-X- ", yosys_xtrace-1);
@ -358,34 +361,35 @@ namespace RTLIL
// often one needs to check if a given IdString is part of a list (for example a list
// of cell types). the following functions helps with that.
template<typename T, typename... Args>
bool in(T first, Args... rest) const {
return in(first) || in(rest...);
template<typename... Args>
bool in(Args... args) const {
// Credit: https://articles.emptycrate.com/2016/05/14/folds_in_cpp11_ish.html
bool result = false;
(void) std::initializer_list<int>{ (result = result || in(args), 0)... };
return result;
}
bool in(IdString rhs) const { return *this == rhs; }
bool in(const IdString &rhs) const { return *this == rhs; }
bool in(const char *rhs) const { return *this == rhs; }
bool in(const std::string &rhs) const { return *this == rhs; }
bool in(const pool<IdString> &rhs) const { return rhs.count(*this) != 0; }
};
namespace ID {
// defined in rtlil.cc, initialized in yosys.cc
extern IdString A, B, Y;
extern IdString keep;
extern IdString whitebox;
extern IdString blackbox;
#define X(_id) extern IdString _id;
#include "constids.inc"
#undef X
};
extern dict<std::string, std::string> constpad;
static inline std::string escape_id(std::string str) {
static inline std::string escape_id(const std::string &str) {
if (str.size() > 0 && str[0] != '\\' && str[0] != '$')
return "\\" + str;
return str;
}
static inline std::string unescape_id(std::string str) {
static inline std::string unescape_id(const std::string &str) {
if (str.size() < 2)
return str;
if (str[0] != '\\')
@ -401,7 +405,7 @@ namespace RTLIL
return unescape_id(str.str());
}
static inline const char *id2cstr(const RTLIL::IdString &str) {
static inline const char *id2cstr(RTLIL::IdString str) {
return log_id(str);
}
@ -606,7 +610,7 @@ struct RTLIL::Const
bool as_bool() const;
int as_int(bool is_signed = false) const;
std::string as_string() const;
static Const from_string(std::string str);
static Const from_string(const std::string &str);
std::string decode_string() const;
@ -678,7 +682,7 @@ struct RTLIL::SigChunk
SigChunk(const std::string &str);
SigChunk(int val, int width = 32);
SigChunk(RTLIL::State bit, int width = 1);
SigChunk(RTLIL::SigBit bit);
SigChunk(const RTLIL::SigBit &bit);
SigChunk(const RTLIL::SigChunk &sigchunk);
RTLIL::SigChunk &operator =(const RTLIL::SigChunk &other) = default;
@ -758,11 +762,15 @@ private:
unpack();
}
// Only used by Module::remove(const pool<Wire*> &wires)
// but cannot be more specific as it isn't yet declared
friend struct RTLIL::Module;
public:
SigSpec();
SigSpec(const RTLIL::SigSpec &other);
SigSpec(std::initializer_list<RTLIL::SigSpec> parts);
const RTLIL::SigSpec &operator=(const RTLIL::SigSpec &other);
RTLIL::SigSpec &operator=(const RTLIL::SigSpec &other);
SigSpec(const RTLIL::Const &value);
SigSpec(const RTLIL::SigChunk &chunk);
@ -771,11 +779,11 @@ public:
SigSpec(const std::string &str);
SigSpec(int val, int width = 32);
SigSpec(RTLIL::State bit, int width = 1);
SigSpec(RTLIL::SigBit bit, int width = 1);
SigSpec(std::vector<RTLIL::SigChunk> chunks);
SigSpec(std::vector<RTLIL::SigBit> bits);
SigSpec(pool<RTLIL::SigBit> bits);
SigSpec(std::set<RTLIL::SigBit> bits);
SigSpec(const RTLIL::SigBit &bit, int width = 1);
SigSpec(const std::vector<RTLIL::SigChunk> &chunks);
SigSpec(const std::vector<RTLIL::SigBit> &bits);
SigSpec(const pool<RTLIL::SigBit> &bits);
SigSpec(const std::set<RTLIL::SigBit> &bits);
SigSpec(bool bit);
SigSpec(RTLIL::SigSpec &&other) {
@ -845,7 +853,13 @@ public:
RTLIL::SigSpec extract_end(int offset) const { return extract(offset, width_ - offset); }
void append(const RTLIL::SigSpec &signal);
void append_bit(const RTLIL::SigBit &bit);
inline void append(Wire *wire) { append(RTLIL::SigSpec(wire)); }
inline void append(const RTLIL::SigChunk &chunk) { append(RTLIL::SigSpec(chunk)); }
inline void append(const RTLIL::Const &const_) { append(RTLIL::SigSpec(const_)); }
void append(const RTLIL::SigBit &bit);
inline void append(RTLIL::State state) { append(RTLIL::SigBit(state)); }
inline void append(bool bool_) { append(RTLIL::SigBit(bool_)); }
void extend_u0(int width, bool is_signed = false);
@ -877,7 +891,7 @@ public:
RTLIL::SigChunk as_chunk() const;
RTLIL::SigBit as_bit() const;
bool match(std::string pattern) const;
bool match(const char* pattern) const;
std::set<RTLIL::SigBit> to_sigbit_set() const;
pool<RTLIL::SigBit> to_sigbit_pool() const;
@ -891,7 +905,7 @@ public:
operator std::vector<RTLIL::SigChunk>() const { return chunks(); }
operator std::vector<RTLIL::SigBit>() const { return bits(); }
RTLIL::SigBit at(int offset, const RTLIL::SigBit &defval) { return offset < width_ ? (*this)[offset] : defval; }
const RTLIL::SigBit &at(int offset, const RTLIL::SigBit &defval) { return offset < width_ ? (*this)[offset] : defval; }
unsigned int hash() const { if (!hash_) updhash(); return hash_; };
@ -946,12 +960,15 @@ struct RTLIL::Monitor
virtual ~Monitor() { }
virtual void notify_module_add(RTLIL::Module*) { }
virtual void notify_module_del(RTLIL::Module*) { }
virtual void notify_connect(RTLIL::Cell*, const RTLIL::IdString&, const RTLIL::SigSpec&, RTLIL::SigSpec&) { }
virtual void notify_connect(RTLIL::Cell*, const RTLIL::IdString&, const RTLIL::SigSpec&, const RTLIL::SigSpec&) { }
virtual void notify_connect(RTLIL::Module*, const RTLIL::SigSig&) { }
virtual void notify_connect(RTLIL::Module*, const std::vector<RTLIL::SigSig>&) { }
virtual void notify_blackout(RTLIL::Module*) { }
};
// Forward declaration; defined in preproc.h.
struct define_map_t;
struct RTLIL::Design
{
unsigned int hashidx_;
@ -963,7 +980,7 @@ struct RTLIL::Design
int refcount_modules_;
dict<RTLIL::IdString, RTLIL::Module*> modules_;
std::vector<AST::AstNode*> verilog_packages, verilog_globals;
dict<std::string, std::pair<std::string, bool>> verilog_defines;
std::unique_ptr<define_map_t> verilog_defines;
std::vector<RTLIL::Selection> selection_stack;
dict<RTLIL::IdString, RTLIL::Selection> selection_vars;
@ -985,15 +1002,15 @@ struct RTLIL::Design
void remove(RTLIL::Module *module);
void rename(RTLIL::Module *module, RTLIL::IdString new_name);
void scratchpad_unset(std::string varname);
void scratchpad_unset(const std::string &varname);
void scratchpad_set_int(std::string varname, int value);
void scratchpad_set_bool(std::string varname, bool value);
void scratchpad_set_string(std::string varname, std::string value);
void scratchpad_set_int(const std::string &varname, int value);
void scratchpad_set_bool(const std::string &varname, bool value);
void scratchpad_set_string(const std::string &varname, std::string value);
int scratchpad_get_int(std::string varname, int default_value = 0) const;
bool scratchpad_get_bool(std::string varname, bool default_value = false) const;
std::string scratchpad_get_string(std::string varname, std::string default_value = std::string()) const;
int scratchpad_get_int(const std::string &varname, int default_value = 0) const;
bool scratchpad_get_bool(const std::string &varname, bool default_value = false) const;
std::string scratchpad_get_string(const std::string &varname, const std::string &default_value = std::string()) const;
void sort();
void check();
@ -1069,10 +1086,10 @@ public:
Module();
virtual ~Module();
virtual RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail = false);
virtual RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail = false);
virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool mayfail = false);
virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail = false);
virtual size_t count_id(RTLIL::IdString id);
virtual void reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module *> local_interfaces);
virtual void reprocess_module(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces);
virtual void sort();
virtual void check();
@ -1133,166 +1150,166 @@ public:
// The add* methods create a cell and return the created cell. All signals must exist in advance.
RTLIL::Cell* addNot (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addPos (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addNeg (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addPos (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addNeg (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addXor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addXnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addXor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addXnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addReduceAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addReduceOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addReduceXor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addReduceXnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addReduceBool (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addReduceAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addReduceOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addReduceXor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addReduceXnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addReduceBool (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addShl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addShr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addSshl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addSshr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addShift (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addShiftx (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addShl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addShr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addSshl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addSshr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addShift (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addShiftx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addLt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addLe (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addEq (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addNe (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addEqx (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addNex (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addGe (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addGt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addLt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addLe (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addEq (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addNe (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addEqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addNex (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addGe (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addGt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addAdd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addSub (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addMul (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addDiv (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addMod (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addPow (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool a_signed = false, bool b_signed = false, const std::string &src = "");
RTLIL::Cell* addAdd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addSub (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addMul (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addDiv (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addMod (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addPow (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool a_signed = false, bool b_signed = false, const std::string &src = "");
RTLIL::Cell* addLogicNot (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addLogicAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addLogicOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addLogicNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addLogicAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addLogicOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addMux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y, const std::string &src = "");
RTLIL::Cell* addPmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y, const std::string &src = "");
RTLIL::Cell* addMux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addPmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addSlice (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const offset, const std::string &src = "");
RTLIL::Cell* addConcat (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src = "");
RTLIL::Cell* addLut (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const lut, const std::string &src = "");
RTLIL::Cell* addTribuf (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_y, const std::string &src = "");
RTLIL::Cell* addAssert (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src = "");
RTLIL::Cell* addAssume (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src = "");
RTLIL::Cell* addLive (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src = "");
RTLIL::Cell* addFair (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src = "");
RTLIL::Cell* addCover (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src = "");
RTLIL::Cell* addEquiv (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src = "");
RTLIL::Cell* addSlice (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const offset, const std::string &src = "");
RTLIL::Cell* addConcat (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addLut (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const lut, const std::string &src = "");
RTLIL::Cell* addTribuf (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addAssert (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
RTLIL::Cell* addAssume (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
RTLIL::Cell* addLive (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
RTLIL::Cell* addFair (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
RTLIL::Cell* addCover (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
RTLIL::Cell* addEquiv (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addSr (RTLIL::IdString name, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_q, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addFf (RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, const std::string &src = "");
RTLIL::Cell* addDff (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffe (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffsr (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addAdff (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q,
RTLIL::Cell* addSr (RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, const RTLIL::SigSpec &sig_q, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addFf (RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src = "");
RTLIL::Cell* addDff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addAdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
RTLIL::Const arst_value, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = "");
RTLIL::Cell* addDlatch (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, const std::string &src = "");
RTLIL::Cell* addDlatchsr (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addDlatch (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, const std::string &src = "");
RTLIL::Cell* addDlatchsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addBufGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addNotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addAndGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addNandGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addOrGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addNorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addXorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addXnorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addAndnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addOrnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addMuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addNmuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addAoi3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addOai3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addAoi4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addOai4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addBufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addNotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addAndGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addNandGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addOrGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addNorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addXorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addXnorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addAndnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addOrnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addMuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addNmuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addAoi3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addOai3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addAoi4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addOai4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addFfGate (RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, const std::string &src = "");
RTLIL::Cell* addDffGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffeGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffsrGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addAdffGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q,
RTLIL::Cell* addFfGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src = "");
RTLIL::Cell* addDffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffsrGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addAdffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool arst_value = false, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = "");
RTLIL::Cell* addDlatchGate (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, const std::string &src = "");
RTLIL::Cell* addDlatchsrGate (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addDlatchGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, const std::string &src = "");
RTLIL::Cell* addDlatchsrGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
// The methods without the add* prefix create a cell and an output signal. They return the newly created output signal.
RTLIL::SigSpec Not (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Pos (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Bu0 (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Neg (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Not (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Pos (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Bu0 (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Neg (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec And (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Or (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Xor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Xnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec And (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Or (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Xor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Xnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceXor (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceXnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceBool (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceXor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceXnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceBool (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Shl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Shr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Sshl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Sshr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Shift (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Shiftx (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Shl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Shr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Sshl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Sshr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Shift (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Shiftx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Lt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Le (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Eq (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Ne (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Eqx (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Nex (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Ge (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Gt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Lt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Le (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Eq (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Ne (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Eqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Nex (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Ge (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Gt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Add (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Sub (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Mul (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Div (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Mod (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Pow (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool a_signed = false, bool b_signed = false, const std::string &src = "");
RTLIL::SigSpec Add (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Sub (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Mul (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Div (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Mod (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Pow (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool a_signed = false, bool b_signed = false, const std::string &src = "");
RTLIL::SigSpec LogicNot (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec LogicAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec LogicOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec LogicNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec LogicAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec LogicOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Mux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, const std::string &src = "");
RTLIL::SigSpec Pmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, const std::string &src = "");
RTLIL::SigSpec Mux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const std::string &src = "");
RTLIL::SigSpec Pmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const std::string &src = "");
RTLIL::SigBit BufGate (RTLIL::IdString name, RTLIL::SigBit sig_a, const std::string &src = "");
RTLIL::SigBit NotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, const std::string &src = "");
RTLIL::SigBit AndGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
RTLIL::SigBit NandGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
RTLIL::SigBit OrGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
RTLIL::SigBit NorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
RTLIL::SigBit XorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
RTLIL::SigBit XnorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
RTLIL::SigBit AndnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
RTLIL::SigBit OrnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
RTLIL::SigBit MuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, const std::string &src = "");
RTLIL::SigBit NmuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, const std::string &src = "");
RTLIL::SigBit Aoi3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, const std::string &src = "");
RTLIL::SigBit Oai3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, const std::string &src = "");
RTLIL::SigBit Aoi4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, const std::string &src = "");
RTLIL::SigBit Oai4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, const std::string &src = "");
RTLIL::SigBit BufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const std::string &src = "");
RTLIL::SigBit NotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const std::string &src = "");
RTLIL::SigBit AndGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit NandGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit OrGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit NorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit XorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit XnorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit AndnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit OrnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit MuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const std::string &src = "");
RTLIL::SigBit NmuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const std::string &src = "");
RTLIL::SigBit Aoi3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const std::string &src = "");
RTLIL::SigBit Oai3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const std::string &src = "");
RTLIL::SigBit Aoi4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const std::string &src = "");
RTLIL::SigBit Oai4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const std::string &src = "");
RTLIL::SigSpec Anyconst (RTLIL::IdString name, int width = 1, const std::string &src = "");
RTLIL::SigSpec Anyseq (RTLIL::IdString name, int width = 1, const std::string &src = "");
@ -1465,7 +1482,7 @@ inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_as
inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire != nullptr); }
inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data[0]; }
inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data[index]; }
inline RTLIL::SigBit::SigBit(const RTLIL::SigBit &sigbit) : wire(sigbit.wire), data(sigbit.data){if(wire) offset = sigbit.offset;}
inline RTLIL::SigBit::SigBit(const RTLIL::SigBit &sigbit) : wire(sigbit.wire), data(sigbit.data){ if (wire) offset = sigbit.offset; }
inline bool RTLIL::SigBit::operator<(const RTLIL::SigBit &other) const {
if (wire == other.wire)

View file

@ -224,8 +224,8 @@ struct SatGen
void extendSignalWidth(std::vector<int> &vec_a, std::vector<int> &vec_b, RTLIL::Cell *cell, size_t y_width = 0, bool forced_signed = false)
{
bool is_signed = forced_signed;
if (!forced_signed && cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters.count(ID(B_SIGNED)) > 0)
is_signed = cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool();
if (!forced_signed && cell->parameters.count(ID::A_SIGNED) > 0 && cell->parameters.count(ID::B_SIGNED) > 0)
is_signed = cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool();
while (vec_a.size() < vec_b.size() || vec_a.size() < y_width)
vec_a.push_back(is_signed && vec_a.size() > 0 ? vec_a.back() : ez->CONST_FALSE);
while (vec_b.size() < vec_a.size() || vec_b.size() < y_width)
@ -241,7 +241,7 @@ struct SatGen
void extendSignalWidthUnary(std::vector<int> &vec_a, std::vector<int> &vec_y, RTLIL::Cell *cell, bool forced_signed = false)
{
bool is_signed = forced_signed || (cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters[ID(A_SIGNED)].as_bool());
bool is_signed = forced_signed || (cell->parameters.count(ID::A_SIGNED) > 0 && cell->parameters[ID::A_SIGNED].as_bool());
while (vec_a.size() < vec_y.size())
vec_a.push_back(is_signed && vec_a.size() > 0 ? vec_a.back() : ez->CONST_FALSE);
while (vec_y.size() < vec_a.size())
@ -397,8 +397,8 @@ struct SatGen
int a = importDefSigSpec(cell->getPort(ID::A), timestep).at(0);
int b = importDefSigSpec(cell->getPort(ID::B), 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 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 y = importDefSigSpec(cell->getPort(ID::Y), timestep).at(0);
int yy = model_undef ? ez->literal() : y;
@ -411,8 +411,8 @@ struct SatGen
{
int undef_a = importUndefSigSpec(cell->getPort(ID::A), 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_d = three_mode ? ez->CONST_FALSE : importUndefSigSpec(cell->getPort(ID(D)), 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_y = importUndefSigSpec(cell->getPort(ID::Y), timestep).at(0);
if (aoi_mode)
@ -479,7 +479,7 @@ struct SatGen
{
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), 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> yy = model_undef ? ez->vec_var(y.size()) : y;
@ -492,7 +492,7 @@ struct SatGen
{
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_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> unequal_ab = ez->vec_not(ez->vec_iff(a, b));
@ -508,7 +508,7 @@ struct SatGen
{
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), 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> yy = model_undef ? ez->vec_var(y.size()) : y;
@ -524,7 +524,7 @@ struct SatGen
{
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_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);
int maybe_a = ez->CONST_TRUE;
@ -684,7 +684,7 @@ struct SatGen
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> b = importDefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
@ -774,7 +774,7 @@ struct SatGen
int extend_bit = ez->CONST_FALSE;
if (!cell->type.in(ID($shift), ID($shiftx)) && cell->parameters[ID(A_SIGNED)].as_bool())
if (!cell->type.in(ID($shift), ID($shiftx)) && cell->parameters[ID::A_SIGNED].as_bool())
extend_bit = a.back();
while (y.size() < a.size())
@ -792,10 +792,10 @@ struct SatGen
shifted_a = ez->vec_shift_right(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE);
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.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));
@ -807,7 +807,7 @@ struct SatGen
std::vector<int> undef_a_shifted;
extend_bit = cell->type == ID($shiftx) ? ez->CONST_TRUE : ez->CONST_FALSE;
if (!cell->type.in(ID($shift), ID($shiftx)) && cell->parameters[ID(A_SIGNED)].as_bool())
if (!cell->type.in(ID($shift), ID($shiftx)) && cell->parameters[ID::A_SIGNED].as_bool())
extend_bit = undef_a.back();
while (undef_y.size() < undef_a.size())
@ -822,13 +822,13 @@ struct SatGen
undef_a_shifted = ez->vec_shift_right(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($sshr))
undef_a_shifted = ez->vec_shift_right(undef_a, b, false, cell->parameters[ID(A_SIGNED)].as_bool() ? undef_a.back() : ez->CONST_FALSE, ez->CONST_FALSE);
undef_a_shifted = ez->vec_shift_right(undef_a, b, false, cell->parameters[ID::A_SIGNED].as_bool() ? undef_a.back() : ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($shift))
undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID(B_SIGNED)].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE);
undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($shiftx))
undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID(B_SIGNED)].as_bool(), ez->CONST_TRUE, ez->CONST_TRUE);
undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_TRUE, ez->CONST_TRUE);
int undef_any_b = ez->expression(ezSAT::OpOr, undef_b);
std::vector<int> undef_all_y_bits(undef_y.size(), undef_any_b);
@ -945,7 +945,7 @@ struct SatGen
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
std::vector<int> a_u, b_u;
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()) {
a_u = ez->vec_ite(a.back(), ez->vec_neg(a), a);
b_u = ez->vec_ite(b.back(), ez->vec_neg(b), b);
} else {
@ -971,12 +971,12 @@ struct SatGen
std::vector<int> y_tmp = ignore_div_by_zero ? yy : ez->vec_var(y.size());
if (cell->type == ID($div)) {
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())
ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(ez->XOR(a.back(), b.back()), ez->vec_neg(y_u), y_u)));
else
ez->assume(ez->vec_eq(y_tmp, y_u));
} else {
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())
ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(a.back(), ez->vec_neg(chain_buf), chain_buf)));
else
ez->assume(ez->vec_eq(y_tmp, chain_buf));
@ -987,7 +987,7 @@ struct SatGen
} else {
std::vector<int> div_zero_result;
if (cell->type == ID($div)) {
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()) {
std::vector<int> all_ones(y.size(), ez->CONST_TRUE);
std::vector<int> only_first_one(y.size(), ez->CONST_FALSE);
only_first_one.at(0) = ez->CONST_TRUE;
@ -999,7 +999,7 @@ struct SatGen
} else {
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);
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());
else
div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE);
@ -1021,7 +1021,7 @@ struct SatGen
std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> lut;
for (auto bit : cell->getParam(ID(LUT)).bits)
for (auto bit : cell->getParam(ID::LUT).bits)
lut.push_back(bit == State::S1 ? ez->CONST_TRUE : ez->CONST_FALSE);
while (GetSize(lut) < (1 << GetSize(a)))
lut.push_back(ez->CONST_FALSE);
@ -1070,10 +1070,10 @@ struct SatGen
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
int y = importDefSigSpec(cell->getPort(ID::Y), timestep).at(0);
int width = cell->getParam(ID(WIDTH)).as_int();
int depth = cell->getParam(ID(DEPTH)).as_int();
int width = cell->getParam(ID::WIDTH).as_int();
int depth = cell->getParam(ID::DEPTH).as_int();
vector<State> table_raw = cell->getParam(ID(TABLE)).bits;
vector<State> table_raw = cell->getParam(ID::TABLE).bits;
while (GetSize(table_raw) < 2*width*depth)
table_raw.push_back(State::S0);
@ -1151,9 +1151,9 @@ struct SatGen
{
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), 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> 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> xx = model_undef ? ez->vec_var(x.size()) : x;
@ -1169,10 +1169,10 @@ struct SatGen
{
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_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_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_x, undef_y));
@ -1185,10 +1185,10 @@ struct SatGen
if (cell->type == ID($lcu))
{
std::vector<int> p = importDefSigSpec(cell->getPort(ID(P)), timestep);
std::vector<int> g = importDefSigSpec(cell->getPort(ID(G)), timestep);
std::vector<int> ci = importDefSigSpec(cell->getPort(ID(CI)), timestep);
std::vector<int> co = importDefSigSpec(cell->getPort(ID(CO)), timestep);
std::vector<int> p = importDefSigSpec(cell->getPort(ID::P), timestep);
std::vector<int> g = importDefSigSpec(cell->getPort(ID::G), timestep);
std::vector<int> ci = importDefSigSpec(cell->getPort(ID::CI), timestep);
std::vector<int> co = importDefSigSpec(cell->getPort(ID::CO), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(co.size()) : co;
@ -1197,10 +1197,10 @@ struct SatGen
if (model_undef)
{
std::vector<int> undef_p = importUndefSigSpec(cell->getPort(ID(P)), timestep);
std::vector<int> undef_g = importUndefSigSpec(cell->getPort(ID(G)), timestep);
std::vector<int> undef_ci = importUndefSigSpec(cell->getPort(ID(CI)), timestep);
std::vector<int> undef_co = importUndefSigSpec(cell->getPort(ID(CO)), timestep);
std::vector<int> undef_p = importUndefSigSpec(cell->getPort(ID::P), timestep);
std::vector<int> undef_g = importUndefSigSpec(cell->getPort(ID::G), timestep);
std::vector<int> undef_ci = importUndefSigSpec(cell->getPort(ID::CI), timestep);
std::vector<int> undef_co = importUndefSigSpec(cell->getPort(ID::CO), timestep);
int undef_any_p = ez->expression(ezSAT::OpOr, undef_p);
int undef_any_g = ez->expression(ezSAT::OpOr, undef_g);
@ -1220,10 +1220,10 @@ struct SatGen
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> x = importDefSigSpec(cell->getPort(ID(X)), timestep);
std::vector<int> ci = importDefSigSpec(cell->getPort(ID(CI)), timestep);
std::vector<int> bi = importDefSigSpec(cell->getPort(ID(BI)), timestep);
std::vector<int> co = importDefSigSpec(cell->getPort(ID(CO)), timestep);
std::vector<int> x = importDefSigSpec(cell->getPort(ID::X), timestep);
std::vector<int> ci = importDefSigSpec(cell->getPort(ID::CI), timestep);
std::vector<int> bi = importDefSigSpec(cell->getPort(ID::BI), timestep);
std::vector<int> co = importDefSigSpec(cell->getPort(ID::CO), timestep);
extendSignalWidth(a, b, y, cell);
extendSignalWidth(a, b, x, cell);
@ -1250,12 +1250,12 @@ struct SatGen
{
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_ci = importUndefSigSpec(cell->getPort(ID(CI)), timestep);
std::vector<int> undef_bi = importUndefSigSpec(cell->getPort(ID(BI)), 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_y = importUndefSigSpec(cell->getPort(ID::Y), 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_x = importUndefSigSpec(cell->getPort(ID::X), timestep);
std::vector<int> undef_co = importUndefSigSpec(cell->getPort(ID::CO), timestep);
extendSignalWidth(undef_a, undef_b, undef_y, cell);
extendSignalWidth(undef_a, undef_b, undef_x, cell);
@ -1285,7 +1285,7 @@ struct SatGen
{
RTLIL::SigSpec a = cell->getPort(ID::A);
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;
}
@ -1306,20 +1306,20 @@ struct SatGen
{
if (timestep == 1)
{
initial_state.add((*sigmap)(cell->getPort(ID(Q))));
initial_state.add((*sigmap)(cell->getPort(ID::Q)));
}
else
{
std::vector<int> d = importDefSigSpec(cell->getPort(ID(D)), timestep-1);
std::vector<int> q = importDefSigSpec(cell->getPort(ID(Q)), timestep);
std::vector<int> d = importDefSigSpec(cell->getPort(ID::D), timestep-1);
std::vector<int> q = importDefSigSpec(cell->getPort(ID::Q), timestep);
std::vector<int> qq = model_undef ? ez->vec_var(q.size()) : q;
ez->assume(ez->vec_eq(d, qq));
if (model_undef)
{
std::vector<int> undef_d = importUndefSigSpec(cell->getPort(ID(D)), timestep-1);
std::vector<int> undef_q = importUndefSigSpec(cell->getPort(ID(Q)), timestep);
std::vector<int> undef_d = importUndefSigSpec(cell->getPort(ID::D), timestep-1);
std::vector<int> undef_q = importUndefSigSpec(cell->getPort(ID::Q), timestep);
ez->assume(ez->vec_eq(undef_d, undef_q));
undefGating(q, qq, undef_q);
@ -1397,7 +1397,7 @@ struct SatGen
{
std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep));
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;
}
@ -1405,7 +1405,7 @@ struct SatGen
{
std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep));
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;
}

View file

@ -39,7 +39,7 @@ struct SigPool
bits.clear();
}
void add(RTLIL::SigSpec sig)
void add(const RTLIL::SigSpec &sig)
{
for (auto &bit : sig)
if (bit.wire != NULL)
@ -52,7 +52,7 @@ struct SigPool
bits.insert(bit);
}
void del(RTLIL::SigSpec sig)
void del(const RTLIL::SigSpec &sig)
{
for (auto &bit : sig)
if (bit.wire != NULL)
@ -65,7 +65,7 @@ struct SigPool
bits.erase(bit);
}
void expand(RTLIL::SigSpec from, RTLIL::SigSpec to)
void expand(const RTLIL::SigSpec &from, const RTLIL::SigSpec &to)
{
log_assert(GetSize(from) == GetSize(to));
for (int i = 0; i < GetSize(from); i++) {
@ -75,16 +75,16 @@ struct SigPool
}
}
RTLIL::SigSpec extract(RTLIL::SigSpec sig)
RTLIL::SigSpec extract(const RTLIL::SigSpec &sig) const
{
RTLIL::SigSpec result;
for (auto &bit : sig)
if (bit.wire != NULL && bits.count(bit))
result.append_bit(bit);
result.append(bit);
return result;
}
RTLIL::SigSpec remove(RTLIL::SigSpec sig)
RTLIL::SigSpec remove(const RTLIL::SigSpec &sig) const
{
RTLIL::SigSpec result;
for (auto &bit : sig)
@ -93,12 +93,12 @@ struct SigPool
return result;
}
bool check(RTLIL::SigBit bit)
bool check(const RTLIL::SigBit &bit) const
{
return bit.wire != NULL && bits.count(bit);
}
bool check_any(RTLIL::SigSpec sig)
bool check_any(const RTLIL::SigSpec &sig) const
{
for (auto &bit : sig)
if (bit.wire != NULL && bits.count(bit))
@ -106,7 +106,7 @@ struct SigPool
return false;
}
bool check_all(RTLIL::SigSpec sig)
bool check_all(const RTLIL::SigSpec &sig) const
{
for (auto &bit : sig)
if (bit.wire != NULL && bits.count(bit) == 0)
@ -114,14 +114,14 @@ struct SigPool
return true;
}
RTLIL::SigSpec export_one()
RTLIL::SigSpec export_one() const
{
for (auto &bit : bits)
return RTLIL::SigSpec(bit.first, bit.second);
return RTLIL::SigSpec();
}
RTLIL::SigSpec export_all()
RTLIL::SigSpec export_all() const
{
pool<RTLIL::SigBit> sig;
for (auto &bit : bits)
@ -153,67 +153,67 @@ struct SigSet
bits.clear();
}
void insert(RTLIL::SigSpec sig, T data)
void insert(const RTLIL::SigSpec &sig, T data)
{
for (auto &bit : sig)
for (const auto &bit : sig)
if (bit.wire != NULL)
bits[bit].insert(data);
}
void insert(RTLIL::SigSpec sig, const std::set<T> &data)
void insert(const RTLIL::SigSpec& sig, const std::set<T> &data)
{
for (auto &bit : sig)
for (const auto &bit : sig)
if (bit.wire != NULL)
bits[bit].insert(data.begin(), data.end());
}
void erase(RTLIL::SigSpec sig)
void erase(const RTLIL::SigSpec& sig)
{
for (auto &bit : sig)
for (const auto &bit : sig)
if (bit.wire != NULL)
bits[bit].clear();
}
void erase(RTLIL::SigSpec sig, T data)
void erase(const RTLIL::SigSpec &sig, T data)
{
for (auto &bit : sig)
for (const auto &bit : sig)
if (bit.wire != NULL)
bits[bit].erase(data);
}
void erase(RTLIL::SigSpec sig, const std::set<T> &data)
void erase(const RTLIL::SigSpec &sig, const std::set<T> &data)
{
for (auto &bit : sig)
for (const auto &bit : sig)
if (bit.wire != NULL)
bits[bit].erase(data.begin(), data.end());
}
void find(RTLIL::SigSpec sig, std::set<T> &result)
void find(const RTLIL::SigSpec &sig, std::set<T> &result)
{
for (auto &bit : sig)
for (const auto &bit : sig)
if (bit.wire != NULL) {
auto &data = bits[bit];
result.insert(data.begin(), data.end());
}
}
void find(RTLIL::SigSpec sig, pool<T> &result)
void find(const RTLIL::SigSpec &sig, pool<T> &result)
{
for (auto &bit : sig)
for (const auto &bit : sig)
if (bit.wire != NULL) {
auto &data = bits[bit];
result.insert(data.begin(), data.end());
}
}
std::set<T> find(RTLIL::SigSpec sig)
std::set<T> find(const RTLIL::SigSpec &sig)
{
std::set<T> result;
find(sig, result);
return result;
}
bool has(RTLIL::SigSpec sig)
bool has(const RTLIL::SigSpec &sig)
{
for (auto &bit : sig)
if (bit.wire != NULL && bits.count(bit))
@ -262,7 +262,7 @@ struct SigMap
add(it.first, it.second);
}
void add(RTLIL::SigSpec from, RTLIL::SigSpec to)
void add(const RTLIL::SigSpec& from, const RTLIL::SigSpec& to)
{
log_assert(GetSize(from) == GetSize(to));
@ -287,15 +287,21 @@ struct SigMap
}
}
void add(RTLIL::SigSpec sig)
void add(const RTLIL::SigBit &bit)
{
for (auto &bit : sig) {
RTLIL::SigBit b = database.find(bit);
if (b.wire != nullptr)
database.promote(bit);
}
const auto &b = database.find(bit);
if (b.wire != nullptr)
database.promote(bit);
}
void add(const RTLIL::SigSpec &sig)
{
for (const auto &bit : sig)
add(bit);
}
inline void add(Wire *wire) { return add(RTLIL::SigSpec(wire)); }
void apply(RTLIL::SigBit &bit) const
{
bit = database.find(bit);
@ -329,7 +335,7 @@ struct SigMap
RTLIL::SigSpec allbits() const
{
RTLIL::SigSpec sig;
for (auto &bit : database)
for (const auto &bit : database)
if (bit.wire != nullptr)
sig.append(bit);
return sig;

View file

@ -82,20 +82,20 @@ struct TimingInfo
for (auto cell : module->cells()) {
if (cell->type == ID($specify2)) {
auto src = cell->getPort(ID(SRC));
auto dst = cell->getPort(ID(DST));
auto src = cell->getPort(ID::SRC);
auto dst = cell->getPort(ID::DST);
for (const auto &c : src.chunks())
if (!c.wire->port_input)
log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(src));
for (const auto &c : dst.chunks())
if (!c.wire->port_output)
log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module output.\n", log_id(module), log_id(cell), log_signal(dst));
int rise_max = cell->getParam(ID(T_RISE_MAX)).as_int();
int fall_max = cell->getParam(ID(T_FALL_MAX)).as_int();
int rise_max = cell->getParam(ID::T_RISE_MAX).as_int();
int fall_max = cell->getParam(ID::T_FALL_MAX).as_int();
int max = std::max(rise_max,fall_max);
if (max < 0)
log_error("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX < 0.\n", log_id(module), log_id(cell));
if (cell->getParam(ID(FULL)).as_bool()) {
if (cell->getParam(ID::FULL).as_bool()) {
for (const auto &s : src)
for (const auto &d : dst) {
auto r = t.comb.insert(BitBit(s,d));
@ -117,16 +117,16 @@ struct TimingInfo
}
}
else if (cell->type == ID($specify3)) {
auto src = cell->getPort(ID(SRC));
auto dst = cell->getPort(ID(DST));
auto src = cell->getPort(ID::SRC);
auto dst = cell->getPort(ID::DST);
for (const auto &c : src.chunks())
if (!c.wire->port_input)
log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(src));
for (const auto &c : dst.chunks())
if (!c.wire->port_output)
log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module output.\n", log_id(module), log_id(cell), log_signal(dst));
int rise_max = cell->getParam(ID(T_RISE_MAX)).as_int();
int fall_max = cell->getParam(ID(T_FALL_MAX)).as_int();
int rise_max = cell->getParam(ID::T_RISE_MAX).as_int();
int fall_max = cell->getParam(ID::T_FALL_MAX).as_int();
int max = std::max(rise_max,fall_max);
if (max < 0)
log_warning("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX < 0 which is currently unsupported. Ignoring.\n", log_id(module), log_id(cell));
@ -140,18 +140,18 @@ struct TimingInfo
}
}
else if (cell->type == ID($specrule)) {
auto type = cell->getParam(ID(TYPE)).decode_string();
auto type = cell->getParam(ID::TYPE).decode_string();
if (type != "$setup" && type != "$setuphold")
continue;
auto src = cell->getPort(ID(SRC));
auto dst = cell->getPort(ID(DST));
auto src = cell->getPort(ID::SRC);
auto dst = cell->getPort(ID::DST);
for (const auto &c : src.chunks())
if (!c.wire->port_input)
log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(src));
for (const auto &c : dst.chunks())
if (!c.wire->port_input)
log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(dst));
int max = cell->getParam(ID(T_LIMIT_MAX)).as_int();
int max = cell->getParam(ID::T_LIMIT_MAX).as_int();
if (max < 0)
log_warning("Module '%s' contains specify cell '%s' with T_LIMIT_MAX < 0 which is currently unsupported. Ignoring.\n", log_id(module), log_id(cell));
if (max <= 0) {

View file

@ -515,12 +515,9 @@ void yosys_setup()
return;
already_setup = true;
RTLIL::ID::A = "\\A";
RTLIL::ID::B = "\\B";
RTLIL::ID::Y = "\\Y";
RTLIL::ID::keep = "\\keep";
RTLIL::ID::whitebox = "\\whitebox";
RTLIL::ID::blackbox = "\\blackbox";
#define X(_id) RTLIL::ID::_id = "\\" # _id;
#include "constids.inc"
#undef X
#ifdef WITH_PYTHON
PyImport_AppendInittab((char*)"libyosys", INIT_MODULE);
@ -1098,30 +1095,29 @@ static char *readline_obj_generator(const char *text, int state)
if (design->selected_active_module.empty())
{
for (auto &it : design->modules_)
if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
for (auto mod : design->modules())
if (RTLIL::unescape_id(mod->name).compare(0, len, text) == 0)
obj_names.push_back(strdup(log_id(mod->name)));
}
else
if (design->modules_.count(design->selected_active_module) > 0)
else if (design->module(design->selected_active_module) != nullptr)
{
RTLIL::Module *module = design->modules_.at(design->selected_active_module);
RTLIL::Module *module = design->module(design->selected_active_module);
for (auto &it : module->wires_)
if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
for (auto w : module->wires())
if (RTLIL::unescape_id(w->name).compare(0, len, text) == 0)
obj_names.push_back(strdup(log_id(w->name)));
for (auto &it : module->memories)
if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
obj_names.push_back(strdup(log_id(it.first)));
for (auto &it : module->cells_)
if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
for (auto cell : module->cells())
if (RTLIL::unescape_id(cell->name).compare(0, len, text) == 0)
obj_names.push_back(strdup(log_id(cell->name)));
for (auto &it : module->processes)
if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
obj_names.push_back(strdup(log_id(it.first)));
}
std::sort(obj_names.begin(), obj_names.end());

View file

@ -306,9 +306,9 @@ RTLIL::IdString new_id(std::string file, int line, std::string func);
#define NEW_ID \
YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__)
// Create a statically allocated IdString object, using for example ID(A) or ID($add).
// Create a statically allocated IdString object, using for example ID::A or ID($add).
//
// Recipe for Converting old code that is using conversion of strings like "\\A" and
// Recipe for Converting old code that is using conversion of strings like ID::A and
// "$add" for creating IdStrings: Run below SED command on the .cc file and then use for
// example "meld foo.cc foo.cc.orig" to manually compile errors, if necessary.
//

View file

@ -1371,24 +1371,39 @@ int ezSAT::onehot(const std::vector<int> &vec, bool max_only)
if (max_only == false)
formula.push_back(expression(OpOr, vec));
// create binary vector
int num_bits = clog2(vec.size());
std::vector<int> bits;
for (int k = 0; k < num_bits; k++)
bits.push_back(literal());
if (vec.size() < 8)
{
// fall-back to simple O(n^2) solution for small cases
for (size_t i = 0; i < vec.size(); i++)
for (size_t j = i+1; j < vec.size(); j++) {
std::vector<int> clause;
clause.push_back(NOT(vec[i]));
clause.push_back(NOT(vec[j]));
formula.push_back(expression(OpOr, clause));
}
}
else
{
// create binary vector
int num_bits = clog2(vec.size());
std::vector<int> bits;
for (int k = 0; k < num_bits; k++)
bits.push_back(literal());
// add at-most-one clauses using binary encoding
for (size_t i = 0; i < vec.size(); i++)
for (int k = 0; k < num_bits; k++) {
std::vector<int> clause;
clause.push_back(NOT(vec[i]));
clause.push_back((i & (1 << k)) != 0 ? bits[k] : NOT(bits[k]));
formula.push_back(expression(OpOr, clause));
}
// add at-most-one clauses using binary encoding
for (size_t i = 0; i < vec.size(); i++)
for (int k = 0; k < num_bits; k++) {
std::vector<int> clause;
clause.push_back(NOT(vec[i]));
clause.push_back((i & (1 << k)) != 0 ? bits[k] : NOT(bits[k]));
formula.push_back(expression(OpOr, clause));
}
}
return expression(OpAnd, formula);
}
#if 0
int ezSAT::manyhot(const std::vector<int> &vec, int min_hot, int max_hot)
{
// many-hot encoding using a simple sorting network
@ -1426,6 +1441,123 @@ int ezSAT::manyhot(const std::vector<int> &vec, int min_hot, int max_hot)
return expression(OpAnd, formula);
}
#else
static std::vector<int> lfsr_sym(ezSAT *that, const std::vector<int> &vec, int poly)
{
std::vector<int> out;
for (int i = 0; i < int(vec.size()); i++)
if ((poly & (1 << (i+1))) != 0) {
if (out.empty())
out.push_back(vec.at(i));
else
out.at(0) = that->XOR(out.at(0), vec.at(i));
}
for (int i = 0; i+1 < int(vec.size()); i++)
out.push_back(vec.at(i));
return out;
}
static int lfsr_num(int vec, int poly, int cnt = 1)
{
int mask = poly >> 1;
mask |= mask >> 1;
mask |= mask >> 2;
mask |= mask >> 4;
mask |= mask >> 8;
mask |= mask >> 16;
while (cnt-- > 0) {
int bits = vec & (poly >> 1);
bits = ((bits & 0xAAAAAAAA) >> 1) ^ (bits & 0x55555555);
bits = ((bits & 0x44444444) >> 2) ^ (bits & 0x11111111);
bits = ((bits & 0x10101010) >> 4) ^ (bits & 0x01010101);
bits = ((bits & 0x01000100) >> 8) ^ (bits & 0x00010001);
bits = ((bits & 0x00010000) >> 16) ^ (bits & 0x00000001);
vec = ((vec << 1) | bits) & mask;
}
return vec;
}
int ezSAT::manyhot(const std::vector<int> &vec, int min_hot, int max_hot)
{
// many-hot encoding using LFSR as counter
int poly = 0;
int nbits = 0;
if (vec.size() < 3) {
poly = (1 << 2) | (1 << 1) | 1;
nbits = 2;
} else
if (vec.size() < 7) {
poly = (1 << 3) | (1 << 2) | 1;
nbits = 3;
} else
if (vec.size() < 15) {
poly = (1 << 4) | (1 << 3) | 1;
nbits = 4;
} else
if (vec.size() < 31) {
poly = (1 << 5) | (1 << 3) | 1;
nbits = 5;
} else
if (vec.size() < 63) {
poly = (1 << 6) | (1 << 5) | 1;
nbits = 6;
} else
if (vec.size() < 127) {
poly = (1 << 7) | (1 << 6) | 1;
nbits = 7;
} else
// if (vec.size() < 255) {
// poly = (1 << 8) | (1 << 6) | (1 << 5) | (1 << 4) | 1;
// nbits = 8;
// } else
if (vec.size() < 511) {
poly = (1 << 9) | (1 << 5) | 1;
nbits = 9;
} else {
assert(0);
}
std::vector<int> min_val;
std::vector<int> max_val;
if (min_hot > 1)
min_val = vec_const_unsigned(lfsr_num(1, poly, min_hot), nbits);
if (max_hot >= 0)
max_val = vec_const_unsigned(lfsr_num(1, poly, max_hot+1), nbits);
std::vector<int> state = vec_const_unsigned(1, nbits);
std::vector<int> match_min;
std::vector<int> match_max;
if (min_hot == 1)
match_min = vec;
for (int i = 0; i < int(vec.size()); i++)
{
state = vec_ite(vec[i], lfsr_sym(this, state, poly), state);
if (!min_val.empty() && i+1 >= min_hot)
match_min.push_back(vec_eq(min_val, state));
if (!max_val.empty() && i >= max_hot)
match_max.push_back(vec_eq(max_val, state));
}
int min_matched = min_hot ? vec_reduce_or(match_min) : CONST_TRUE;
int max_matched = vec_reduce_or(match_max);
return AND(min_matched, NOT(max_matched));
}
#endif
int ezSAT::ordered(const std::vector<int> &vec1, const std::vector<int> &vec2, bool allow_equal)
{

View file

@ -5350,7 +5350,7 @@ never transition from a non-zero value to a zero value.
For this proof we create the following template (test.tpl).
; we need QF_UFBV for this poof
; we need QF_UFBV for this proof
(set-logic QF_UFBV)
; insert the auto-generated code here

View file

@ -1,4 +1,5 @@
OBJS += passes/cmds/exec.o
OBJS += passes/cmds/add.o
OBJS += passes/cmds/delete.o
OBJS += passes/cmds/design.o

View file

@ -42,9 +42,9 @@ static void add_formal(RTLIL::Module *module, const std::string &celltype, const
}
else {
RTLIL::Cell *formal_cell = module->addCell(NEW_ID, "$" + celltype);
formal_cell->setPort(ID(A), wire);
formal_cell->setPort(ID::A, wire);
if(enable_name == "") {
formal_cell->setPort(ID(EN), State::S1);
formal_cell->setPort(ID::EN, State::S1);
log("Added $%s cell for wire \"%s.%s\"\n", celltype.c_str(), module->name.str().c_str(), name.c_str());
}
else {
@ -52,7 +52,7 @@ static void add_formal(RTLIL::Module *module, const std::string &celltype, const
if(enable_wire == nullptr)
log_error("Could not find enable wire with name \"%s\".\n", enable_name.c_str());
formal_cell->setPort(ID(EN), enable_wire);
formal_cell->setPort(ID::EN, enable_wire);
log("Added $%s cell for wire \"%s.%s\" enabled by wire \"%s.%s\".\n", celltype.c_str(), module->name.str().c_str(), name.c_str(), module->name.str().c_str(), enable_name.c_str());
}
}
@ -206,19 +206,23 @@ struct AddPass : public Pass {
extra_args(args, argidx, design);
bool selected_anything = false;
for (auto module : design->modules())
{
log_assert(module != nullptr);
if (!design->selected_whole_module(module->name))
continue;
if (module->get_bool_attribute("\\blackbox"))
if (module->get_bool_attribute(ID::blackbox))
continue;
selected_anything = true;
if (is_formal_celltype(command))
add_formal(module, command, arg_name, enable_name);
else if (command == "wire")
add_wire(design, module, arg_name, arg_width, arg_flag_input, arg_flag_output, arg_flag_global);
}
if (!selected_anything)
log_warning("No modules selected, or only blackboxes. Nothing was added.\n");
}
} AddPass;

View file

@ -73,7 +73,7 @@ struct BlackboxPass : public Pass {
module->remove(remove_wires);
module->set_bool_attribute("\\blackbox");
module->set_bool_attribute(ID::blackbox);
}
}
} BlackboxPass;

View file

@ -114,8 +114,8 @@ struct BugpointPass : public Pass {
return design;
RTLIL::Design *design_copy = new RTLIL::Design;
for (auto &it : design->modules_)
design_copy->add(it.second->clone());
for (auto module : design->modules())
design_copy->add(module->clone());
Pass::call(design_copy, "proc_clean -quiet");
Pass::call(design_copy, "clean -purge");
@ -127,21 +127,21 @@ struct BugpointPass : public Pass {
RTLIL::Design *simplify_something(RTLIL::Design *design, int &seed, bool stage2, bool modules, bool ports, bool cells, bool connections, bool assigns, bool updates)
{
RTLIL::Design *design_copy = new RTLIL::Design;
for (auto &it : design->modules_)
design_copy->add(it.second->clone());
for (auto module : design->modules())
design_copy->add(module->clone());
int index = 0;
if (modules)
{
for (auto &it : design_copy->modules_)
for (auto module : design_copy->modules())
{
if (it.second->get_blackbox_attribute())
if (module->get_blackbox_attribute())
continue;
if (index++ == seed)
{
log("Trying to remove module %s.\n", it.first.c_str());
design_copy->remove(it.second);
log("Trying to remove module %s.\n", module->name.c_str());
design_copy->remove(module);
return design_copy;
}
}
@ -155,7 +155,7 @@ struct BugpointPass : public Pass {
for (auto wire : mod->wires())
{
if (!stage2 && wire->get_bool_attribute("$bugpoint"))
if (!stage2 && wire->get_bool_attribute(ID($bugpoint)))
continue;
if (wire->port_input || wire->port_output)
@ -178,12 +178,12 @@ struct BugpointPass : public Pass {
if (mod->get_blackbox_attribute())
continue;
for (auto &it : mod->cells_)
for (auto cell : mod->cells())
{
if (index++ == seed)
{
log("Trying to remove cell %s.%s.\n", mod->name.c_str(), it.first.c_str());
mod->remove(it.second);
log("Trying to remove cell %s.%s.\n", mod->name.c_str(), cell->name.c_str());
mod->remove(cell);
return design_copy;
}
}
@ -220,7 +220,7 @@ struct BugpointPass : public Pass {
{
log("Trying to expose cell port %s.%s.%s as module port.\n", mod->name.c_str(), cell->name.c_str(), it.first.c_str());
RTLIL::Wire *wire = mod->addWire(NEW_ID, port.size());
wire->set_bool_attribute("$bugpoint");
wire->set_bool_attribute(ID($bugpoint));
wire->port_input = cell->input(it.first);
wire->port_output = cell->output(it.first);
cell->unsetPort(it.first);
@ -285,7 +285,7 @@ struct BugpointPass : public Pass {
}
}
}
return NULL;
return nullptr;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@ -433,8 +433,8 @@ struct BugpointPass : public Pass {
{
Pass::call(design, "design -reset");
crashing_design = clean_design(crashing_design, clean, /*do_delete=*/true);
for (auto &it : crashing_design->modules_)
design->add(it.second->clone());
for (auto module : crashing_design->modules())
design->add(module->clone());
delete crashing_design;
}
}

View file

@ -99,47 +99,47 @@ struct CheckPass : public Pass {
log_header(design, "Executing CHECK pass (checking for obvious problems).\n");
pool<IdString> fftypes;
fftypes.insert("$sr");
fftypes.insert("$ff");
fftypes.insert("$dff");
fftypes.insert("$dffe");
fftypes.insert("$dffsr");
fftypes.insert("$adff");
fftypes.insert("$dlatch");
fftypes.insert("$dlatchsr");
fftypes.insert("$_DFFE_NN_");
fftypes.insert("$_DFFE_NP_");
fftypes.insert("$_DFFE_PN_");
fftypes.insert("$_DFFE_PP_");
fftypes.insert("$_DFFSR_NNN_");
fftypes.insert("$_DFFSR_NNP_");
fftypes.insert("$_DFFSR_NPN_");
fftypes.insert("$_DFFSR_NPP_");
fftypes.insert("$_DFFSR_PNN_");
fftypes.insert("$_DFFSR_PNP_");
fftypes.insert("$_DFFSR_PPN_");
fftypes.insert("$_DFFSR_PPP_");
fftypes.insert("$_DFF_NN0_");
fftypes.insert("$_DFF_NN1_");
fftypes.insert("$_DFF_NP0_");
fftypes.insert("$_DFF_NP1_");
fftypes.insert("$_DFF_N_");
fftypes.insert("$_DFF_PN0_");
fftypes.insert("$_DFF_PN1_");
fftypes.insert("$_DFF_PP0_");
fftypes.insert("$_DFF_PP1_");
fftypes.insert("$_DFF_P_");
fftypes.insert("$_DLATCHSR_NNN_");
fftypes.insert("$_DLATCHSR_NNP_");
fftypes.insert("$_DLATCHSR_NPN_");
fftypes.insert("$_DLATCHSR_NPP_");
fftypes.insert("$_DLATCHSR_PNN_");
fftypes.insert("$_DLATCHSR_PNP_");
fftypes.insert("$_DLATCHSR_PPN_");
fftypes.insert("$_DLATCHSR_PPP_");
fftypes.insert("$_DLATCH_N_");
fftypes.insert("$_DLATCH_P_");
fftypes.insert("$_FF_");
fftypes.insert(ID($sr));
fftypes.insert(ID($ff));
fftypes.insert(ID($dff));
fftypes.insert(ID($dffe));
fftypes.insert(ID($dffsr));
fftypes.insert(ID($adff));
fftypes.insert(ID($dlatch));
fftypes.insert(ID($dlatchsr));
fftypes.insert(ID($_DFFE_NN_));
fftypes.insert(ID($_DFFE_NP_));
fftypes.insert(ID($_DFFE_PN_));
fftypes.insert(ID($_DFFE_PP_));
fftypes.insert(ID($_DFFSR_NNN_));
fftypes.insert(ID($_DFFSR_NNP_));
fftypes.insert(ID($_DFFSR_NPN_));
fftypes.insert(ID($_DFFSR_NPP_));
fftypes.insert(ID($_DFFSR_PNN_));
fftypes.insert(ID($_DFFSR_PNP_));
fftypes.insert(ID($_DFFSR_PPN_));
fftypes.insert(ID($_DFFSR_PPP_));
fftypes.insert(ID($_DFF_NN0_));
fftypes.insert(ID($_DFF_NN1_));
fftypes.insert(ID($_DFF_NP0_));
fftypes.insert(ID($_DFF_NP1_));
fftypes.insert(ID($_DFF_N_));
fftypes.insert(ID($_DFF_PN0_));
fftypes.insert(ID($_DFF_PN1_));
fftypes.insert(ID($_DFF_PP0_));
fftypes.insert(ID($_DFF_PP1_));
fftypes.insert(ID($_DFF_P_));
fftypes.insert(ID($_DLATCHSR_NNN_));
fftypes.insert(ID($_DLATCHSR_NNP_));
fftypes.insert(ID($_DLATCHSR_NPN_));
fftypes.insert(ID($_DLATCHSR_NPP_));
fftypes.insert(ID($_DLATCHSR_PNN_));
fftypes.insert(ID($_DLATCHSR_PNP_));
fftypes.insert(ID($_DLATCHSR_PPN_));
fftypes.insert(ID($_DLATCHSR_PPP_));
fftypes.insert(ID($_DLATCH_N_));
fftypes.insert(ID($_DLATCH_P_));
fftypes.insert(ID($_FF_));
for (auto module : design->selected_whole_modules_warn())
{
@ -202,8 +202,8 @@ struct CheckPass : public Pass {
if (wire->port_input && !wire->port_output)
for (auto bit : sigmap(wire))
if (bit.wire) wire_drivers_count[bit]++;
if (wire->attributes.count("\\init")) {
Const initval = wire->attributes.at("\\init");
if (wire->attributes.count(ID::init)) {
Const initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++)
if (initval[i] == State::S0 || initval[i] == State::S1)
init_bits.insert(sigmap(SigBit(wire, i)));
@ -245,7 +245,7 @@ struct CheckPass : public Pass {
if (fftypes.count(cell->type) == 0)
continue;
for (auto bit : sigmap(cell->getPort("\\Q")))
for (auto bit : sigmap(cell->getPort(ID::Q)))
init_bits.erase(bit);
}

View file

@ -77,23 +77,23 @@ struct ChformalPass : public Pass {
for (argidx = 1; argidx < args.size(); argidx++)
{
if (args[argidx] == "-assert") {
constr_types.insert("$assert");
constr_types.insert(ID($assert));
continue;
}
if (args[argidx] == "-assume") {
constr_types.insert("$assume");
constr_types.insert(ID($assume));
continue;
}
if (args[argidx] == "-live") {
constr_types.insert("$live");
constr_types.insert(ID($live));
continue;
}
if (args[argidx] == "-fair") {
constr_types.insert("$fair");
constr_types.insert(ID($fair));
continue;
}
if (args[argidx] == "-cover") {
constr_types.insert("$cover");
constr_types.insert(ID($cover));
continue;
}
if (mode == 0 && args[argidx] == "-remove") {
@ -139,11 +139,11 @@ struct ChformalPass : public Pass {
extra_args(args, argidx, design);
if (constr_types.empty()) {
constr_types.insert("$assert");
constr_types.insert("$assume");
constr_types.insert("$live");
constr_types.insert("$fair");
constr_types.insert("$cover");
constr_types.insert(ID($assert));
constr_types.insert(ID($assume));
constr_types.insert(ID($live));
constr_types.insert(ID($fair));
constr_types.insert(ID($cover));
}
if (mode == 0)
@ -171,11 +171,11 @@ struct ChformalPass : public Pass {
for (auto wire : module->wires())
{
if (wire->attributes.count("\\init") == 0)
if (wire->attributes.count(ID::init) == 0)
continue;
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++) {
if (initval[i] == State::S0)
@ -187,17 +187,17 @@ struct ChformalPass : public Pass {
for (auto cell : module->selected_cells())
{
if (cell->type == "$ff") {
SigSpec D = sigmap(cell->getPort("\\D"));
SigSpec Q = sigmap(cell->getPort("\\Q"));
if (cell->type == ID($ff)) {
SigSpec D = sigmap(cell->getPort(ID::D));
SigSpec Q = sigmap(cell->getPort(ID::Q));
for (int i = 0; i < GetSize(D); i++)
ffmap[Q[i]] = make_pair(D[i], make_pair(State::Sm, false));
}
if (cell->type == "$dff") {
SigSpec D = sigmap(cell->getPort("\\D"));
SigSpec Q = sigmap(cell->getPort("\\Q"));
SigSpec C = sigmap(cell->getPort("\\CLK"));
bool clockpol = cell->getParam("\\CLK_POLARITY").as_bool();
if (cell->type == ID($dff)) {
SigSpec D = sigmap(cell->getPort(ID::D));
SigSpec Q = sigmap(cell->getPort(ID::Q));
SigSpec C = sigmap(cell->getPort(ID::CLK));
bool clockpol = cell->getParam(ID::CLK_POLARITY).as_bool();
for (int i = 0; i < GetSize(D); i++)
ffmap[Q[i]] = make_pair(D[i], make_pair(C, clockpol));
}
@ -206,15 +206,15 @@ struct ChformalPass : public Pass {
for (auto cell : constr_cells)
while (true)
{
SigSpec A = sigmap(cell->getPort("\\A"));
SigSpec EN = sigmap(cell->getPort("\\EN"));
SigSpec A = sigmap(cell->getPort(ID::A));
SigSpec EN = sigmap(cell->getPort(ID::EN));
if (ffmap.count(A) == 0 || ffmap.count(EN) == 0)
break;
if (!init_zero.count(EN)) {
if (cell->type == "$cover") break;
if (cell->type.in("$assert", "$assume") && !init_one.count(A)) break;
if (cell->type == ID($cover)) break;
if (cell->type.in(ID($assert), ID($assume)) && !init_one.count(A)) break;
}
const auto &A_map = ffmap.at(A);
@ -223,8 +223,8 @@ struct ChformalPass : public Pass {
if (A_map.second != EN_map.second)
break;
cell->setPort("\\A", A_map.first);
cell->setPort("\\EN", EN_map.first);
cell->setPort(ID::A, A_map.first);
cell->setPort(ID::EN, EN_map.first);
}
}
else
@ -233,18 +233,18 @@ struct ChformalPass : public Pass {
for (auto cell : constr_cells)
for (int i = 0; i < mode_arg; i++)
{
SigSpec orig_a = cell->getPort("\\A");
SigSpec orig_en = cell->getPort("\\EN");
SigSpec orig_a = cell->getPort(ID::A);
SigSpec orig_en = cell->getPort(ID::EN);
Wire *new_a = module->addWire(NEW_ID);
Wire *new_en = module->addWire(NEW_ID);
new_en->attributes["\\init"] = State::S0;
new_en->attributes[ID::init] = State::S0;
module->addFf(NEW_ID, orig_a, new_a);
module->addFf(NEW_ID, orig_en, new_en);
cell->setPort("\\A", new_a);
cell->setPort("\\EN", new_en);
cell->setPort(ID::A, new_a);
cell->setPort(ID::EN, new_en);
}
}
else
@ -254,26 +254,26 @@ struct ChformalPass : public Pass {
for (int i = 0; i < mode_arg; i++) {
Wire *w = module->addWire(NEW_ID);
w->attributes["\\init"] = State::S0;
w->attributes[ID::init] = State::S0;
module->addFf(NEW_ID, en, w);
en = w;
}
for (auto cell : constr_cells)
cell->setPort("\\EN", module->LogicAnd(NEW_ID, en, cell->getPort("\\EN")));
cell->setPort(ID::EN, module->LogicAnd(NEW_ID, en, cell->getPort(ID::EN)));
}
else
if (mode == 'c')
{
for (auto cell : constr_cells)
if (assert2assume && cell->type == "$assert")
cell->type = "$assume";
else if (assume2assert && cell->type == "$assume")
cell->type = "$assert";
else if (live2fair && cell->type == "$live")
cell->type = "$fair";
else if (fair2live && cell->type == "$fair")
cell->type = "$live";
if (assert2assume && cell->type == ID($assert))
cell->type = ID($assume);
else if (assume2assert && cell->type == ID($assume))
cell->type = ID($assert);
else if (live2fair && cell->type == ID($live))
cell->type = ID($fair);
else if (fair2live && cell->type == ID($fair))
cell->type = ID($live);
}
}
}

View file

@ -65,15 +65,13 @@ struct ConnwrappersWorker
decls[key] = decl;
}
void work(RTLIL::Design *design, RTLIL::Module *module)
void work(RTLIL::Module *module)
{
std::map<RTLIL::SigBit, std::pair<bool, RTLIL::SigSpec>> extend_map;
SigMap sigmap(module);
for (auto &it : module->cells_)
for (auto cell : module->cells())
{
RTLIL::Cell *cell = it.second;
if (!decl_celltypes.count(cell->type))
continue;
@ -105,13 +103,8 @@ struct ConnwrappersWorker
}
}
for (auto &it : module->cells_)
for (auto cell : module->selected_cells())
{
RTLIL::Cell *cell = it.second;
if (!design->selected(module, cell))
continue;
for (auto &conn : cell->connections_)
{
std::vector<RTLIL::SigBit> sigbits = sigmap(conn.second).to_sigbit_vector();
@ -141,8 +134,8 @@ struct ConnwrappersWorker
}
if (old_sig.size())
log("Connected extended bits of %s.%s:%s: %s -> %s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name),
RTLIL::id2cstr(conn.first), log_signal(old_sig), log_signal(conn.second));
log("Connected extended bits of %s.%s:%s: %s -> %s\n", log_id(module->name), log_id(cell->name),
log_id(conn.first), log_signal(old_sig), log_signal(conn.second));
}
}
}
@ -200,9 +193,8 @@ struct ConnwrappersPass : public Pass {
log_header(design, "Executing CONNWRAPPERS pass (connect extended ports of wrapper cells).\n");
for (auto &mod_it : design->modules_)
if (design->selected(mod_it.second))
worker.work(design, mod_it.second);
for (auto module : design->selected_modules())
worker.work(module);
}
} ConnwrappersPass;

View file

@ -44,10 +44,10 @@ struct CopyPass : public Pass {
std::string src_name = RTLIL::escape_id(args[1]);
std::string trg_name = RTLIL::escape_id(args[2]);
if (design->modules_.count(src_name) == 0)
if (design->module(src_name) == nullptr)
log_cmd_error("Can't find source module %s.\n", src_name.c_str());
if (design->modules_.count(trg_name) != 0)
if (design->module(trg_name) != nullptr)
log_cmd_error("Target module name %s already exists.\n", trg_name.c_str());
RTLIL::Module *new_mod = design->module(src_name)->clone();

View file

@ -65,27 +65,24 @@ struct DeletePass : public Pass {
}
extra_args(args, argidx, design);
std::vector<RTLIL::IdString> delete_mods;
for (auto &mod_it : design->modules_)
std::vector<RTLIL::Module *> delete_mods;
for (auto module : design->modules())
{
if (design->selected_whole_module(mod_it.first) && !flag_input && !flag_output) {
delete_mods.push_back(mod_it.first);
if (design->selected_whole_module(module->name) && !flag_input && !flag_output) {
delete_mods.push_back(module);
continue;
}
if (!design->selected_module(mod_it.first))
if (!design->selected_module(module->name))
continue;
RTLIL::Module *module = mod_it.second;
if (flag_input || flag_output) {
for (auto &it : module->wires_)
if (design->selected(module, it.second)) {
for (auto wire : module->wires())
if (design->selected(module, wire)) {
if (flag_input)
it.second->port_input = false;
wire->port_input = false;
if (flag_output)
it.second->port_output = false;
wire->port_output = false;
}
module->fixup_ports();
continue;
@ -96,20 +93,19 @@ struct DeletePass : public Pass {
pool<RTLIL::IdString> delete_procs;
pool<RTLIL::IdString> delete_mems;
for (auto &it : module->wires_)
if (design->selected(module, it.second))
delete_wires.insert(it.second);
for (auto wire : module->selected_wires())
delete_wires.insert(wire);
for (auto &it : module->memories)
if (design->selected(module, it.second))
delete_mems.insert(it.first);
for (auto &it : module->cells_) {
if (design->selected(module, it.second))
delete_cells.insert(it.second);
if (it.second->type.in("$memrd", "$memwr") &&
delete_mems.count(it.second->parameters.at("\\MEMID").decode_string()) != 0)
delete_cells.insert(it.second);
for (auto cell : module->cells()) {
if (design->selected(module, cell))
delete_cells.insert(cell);
if (cell->type.in(ID($memrd), ID($memwr)) &&
delete_mems.count(cell->parameters.at(ID::MEMID).decode_string()) != 0)
delete_cells.insert(cell);
}
for (auto &it : module->processes)
@ -134,9 +130,8 @@ struct DeletePass : public Pass {
module->fixup_ports();
}
for (auto &it : delete_mods) {
delete design->modules_.at(it);
design->modules_.erase(it);
for (auto mod : delete_mods) {
design->remove(mod);
}
}
} DeletePass;

View file

@ -18,6 +18,7 @@
*/
#include "kernel/yosys.h"
#include "frontends/verilog/preproc.h"
#include "frontends/ast/ast.h"
YOSYS_NAMESPACE_BEGIN
@ -59,6 +60,11 @@ struct DesignPass : public Pass {
log("Push the current design to the stack and then clear the current design.\n");
log("\n");
log("\n");
log(" design -push-copy\n");
log("\n");
log("Push the current design to the stack without clearing the current design.\n");
log("\n");
log("\n");
log(" design -pop\n");
log("\n");
log("Reset the current design and pop the last design from the stack.\n");
@ -100,6 +106,7 @@ struct DesignPass : public Pass {
bool reset_mode = false;
bool reset_vlog_mode = false;
bool push_mode = false;
bool push_copy_mode = false;
bool pop_mode = false;
bool import_mode = false;
RTLIL::Design *copy_from_design = NULL, *copy_to_design = NULL;
@ -125,6 +132,11 @@ struct DesignPass : public Pass {
push_mode = true;
continue;
}
if (!got_mode && args[argidx] == "-push-copy") {
got_mode = true;
push_copy_mode = true;
continue;
}
if (!got_mode && args[argidx] == "-pop") {
got_mode = true;
pop_mode = true;
@ -194,19 +206,19 @@ struct DesignPass : public Pass {
argidx = args.size();
}
for (auto &it : copy_from_design->modules_) {
if (sel.selected_whole_module(it.first)) {
copy_src_modules.push_back(it.second);
for (auto mod : copy_from_design->modules()) {
if (sel.selected_whole_module(mod->name)) {
copy_src_modules.push_back(mod);
continue;
}
if (sel.selected_module(it.first))
log_cmd_error("Module %s is only partly selected.\n", RTLIL::id2cstr(it.first));
if (sel.selected_module(mod->name))
log_cmd_error("Module %s is only partly selected.\n", log_id(mod->name));
}
if (import_mode) {
for (auto module : copy_src_modules)
{
if (module->get_bool_attribute("\\top")) {
if (module->get_bool_attribute(ID::top)) {
copy_src_modules.clear();
copy_src_modules.push_back(module);
break;
@ -230,8 +242,8 @@ struct DesignPass : public Pass {
pool<Module*> queue;
dict<IdString, IdString> done;
if (copy_to_design->modules_.count(prefix))
delete copy_to_design->modules_.at(prefix);
if (copy_to_design->module(prefix) != nullptr)
copy_to_design->remove(copy_to_design->module(prefix));
if (GetSize(copy_src_modules) != 1)
log_cmd_error("No top module found in source design.\n");
@ -240,12 +252,13 @@ struct DesignPass : public Pass {
{
log("Importing %s as %s.\n", log_id(mod), log_id(prefix));
copy_to_design->modules_[prefix] = mod->clone();
copy_to_design->modules_[prefix]->name = prefix;
copy_to_design->modules_[prefix]->design = copy_to_design;
copy_to_design->modules_[prefix]->attributes.erase("\\top");
RTLIL::Module *t = mod->clone();
t->name = prefix;
t->design = copy_to_design;
t->attributes.erase(ID::top);
copy_to_design->add(t);
queue.insert(copy_to_design->modules_[prefix]);
queue.insert(t);
done[mod->name] = prefix;
}
@ -268,15 +281,16 @@ struct DesignPass : public Pass {
log("Importing %s as %s.\n", log_id(fmod), log_id(trg_name));
if (copy_to_design->modules_.count(trg_name))
delete copy_to_design->modules_.at(trg_name);
if (copy_to_design->module(trg_name) != nullptr)
copy_to_design->remove(copy_to_design->module(trg_name));
copy_to_design->modules_[trg_name] = fmod->clone();
copy_to_design->modules_[trg_name]->name = trg_name;
copy_to_design->modules_[trg_name]->design = copy_to_design;
copy_to_design->modules_[trg_name]->attributes.erase("\\top");
RTLIL::Module *t = fmod->clone();
t->name = trg_name;
t->design = copy_to_design;
t->attributes.erase(ID::top);
copy_to_design->add(t);
queue.insert(copy_to_design->modules_[trg_name]);
queue.insert(t);
done[cell->type] = trg_name;
}
@ -294,21 +308,22 @@ struct DesignPass : public Pass {
{
std::string trg_name = as_name.empty() ? mod->name.str() : RTLIL::escape_id(as_name);
if (copy_to_design->modules_.count(trg_name))
delete copy_to_design->modules_.at(trg_name);
if (copy_to_design->module(trg_name) != nullptr)
copy_to_design->remove(copy_to_design->module(trg_name));
copy_to_design->modules_[trg_name] = mod->clone();
copy_to_design->modules_[trg_name]->name = trg_name;
copy_to_design->modules_[trg_name]->design = copy_to_design;
RTLIL::Module *t = mod->clone();
t->name = trg_name;
t->design = copy_to_design;
copy_to_design->add(t);
}
}
if (!save_name.empty() || push_mode)
if (!save_name.empty() || push_mode || push_copy_mode)
{
RTLIL::Design *design_copy = new RTLIL::Design;
for (auto &it : design->modules_)
design_copy->add(it.second->clone());
for (auto mod : design->modules())
design_copy->add(mod->clone());
design_copy->selection_stack = design->selection_stack;
design_copy->selection_vars = design->selection_vars;
@ -317,7 +332,7 @@ struct DesignPass : public Pass {
if (saved_designs.count(save_name))
delete saved_designs.at(save_name);
if (push_mode)
if (push_mode || push_copy_mode)
pushed_designs.push_back(design_copy);
else
saved_designs[save_name] = design_copy;
@ -325,9 +340,8 @@ struct DesignPass : public Pass {
if (reset_mode || !load_name.empty() || push_mode || pop_mode)
{
for (auto &it : design->modules_)
delete it.second;
design->modules_.clear();
for (auto mod : design->modules())
design->remove(mod);
design->selection_stack.clear();
design->selection_vars.clear();
@ -346,15 +360,15 @@ struct DesignPass : public Pass {
delete node;
design->verilog_globals.clear();
design->verilog_defines.clear();
design->verilog_defines->clear();
}
if (!load_name.empty() || pop_mode)
{
RTLIL::Design *saved_design = pop_mode ? pushed_designs.back() : saved_designs.at(load_name);
for (auto &it : saved_design->modules_)
design->add(it.second->clone());
for (auto mod : saved_design->modules())
design->add(mod->clone());
design->selection_stack = saved_design->selection_stack;
design->selection_vars = saved_design->selection_vars;

205
passes/cmds/exec.cc Normal file
View file

@ -0,0 +1,205 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 - 2020 Claire Wolf <claire@symbioticeda.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/register.h"
#include "kernel/log.h"
#include <cstdio>
#if defined(_WIN32)
# include <csignal>
# define WIFEXITED(x) 1
# define WIFSIGNALED(x) 0
# define WIFSTOPPED(x) 0
# define WEXITSTATUS(x) ((x) & 0xff)
# define WTERMSIG(x) SIGTERM
# define WSTOPSIG(x) 0
#else
# include <sys/wait.h>
#endif
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
struct ExecPass : public Pass {
ExecPass() : Pass("exec", "execute commands in the operating system shell") { }
void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" exec [options] -- [command]\n");
log("\n");
log("Execute a command in the operating system shell. All supplied arguments are\n");
log("concatenated and passed as a command to popen(3). Whitespace is not guaranteed\n");
log("to be preserved, even if quoted. stdin and stderr are not connected, while stdout is\n");
log("logged unless the \"-q\" option is specified.\n");
log("\n");
log("\n");
log(" -q\n");
log(" Suppress stdout and stderr from subprocess\n");
log("\n");
log(" -expect-return <int>\n");
log(" Generate an error if popen() does not return specified value.\n");
log(" May only be specified once; the final specified value is controlling\n");
log(" if specified multiple times.\n");
log("\n");
log(" -expect-stdout <regex>\n");
log(" Generate an error if the specified regex does not match any line\n");
log(" in subprocess's stdout. May be specified multiple times.\n");
log("\n");
log(" -not-expect-stdout <regex>\n");
log(" Generate an error if the specified regex matches any line\n");
log(" in subprocess's stdout. May be specified multiple times.\n");
log("\n");
log("\n");
log(" Example: exec -q -expect-return 0 -- echo \"bananapie\" | grep \"nana\"\n");
log("\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
std::string cmd = "";
char buf[1024] = {};
std::string linebuf = "";
bool flag_cmd = false;
bool flag_quiet = false;
bool flag_expect_return = false;
int expect_return_value = 0;
bool flag_expect_stdout = false;
struct expect_stdout_elem {
bool matched;
bool polarity; //true: this regex must match at least one line
//false: this regex must not match any line
std::string str;
YS_REGEX_TYPE re;
expect_stdout_elem() : matched(false), polarity(true), str(), re(){};
};
std::vector<expect_stdout_elem> expect_stdout;
if(args.size() == 0)
log_cmd_error("No command provided.\n");
for(size_t argidx = 1; argidx < args.size(); ++argidx) {
if (flag_cmd) {
cmd += args[argidx] + (argidx != (args.size() - 1)? " " : "");
} else {
if (args[argidx] == "--")
flag_cmd = true;
else if (args[argidx] == "-q")
flag_quiet = true;
else if (args[argidx] == "-expect-return") {
flag_expect_return = true;
++argidx;
if (argidx >= args.size())
log_cmd_error("No expected return value specified.\n");
expect_return_value = atoi(args[argidx].c_str());
} else if (args[argidx] == "-expect-stdout") {
flag_expect_stdout = true;
++argidx;
if (argidx >= args.size())
log_cmd_error("No expected regular expression specified.\n");
try{
expect_stdout_elem x;
x.str = args[argidx];
x.re = YS_REGEX_COMPILE(args[argidx]);
expect_stdout.push_back(x);
} catch (const YS_REGEX_NS::regex_error& e) {
log_cmd_error("Error in regex expression '%s' !\n", args[argidx].c_str());
}
} else if (args[argidx] == "-not-expect-stdout") {
flag_expect_stdout = true;
++argidx;
if (argidx >= args.size())
log_cmd_error("No expected regular expression specified.\n");
try{
expect_stdout_elem x;
x.str = args[argidx];
x.re = YS_REGEX_COMPILE(args[argidx]);
x.polarity = false;
expect_stdout.push_back(x);
} catch (const YS_REGEX_NS::regex_error& e) {
log_cmd_error("Error in regex expression '%s' !\n", args[argidx].c_str());
}
} else
log_cmd_error("Unknown option \"%s\" or \"--\" doesn\'t precede command.", args[argidx].c_str());
}
}
log_header(design, "Executing command \"%s\".\n", cmd.c_str());
log_push();
fflush(stdout);
bool keep_reading = true;
int status = 0;
int retval = 0;
#ifndef EMSCRIPTEN
FILE *f = popen(cmd.c_str(), "r");
if (f == nullptr)
log_cmd_error("errno %d after popen() returned NULL.\n", errno);
while (keep_reading) {
keep_reading = (fgets(buf, sizeof(buf), f) != nullptr);
linebuf += buf;
memset(buf, 0, sizeof(buf));
auto pos = linebuf.find('\n');
while (pos != std::string::npos) {
std::string line = linebuf.substr(0, pos);
linebuf.erase(0, pos + 1);
if (!flag_quiet)
log("%s\n", line.c_str());
if (flag_expect_stdout)
for(auto &x : expect_stdout)
if (YS_REGEX_NS::regex_search(line, x.re))
x.matched = true;
pos = linebuf.find('\n');
}
}
status = pclose(f);
#endif
if(WIFEXITED(status)) {
retval = WEXITSTATUS(status);
}
else if(WIFSIGNALED(status)) {
retval = WTERMSIG(status);
}
else if(WIFSTOPPED(status)) {
retval = WSTOPSIG(status);
}
if (flag_expect_return && retval != expect_return_value)
log_cmd_error("Return value %d did not match expected return value %d.\n", retval, expect_return_value);
if (flag_expect_stdout)
for (auto &x : expect_stdout)
if (x.polarity ^ x.matched)
log_cmd_error("Command stdout did%s have a line matching given regex \"%s\".\n", (x.polarity? " not" : ""), x.str.c_str());
log_pop();
}
} ExecPass;
PRIVATE_NAMESPACE_END

View file

@ -737,7 +737,7 @@ struct QwpWorker
for (auto &node : nodes)
if (node.cell != nullptr)
node.cell->attributes["\\qwp_position"] = stringf("%f %f", node.pos, node.alt_pos);
node.cell->attributes[ID::qwp_position] = stringf("%f %f", node.pos, node.alt_pos);
vector<double> edge_lengths;
vector<double> weighted_edge_lengths;

View file

@ -625,9 +625,13 @@ static void select_filter_active_mod(RTLIL::Design *design, RTLIL::Selection &se
}
}
static void select_stmt(RTLIL::Design *design, std::string arg)
static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_empty_warning = false)
{
std::string arg_mod, arg_memb;
std::unordered_map<std::string, bool> arg_mod_found;
std::unordered_map<std::string, bool> arg_memb_found;
auto isalpha = [](const char &x) { return ((x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z')); };
bool prefixed = GetSize(arg) >= 2 && isalpha(arg[0]) && arg[1] == ':';
if (arg.size() == 0)
return;
@ -758,19 +762,21 @@ static void select_stmt(RTLIL::Design *design, std::string arg)
if (!design->selected_active_module.empty()) {
arg_mod = design->selected_active_module;
arg_memb = arg;
if (!prefixed) arg_memb_found[arg_memb] = false;
} else
if (GetSize(arg) >= 2 && arg[0] >= 'a' && arg[0] <= 'z' && arg[1] == ':') {
if (prefixed && arg[0] >= 'a' && arg[0] <= 'z') {
arg_mod = "*", arg_memb = arg;
} else {
size_t pos = arg.find('/');
if (pos == std::string::npos) {
if (arg.find(':') == std::string::npos || arg.compare(0, 1, "A") == 0)
arg_mod = arg;
else
arg_mod = "*", arg_memb = arg;
arg_mod = arg;
if (!prefixed) arg_mod_found[arg_mod] = false;
} else {
arg_mod = arg.substr(0, pos);
if (!prefixed) arg_mod_found[arg_mod] = false;
arg_memb = arg.substr(pos+1);
bool arg_memb_prefixed = GetSize(arg_memb) >= 2 && isalpha(arg_memb[0]) && arg_memb[1] == ':';
if (!arg_memb_prefixed) arg_memb_found[arg_memb] = false;
}
}
@ -789,8 +795,14 @@ static void select_stmt(RTLIL::Design *design, std::string arg)
if (!match_attr(mod->attributes, arg_mod.substr(2)))
continue;
} else
if (arg_mod.compare(0, 2, "N:") == 0) {
if (!match_ids(mod->name, arg_mod.substr(2)))
continue;
} else
if (!match_ids(mod->name, arg_mod))
continue;
else
arg_mod_found[arg_mod] = true;
if (arg_memb == "") {
sel.selected_modules.insert(mod->name);
@ -839,7 +851,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg)
if (match_ids(it.first, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(it.first);
} else
if (arg_memb.compare(0, 2, "c:") ==0) {
if (arg_memb.compare(0, 2, "c:") == 0) {
for (auto cell : mod->cells())
if (match_ids(cell->name, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(cell->name);
@ -873,24 +885,44 @@ static void select_stmt(RTLIL::Design *design, std::string arg)
if (match_attr(cell->parameters, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(cell->name);
} else {
std::string orig_arg_memb = arg_memb;
if (arg_memb.compare(0, 2, "n:") == 0)
arg_memb = arg_memb.substr(2);
for (auto wire : mod->wires())
if (match_ids(wire->name, arg_memb))
if (match_ids(wire->name, arg_memb)) {
sel.selected_members[mod->name].insert(wire->name);
arg_memb_found[orig_arg_memb] = true;
}
for (auto &it : mod->memories)
if (match_ids(it.first, arg_memb))
if (match_ids(it.first, arg_memb)) {
sel.selected_members[mod->name].insert(it.first);
arg_memb_found[orig_arg_memb] = true;
}
for (auto cell : mod->cells())
if (match_ids(cell->name, arg_memb))
if (match_ids(cell->name, arg_memb)) {
sel.selected_members[mod->name].insert(cell->name);
arg_memb_found[orig_arg_memb] = true;
}
for (auto &it : mod->processes)
if (match_ids(it.first, arg_memb))
if (match_ids(it.first, arg_memb)) {
sel.selected_members[mod->name].insert(it.first);
arg_memb_found[orig_arg_memb] = true;
}
}
}
select_filter_active_mod(design, work_stack.back());
for (auto &it : arg_mod_found) {
if (it.second == false && !disable_empty_warning) {
log_warning("Selection \"%s\" did not match any module.\n", it.first.c_str());
}
}
for (auto &it : arg_memb_found) {
if (it.second == false && !disable_empty_warning) {
log_warning("Selection \"%s\" did not match any object.\n", it.first.c_str());
}
}
}
static std::string describe_selection_for_assert(RTLIL::Design *design, RTLIL::Selection *sel)
@ -1074,6 +1106,10 @@ struct SelectPass : public Pass {
log(" all modules with an attribute matching the given pattern\n");
log(" in addition to = also <, <=, >=, and > are supported\n");
log("\n");
log(" N:<pattern>\n");
log(" all modules with a name matching the given pattern\n");
log(" (i.e. 'N:' is optional as it is the default matching rule)\n");
log("\n");
log("An <obj_pattern> can be an object name, wildcard expression, or one of\n");
log("the following:\n");
log("\n");
@ -1276,7 +1312,8 @@ struct SelectPass : public Pass {
}
if (arg.size() > 0 && arg[0] == '-')
log_cmd_error("Unknown option %s.\n", arg.c_str());
select_stmt(design, arg);
bool disable_empty_warning = count_mode || assert_none || assert_any || (assert_count != -1) || (assert_max != -1) || (assert_min != -1);
select_stmt(design, arg, disable_empty_warning);
sel_str += " " + arg;
}

View file

@ -38,7 +38,7 @@ struct setunset_t
value = RTLIL::Const(set_value.substr(1, GetSize(set_value)-2));
} else {
RTLIL::SigSpec sig_value;
if (!RTLIL::SigSpec::parse(sig_value, NULL, set_value))
if (!RTLIL::SigSpec::parse(sig_value, nullptr, set_value))
log_cmd_error("Can't decode value '%s'!\n", set_value.c_str());
value = sig_value.as_const();
}
@ -96,10 +96,8 @@ struct SetattrPass : public Pass {
}
extra_args(args, argidx, design);
for (auto &mod : design->modules_)
for (auto module : design->modules())
{
RTLIL::Module *module = mod.second;
if (flag_mod) {
if (design->selected_whole_module(module->name))
do_setunset(module->attributes, setunset_list);
@ -109,17 +107,17 @@ struct SetattrPass : public Pass {
if (!design->selected(module))
continue;
for (auto &it : module->wires_)
if (design->selected(module, it.second))
do_setunset(it.second->attributes, setunset_list);
for (auto wire : module->wires())
if (design->selected(module, wire))
do_setunset(wire->attributes, setunset_list);
for (auto &it : module->memories)
if (design->selected(module, it.second))
do_setunset(it.second->attributes, setunset_list);
for (auto &it : module->cells_)
if (design->selected(module, it.second))
do_setunset(it.second->attributes, setunset_list);
for (auto cell : module->cells())
if (design->selected(module, cell))
do_setunset(cell->attributes, setunset_list);
for (auto &it : module->processes)
if (design->selected(module, it.second))
@ -159,10 +157,10 @@ struct WbflipPass : public Pass {
if (!design->selected(module))
continue;
if (module->get_bool_attribute("\\blackbox"))
if (module->get_bool_attribute(ID::blackbox))
continue;
module->set_bool_attribute("\\whitebox", !module->get_bool_attribute("\\whitebox"));
module->set_bool_attribute(ID::whitebox, !module->get_bool_attribute(ID::whitebox));
}
}
} WbflipPass;
@ -208,19 +206,13 @@ struct SetparamPass : public Pass {
}
extra_args(args, argidx, design);
for (auto &mod : design->modules_)
for (auto module : design->selected_modules())
{
RTLIL::Module *module = mod.second;
if (!design->selected(module))
continue;
for (auto &it : module->cells_)
if (design->selected(module, it.second)) {
if (!new_cell_type.empty())
it.second->type = new_cell_type;
do_setunset(it.second->parameters, setunset_list);
}
for (auto cell : module->selected_cells()) {
if (!new_cell_type.empty())
cell->type = new_cell_type;
do_setunset(cell->parameters, setunset_list);
}
}
}
} SetparamPass;

View file

@ -360,10 +360,10 @@ struct SetundefPass : public Pass {
pool<Wire*> initwires;
pool<IdString> fftypes;
fftypes.insert("$dff");
fftypes.insert("$dffe");
fftypes.insert("$dffsr");
fftypes.insert("$adff");
fftypes.insert(ID($dff));
fftypes.insert(ID($dffe));
fftypes.insert(ID($dffsr));
fftypes.insert(ID($adff));
std::vector<char> list_np = {'N', 'P'}, list_01 = {'0', '1'};
@ -389,7 +389,7 @@ struct SetundefPass : public Pass {
if (!fftypes.count(cell->type))
continue;
for (auto bit : sigmap(cell->getPort("\\Q")))
for (auto bit : sigmap(cell->getPort(ID::Q)))
ffbits.insert(bit);
}
@ -411,7 +411,7 @@ struct SetundefPass : public Pass {
for (auto wire : initwires)
{
Const &initval = wire->attributes["\\init"];
Const &initval = wire->attributes[ID::init];
initval.bits.resize(GetSize(wire), State::Sx);
for (int i = 0; i < GetSize(wire); i++) {
@ -423,7 +423,7 @@ struct SetundefPass : public Pass {
}
if (initval.is_fully_undef())
wire->attributes.erase("\\init");
wire->attributes.erase(ID::init);
}
initwires.clear();
@ -439,14 +439,14 @@ struct SetundefPass : public Pass {
if (wire->name[0] == (wire_types ? '\\' : '$'))
continue;
if (!wire->attributes.count("\\init"))
if (!wire->attributes.count(ID::init))
continue;
Const &initval = wire->attributes["\\init"];
Const &initval = wire->attributes[ID::init];
initval.bits.resize(GetSize(wire), State::Sx);
if (initval.is_fully_undef()) {
wire->attributes.erase("\\init");
wire->attributes.erase(ID::init);
continue;
}

View file

@ -41,8 +41,6 @@
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
using RTLIL::id2cstr;
#undef CLUSTER_CELLS_AND_PORTBOXES
struct ShowWorker
@ -101,7 +99,7 @@ struct ShowWorker
{
sig.sort_and_unify();
for (auto &c : sig.chunks()) {
if (c.wire != NULL)
if (c.wire != nullptr)
for (auto &s : color_selections)
if (s.second.selected_members.count(module->name) > 0 && s.second.selected_members.at(module->name).count(c.wire->name) > 0)
return stringf("color=\"%s\"", s.first.c_str());
@ -218,7 +216,7 @@ struct ShowWorker
if (sig.is_chunk()) {
const RTLIL::SigChunk &c = sig.as_chunk();
if (c.wire != NULL && design->selected_member(module->name, c.wire->name)) {
if (c.wire != nullptr && design->selected_member(module->name, c.wire->name)) {
if (!range_check || c.wire->width == c.width)
return stringf("n%d", id2num(c.wire->name));
} else {
@ -230,7 +228,7 @@ struct ShowWorker
return std::string();
}
std::string gen_portbox(std::string port, RTLIL::SigSpec sig, bool driver, std::string *node = NULL)
std::string gen_portbox(std::string port, RTLIL::SigSpec sig, bool driver, std::string *node = nullptr)
{
std::string code;
std::string net = gen_signode_simple(sig);
@ -287,7 +285,7 @@ struct ShowWorker
else
code += stringf("x%d:e -> %s:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, %s, %s];\n", idx, port.c_str(), nextColor(sig).c_str(), widthLabel(sig.size()).c_str());
}
if (node != NULL)
if (node != nullptr)
*node = stringf("x%d", idx);
}
else
@ -300,7 +298,7 @@ struct ShowWorker
net_conn_map[net].bits = sig.size();
net_conn_map[net].color = nextColor(sig, net_conn_map[net].color);
}
if (node != NULL)
if (node != nullptr)
*node = net;
}
return code;
@ -366,22 +364,20 @@ struct ShowWorker
std::set<std::string> all_sources, all_sinks;
std::map<std::string, std::string> wires_on_demand;
for (auto &it : module->wires_) {
if (!design->selected_member(module->name, it.first))
continue;
for (auto wire : module->selected_wires()) {
const char *shape = "diamond";
if (it.second->port_input || it.second->port_output)
if (wire->port_input || wire->port_output)
shape = "octagon";
if (it.first[0] == '\\') {
if (wire->name[0] == '\\') {
fprintf(f, "n%d [ shape=%s, label=\"%s\", %s, fontcolor=\"black\" ];\n",
id2num(it.first), shape, findLabel(it.first.str()),
nextColor(RTLIL::SigSpec(it.second), "color=\"black\"").c_str());
if (it.second->port_input)
all_sources.insert(stringf("n%d", id2num(it.first)));
else if (it.second->port_output)
all_sinks.insert(stringf("n%d", id2num(it.first)));
id2num(wire->name), shape, findLabel(wire->name.str()),
nextColor(RTLIL::SigSpec(wire), "color=\"black\"").c_str());
if (wire->port_input)
all_sources.insert(stringf("n%d", id2num(wire->name)));
else if (wire->port_output)
all_sinks.insert(stringf("n%d", id2num(wire->name)));
} else {
wires_on_demand[stringf("n%d", id2num(it.first))] = it.first.str();
wires_on_demand[stringf("n%d", id2num(wire->name))] = wire->name.str();
}
}
@ -398,15 +394,12 @@ struct ShowWorker
fprintf(f, "}\n");
}
for (auto &it : module->cells_)
for (auto cell : module->selected_cells())
{
if (!design->selected_member(module->name, it.first))
continue;
std::vector<RTLIL::IdString> in_ports, out_ports;
for (auto &conn : it.second->connections()) {
if (!ct.cell_output(it.second->type, conn.first))
for (auto &conn : cell->connections()) {
if (!ct.cell_output(cell->type, conn.first))
in_ports.push_back(conn.first);
else
out_ports.push_back(conn.first);
@ -419,12 +412,12 @@ struct ShowWorker
for (auto &p : in_ports)
label_string += stringf("<p%d> %s%s|", id2num(p), escape(p.str()),
genSignedLabels && it.second->hasParam(p.str() + "_SIGNED") &&
it.second->getParam(p.str() + "_SIGNED").as_bool() ? "*" : "");
genSignedLabels && cell->hasParam(p.str() + "_SIGNED") &&
cell->getParam(p.str() + "_SIGNED").as_bool() ? "*" : "");
if (label_string[label_string.size()-1] == '|')
label_string = label_string.substr(0, label_string.size()-1);
label_string += stringf("}|%s\\n%s|{", findLabel(it.first.str()), escape(it.second->type.str()));
label_string += stringf("}|%s\\n%s|{", findLabel(cell->name.str()), escape(cell->type.str()));
for (auto &p : out_ports)
label_string += stringf("<p%d> %s|", id2num(p), escape(p.str()));
@ -434,19 +427,19 @@ struct ShowWorker
label_string += "}}";
std::string code;
for (auto &conn : it.second->connections()) {
code += gen_portbox(stringf("c%d:p%d", id2num(it.first), id2num(conn.first)),
conn.second, ct.cell_output(it.second->type, conn.first));
for (auto &conn : cell->connections()) {
code += gen_portbox(stringf("c%d:p%d", id2num(cell->name), id2num(conn.first)),
conn.second, ct.cell_output(cell->type, conn.first));
}
#ifdef CLUSTER_CELLS_AND_PORTBOXES
if (!code.empty())
fprintf(f, "subgraph cluster_c%d {\nc%d [ shape=record, label=\"%s\"%s ];\n%s}\n",
id2num(it.first), id2num(it.first), label_string.c_str(), findColor(it.first), code.c_str());
id2num(cell->name), id2num(cell->name), label_string.c_str(), findColor(cell->name), code.c_str());
else
#endif
fprintf(f, "c%d [ shape=record, label=\"%s\"%s ];\n%s",
id2num(it.first), label_string.c_str(), findColor(it.first.str()), code.c_str());
id2num(cell->name), label_string.c_str(), findColor(cell->name.str()), code.c_str());
}
for (auto &it : module->processes)
@ -482,8 +475,8 @@ struct ShowWorker
}
std::string proc_src = RTLIL::unescape_id(proc->name);
if (proc->attributes.count("\\src") > 0)
proc_src = proc->attributes.at("\\src").decode_string();
if (proc->attributes.count(ID::src) > 0)
proc_src = proc->attributes.at(ID::src).decode_string();
fprintf(f, "p%d [shape=box, style=rounded, label=\"PROC %s\\n%s\"];\n", pidx, findLabel(proc->name.str()), proc_src.c_str());
}
@ -491,12 +484,12 @@ struct ShowWorker
{
bool found_lhs_wire = false;
for (auto &c : conn.first.chunks()) {
if (c.wire == NULL || design->selected_member(module->name, c.wire->name))
if (c.wire == nullptr || design->selected_member(module->name, c.wire->name))
found_lhs_wire = true;
}
bool found_rhs_wire = false;
for (auto &c : conn.second.chunks()) {
if (c.wire == NULL || design->selected_member(module->name, c.wire->name))
if (c.wire == nullptr || design->selected_member(module->name, c.wire->name))
found_rhs_wire = true;
}
if (!found_lhs_wire || !found_rhs_wire)
@ -572,23 +565,21 @@ struct ShowWorker
design->optimize();
page_counter = 0;
for (auto &mod_it : design->modules_)
for (auto mod : design->selected_modules())
{
module = mod_it.second;
if (!design->selected_module(module->name))
continue;
module = mod;
if (design->selected_whole_module(module->name)) {
if (module->get_blackbox_attribute()) {
// log("Skipping blackbox module %s.\n", id2cstr(module->name));
// log("Skipping blackbox module %s.\n", log_id(module->name));
continue;
} else
if (module->cells_.empty() && module->connections().empty() && module->processes.empty()) {
log("Skipping empty module %s.\n", id2cstr(module->name));
if (module->cells().size() == 0 && module->connections().empty() && module->processes.empty()) {
log("Skipping empty module %s.\n", log_id(module->name));
continue;
} else
log("Dumping module %s to page %d.\n", id2cstr(module->name), ++page_counter);
log("Dumping module %s to page %d.\n", log_id(module->name), ++page_counter);
} else
log("Dumping selected parts of module %s to page %d.\n", id2cstr(module->name), ++page_counter);
log("Dumping selected parts of module %s to page %d.\n", log_id(module->name), ++page_counter);
handle_module();
}
}
@ -802,13 +793,12 @@ struct ShowPass : public Pass {
if (format != "ps" && format != "dot") {
int modcount = 0;
for (auto &mod_it : design->modules_) {
if (mod_it.second->get_blackbox_attribute())
for (auto module : design->selected_modules()) {
if (module->get_blackbox_attribute())
continue;
if (mod_it.second->cells_.empty() && mod_it.second->connections().empty())
if (module->cells().size() == 0 && module->connections().empty())
continue;
if (design->selected_module(mod_it.first))
modcount++;
modcount++;
}
if (modcount > 1)
log_cmd_error("For formats different than 'ps' or 'dot' only one module must be selected.\n");
@ -835,7 +825,7 @@ struct ShowPass : public Pass {
FILE *f = fopen(dot_file.c_str(), "w");
if (custom_prefix)
yosys_output_files.insert(dot_file);
if (f == NULL) {
if (f == nullptr) {
for (auto lib : libs)
delete lib;
log_cmd_error("Can't open dot file `%s' for writing.\n", dot_file.c_str());
@ -889,8 +879,8 @@ struct ShowPass : public Pass {
if (flag_pause) {
#ifdef YOSYS_ENABLE_READLINE
char *input = NULL;
while ((input = readline("Press ENTER to continue (or type 'shell' to open a shell)> ")) != NULL) {
char *input = nullptr;
while ((input = readline("Press ENTER to continue (or type 'shell' to open a shell)> ")) != nullptr) {
if (input[strspn(input, " \t\r\n")] == 0)
break;
char *p = input + strspn(input, " \t\r\n");

View file

@ -75,13 +75,13 @@ struct SpliceWorker
RTLIL::SigSpec new_sig = sig;
if (sig_a.size() != sig.size()) {
RTLIL::Cell *cell = module->addCell(NEW_ID, "$slice");
cell->parameters["\\OFFSET"] = offset;
cell->parameters["\\A_WIDTH"] = sig_a.size();
cell->parameters["\\Y_WIDTH"] = sig.size();
cell->setPort("\\A", sig_a);
cell->setPort("\\Y", module->addWire(NEW_ID, sig.size()));
new_sig = cell->getPort("\\Y");
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($slice));
cell->parameters[ID::OFFSET] = offset;
cell->parameters[ID::A_WIDTH] = sig_a.size();
cell->parameters[ID::Y_WIDTH] = sig.size();
cell->setPort(ID::A, sig_a);
cell->setPort(ID::Y, module->addWire(NEW_ID, sig.size()));
new_sig = cell->getPort(ID::Y);
}
sliced_signals_cache[sig] = new_sig;
@ -102,7 +102,7 @@ struct SpliceWorker
for (auto &bit : sig.to_sigbit_vector())
{
if (bit.wire == NULL)
if (bit.wire == nullptr)
{
if (last_bit == 0)
chunks.back().append(bit);
@ -132,13 +132,13 @@ struct SpliceWorker
RTLIL::SigSpec new_sig = get_sliced_signal(chunks.front());
for (size_t i = 1; i < chunks.size(); i++) {
RTLIL::SigSpec sig2 = get_sliced_signal(chunks[i]);
RTLIL::Cell *cell = module->addCell(NEW_ID, "$concat");
cell->parameters["\\A_WIDTH"] = new_sig.size();
cell->parameters["\\B_WIDTH"] = sig2.size();
cell->setPort("\\A", new_sig);
cell->setPort("\\B", sig2);
cell->setPort("\\Y", module->addWire(NEW_ID, new_sig.size() + sig2.size()));
new_sig = cell->getPort("\\Y");
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($concat));
cell->parameters[ID::A_WIDTH] = new_sig.size();
cell->parameters[ID::B_WIDTH] = sig2.size();
cell->setPort(ID::A, new_sig);
cell->setPort(ID::B, sig2);
cell->setPort(ID::Y, module->addWire(NEW_ID, new_sig.size() + sig2.size()));
new_sig = cell->getPort(ID::Y);
}
spliced_signals_cache[sig] = new_sig;
@ -149,23 +149,23 @@ struct SpliceWorker
void run()
{
log("Splicing signals in module %s:\n", RTLIL::id2cstr(module->name));
log("Splicing signals in module %s:\n", log_id(module->name));
driven_bits.push_back(RTLIL::State::Sm);
driven_bits.push_back(RTLIL::State::Sm);
for (auto &it : module->wires_)
if (it.second->port_input) {
RTLIL::SigSpec sig = sigmap(it.second);
for (auto wire : module->wires())
if (wire->port_input) {
RTLIL::SigSpec sig = sigmap(wire);
driven_chunks.insert(sig);
for (auto &bit : sig.to_sigbit_vector())
driven_bits.push_back(bit);
driven_bits.push_back(RTLIL::State::Sm);
}
for (auto &it : module->cells_)
for (auto &conn : it.second->connections())
if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first)) {
for (auto cell : module->cells())
for (auto &conn : cell->connections())
if (!ct.cell_known(cell->type) || ct.cell_output(cell->type, conn.first)) {
RTLIL::SigSpec sig = sigmap(conn.second);
driven_chunks.insert(sig);
for (auto &bit : sig.to_sigbit_vector())
@ -180,9 +180,8 @@ struct SpliceWorker
SigPool selected_bits;
if (!sel_by_cell)
for (auto &it : module->wires_)
if (design->selected(module, it.second))
selected_bits.add(sigmap(it.second));
for (auto wire : module->selected_wires())
selected_bits.add(sigmap(wire));
std::vector<Cell*> mod_cells = module->cells();
@ -343,17 +342,14 @@ struct SplicePass : public Pass {
log_header(design, "Executing SPLICE pass (creating cells for signal splicing).\n");
for (auto &mod_it : design->modules_)
for (auto module : design->selected_modules())
{
if (!design->selected(mod_it.second))
continue;
if (mod_it.second->processes.size()) {
log("Skipping module %s as it contains processes.\n", mod_it.second->name.c_str());
if (module->processes.size()) {
log("Skipping module %s as it contains processes.\n", module->name.c_str());
continue;
}
SpliceWorker worker(design, mod_it.second);
SpliceWorker worker(design, module);
worker.sel_by_cell = sel_by_cell;
worker.sel_by_wire = sel_by_wire;
worker.sel_any_bit = sel_any_bit;

View file

@ -60,17 +60,17 @@ struct SplitnetsWorker
new_wire->port_input = wire->port_input;
new_wire->port_output = wire->port_output;
if (wire->attributes.count("\\src"))
new_wire->attributes["\\src"] = wire->attributes.at("\\src");
if (wire->attributes.count(ID::src))
new_wire->attributes[ID::src] = wire->attributes.at(ID::src);
if (wire->attributes.count("\\keep"))
new_wire->attributes["\\keep"] = wire->attributes.at("\\keep");
if (wire->attributes.count(ID::keep))
new_wire->attributes[ID::keep] = wire->attributes.at(ID::keep);
if (wire->attributes.count("\\init")) {
Const old_init = wire->attributes.at("\\init"), new_init;
if (wire->attributes.count(ID::init)) {
Const old_init = wire->attributes.at(ID::init), new_init;
for (int i = offset; i < offset+width; i++)
new_init.bits.push_back(i < GetSize(old_init) ? old_init.bits.at(i) : State::Sx);
new_wire->attributes["\\init"] = new_init;
new_wire->attributes[ID::init] = new_init;
}
std::vector<RTLIL::SigBit> sigvec = RTLIL::SigSpec(new_wire).to_sigbit_vector();

View file

@ -79,18 +79,15 @@ struct statdata_t
STAT_NUMERIC_MEMBERS
#undef X
for (auto &it : mod->wires_)
for (auto wire : mod->selected_wires())
{
if (!design->selected(mod, it.second))
continue;
if (it.first[0] == '\\') {
if (wire->name[0] == '\\') {
num_pub_wires++;
num_pub_wire_bits += it.second->width;
num_pub_wire_bits += wire->width;
}
num_wires++;
num_wire_bits += it.second->width;
num_wire_bits += wire->width;
}
for (auto &it : mod->memories) {
@ -100,31 +97,28 @@ struct statdata_t
num_memory_bits += it.second->width * it.second->size;
}
for (auto &it : mod->cells_)
for (auto cell : mod->selected_cells())
{
if (!design->selected(mod, it.second))
continue;
RTLIL::IdString cell_type = it.second->type;
RTLIL::IdString cell_type = cell->type;
if (width_mode)
{
if (cell_type.in("$not", "$pos", "$neg",
"$logic_not", "$logic_and", "$logic_or",
"$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool",
"$lut", "$and", "$or", "$xor", "$xnor",
"$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx",
"$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt",
"$add", "$sub", "$mul", "$div", "$mod", "$pow", "$alu")) {
int width_a = it.second->hasPort("\\A") ? GetSize(it.second->getPort("\\A")) : 0;
int width_b = it.second->hasPort("\\B") ? GetSize(it.second->getPort("\\B")) : 0;
int width_y = it.second->hasPort("\\Y") ? GetSize(it.second->getPort("\\Y")) : 0;
if (cell_type.in(ID($not), ID($pos), ID($neg),
ID($logic_not), ID($logic_and), ID($logic_or),
ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool),
ID($lut), ID($and), ID($or), ID($xor), ID($xnor),
ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx),
ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt),
ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow), ID($alu))) {
int width_a = cell->hasPort(ID::A) ? GetSize(cell->getPort(ID::A)) : 0;
int width_b = cell->hasPort(ID::B) ? GetSize(cell->getPort(ID::B)) : 0;
int width_y = cell->hasPort(ID::Y) ? GetSize(cell->getPort(ID::Y)) : 0;
cell_type = stringf("%s_%d", cell_type.c_str(), max<int>({width_a, width_b, width_y}));
}
else if (cell_type.in("$mux", "$pmux"))
cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(it.second->getPort("\\Y")));
else if (cell_type.in("$sr", "$dff", "$dffsr", "$adff", "$dlatch", "$dlatchsr"))
cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(it.second->getPort("\\Q")));
else if (cell_type.in(ID($mux), ID($pmux)))
cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(cell->getPort(ID::Y)));
else if (cell_type.in(ID($sr), ID($dff), ID($dffsr), ID($adff), ID($dlatch), ID($dlatchsr)))
cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(cell->getPort(ID::Q)));
}
if (!cell_area.empty()) {
@ -157,7 +151,7 @@ struct statdata_t
log(" Number of cells: %6d\n", num_cells);
for (auto &it : num_cells_by_type)
if (it.second)
log(" %-26s %6d\n", RTLIL::id2cstr(it.first), it.second);
log(" %-26s %6d\n", log_id(it.first), it.second);
if (!unknown_cell_area.empty()) {
log("\n");
@ -172,12 +166,12 @@ struct statdata_t
if (tech == "xilinx")
{
int lut6_cnt = num_cells_by_type["\\LUT6"];
int lut5_cnt = num_cells_by_type["\\LUT5"];
int lut4_cnt = num_cells_by_type["\\LUT4"];
int lut3_cnt = num_cells_by_type["\\LUT3"];
int lut2_cnt = num_cells_by_type["\\LUT2"];
int lut1_cnt = num_cells_by_type["\\LUT1"];
int lut6_cnt = num_cells_by_type[ID(LUT6)];
int lut5_cnt = num_cells_by_type[ID(LUT5)];
int lut4_cnt = num_cells_by_type[ID(LUT4)];
int lut3_cnt = num_cells_by_type[ID(LUT3)];
int lut2_cnt = num_cells_by_type[ID(LUT2)];
int lut1_cnt = num_cells_by_type[ID(LUT1)];
int lc_cnt = 0;
lc_cnt += lut6_cnt;
@ -235,7 +229,7 @@ struct statdata_t
if (gate_costs.count(ctype))
tran_cnt += cnum * gate_costs.at(ctype);
else if (ctype.in("$_DFF_P_", "$_DFF_N_"))
else if (ctype.in(ID($_DFF_P_), ID($_DFF_N_)))
tran_cnt += cnum * 16;
else
tran_cnt_exact = false;
@ -255,7 +249,7 @@ statdata_t hierarchy_worker(std::map<RTLIL::IdString, statdata_t> &mod_stat, RTL
for (auto &it : num_cells_by_type)
if (mod_stat.count(it.first) > 0) {
log(" %*s%-*s %6d\n", 2*level, "", 26-2*level, RTLIL::id2cstr(it.first), it.second);
log(" %*s%-*s %6d\n", 2*level, "", 26-2*level, log_id(it.first), it.second);
mod_data = mod_data + hierarchy_worker(mod_stat, it.first, level+1) * it.second;
mod_data.num_cells -= it.second;
} else {
@ -281,7 +275,7 @@ void read_liberty_cellarea(dict<IdString, double> &cell_area, string liberty_fil
continue;
LibertyAst *ar = cell->find("area");
if (ar != NULL && !ar->value.empty())
if (ar != nullptr && !ar->value.empty())
cell_area["\\" + cell->args[0]] = atof(ar->value.c_str());
}
}
@ -319,7 +313,7 @@ struct StatPass : public Pass {
log_header(design, "Printing statistics.\n");
bool width_mode = false;
RTLIL::Module *top_mod = NULL;
RTLIL::Module *top_mod = nullptr;
std::map<RTLIL::IdString, statdata_t> mod_stat;
dict<IdString, double> cell_area;
string techname;
@ -342,9 +336,9 @@ struct StatPass : public Pass {
continue;
}
if (args[argidx] == "-top" && argidx+1 < args.size()) {
if (design->modules_.count(RTLIL::escape_id(args[argidx+1])) == 0)
if (design->module(RTLIL::escape_id(args[argidx+1])) == nullptr)
log_cmd_error("Can't find module %s.\n", args[argidx+1].c_str());
top_mod = design->modules_.at(RTLIL::escape_id(args[++argidx]));
top_mod = design->module(RTLIL::escape_id(args[++argidx]));
continue;
}
break;
@ -357,25 +351,25 @@ struct StatPass : public Pass {
for (auto mod : design->selected_modules())
{
if (!top_mod && design->full_selection())
if (mod->get_bool_attribute("\\top"))
if (mod->get_bool_attribute(ID::top))
top_mod = mod;
statdata_t data(design, mod, width_mode, cell_area, techname);
mod_stat[mod->name] = data;
log("\n");
log("=== %s%s ===\n", RTLIL::id2cstr(mod->name), design->selected_whole_module(mod->name) ? "" : " (partially selected)");
log("=== %s%s ===\n", log_id(mod->name), design->selected_whole_module(mod->name) ? "" : " (partially selected)");
log("\n");
data.log_data(mod->name, false);
}
if (top_mod != NULL && GetSize(mod_stat) > 1)
if (top_mod != nullptr && GetSize(mod_stat) > 1)
{
log("\n");
log("=== design hierarchy ===\n");
log("\n");
log(" %-28s %6d\n", RTLIL::id2cstr(top_mod->name), 1);
log(" %-28s %6d\n", log_id(top_mod->name), 1);
statdata_t data = hierarchy_worker(mod_stat, top_mod->name, 0);
log("\n");

View file

@ -81,9 +81,9 @@ struct TorderPass : public Pass {
continue;
if (!noautostop && yosys_celltypes.cell_known(cell->type)) {
if (conn.first.in("\\Q", "\\CTRL_OUT", "\\RD_DATA"))
if (conn.first.in(ID::Q, ID::CTRL_OUT, ID::RD_DATA))
continue;
if (cell->type == "$memrd" && conn.first == "\\DATA")
if (cell->type == ID($memrd) && conn.first == ID::DATA)
continue;
}

View file

@ -35,7 +35,7 @@ struct TraceMonitor : public RTLIL::Monitor
log("#TRACE# Module delete: %s\n", log_id(module));
}
void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) YS_OVERRIDE
void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) YS_OVERRIDE
{
log("#TRACE# Cell connect: %s.%s.%s = %s (was: %s)\n", log_id(cell->module), log_id(cell), log_id(port), log_signal(sig), log_signal(old_sig));
}

View file

@ -152,7 +152,7 @@ struct EquivAddPass : public Pass {
for (int i = 0; i < GetSize(gold_signal); i++) {
Cell *equiv_cell = module->addEquiv(NEW_ID, gold_signal[i], gate_signal[i], equiv_signal[i]);
equiv_cell->set_bool_attribute("\\keep");
equiv_cell->set_bool_attribute(ID::keep);
to_equiv_bits[gold_signal[i]] = equiv_signal[i];
to_equiv_bits[gate_signal[i]] = equiv_signal[i];
added_equiv_cells.insert(equiv_cell);

View file

@ -58,9 +58,9 @@ struct EquivInductWorker
log_warning("No SAT model available for cell %s (%s).\n", log_id(cell), log_id(cell->type));
cell_warn_cache.insert(cell);
}
if (cell->type == "$equiv") {
SigBit bit_a = sigmap(cell->getPort("\\A")).as_bit();
SigBit bit_b = sigmap(cell->getPort("\\B")).as_bit();
if (cell->type == ID($equiv)) {
SigBit bit_a = sigmap(cell->getPort(ID::A)).as_bit();
SigBit bit_b = sigmap(cell->getPort(ID::B)).as_bit();
if (bit_a != bit_b) {
int ez_a = satgen.importSigBit(bit_a, step);
int ez_b = satgen.importSigBit(bit_b, step);
@ -125,7 +125,7 @@ struct EquivInductWorker
if (!ez->solve(new_step_not_consistent)) {
log(" Proof for induction step holds. Entire workset of %d cells proven!\n", GetSize(workset));
for (auto cell : workset)
cell->setPort("\\B", cell->getPort("\\A"));
cell->setPort(ID::B, cell->getPort(ID::A));
success_counter += GetSize(workset);
return;
}
@ -137,10 +137,10 @@ struct EquivInductWorker
for (auto cell : workset)
{
SigBit bit_a = sigmap(cell->getPort("\\A")).as_bit();
SigBit bit_b = sigmap(cell->getPort("\\B")).as_bit();
SigBit bit_a = sigmap(cell->getPort(ID::A)).as_bit();
SigBit bit_b = sigmap(cell->getPort(ID::B)).as_bit();
log(" Trying to prove $equiv for %s:", log_signal(sigmap(cell->getPort("\\Y"))));
log(" Trying to prove $equiv for %s:", log_signal(sigmap(cell->getPort(ID::Y))));
int ez_a = satgen.importSigBit(bit_a, max_seq+1);
int ez_b = satgen.importSigBit(bit_b, max_seq+1);
@ -151,7 +151,7 @@ struct EquivInductWorker
if (!ez->solve(cond)) {
log(" success!\n");
cell->setPort("\\B", cell->getPort("\\A"));
cell->setPort(ID::B, cell->getPort(ID::A));
success_counter++;
} else {
log(" failed.\n");
@ -219,8 +219,8 @@ struct EquivInductPass : public Pass {
pool<Cell*> unproven_equiv_cells;
for (auto cell : module->selected_cells())
if (cell->type == "$equiv") {
if (cell->getPort("\\A") != cell->getPort("\\B"))
if (cell->type == ID($equiv)) {
if (cell->getPort(ID::A) != cell->getPort(ID::B))
unproven_equiv_cells.insert(cell);
}

View file

@ -406,7 +406,7 @@ struct EquivMakeWorker
void init_bit2driven()
{
for (auto cell : equiv_mod->cells()) {
if (!ct.cell_known(cell->type) && !cell->type.in("$dff", "$_DFF_P_", "$_DFF_N_", "$ff", "$_FF_"))
if (!ct.cell_known(cell->type) && !cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_), ID($ff), ID($_FF_)))
continue;
for (auto &conn : cell->connections())
{

View file

@ -48,7 +48,7 @@ struct EquivMarkWorker
{
for (auto cell : module->cells())
{
if (cell->type == "$equiv")
if (cell->type == ID($equiv))
equiv_cells.insert(cell->name);
for (auto &port : cell->connections())
@ -122,8 +122,8 @@ struct EquivMarkWorker
{
auto cell = module->cell(cell_name);
SigSpec sig_a = sigmap(cell->getPort("\\A"));
SigSpec sig_b = sigmap(cell->getPort("\\B"));
SigSpec sig_a = sigmap(cell->getPort(ID::A));
SigSpec sig_b = sigmap(cell->getPort(ID::B));
if (sig_a == sig_b) {
for (auto bit : sig_a)
@ -139,11 +139,11 @@ struct EquivMarkWorker
for (auto cell : module->cells())
{
if (cell_regions.count(cell->name) || cell->type != "$equiv")
if (cell_regions.count(cell->name) || cell->type != ID($equiv))
continue;
SigSpec sig_a = sigmap(cell->getPort("\\A"));
SigSpec sig_b = sigmap(cell->getPort("\\B"));
SigSpec sig_a = sigmap(cell->getPort(ID::A));
SigSpec sig_b = sigmap(cell->getPort(ID::B));
log_assert(sig_a != sig_b);
@ -176,10 +176,10 @@ struct EquivMarkWorker
{
if (cell_regions.count(cell->name)) {
int r = final_region_map.at(cell_regions.at(cell->name));
cell->attributes["\\equiv_region"] = Const(r);
cell->attributes[ID::equiv_region] = Const(r);
region_cell_count[r]++;
} else
cell->attributes.erase("\\equiv_region");
cell->attributes.erase(ID::equiv_region);
}
for (auto wire : module->wires())
@ -191,10 +191,10 @@ struct EquivMarkWorker
if (GetSize(regions) == 1) {
int r = final_region_map.at(*regions.begin());
wire->attributes["\\equiv_region"] = Const(r);
wire->attributes[ID::equiv_region] = Const(r);
region_wire_count[r]++;
} else
wire->attributes.erase("\\equiv_region");
wire->attributes.erase(ID::equiv_region);
}
for (int i = 0; i < next_final_region; i++)

View file

@ -47,7 +47,7 @@ struct EquivMiterWorker
if (cone.count(c))
return;
if (c->type == "$equiv" && !seed_cells.count(c)) {
if (c->type == ID($equiv) && !seed_cells.count(c)) {
leaves.insert(c);
return;
}
@ -57,7 +57,7 @@ struct EquivMiterWorker
for (auto &conn : c->connections()) {
if (!ct.cell_input(c->type, conn.first))
continue;
if (c->type == "$equiv" && (conn.first == "\\A") != gold_mode)
if (c->type == ID($equiv) && (conn.first == ID::A) != gold_mode)
continue;
for (auto bit : sigmap(conn.second))
if (bit_to_driver.count(bit))
@ -81,7 +81,7 @@ struct EquivMiterWorker
// find seed cells
for (auto c : source_module->selected_cells())
if (c->type == "$equiv") {
if (c->type == ID($equiv)) {
log("Seed $equiv cell: %s\n", log_id(c));
seed_cells.insert(c);
}
@ -213,18 +213,18 @@ struct EquivMiterWorker
vector<Cell*> equiv_cells;
for (auto c : miter_module->cells())
if (c->type == "$equiv" && c->getPort("\\A") != c->getPort("\\B"))
if (c->type == ID($equiv) && c->getPort(ID::A) != c->getPort(ID::B))
equiv_cells.push_back(c);
for (auto c : equiv_cells)
{
SigSpec cmp = mode_undef ?
miter_module->LogicOr(NEW_ID, miter_module->Eqx(NEW_ID, c->getPort("\\A"), State::Sx),
miter_module->Eqx(NEW_ID, c->getPort("\\A"), c->getPort("\\B"))) :
miter_module->Eq(NEW_ID, c->getPort("\\A"), c->getPort("\\B"));
miter_module->LogicOr(NEW_ID, miter_module->Eqx(NEW_ID, c->getPort(ID::A), State::Sx),
miter_module->Eqx(NEW_ID, c->getPort(ID::A), c->getPort(ID::B))) :
miter_module->Eq(NEW_ID, c->getPort(ID::A), c->getPort(ID::B));
if (mode_cmp) {
string cmp_name = string("\\cmp") + log_signal(c->getPort("\\Y"));
string cmp_name = stringf("\\cmp%s", log_signal(c->getPort(ID::Y)));
for (int i = 1; i < GetSize(cmp_name); i++)
if (cmp_name[i] == '\\')
cmp_name[i] = '_';
@ -242,7 +242,7 @@ struct EquivMiterWorker
}
if (mode_trigger) {
auto w = miter_module->addWire("\\trigger");
auto w = miter_module->addWire(ID(trigger));
w->port_output = true;
miter_module->addReduceOr(NEW_ID, trigger_signals, w);
}

View file

@ -102,7 +102,7 @@ struct EquivPurgeWorker
for (auto cell : module->cells())
{
if (cell->type != "$equiv") {
if (cell->type != ID($equiv)) {
for (auto &port : cell->connections()) {
if (cell->input(port.first))
for (auto bit : sigmap(port.second))
@ -114,9 +114,9 @@ struct EquivPurgeWorker
continue;
}
SigSpec sig_a = sigmap(cell->getPort("\\A"));
SigSpec sig_b = sigmap(cell->getPort("\\B"));
SigSpec sig_y = sigmap(cell->getPort("\\Y"));
SigSpec sig_a = sigmap(cell->getPort(ID::A));
SigSpec sig_b = sigmap(cell->getPort(ID::B));
SigSpec sig_y = sigmap(cell->getPort(ID::Y));
if (sig_a == sig_b)
continue;
@ -130,7 +130,7 @@ struct EquivPurgeWorker
for (auto bit : sig_y)
visited.insert(bit);
cell->setPort("\\Y", make_output(sig_y, cell->name));
cell->setPort(ID::Y, make_output(sig_y, cell->name));
}
SigSpec srcsig;
@ -167,8 +167,8 @@ struct EquivPurgeWorker
rewrite_sigmap.add(chunk, make_input(chunk));
for (auto cell : module->cells())
if (cell->type == "$equiv")
cell->setPort("\\Y", rewrite_sigmap(sigmap(cell->getPort("\\Y"))));
if (cell->type == ID($equiv))
cell->setPort(ID::Y, rewrite_sigmap(sigmap(cell->getPort(ID::Y))));
module->fixup_ports();
}

View file

@ -68,9 +68,9 @@ struct EquivRemovePass : public Pass {
for (auto module : design->selected_modules())
{
for (auto cell : module->selected_cells())
if (cell->type == "$equiv" && (mode_gold || mode_gate || cell->getPort("\\A") == cell->getPort("\\B"))) {
log("Removing $equiv cell %s.%s (%s).\n", log_id(module), log_id(cell), log_signal(cell->getPort("\\Y")));
module->connect(cell->getPort("\\Y"), mode_gate ? cell->getPort("\\B") : cell->getPort("\\A"));
if (cell->type == ID($equiv) && (mode_gold || mode_gate || cell->getPort(ID::A) == cell->getPort(ID::B))) {
log("Removing $equiv cell %s.%s (%s).\n", log_id(module), log_id(cell), log_signal(cell->getPort(ID::Y)));
module->connect(cell->getPort(ID::Y), mode_gate ? cell->getPort(ID::B) : cell->getPort(ID::A));
module->remove(cell);
remove_count++;
}

View file

@ -60,8 +60,8 @@ struct EquivSimpleWorker
for (auto &conn : cell->connections())
if (yosys_celltypes.cell_input(cell->type, conn.first))
for (auto bit : sigmap(conn.second)) {
if (cell->type.in("$dff", "$_DFF_P_", "$_DFF_N_", "$ff", "$_FF_")) {
if (!conn.first.in("\\CLK", "\\C"))
if (cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_), ID($ff), ID($_FF_))) {
if (!conn.first.in(ID::CLK, ID::C))
next_seed.insert(bit);
} else
find_input_cone(next_seed, cells_cone, bits_cone, cells_stop, bits_stop, input_bits, bit);
@ -90,8 +90,8 @@ struct EquivSimpleWorker
bool run_cell()
{
SigBit bit_a = sigmap(equiv_cell->getPort("\\A")).as_bit();
SigBit bit_b = sigmap(equiv_cell->getPort("\\B")).as_bit();
SigBit bit_a = sigmap(equiv_cell->getPort(ID::A)).as_bit();
SigBit bit_b = sigmap(equiv_cell->getPort(ID::B)).as_bit();
int ez_context = ez->frozen_literal();
if (satgen.model_undef)
@ -115,9 +115,9 @@ struct EquivSimpleWorker
if (verbose) {
log(" Trying to prove $equiv cell %s:\n", log_id(equiv_cell));
log(" A = %s, B = %s, Y = %s\n", log_signal(bit_a), log_signal(bit_b), log_signal(equiv_cell->getPort("\\Y")));
log(" A = %s, B = %s, Y = %s\n", log_signal(bit_a), log_signal(bit_b), log_signal(equiv_cell->getPort(ID::Y)));
} else {
log(" Trying to prove $equiv for %s:", log_signal(equiv_cell->getPort("\\Y")));
log(" Trying to prove $equiv for %s:", log_signal(equiv_cell->getPort(ID::Y)));
}
int step = max_seq;
@ -199,7 +199,7 @@ struct EquivSimpleWorker
if (!ez->solve(ez_context)) {
log(verbose ? " Proved equivalence! Marking $equiv cell as proven.\n" : " success!\n");
equiv_cell->setPort("\\B", equiv_cell->getPort("\\A"));
equiv_cell->setPort(ID::B, equiv_cell->getPort(ID::A));
ez->assume(ez->NOT(ez_context));
return true;
}
@ -256,7 +256,7 @@ struct EquivSimpleWorker
if (GetSize(equiv_cells) > 1) {
SigSpec sig;
for (auto c : equiv_cells)
sig.append(sigmap(c->getPort("\\Y")));
sig.append(sigmap(c->getPort(ID::Y)));
log(" Grouping SAT models for %s:\n", log_signal(sig));
}
@ -344,8 +344,8 @@ struct EquivSimplePass : public Pass {
int unproven_cells_counter = 0;
for (auto cell : module->selected_cells())
if (cell->type == "$equiv" && cell->getPort("\\A") != cell->getPort("\\B")) {
auto bit = sigmap(cell->getPort("\\Y").as_bit());
if (cell->type == ID($equiv) && cell->getPort(ID::A) != cell->getPort(ID::B)) {
auto bit = sigmap(cell->getPort(ID::Y).as_bit());
auto bit_group = bit;
if (!nogroup && bit_group.wire)
bit_group.offset = 0;
@ -360,7 +360,7 @@ struct EquivSimplePass : public Pass {
unproven_cells_counter, GetSize(unproven_equiv_cells), log_id(module));
for (auto cell : module->cells()) {
if (!ct.cell_known(cell->type) && !cell->type.in("$dff", "$_DFF_P_", "$_DFF_N_", "$ff", "$_FF_"))
if (!ct.cell_known(cell->type) && !cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_), ID($ff), ID($_FF_)))
continue;
for (auto &conn : cell->connections())
if (yosys_celltypes.cell_output(cell->type, conn.first))

View file

@ -59,8 +59,8 @@ struct EquivStatusPass : public Pass {
int proven_equiv_cells = 0;
for (auto cell : module->selected_cells())
if (cell->type == "$equiv") {
if (cell->getPort("\\A") != cell->getPort("\\B"))
if (cell->type == ID($equiv)) {
if (cell->getPort(ID::A) != cell->getPort(ID::B))
unproven_equiv_cells.push_back(cell);
else
proven_equiv_cells++;
@ -77,7 +77,7 @@ struct EquivStatusPass : public Pass {
log(" Equivalence successfully proven!\n");
} else {
for (auto cell : unproven_equiv_cells)
log(" Unproven $equiv %s: %s %s\n", log_id(cell), log_signal(cell->getPort("\\A")), log_signal(cell->getPort("\\B")));
log(" Unproven $equiv %s: %s %s\n", log_id(cell), log_signal(cell->getPort(ID::A)), log_signal(cell->getPort(ID::B)));
}
unproven_count += GetSize(unproven_equiv_cells);

View file

@ -110,9 +110,9 @@ struct EquivStructWorker
module->connect(sig_b, sig_a);
}
auto merged_attr = cell_b->get_strpool_attribute("\\equiv_merged");
auto merged_attr = cell_b->get_strpool_attribute(ID::equiv_merged);
merged_attr.insert(log_id(cell_b));
cell_a->add_strpool_attribute("\\equiv_merged", merged_attr);
cell_a->add_strpool_attribute(ID::equiv_merged, merged_attr);
module->remove(cell_b);
}
@ -126,9 +126,9 @@ struct EquivStructWorker
pool<IdString> cells;
for (auto cell : module->selected_cells())
if (cell->type == "$equiv") {
SigBit sig_a = sigmap(cell->getPort("\\A").as_bit());
SigBit sig_b = sigmap(cell->getPort("\\B").as_bit());
if (cell->type == ID($equiv)) {
SigBit sig_a = sigmap(cell->getPort(ID::A).as_bit());
SigBit sig_b = sigmap(cell->getPort(ID::B).as_bit());
equiv_bits.add(sig_b, sig_a);
equiv_inputs.insert(sig_a);
equiv_inputs.insert(sig_b);
@ -139,10 +139,10 @@ struct EquivStructWorker
}
for (auto cell : module->selected_cells())
if (cell->type == "$equiv") {
SigBit sig_a = sigmap(cell->getPort("\\A").as_bit());
SigBit sig_b = sigmap(cell->getPort("\\B").as_bit());
SigBit sig_y = sigmap(cell->getPort("\\Y").as_bit());
if (cell->type == ID($equiv)) {
SigBit sig_a = sigmap(cell->getPort(ID::A).as_bit());
SigBit sig_b = sigmap(cell->getPort(ID::B).as_bit());
SigBit sig_y = sigmap(cell->getPort(ID::Y).as_bit());
if (sig_a == sig_b && equiv_inputs.count(sig_y)) {
log(" Purging redundant $equiv cell %s.\n", log_id(cell));
module->connect(sig_y, sig_a);
@ -316,7 +316,7 @@ struct EquivStructPass : public Pass {
}
void execute(std::vector<std::string> args, Design *design) YS_OVERRIDE
{
pool<IdString> fwonly_cells({ "$equiv" });
pool<IdString> fwonly_cells({ ID($equiv) });
bool mode_icells = false;
bool mode_fwd = false;
int max_iter = -1;

View file

@ -55,7 +55,7 @@ ret_false:
sig2driver.find(sig, cellport_list);
for (auto &cellport : cellport_list)
{
if ((cellport.first->type != "$mux" && cellport.first->type != "$pmux") || cellport.second != "\\Y") {
if ((cellport.first->type != ID($mux) && cellport.first->type != ID($pmux)) || cellport.second != ID::Y) {
goto ret_false;
}
@ -67,8 +67,8 @@ ret_false:
recursion_monitor.insert(cellport.first);
RTLIL::SigSpec sig_a = assign_map(cellport.first->getPort("\\A"));
RTLIL::SigSpec sig_b = assign_map(cellport.first->getPort("\\B"));
RTLIL::SigSpec sig_a = assign_map(cellport.first->getPort(ID::A));
RTLIL::SigSpec sig_b = assign_map(cellport.first->getPort(ID::B));
if (!check_state_mux_tree(old_sig, sig_a, recursion_monitor, mux_tree_cache)) {
recursion_monitor.erase(cellport.first);
@ -99,18 +99,18 @@ static bool check_state_users(RTLIL::SigSpec sig)
RTLIL::Cell *cell = cellport.first;
if (muxtree_cells.count(cell) > 0)
continue;
if (cell->type == "$logic_not" && assign_map(cell->getPort("\\A")) == sig)
if (cell->type == ID($logic_not) && assign_map(cell->getPort(ID::A)) == sig)
continue;
if (cellport.second != "\\A" && cellport.second != "\\B")
if (cellport.second != ID::A && cellport.second != ID::B)
return false;
if (!cell->hasPort("\\A") || !cell->hasPort("\\B") || !cell->hasPort("\\Y"))
if (!cell->hasPort(ID::A) || !cell->hasPort(ID::B) || !cell->hasPort(ID::Y))
return false;
for (auto &port_it : cell->connections())
if (port_it.first != "\\A" && port_it.first != "\\B" && port_it.first != "\\Y")
if (port_it.first != ID::A && port_it.first != ID::B && port_it.first != ID::Y)
return false;
if (assign_map(cell->getPort("\\A")) == sig && cell->getPort("\\B").is_fully_const())
if (assign_map(cell->getPort(ID::A)) == sig && cell->getPort(ID::B).is_fully_const())
continue;
if (assign_map(cell->getPort("\\B")) == sig && cell->getPort("\\A").is_fully_const())
if (assign_map(cell->getPort(ID::B)) == sig && cell->getPort(ID::A).is_fully_const())
continue;
return false;
}
@ -120,9 +120,9 @@ static bool check_state_users(RTLIL::SigSpec sig)
static void detect_fsm(RTLIL::Wire *wire)
{
bool has_fsm_encoding_attr = wire->attributes.count("\\fsm_encoding") > 0 && wire->attributes.at("\\fsm_encoding").decode_string() != "none";
bool has_fsm_encoding_none = wire->attributes.count("\\fsm_encoding") > 0 && wire->attributes.at("\\fsm_encoding").decode_string() == "none";
bool has_init_attr = wire->attributes.count("\\init") > 0;
bool has_fsm_encoding_attr = wire->attributes.count(ID::fsm_encoding) > 0 && wire->attributes.at(ID::fsm_encoding).decode_string() != "none";
bool has_fsm_encoding_none = wire->attributes.count(ID::fsm_encoding) > 0 && wire->attributes.at(ID::fsm_encoding).decode_string() == "none";
bool has_init_attr = wire->attributes.count(ID::init) > 0;
bool is_module_port = sig_at_port.check_any(assign_map(RTLIL::SigSpec(wire)));
bool looks_like_state_reg = false, looks_like_good_state_reg = false;
bool is_self_resetting = false;
@ -133,7 +133,7 @@ static void detect_fsm(RTLIL::Wire *wire)
if (wire->width <= 1) {
if (has_fsm_encoding_attr) {
log_warning("Removing fsm_encoding attribute from 1-bit net: %s.%s\n", log_id(wire->module), log_id(wire));
wire->attributes.erase("\\fsm_encoding");
wire->attributes.erase(ID::fsm_encoding);
}
return;
}
@ -143,13 +143,13 @@ static void detect_fsm(RTLIL::Wire *wire)
for (auto &cellport : cellport_list)
{
if ((cellport.first->type != "$dff" && cellport.first->type != "$adff") || cellport.second != "\\Q")
if ((cellport.first->type != ID($dff) && cellport.first->type != ID($adff)) || cellport.second != ID::Q)
continue;
muxtree_cells.clear();
pool<Cell*> recursion_monitor;
RTLIL::SigSpec sig_q = assign_map(cellport.first->getPort("\\Q"));
RTLIL::SigSpec sig_d = assign_map(cellport.first->getPort("\\D"));
RTLIL::SigSpec sig_q = assign_map(cellport.first->getPort(ID::Q));
RTLIL::SigSpec sig_d = assign_map(cellport.first->getPort(ID::D));
dict<RTLIL::SigSpec, bool> mux_tree_cache;
if (sig_q != assign_map(wire))
@ -173,10 +173,10 @@ static void detect_fsm(RTLIL::Wire *wire)
RTLIL::Cell *cell = cellport.first;
bool set_output = false, clr_output = false;
if (cell->type.in("$ne", "$reduce_or", "$reduce_bool"))
if (cell->type.in(ID($ne), ID($reduce_or), ID($reduce_bool)))
set_output = true;
if (cell->type.in("$eq", "$logic_not", "$reduce_and"))
if (cell->type.in(ID($eq), ID($logic_not), ID($reduce_and)))
clr_output = true;
if (set_output || clr_output) {
@ -234,7 +234,7 @@ static void detect_fsm(RTLIL::Wire *wire)
if (looks_like_state_reg && looks_like_good_state_reg && !has_init_attr && !is_module_port && !is_self_resetting)
{
log("Found FSM state register %s.%s.\n", log_id(wire->module), log_id(wire));
wire->attributes["\\fsm_encoding"] = RTLIL::Const("auto");
wire->attributes[ID::fsm_encoding] = RTLIL::Const("auto");
}
else
if (looks_like_state_reg)
@ -284,38 +284,34 @@ struct FsmDetectPass : public Pass {
ct.setup_stdcells();
ct.setup_stdcells_mem();
for (auto &mod_it : design->modules_)
for (auto mod : design->selected_modules())
{
if (!design->selected(mod_it.second))
continue;
module = mod_it.second;
module = mod;
assign_map.set(module);
sig2driver.clear();
sig2user.clear();
sig_at_port.clear();
for (auto &cell_it : module->cells_)
for (auto &conn_it : cell_it.second->connections()) {
if (ct.cell_output(cell_it.second->type, conn_it.first) || !ct.cell_known(cell_it.second->type)) {
for (auto cell : module->cells())
for (auto &conn_it : cell->connections()) {
if (ct.cell_output(cell->type, conn_it.first) || !ct.cell_known(cell->type)) {
RTLIL::SigSpec sig = conn_it.second;
assign_map.apply(sig);
sig2driver.insert(sig, sig2driver_entry_t(cell_it.second, conn_it.first));
sig2driver.insert(sig, sig2driver_entry_t(cell, conn_it.first));
}
if (!ct.cell_known(cell_it.second->type) || ct.cell_input(cell_it.second->type, conn_it.first)) {
if (!ct.cell_known(cell->type) || ct.cell_input(cell->type, conn_it.first)) {
RTLIL::SigSpec sig = conn_it.second;
assign_map.apply(sig);
sig2user.insert(sig, sig2driver_entry_t(cell_it.second, conn_it.first));
sig2user.insert(sig, sig2driver_entry_t(cell, conn_it.first));
}
}
for (auto &wire_it : module->wires_)
if (wire_it.second->port_id != 0)
sig_at_port.add(assign_map(RTLIL::SigSpec(wire_it.second)));
for (auto wire : module->wires())
if (wire->port_id != 0)
sig_at_port.add(assign_map(wire));
for (auto &wire_it : module->wires_)
if (design->selected(module, wire_it.second))
detect_fsm(wire_it.second);
for (auto wire : module->selected_wires())
detect_fsm(wire);
}
assign_map.clear();

View file

@ -47,42 +47,42 @@ struct FsmExpand
bool is_cell_merge_candidate(RTLIL::Cell *cell)
{
if (full_mode || cell->type == "$_MUX_")
if (full_mode || cell->type == ID($_MUX_))
return true;
if (cell->type.in("$mux", "$pmux"))
if (cell->getPort("\\A").size() < 2)
if (cell->type.in(ID($mux), ID($pmux)))
if (cell->getPort(ID::A).size() < 2)
return true;
int in_bits = 0;
RTLIL::SigSpec new_signals;
if (cell->hasPort("\\A")) {
in_bits += GetSize(cell->getPort("\\A"));
new_signals.append(assign_map(cell->getPort("\\A")));
if (cell->hasPort(ID::A)) {
in_bits += GetSize(cell->getPort(ID::A));
new_signals.append(assign_map(cell->getPort(ID::A)));
}
if (cell->hasPort("\\B")) {
in_bits += GetSize(cell->getPort("\\B"));
new_signals.append(assign_map(cell->getPort("\\B")));
if (cell->hasPort(ID::B)) {
in_bits += GetSize(cell->getPort(ID::B));
new_signals.append(assign_map(cell->getPort(ID::B)));
}
if (cell->hasPort("\\S")) {
in_bits += GetSize(cell->getPort("\\S"));
new_signals.append(assign_map(cell->getPort("\\S")));
if (cell->hasPort(ID::S)) {
in_bits += GetSize(cell->getPort(ID::S));
new_signals.append(assign_map(cell->getPort(ID::S)));
}
if (in_bits > 8)
return false;
if (cell->hasPort("\\Y"))
new_signals.append(assign_map(cell->getPort("\\Y")));
if (cell->hasPort(ID::Y))
new_signals.append(assign_map(cell->getPort(ID::Y)));
new_signals.sort_and_unify();
new_signals.remove_const();
new_signals.remove(assign_map(fsm_cell->getPort("\\CTRL_IN")));
new_signals.remove(assign_map(fsm_cell->getPort("\\CTRL_OUT")));
new_signals.remove(assign_map(fsm_cell->getPort(ID::CTRL_IN)));
new_signals.remove(assign_map(fsm_cell->getPort(ID::CTRL_OUT)));
if (new_signals.size() > 3)
return false;
@ -94,10 +94,10 @@ struct FsmExpand
{
std::vector<RTLIL::Cell*> cell_list;
for (auto c : sig2driver.find(assign_map(fsm_cell->getPort("\\CTRL_IN"))))
for (auto c : sig2driver.find(assign_map(fsm_cell->getPort(ID::CTRL_IN))))
cell_list.push_back(c);
for (auto c : sig2user.find(assign_map(fsm_cell->getPort("\\CTRL_OUT"))))
for (auto c : sig2user.find(assign_map(fsm_cell->getPort(ID::CTRL_OUT))))
cell_list.push_back(c);
current_set.clear();
@ -106,7 +106,7 @@ struct FsmExpand
if (merged_set.count(c) > 0 || current_set.count(c) > 0 || no_candidate_set.count(c) > 0)
continue;
for (auto &p : c->connections()) {
if (p.first != "\\A" && p.first != "\\B" && p.first != "\\S" && p.first != "\\Y")
if (p.first != ID::A && p.first != ID::B && p.first != ID::S && p.first != ID::Y)
goto next_cell;
}
if (!is_cell_merge_candidate(c)) {
@ -123,14 +123,14 @@ struct FsmExpand
if (already_optimized)
return;
int trans_num = fsm_cell->parameters["\\TRANS_NUM"].as_int();
int trans_num = fsm_cell->parameters[ID::TRANS_NUM].as_int();
if (trans_num > limit_transitions)
{
log(" grown transition table to %d entries -> optimize.\n", trans_num);
FsmData::optimize_fsm(fsm_cell, module);
already_optimized = true;
trans_num = fsm_cell->parameters["\\TRANS_NUM"].as_int();
trans_num = fsm_cell->parameters[ID::TRANS_NUM].as_int();
log(" transition table size after optimizaton: %d\n", trans_num);
limit_transitions = 16 * trans_num;
}
@ -159,12 +159,12 @@ struct FsmExpand
for (int i = 0; i < (1 << input_sig.size()); i++) {
RTLIL::Const in_val(i, input_sig.size());
RTLIL::SigSpec A, B, S;
if (cell->hasPort("\\A"))
A = assign_map(cell->getPort("\\A"));
if (cell->hasPort("\\B"))
B = assign_map(cell->getPort("\\B"));
if (cell->hasPort("\\S"))
S = assign_map(cell->getPort("\\S"));
if (cell->hasPort(ID::A))
A = assign_map(cell->getPort(ID::A));
if (cell->hasPort(ID::B))
B = assign_map(cell->getPort(ID::B));
if (cell->hasPort(ID::S))
S = assign_map(cell->getPort(ID::S));
A.replace(input_sig, RTLIL::SigSpec(in_val));
B.replace(input_sig, RTLIL::SigSpec(in_val));
S.replace(input_sig, RTLIL::SigSpec(in_val));
@ -178,14 +178,14 @@ struct FsmExpand
fsm_data.copy_from_cell(fsm_cell);
fsm_data.num_inputs += input_sig.size();
RTLIL::SigSpec new_ctrl_in = fsm_cell->getPort("\\CTRL_IN");
RTLIL::SigSpec new_ctrl_in = fsm_cell->getPort(ID::CTRL_IN);
new_ctrl_in.append(input_sig);
fsm_cell->setPort("\\CTRL_IN", new_ctrl_in);
fsm_cell->setPort(ID::CTRL_IN, new_ctrl_in);
fsm_data.num_outputs += output_sig.size();
RTLIL::SigSpec new_ctrl_out = fsm_cell->getPort("\\CTRL_OUT");
RTLIL::SigSpec new_ctrl_out = fsm_cell->getPort(ID::CTRL_OUT);
new_ctrl_out.append(output_sig);
fsm_cell->setPort("\\CTRL_OUT", new_ctrl_out);
fsm_cell->setPort(ID::CTRL_OUT, new_ctrl_out);
if (GetSize(input_sig) > 10)
log_warning("Cell %s.%s (%s) has %d input bits, merging into FSM %s.%s might be problematic.\n",
@ -246,7 +246,7 @@ struct FsmExpand
log("Expanding FSM `%s' from module `%s':\n", fsm_cell->name.c_str(), module->name.c_str());
already_optimized = false;
limit_transitions = 16 * fsm_cell->parameters["\\TRANS_NUM"].as_int();
limit_transitions = 16 * fsm_cell->parameters[ID::TRANS_NUM].as_int();
for (create_current_set(); current_set.size() > 0; create_current_set()) {
for (auto c : current_set)
@ -295,15 +295,13 @@ struct FsmExpandPass : public Pass {
}
extra_args(args, argidx, design);
for (auto &mod_it : design->modules_) {
if (!design->selected(mod_it.second))
continue;
for (auto mod : design->selected_modules()) {
std::vector<RTLIL::Cell*> fsm_cells;
for (auto &cell_it : mod_it.second->cells_)
if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second))
fsm_cells.push_back(cell_it.second);
for (auto cell : mod->selected_cells())
if (cell->type == ID($fsm))
fsm_cells.push_back(cell);
for (auto c : fsm_cells) {
FsmExpand fsm_expand(c, design, mod_it.second, full_mode);
FsmExpand fsm_expand(c, design, mod, full_mode);
fsm_expand.execute();
}
}

View file

@ -57,7 +57,7 @@ void write_kiss2(struct RTLIL::Module *module, struct RTLIL::Cell *cell, std::st
std::string kiss_name;
size_t i;
attr_it = cell->attributes.find("\\fsm_export");
attr_it = cell->attributes.find(ID::fsm_export);
if (!filename.empty()) {
kiss_name.assign(filename);
} else if (attr_it != cell->attributes.end() && attr_it->second.decode_string() != "") {
@ -173,16 +173,15 @@ struct FsmExportPass : public Pass {
}
extra_args(args, argidx, design);
for (auto &mod_it : design->modules_)
if (design->selected(mod_it.second))
for (auto &cell_it : mod_it.second->cells_)
if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) {
attr_it = cell_it.second->attributes.find("\\fsm_export");
if (!flag_noauto || (attr_it != cell_it.second->attributes.end())) {
write_kiss2(mod_it.second, cell_it.second, filename, flag_origenc);
filename.clear();
}
for (auto mod : design->selected_modules())
for (auto cell : mod->selected_cells())
if (cell->type == ID($fsm)) {
attr_it = cell->attributes.find(ID::fsm_export);
if (!flag_noauto || (attr_it != cell->attributes.end())) {
write_kiss2(mod, cell, filename, flag_origenc);
filename.clear();
}
}
}
} FsmExportPass;

View file

@ -70,15 +70,15 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL
for (auto &cellport : cellport_list)
{
RTLIL::Cell *cell = module->cells_.at(cellport.first);
if ((cell->type != "$mux" && cell->type != "$pmux") || cellport.second != "\\Y") {
if ((cell->type != ID($mux) && cell->type != ID($pmux)) || cellport.second != ID::Y) {
log(" unexpected cell type %s (%s) found in state selection tree.\n", cell->type.c_str(), cell->name.c_str());
return false;
}
RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A"));
RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B"));
RTLIL::SigSpec sig_s = assign_map(cell->getPort("\\S"));
RTLIL::SigSpec sig_y = assign_map(cell->getPort("\\Y"));
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B));
RTLIL::SigSpec sig_s = assign_map(cell->getPort(ID::S));
RTLIL::SigSpec sig_y = assign_map(cell->getPort(ID::Y));
RTLIL::SigSpec sig_aa = sig;
sig_aa.replace(sig_y, sig_a);
@ -272,17 +272,17 @@ static void extract_fsm(RTLIL::Wire *wire)
sig2driver.find(dff_out, cellport_list);
for (auto &cellport : cellport_list) {
RTLIL::Cell *cell = module->cells_.at(cellport.first);
if ((cell->type != "$dff" && cell->type != "$adff") || cellport.second != "\\Q")
if ((cell->type != ID($dff) && cell->type != ID($adff)) || cellport.second != ID::Q)
continue;
log(" found %s cell for state register: %s\n", cell->type.c_str(), cell->name.c_str());
RTLIL::SigSpec sig_q = assign_map(cell->getPort("\\Q"));
RTLIL::SigSpec sig_d = assign_map(cell->getPort("\\D"));
clk = cell->getPort("\\CLK");
clk_polarity = cell->parameters["\\CLK_POLARITY"].as_bool();
if (cell->type == "$adff") {
arst = cell->getPort("\\ARST");
arst_polarity = cell->parameters["\\ARST_POLARITY"].as_bool();
reset_state = cell->parameters["\\ARST_VALUE"];
RTLIL::SigSpec sig_q = assign_map(cell->getPort(ID::Q));
RTLIL::SigSpec sig_d = assign_map(cell->getPort(ID::D));
clk = cell->getPort(ID::CLK);
clk_polarity = cell->parameters[ID::CLK_POLARITY].as_bool();
if (cell->type == ID($adff)) {
arst = cell->getPort(ID::ARST);
arst_polarity = cell->parameters[ID::ARST_POLARITY].as_bool();
reset_state = cell->parameters[ID::ARST_VALUE];
}
sig_q.replace(dff_out, sig_d, &dff_in);
break;
@ -320,14 +320,14 @@ static void extract_fsm(RTLIL::Wire *wire)
sig2trigger.find(dff_out, cellport_list);
for (auto &cellport : cellport_list) {
RTLIL::Cell *cell = module->cells_.at(cellport.first);
RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A"));
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec sig_b;
if (cell->hasPort("\\B"))
sig_b = assign_map(cell->getPort("\\B"));
RTLIL::SigSpec sig_y = assign_map(cell->getPort("\\Y"));
if (cellport.second == "\\A" && !sig_b.is_fully_const())
if (cell->hasPort(ID::B))
sig_b = assign_map(cell->getPort(ID::B));
RTLIL::SigSpec sig_y = assign_map(cell->getPort(ID::Y));
if (cellport.second == ID::A && !sig_b.is_fully_const())
continue;
if (cellport.second == "\\B" && !sig_a.is_fully_const())
if (cellport.second == ID::B && !sig_a.is_fully_const())
continue;
log(" found ctrl output: %s\n", log_signal(sig_y));
ctrl_out.append(sig_y);
@ -368,21 +368,21 @@ static void extract_fsm(RTLIL::Wire *wire)
// create fsm cell
RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), autoidx++), "$fsm");
fsm_cell->setPort("\\CLK", clk);
fsm_cell->setPort("\\ARST", arst);
fsm_cell->parameters["\\CLK_POLARITY"] = clk_polarity ? State::S1 : State::S0;
fsm_cell->parameters["\\ARST_POLARITY"] = arst_polarity ? State::S1 : State::S0;
fsm_cell->setPort("\\CTRL_IN", ctrl_in);
fsm_cell->setPort("\\CTRL_OUT", ctrl_out);
fsm_cell->parameters["\\NAME"] = RTLIL::Const(wire->name.str());
RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), autoidx++), ID($fsm));
fsm_cell->setPort(ID::CLK, clk);
fsm_cell->setPort(ID::ARST, arst);
fsm_cell->parameters[ID::CLK_POLARITY] = clk_polarity ? State::S1 : State::S0;
fsm_cell->parameters[ID::ARST_POLARITY] = arst_polarity ? State::S1 : State::S0;
fsm_cell->setPort(ID::CTRL_IN, ctrl_in);
fsm_cell->setPort(ID::CTRL_OUT, ctrl_out);
fsm_cell->parameters[ID::NAME] = RTLIL::Const(wire->name.str());
fsm_cell->attributes = wire->attributes;
fsm_data.copy_to_cell(fsm_cell);
// rename original state wire
module->wires_.erase(wire->name);
wire->attributes.erase("\\fsm_encoding");
wire->attributes.erase(ID::fsm_encoding);
wire->name = stringf("$fsm$oldstate%s", wire->name.c_str());
module->wires_[wire->name] = wire;
@ -422,18 +422,11 @@ struct FsmExtractPass : public Pass {
log_header(design, "Executing FSM_EXTRACT pass (extracting FSM from design).\n");
extra_args(args, 1, design);
CellTypes ct;
ct.setup_internals();
ct.setup_internals_mem();
ct.setup_stdcells();
ct.setup_stdcells_mem();
CellTypes ct(design);
for (auto &mod_it : design->modules_)
for (auto mod : design->selected_modules())
{
if (!design->selected(mod_it.second))
continue;
module = mod_it.second;
module = mod;
assign_map.set(module);
sig2driver.clear();
@ -446,15 +439,15 @@ struct FsmExtractPass : public Pass {
assign_map.apply(sig);
sig2driver.insert(sig, sig2driver_entry_t(cell->name, conn_it.first));
}
if (ct.cell_input(cell->type, conn_it.first) && cell->hasPort("\\Y") &&
cell->getPort("\\Y").size() == 1 && (conn_it.first == "\\A" || conn_it.first == "\\B")) {
if (ct.cell_input(cell->type, conn_it.first) && cell->hasPort(ID::Y) &&
cell->getPort(ID::Y).size() == 1 && (conn_it.first == ID::A || conn_it.first == ID::B)) {
RTLIL::SigSpec sig = conn_it.second;
assign_map.apply(sig);
sig2trigger.insert(sig, sig2driver_entry_t(cell->name, conn_it.first));
}
}
if (cell->type == "$pmux") {
RTLIL::SigSpec sel_sig = assign_map(cell->getPort("\\S"));
if (cell->type == ID($pmux)) {
RTLIL::SigSpec sel_sig = assign_map(cell->getPort(ID::S));
for (auto &bit1 : sel_sig)
for (auto &bit2 : sel_sig)
if (bit1 != bit2)
@ -463,10 +456,9 @@ struct FsmExtractPass : public Pass {
}
std::vector<RTLIL::Wire*> wire_list;
for (auto &wire_it : module->wires_)
if (wire_it.second->attributes.count("\\fsm_encoding") > 0 && wire_it.second->attributes["\\fsm_encoding"].decode_string() != "none")
if (design->selected(module, wire_it.second))
wire_list.push_back(wire_it.second);
for (auto wire : module->selected_wires())
if (wire->attributes.count(ID::fsm_encoding) > 0 && wire->attributes[ID::fsm_encoding].decode_string() != "none")
wire_list.push_back(wire);
for (auto wire : wire_list)
extract_fsm(wire);
}

View file

@ -46,16 +46,15 @@ struct FsmInfoPass : public Pass {
log_header(design, "Executing FSM_INFO pass (dumping all available information on FSM cells).\n");
extra_args(args, 1, design);
for (auto &mod_it : design->modules_)
if (design->selected(mod_it.second))
for (auto &cell_it : mod_it.second->cells_)
if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) {
log("\n");
log("FSM `%s' from module `%s':\n", cell_it.second->name.c_str(), mod_it.first.c_str());
FsmData fsm_data;
fsm_data.copy_from_cell(cell_it.second);
fsm_data.log_info(cell_it.second);
}
for (auto mod : design->selected_modules())
for (auto cell : mod->selected_cells())
if (cell->type == ID($fsm)) {
log("\n");
log("FSM `%s' from module `%s':\n", log_id(cell), log_id(mod));
FsmData fsm_data;
fsm_data.copy_from_cell(cell);
fsm_data.log_info(cell);
}
}
} FsmInfoPass;

View file

@ -74,15 +74,15 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map<RTLIL::Const
RTLIL::Wire *eq_wire = module->addWire(NEW_ID);
and_sig.append(RTLIL::SigSpec(eq_wire));
RTLIL::Cell *eq_cell = module->addCell(NEW_ID, "$eq");
eq_cell->setPort("\\A", eq_sig_a);
eq_cell->setPort("\\B", eq_sig_b);
eq_cell->setPort("\\Y", RTLIL::SigSpec(eq_wire));
eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false);
eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false);
eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(eq_sig_a.size());
eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(eq_sig_b.size());
eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
RTLIL::Cell *eq_cell = module->addCell(NEW_ID, ID($eq));
eq_cell->setPort(ID::A, eq_sig_a);
eq_cell->setPort(ID::B, eq_sig_b);
eq_cell->setPort(ID::Y, RTLIL::SigSpec(eq_wire));
eq_cell->parameters[ID::A_SIGNED] = RTLIL::Const(false);
eq_cell->parameters[ID::B_SIGNED] = RTLIL::Const(false);
eq_cell->parameters[ID::A_WIDTH] = RTLIL::Const(eq_sig_a.size());
eq_cell->parameters[ID::B_WIDTH] = RTLIL::Const(eq_sig_b.size());
eq_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
}
std::set<int> complete_in_state_cache = it.second;
@ -102,12 +102,12 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map<RTLIL::Const
RTLIL::Wire *or_wire = module->addWire(NEW_ID);
and_sig.append(RTLIL::SigSpec(or_wire));
RTLIL::Cell *or_cell = module->addCell(NEW_ID, "$reduce_or");
or_cell->setPort("\\A", or_sig);
or_cell->setPort("\\Y", RTLIL::SigSpec(or_wire));
or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false);
or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(or_sig.size());
or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
RTLIL::Cell *or_cell = module->addCell(NEW_ID, ID($reduce_or));
or_cell->setPort(ID::A, or_sig);
or_cell->setPort(ID::Y, RTLIL::SigSpec(or_wire));
or_cell->parameters[ID::A_SIGNED] = RTLIL::Const(false);
or_cell->parameters[ID::A_WIDTH] = RTLIL::Const(or_sig.size());
or_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
}
}
@ -118,15 +118,15 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map<RTLIL::Const
RTLIL::Wire *and_wire = module->addWire(NEW_ID);
cases_vector.append(RTLIL::SigSpec(and_wire));
RTLIL::Cell *and_cell = module->addCell(NEW_ID, "$and");
and_cell->setPort("\\A", and_sig.extract(0, 1));
and_cell->setPort("\\B", and_sig.extract(1, 1));
and_cell->setPort("\\Y", RTLIL::SigSpec(and_wire));
and_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false);
and_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false);
and_cell->parameters["\\A_WIDTH"] = RTLIL::Const(1);
and_cell->parameters["\\B_WIDTH"] = RTLIL::Const(1);
and_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
RTLIL::Cell *and_cell = module->addCell(NEW_ID, ID($and));
and_cell->setPort(ID::A, and_sig.extract(0, 1));
and_cell->setPort(ID::B, and_sig.extract(1, 1));
and_cell->setPort(ID::Y, RTLIL::SigSpec(and_wire));
and_cell->parameters[ID::A_SIGNED] = RTLIL::Const(false);
and_cell->parameters[ID::B_SIGNED] = RTLIL::Const(false);
and_cell->parameters[ID::A_WIDTH] = RTLIL::Const(1);
and_cell->parameters[ID::B_WIDTH] = RTLIL::Const(1);
and_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
break;
}
case 1:
@ -141,12 +141,12 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map<RTLIL::Const
}
if (cases_vector.size() > 1) {
RTLIL::Cell *or_cell = module->addCell(NEW_ID, "$reduce_or");
or_cell->setPort("\\A", cases_vector);
or_cell->setPort("\\Y", output);
or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false);
or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cases_vector.size());
or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
RTLIL::Cell *or_cell = module->addCell(NEW_ID, ID($reduce_or));
or_cell->setPort(ID::A, cases_vector);
or_cell->setPort(ID::Y, output);
or_cell->parameters[ID::A_SIGNED] = RTLIL::Const(false);
or_cell->parameters[ID::A_WIDTH] = RTLIL::Const(cases_vector.size());
or_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
} else if (cases_vector.size() == 1) {
module->connect(RTLIL::SigSig(output, cases_vector));
} else {
@ -161,31 +161,31 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module)
FsmData fsm_data;
fsm_data.copy_from_cell(fsm_cell);
RTLIL::SigSpec ctrl_in = fsm_cell->getPort("\\CTRL_IN");
RTLIL::SigSpec ctrl_out = fsm_cell->getPort("\\CTRL_OUT");
RTLIL::SigSpec ctrl_in = fsm_cell->getPort(ID::CTRL_IN);
RTLIL::SigSpec ctrl_out = fsm_cell->getPort(ID::CTRL_OUT);
// create state register
RTLIL::Wire *state_wire = module->addWire(module->uniquify(fsm_cell->parameters["\\NAME"].decode_string()), fsm_data.state_bits);
RTLIL::Wire *state_wire = module->addWire(module->uniquify(fsm_cell->parameters[ID::NAME].decode_string()), fsm_data.state_bits);
RTLIL::Wire *next_state_wire = module->addWire(NEW_ID, fsm_data.state_bits);
RTLIL::Cell *state_dff = module->addCell(NEW_ID, "");
if (fsm_cell->getPort("\\ARST").is_fully_const()) {
state_dff->type = "$dff";
if (fsm_cell->getPort(ID::ARST).is_fully_const()) {
state_dff->type = ID($dff);
} else {
state_dff->type = "$adff";
state_dff->parameters["\\ARST_POLARITY"] = fsm_cell->parameters["\\ARST_POLARITY"];
state_dff->parameters["\\ARST_VALUE"] = fsm_data.state_table[fsm_data.reset_state];
for (auto &bit : state_dff->parameters["\\ARST_VALUE"].bits)
state_dff->type = ID($adff);
state_dff->parameters[ID::ARST_POLARITY] = fsm_cell->parameters[ID::ARST_POLARITY];
state_dff->parameters[ID::ARST_VALUE] = fsm_data.state_table[fsm_data.reset_state];
for (auto &bit : state_dff->parameters[ID::ARST_VALUE].bits)
if (bit != RTLIL::State::S1)
bit = RTLIL::State::S0;
state_dff->setPort("\\ARST", fsm_cell->getPort("\\ARST"));
state_dff->setPort(ID::ARST, fsm_cell->getPort(ID::ARST));
}
state_dff->parameters["\\WIDTH"] = RTLIL::Const(fsm_data.state_bits);
state_dff->parameters["\\CLK_POLARITY"] = fsm_cell->parameters["\\CLK_POLARITY"];
state_dff->setPort("\\CLK", fsm_cell->getPort("\\CLK"));
state_dff->setPort("\\D", RTLIL::SigSpec(next_state_wire));
state_dff->setPort("\\Q", RTLIL::SigSpec(state_wire));
state_dff->parameters[ID::WIDTH] = RTLIL::Const(fsm_data.state_bits);
state_dff->parameters[ID::CLK_POLARITY] = fsm_cell->parameters[ID::CLK_POLARITY];
state_dff->setPort(ID::CLK, fsm_cell->getPort(ID::CLK));
state_dff->setPort(ID::D, RTLIL::SigSpec(next_state_wire));
state_dff->setPort(ID::Q, RTLIL::SigSpec(state_wire));
// decode state register
@ -212,20 +212,20 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module)
{
encoding_is_onehot = false;
RTLIL::Cell *eq_cell = module->addCell(NEW_ID, "$eq");
eq_cell->setPort("\\A", sig_a);
eq_cell->setPort("\\B", sig_b);
eq_cell->setPort("\\Y", RTLIL::SigSpec(state_onehot, i));
eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false);
eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false);
eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_a.size());
eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(sig_b.size());
eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
RTLIL::Cell *eq_cell = module->addCell(NEW_ID, ID($eq));
eq_cell->setPort(ID::A, sig_a);
eq_cell->setPort(ID::B, sig_b);
eq_cell->setPort(ID::Y, RTLIL::SigSpec(state_onehot, i));
eq_cell->parameters[ID::A_SIGNED] = RTLIL::Const(false);
eq_cell->parameters[ID::B_SIGNED] = RTLIL::Const(false);
eq_cell->parameters[ID::A_WIDTH] = RTLIL::Const(sig_a.size());
eq_cell->parameters[ID::B_WIDTH] = RTLIL::Const(sig_b.size());
eq_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
}
}
if (encoding_is_onehot)
state_wire->set_bool_attribute("\\onehot");
state_wire->set_bool_attribute(ID::onehot);
// generate next_state signal
@ -285,13 +285,13 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module)
}
}
RTLIL::Cell *mux_cell = module->addCell(NEW_ID, "$pmux");
mux_cell->setPort("\\A", sig_a);
mux_cell->setPort("\\B", sig_b);
mux_cell->setPort("\\S", sig_s);
mux_cell->setPort("\\Y", RTLIL::SigSpec(next_state_wire));
mux_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_a.size());
mux_cell->parameters["\\S_WIDTH"] = RTLIL::Const(sig_s.size());
RTLIL::Cell *mux_cell = module->addCell(NEW_ID, ID($pmux));
mux_cell->setPort(ID::A, sig_a);
mux_cell->setPort(ID::B, sig_b);
mux_cell->setPort(ID::S, sig_s);
mux_cell->setPort(ID::Y, RTLIL::SigSpec(next_state_wire));
mux_cell->parameters[ID::WIDTH] = RTLIL::Const(sig_a.size());
mux_cell->parameters[ID::S_WIDTH] = RTLIL::Const(sig_s.size());
}
}
@ -336,15 +336,13 @@ struct FsmMapPass : public Pass {
log_header(design, "Executing FSM_MAP pass (mapping FSMs to basic logic).\n");
extra_args(args, 1, design);
for (auto &mod_it : design->modules_) {
if (!design->selected(mod_it.second))
continue;
for (auto mod : design->selected_modules()) {
std::vector<RTLIL::Cell*> fsm_cells;
for (auto &cell_it : mod_it.second->cells_)
if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second))
fsm_cells.push_back(cell_it.second);
for (auto cell : mod->selected_cells())
if (cell->type == ID($fsm))
fsm_cells.push_back(cell);
for (auto cell : fsm_cells)
map_fsm(cell, mod_it.second);
map_fsm(cell, mod);
}
}
} FsmMapPass;

View file

@ -81,10 +81,10 @@ struct FsmOpt
{
RTLIL::SigBit bit = sig.as_bit();
if (bit.wire == NULL || bit.wire->attributes.count("\\unused_bits") == 0)
if (bit.wire == NULL || bit.wire->attributes.count(ID::unused_bits) == 0)
return false;
char *str = strdup(bit.wire->attributes["\\unused_bits"].decode_string().c_str());
char *str = strdup(bit.wire->attributes[ID::unused_bits].decode_string().c_str());
for (char *tok = strtok(str, " "); tok != NULL; tok = strtok(NULL, " ")) {
if (tok[0] && bit.offset == atoi(tok)) {
free(str);
@ -98,7 +98,7 @@ struct FsmOpt
void opt_const_and_unused_inputs()
{
RTLIL::SigSpec ctrl_in = cell->getPort("\\CTRL_IN");
RTLIL::SigSpec ctrl_in = cell->getPort(ID::CTRL_IN);
std::vector<bool> ctrl_in_used(ctrl_in.size());
std::vector<FsmData::transition_t> new_transition_table;
@ -119,15 +119,15 @@ struct FsmOpt
for (int i = int(ctrl_in_used.size())-1; i >= 0; i--) {
if (!ctrl_in_used[i]) {
log(" Removing unused input signal %s.\n", log_signal(cell->getPort("\\CTRL_IN").extract(i, 1)));
log(" Removing unused input signal %s.\n", log_signal(cell->getPort(ID::CTRL_IN).extract(i, 1)));
for (auto &tr : new_transition_table) {
RTLIL::SigSpec tmp(tr.ctrl_in);
tmp.remove(i, 1);
tr.ctrl_in = tmp.as_const();
}
RTLIL::SigSpec new_ctrl_in = cell->getPort("\\CTRL_IN");
RTLIL::SigSpec new_ctrl_in = cell->getPort(ID::CTRL_IN);
new_ctrl_in.remove(i, 1);
cell->setPort("\\CTRL_IN", new_ctrl_in);
cell->setPort(ID::CTRL_IN, new_ctrl_in);
fsm_data.num_inputs--;
}
}
@ -139,12 +139,12 @@ struct FsmOpt
void opt_unused_outputs()
{
for (int i = 0; i < fsm_data.num_outputs; i++) {
RTLIL::SigSpec sig = cell->getPort("\\CTRL_OUT").extract(i, 1);
RTLIL::SigSpec sig = cell->getPort(ID::CTRL_OUT).extract(i, 1);
if (signal_is_unused(sig)) {
log(" Removing unused output signal %s.\n", log_signal(sig));
RTLIL::SigSpec new_ctrl_out = cell->getPort("\\CTRL_OUT");
RTLIL::SigSpec new_ctrl_out = cell->getPort(ID::CTRL_OUT);
new_ctrl_out.remove(i, 1);
cell->setPort("\\CTRL_OUT", new_ctrl_out);
cell->setPort(ID::CTRL_OUT, new_ctrl_out);
for (auto &tr : fsm_data.transition_table) {
RTLIL::SigSpec tmp(tr.ctrl_out);
tmp.remove(i, 1);
@ -158,7 +158,7 @@ struct FsmOpt
void opt_alias_inputs()
{
RTLIL::SigSpec &ctrl_in = cell->connections_["\\CTRL_IN"];
RTLIL::SigSpec &ctrl_in = cell->connections_[ID::CTRL_IN];
for (int i = 0; i < ctrl_in.size(); i++)
for (int j = i+1; j < ctrl_in.size(); j++)
@ -195,8 +195,8 @@ struct FsmOpt
void opt_feedback_inputs()
{
RTLIL::SigSpec &ctrl_in = cell->connections_["\\CTRL_IN"];
RTLIL::SigSpec &ctrl_out = cell->connections_["\\CTRL_OUT"];
RTLIL::SigSpec &ctrl_in = cell->connections_[ID::CTRL_IN];
RTLIL::SigSpec &ctrl_out = cell->connections_[ID::CTRL_OUT];
for (int j = 0; j < ctrl_out.size(); j++)
for (int i = 0; i < ctrl_in.size(); i++)
@ -340,12 +340,10 @@ struct FsmOptPass : public Pass {
log_header(design, "Executing FSM_OPT pass (simple optimizations of FSMs).\n");
extra_args(args, 1, design);
for (auto &mod_it : design->modules_) {
if (design->selected(mod_it.second))
for (auto &cell_it : mod_it.second->cells_)
if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second))
FsmData::optimize_fsm(cell_it.second, mod_it.second);
}
for (auto mod : design->selected_modules())
for (auto cell : mod->selected_cells())
if (cell->type == ID($fsm))
FsmData::optimize_fsm(cell, mod);
}
} FsmOptPass;

View file

@ -32,7 +32,7 @@ PRIVATE_NAMESPACE_BEGIN
static void fm_set_fsm_print(RTLIL::Cell *cell, RTLIL::Module *module, FsmData &fsm_data, const char *prefix, FILE *f)
{
std::string name = cell->parameters["\\NAME"].decode_string();
std::string name = cell->parameters[ID::NAME].decode_string();
fprintf(f, "set_fsm_state_vector {");
for (int i = fsm_data.state_bits-1; i >= 0; i--)
@ -53,7 +53,7 @@ static void fm_set_fsm_print(RTLIL::Cell *cell, RTLIL::Module *module, FsmData &
static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fsm_file, FILE *encfile, std::string default_encoding)
{
std::string encoding = cell->attributes.count("\\fsm_encoding") ? cell->attributes.at("\\fsm_encoding").decode_string() : "auto";
std::string encoding = cell->attributes.count(ID::fsm_encoding) ? cell->attributes.at(ID::fsm_encoding).decode_string() : "auto";
log("Recoding FSM `%s' from module `%s' using `%s' encoding:\n", cell->name.c_str(), module->name.c_str(), encoding.c_str());
@ -95,7 +95,7 @@ static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fs
log_error("FSM encoding `%s' is not supported!\n", encoding.c_str());
if (encfile)
fprintf(encfile, ".fsm %s %s\n", log_id(module), RTLIL::unescape_id(cell->parameters["\\NAME"].decode_string()).c_str());
fprintf(encfile, ".fsm %s %s\n", log_id(module), RTLIL::unescape_id(cell->parameters[ID::NAME].decode_string()).c_str());
int state_idx_counter = fsm_data.reset_state >= 0 ? 1 : 0;
for (int i = 0; i < int(fsm_data.state_table.size()); i++)
@ -181,11 +181,10 @@ struct FsmRecodePass : public Pass {
}
extra_args(args, argidx, design);
for (auto &mod_it : design->modules_)
if (design->selected(mod_it.second))
for (auto &cell_it : mod_it.second->cells_)
if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second))
fsm_recode(cell_it.second, mod_it.second, fm_set_fsm_file, encfile, default_encoding);
for (auto mod : design->selected_modules())
for (auto cell : mod->selected_cells())
if (cell->type == ID($fsm))
fsm_recode(cell, mod, fm_set_fsm_file, encfile, default_encoding);
if (fm_set_fsm_file != NULL)
fclose(fm_set_fsm_file);

View file

@ -33,31 +33,31 @@ struct FsmData
void copy_to_cell(RTLIL::Cell *cell)
{
cell->parameters["\\CTRL_IN_WIDTH"] = RTLIL::Const(num_inputs);
cell->parameters["\\CTRL_OUT_WIDTH"] = RTLIL::Const(num_outputs);
cell->parameters[ID::CTRL_IN_WIDTH] = RTLIL::Const(num_inputs);
cell->parameters[ID::CTRL_OUT_WIDTH] = RTLIL::Const(num_outputs);
int state_num_log2 = 0;
for (int i = state_table.size(); i > 0; i = i >> 1)
state_num_log2++;
state_num_log2 = max(state_num_log2, 1);
cell->parameters["\\STATE_BITS"] = RTLIL::Const(state_bits);
cell->parameters["\\STATE_NUM"] = RTLIL::Const(state_table.size());
cell->parameters["\\STATE_NUM_LOG2"] = RTLIL::Const(state_num_log2);
cell->parameters["\\STATE_RST"] = RTLIL::Const(reset_state);
cell->parameters["\\STATE_TABLE"] = RTLIL::Const();
cell->parameters[ID::STATE_BITS] = RTLIL::Const(state_bits);
cell->parameters[ID::STATE_NUM] = RTLIL::Const(state_table.size());
cell->parameters[ID::STATE_NUM_LOG2] = RTLIL::Const(state_num_log2);
cell->parameters[ID::STATE_RST] = RTLIL::Const(reset_state);
cell->parameters[ID::STATE_TABLE] = RTLIL::Const();
for (int i = 0; i < int(state_table.size()); i++) {
std::vector<RTLIL::State> &bits_table = cell->parameters["\\STATE_TABLE"].bits;
std::vector<RTLIL::State> &bits_table = cell->parameters[ID::STATE_TABLE].bits;
std::vector<RTLIL::State> &bits_state = state_table[i].bits;
bits_table.insert(bits_table.end(), bits_state.begin(), bits_state.end());
}
cell->parameters["\\TRANS_NUM"] = RTLIL::Const(transition_table.size());
cell->parameters["\\TRANS_TABLE"] = RTLIL::Const();
cell->parameters[ID::TRANS_NUM] = RTLIL::Const(transition_table.size());
cell->parameters[ID::TRANS_TABLE] = RTLIL::Const();
for (int i = 0; i < int(transition_table.size()); i++)
{
std::vector<RTLIL::State> &bits_table = cell->parameters["\\TRANS_TABLE"].bits;
std::vector<RTLIL::State> &bits_table = cell->parameters[ID::TRANS_TABLE].bits;
transition_t &tr = transition_table[i];
RTLIL::Const const_state_in = RTLIL::Const(tr.state_in, state_num_log2);
@ -78,21 +78,21 @@ struct FsmData
void copy_from_cell(RTLIL::Cell *cell)
{
num_inputs = cell->parameters["\\CTRL_IN_WIDTH"].as_int();
num_outputs = cell->parameters["\\CTRL_OUT_WIDTH"].as_int();
num_inputs = cell->parameters[ID::CTRL_IN_WIDTH].as_int();
num_outputs = cell->parameters[ID::CTRL_OUT_WIDTH].as_int();
state_bits = cell->parameters["\\STATE_BITS"].as_int();
reset_state = cell->parameters["\\STATE_RST"].as_int();
state_bits = cell->parameters[ID::STATE_BITS].as_int();
reset_state = cell->parameters[ID::STATE_RST].as_int();
int state_num = cell->parameters["\\STATE_NUM"].as_int();
int state_num_log2 = cell->parameters["\\STATE_NUM_LOG2"].as_int();
int trans_num = cell->parameters["\\TRANS_NUM"].as_int();
int state_num = cell->parameters[ID::STATE_NUM].as_int();
int state_num_log2 = cell->parameters[ID::STATE_NUM_LOG2].as_int();
int trans_num = cell->parameters[ID::TRANS_NUM].as_int();
if (reset_state < 0 || reset_state >= state_num)
reset_state = -1;
RTLIL::Const state_table = cell->parameters["\\STATE_TABLE"];
RTLIL::Const trans_table = cell->parameters["\\TRANS_TABLE"];
RTLIL::Const state_table = cell->parameters[ID::STATE_TABLE];
RTLIL::Const trans_table = cell->parameters[ID::TRANS_TABLE];
for (int i = 0; i < state_num; i++) {
RTLIL::Const state_code;
@ -134,7 +134,7 @@ struct FsmData
{
log("-------------------------------------\n");
log("\n");
log(" Information on FSM %s (%s):\n", cell->name.c_str(), cell->parameters["\\NAME"].decode_string().c_str());
log(" Information on FSM %s (%s):\n", cell->name.c_str(), cell->parameters[ID::NAME].decode_string().c_str());
log("\n");
log(" Number of input signals: %3d\n", num_inputs);
log(" Number of output signals: %3d\n", num_outputs);
@ -142,13 +142,13 @@ struct FsmData
log("\n");
log(" Input signals:\n");
RTLIL::SigSpec sig_in = cell->getPort("\\CTRL_IN");
RTLIL::SigSpec sig_in = cell->getPort(ID::CTRL_IN);
for (int i = 0; i < GetSize(sig_in); i++)
log(" %3d: %s\n", i, log_signal(sig_in[i]));
log("\n");
log(" Output signals:\n");
RTLIL::SigSpec sig_out = cell->getPort("\\CTRL_OUT");
RTLIL::SigSpec sig_out = cell->getPort(ID::CTRL_OUT);
for (int i = 0; i < GetSize(sig_out); i++)
log(" %3d: %s\n", i, log_signal(sig_out[i]));

View file

@ -42,11 +42,10 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes,
{
std::set<RTLIL::IdString> found_celltypes;
for (auto i1 : design->modules_)
for (auto i2 : i1.second->cells_)
for (auto mod : design->modules())
for (auto cell : mod->cells())
{
RTLIL::Cell *cell = i2.second;
if (design->has(cell->type))
if (design->module(cell->type) != nullptr)
continue;
if (cell->type.begins_with("$__"))
continue;
@ -62,15 +61,15 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes,
std::map<RTLIL::IdString, int> portwidths;
log("Generate module for cell type %s:\n", celltype.c_str());
for (auto i1 : design->modules_)
for (auto i2 : i1.second->cells_)
if (i2.second->type == celltype) {
for (auto &conn : i2.second->connections()) {
for (auto mod : design->modules())
for (auto cell : mod->cells())
if (cell->type == celltype) {
for (auto &conn : cell->connections()) {
if (conn.first[0] != '$')
portnames.insert(conn.first);
portwidths[conn.first] = max(portwidths[conn.first], conn.second.size());
}
for (auto &para : i2.second->parameters)
for (auto &para : cell->parameters)
parameters.insert(para.first);
}
@ -121,7 +120,7 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes,
RTLIL::Module *mod = new RTLIL::Module;
mod->name = celltype;
mod->attributes["\\blackbox"] = RTLIL::Const(1);
mod->attributes[ID::blackbox] = RTLIL::Const(1);
design->add(mod);
for (auto &decl : ports) {
@ -167,27 +166,25 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
// If any of the ports are actually interface ports, we will always need to
// reprocess the module:
if(!module->get_bool_attribute("\\interfaces_replaced_in_module")) {
for (auto &wire : module->wires_) {
if ((wire.second->port_input || wire.second->port_output) && wire.second->get_bool_attribute("\\is_interface"))
if(!module->get_bool_attribute(ID::interfaces_replaced_in_module)) {
for (auto wire : module->wires()) {
if ((wire->port_input || wire->port_output) && wire->get_bool_attribute(ID::is_interface))
has_interface_ports = true;
}
}
// Always keep track of all derived interfaces available in the current module in 'interfaces_in_module':
dict<RTLIL::IdString, RTLIL::Module*> interfaces_in_module;
for (auto &cell_it : module->cells_)
for (auto cell : module->cells())
{
RTLIL::Cell *cell = cell_it.second;
if(cell->get_bool_attribute("\\is_interface")) {
RTLIL::Module *intf_module = design->modules_[cell->type];
if(cell->get_bool_attribute(ID::is_interface)) {
RTLIL::Module *intf_module = design->module(cell->type);
interfaces_in_module[cell->name] = intf_module;
}
}
for (auto &cell_it : module->cells_)
for (auto cell : module->cells())
{
RTLIL::Cell *cell = cell_it.second;
bool has_interfaces_not_found = false;
std::vector<RTLIL::IdString> connections_to_remove;
@ -208,11 +205,11 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
dict<RTLIL::IdString, RTLIL::Module*> interfaces_to_add_to_submodule;
dict<RTLIL::IdString, RTLIL::IdString> modports_used_in_submodule;
if (design->modules_.count(cell->type) == 0)
if (design->module(cell->type) == nullptr)
{
if (design->modules_.count("$abstract" + cell->type.str()))
if (design->module("$abstract" + cell->type.str()) != nullptr)
{
cell->type = design->modules_.at("$abstract" + cell->type.str())->derive(design, cell->parameters);
cell->type = design->module("$abstract" + cell->type.str())->derive(design, cell->parameters);
cell->parameters.clear();
did_something = true;
continue;
@ -246,7 +243,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
continue;
loaded_module:
if (design->modules_.count(cell->type) == 0)
if (design->module(cell->type) == nullptr)
log_error("File `%s' from libdir does not declare module `%s'.\n", filename.c_str(), cell->type.c_str());
did_something = true;
} else {
@ -256,24 +253,24 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
// Go over all connections and see if any of them are SV interfaces. If they are, then add the replacements to
// some lists, so that the ports for sub-modules can be replaced further down:
for (auto &conn : cell->connections()) {
if(mod->wires_.count(conn.first) != 0 && mod->wire(conn.first)->get_bool_attribute("\\is_interface")) { // Check if the connection is present as an interface in the sub-module's port list
//const pool<string> &interface_type_pool = mod->wire(conn.first)->get_strpool_attribute("\\interface_type");
if(mod->wire(conn.first) != nullptr && mod->wire(conn.first)->get_bool_attribute(ID::is_interface)) { // Check if the connection is present as an interface in the sub-module's port list
//const pool<string> &interface_type_pool = mod->wire(conn.first)->get_strpool_attribute(ID::interface_type);
//for (auto &d : interface_type_pool) { // TODO: Compare interface type to type in parent module (not crucially important, but good for robustness)
//}
// Find if the sub-module has set a modport for the current interface connection:
const pool<string> &interface_modport_pool = mod->wire(conn.first)->get_strpool_attribute("\\interface_modport");
const pool<string> &interface_modport_pool = mod->wire(conn.first)->get_strpool_attribute(ID::interface_modport);
std::string interface_modport = "";
for (auto &d : interface_modport_pool) {
interface_modport = "\\" + d;
}
if(conn.second.bits().size() == 1 && conn.second.bits()[0].wire->get_bool_attribute("\\is_interface")) { // Check if the connected wire is a potential interface in the parent module
if(conn.second.bits().size() == 1 && conn.second.bits()[0].wire->get_bool_attribute(ID::is_interface)) { // Check if the connected wire is a potential interface in the parent module
std::string interface_name_str = conn.second.bits()[0].wire->name.str();
interface_name_str.replace(0,23,""); // Strip the prefix '$dummywireforinterface' from the dummy wire to get the name
interface_name_str = "\\" + interface_name_str;
RTLIL::IdString interface_name = interface_name_str;
bool not_found_interface = false;
if(module->get_bool_attribute("\\interfaces_replaced_in_module")) { // If 'interfaces' in the cell have not be been handled yet, there is no need to derive the sub-module either
if(module->get_bool_attribute(ID::interfaces_replaced_in_module)) { // If 'interfaces' in the cell have not be been handled yet, there is no need to derive the sub-module either
// Check if the interface instance is present in module:
// Interface instances may either have the plain name or the name appended with '_inst_from_top_dummy'.
// Check for both of them here
@ -285,11 +282,11 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
if (nexactmatch != 0) // Choose the one with the plain name if it exists
interface_name2 = interface_name;
RTLIL::Module *mod_replace_ports = interfaces_in_module.at(interface_name2);
for (auto &mod_wire : mod_replace_ports->wires_) { // Go over all wires in interface, and add replacements to lists.
std::string signal_name1 = conn.first.str() + "." + log_id(mod_wire.first);
std::string signal_name2 = interface_name.str() + "." + log_id(mod_wire.first);
for (auto mod_wire : mod_replace_ports->wires()) { // Go over all wires in interface, and add replacements to lists.
std::string signal_name1 = conn.first.str() + "." + log_id(mod_wire->name);
std::string signal_name2 = interface_name.str() + "." + log_id(mod_wire);
connections_to_add_name.push_back(RTLIL::IdString(signal_name1));
if(module->wires_.count(signal_name2) == 0) {
if(module->wire(signal_name2) == nullptr) {
log_error("Could not find signal '%s' in '%s'\n", signal_name2.c_str(), log_id(module->name));
}
else {
@ -312,7 +309,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
// which will delay the expansion of this cell:
if (not_found_interface) {
// If we have already gone over all cells in this module, and the interface has still not been found - flag it as an error:
if(!(module->get_bool_attribute("\\cells_not_processed"))) {
if(!(module->get_bool_attribute(ID::cells_not_processed))) {
log_warning("Could not find interface instance for `%s' in `%s'\n", log_id(interface_name), log_id(module));
}
else {
@ -344,9 +341,9 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
}
}
RTLIL::Module *mod = design->modules_[cell->type];
RTLIL::Module *mod = design->module(cell->type);
if (design->modules_.at(cell->type)->get_blackbox_attribute()) {
if (design->module(cell->type)->get_blackbox_attribute()) {
if (flag_simcheck)
log_error("Module `%s' referenced in module `%s' in cell `%s' is a blackbox/whitebox module.\n",
cell->type.c_str(), module->name.c_str(), cell->name.c_str());
@ -370,10 +367,10 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
// If there are no overridden parameters AND not interfaces, then we can use the existing module instance as the type
// for the cell:
if (cell->parameters.size() == 0 && (interfaces_to_add_to_submodule.size() == 0 || !(cell->get_bool_attribute("\\module_not_derived")))) {
if (cell->parameters.size() == 0 && (interfaces_to_add_to_submodule.size() == 0 || !(cell->get_bool_attribute(ID::module_not_derived)))) {
// If the cell being processed is an the interface instance itself, go down to "handle_interface_instance:",
// so that the signals of the interface are added to the parent module.
if (mod->get_bool_attribute("\\is_interface")) {
if (mod->get_bool_attribute(ID::is_interface)) {
goto handle_interface_instance;
}
continue;
@ -387,23 +384,23 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
// We add all the signals of the interface explicitly to the parent module. This is always needed when we encounter
// an interface instance:
if (mod->get_bool_attribute("\\is_interface") && cell->get_bool_attribute("\\module_not_derived")) {
cell->set_bool_attribute("\\is_interface");
RTLIL::Module *derived_module = design->modules_[cell->type];
if (mod->get_bool_attribute(ID::is_interface) && cell->get_bool_attribute(ID::module_not_derived)) {
cell->set_bool_attribute(ID::is_interface);
RTLIL::Module *derived_module = design->module(cell->type);
interfaces_in_module[cell->name] = derived_module;
did_something = true;
}
// We clear 'module_not_derived' such that we will not rederive the cell again (needed when there are interfaces connected to the cell)
cell->attributes.erase("\\module_not_derived");
cell->attributes.erase(ID::module_not_derived);
}
// Clear the attribute 'cells_not_processed' such that it can be known that we
// have been through all cells at least once, and that we can know whether
// to flag an error because of interface instances not found:
module->attributes.erase("\\cells_not_processed");
module->attributes.erase(ID::cells_not_processed);
// If any interface instances or interface ports were found in the module, we need to rederive it completely:
if ((interfaces_in_module.size() > 0 || has_interface_ports) && !module->get_bool_attribute("\\interfaces_replaced_in_module")) {
if ((interfaces_in_module.size() > 0 || has_interface_ports) && !module->get_bool_attribute(ID::interfaces_replaced_in_module)) {
module->reprocess_module(design, interfaces_in_module);
return did_something;
}
@ -414,25 +411,25 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
RTLIL::Cell *cell = it.first;
int idx = it.second.first, num = it.second.second;
if (design->modules_.count(cell->type) == 0)
if (design->module(cell->type) == nullptr)
log_error("Array cell `%s.%s' of unknown type `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
RTLIL::Module *mod = design->modules_[cell->type];
RTLIL::Module *mod = design->module(cell->type);
for (auto &conn : cell->connections_) {
int conn_size = conn.second.size();
RTLIL::IdString portname = conn.first;
if (portname.begins_with("$")) {
int port_id = atoi(portname.substr(1).c_str());
for (auto &wire_it : mod->wires_)
if (wire_it.second->port_id == port_id) {
portname = wire_it.first;
for (auto wire : mod->wires())
if (wire->port_id == port_id) {
portname = wire->name;
break;
}
}
if (mod->wires_.count(portname) == 0)
if (mod->wire(portname) == nullptr)
log_error("Array cell `%s.%s' connects to unknown port `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(conn.first));
int port_size = mod->wires_.at(portname)->width;
int port_size = mod->wire(portname)->width;
if (conn_size == port_size || conn_size == 0)
continue;
if (conn_size != port_size*num)
@ -470,21 +467,21 @@ void hierarchy_clean(RTLIL::Design *design, RTLIL::Module *top, bool purge_lib)
hierarchy_worker(design, used, top, 0);
std::vector<RTLIL::Module*> del_modules;
for (auto &it : design->modules_)
if (used.count(it.second) == 0)
del_modules.push_back(it.second);
for (auto mod : design->modules())
if (used.count(mod) == 0)
del_modules.push_back(mod);
else {
// Now all interface ports must have been exploded, and it is hence
// safe to delete all of the remaining dummy interface ports:
pool<RTLIL::Wire*> del_wires;
for(auto &wire : it.second->wires_) {
if ((wire.second->port_input || wire.second->port_output) && wire.second->get_bool_attribute("\\is_interface")) {
del_wires.insert(wire.second);
for(auto wire : mod->wires()) {
if ((wire->port_input || wire->port_output) && wire->get_bool_attribute(ID::is_interface)) {
del_wires.insert(wire);
}
}
if (del_wires.size() > 0) {
it.second->remove(del_wires);
it.second->fixup_ports();
mod->remove(del_wires);
mod->fixup_ports();
}
}
@ -493,9 +490,8 @@ void hierarchy_clean(RTLIL::Design *design, RTLIL::Module *top, bool purge_lib)
if (!purge_lib && mod->get_blackbox_attribute())
continue;
log("Removing unused module `%s'.\n", mod->name.c_str());
design->modules_.erase(mod->name);
design->remove(mod);
del_counter++;
delete mod;
}
log("Removed %d unused modules.\n", del_counter);
@ -506,7 +502,7 @@ bool set_keep_assert(std::map<RTLIL::Module*, bool> &cache, RTLIL::Module *mod)
if (cache.count(mod) == 0)
for (auto c : mod->cells()) {
RTLIL::Module *m = mod->design->module(c->type);
if ((m != nullptr && set_keep_assert(cache, m)) || c->type.in("$assert", "$assume", "$live", "$fair", "$cover"))
if ((m != nullptr && set_keep_assert(cache, m)) || c->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover)))
return cache[mod] = true;
}
return cache[mod];
@ -536,11 +532,11 @@ int find_top_mod_score(Design *design, Module *module, dict<Module*, int> &db)
RTLIL::Module *check_if_top_has_changed(Design *design, Module *top_mod)
{
if(top_mod != NULL && top_mod->get_bool_attribute("\\initial_top"))
if(top_mod != NULL && top_mod->get_bool_attribute(ID::initial_top))
return top_mod;
else {
for (auto mod : design->modules()) {
if (mod->get_bool_attribute("\\top")) {
if (mod->get_bool_attribute(ID::top)) {
return mod;
}
}
@ -817,9 +813,9 @@ struct HierarchyPass : public Pass {
log_push();
if (top_mod == nullptr)
for (auto &mod_it : design->modules_)
if (mod_it.second->get_bool_attribute("\\top"))
top_mod = mod_it.second;
for (auto mod : design->modules())
if (mod->get_bool_attribute(ID::top))
top_mod = mod;
if (top_mod != nullptr && top_mod->name.begins_with("$abstract")) {
IdString top_name = top_mod->name.substr(strlen("$abstract"));
@ -862,11 +858,11 @@ struct HierarchyPass : public Pass {
log_error("Design has no top module.\n");
if (top_mod != NULL) {
for (auto &mod_it : design->modules_)
if (mod_it.second == top_mod)
mod_it.second->attributes["\\initial_top"] = RTLIL::Const(1);
for (auto mod : design->modules())
if (mod == top_mod)
mod->attributes[ID::initial_top] = RTLIL::Const(1);
else
mod_it.second->attributes.erase("\\initial_top");
mod->attributes.erase(ID::initial_top);
}
bool did_something = true;
@ -900,9 +896,9 @@ struct HierarchyPass : public Pass {
// Delete modules marked as 'to_delete':
std::vector<RTLIL::Module *> modules_to_delete;
for(auto &mod_it : design->modules_) {
if (mod_it.second->get_bool_attribute("\\to_delete")) {
modules_to_delete.push_back(mod_it.second);
for(auto mod : design->modules()) {
if (mod->get_bool_attribute(ID::to_delete)) {
modules_to_delete.push_back(mod);
}
}
for(size_t i=0; i<modules_to_delete.size(); i++) {
@ -917,12 +913,12 @@ struct HierarchyPass : public Pass {
}
if (top_mod != NULL) {
for (auto &mod_it : design->modules_) {
if (mod_it.second == top_mod)
mod_it.second->attributes["\\top"] = RTLIL::Const(1);
for (auto mod : design->modules()) {
if (mod == top_mod)
mod->attributes[ID::top] = RTLIL::Const(1);
else
mod_it.second->attributes.erase("\\top");
mod_it.second->attributes.erase("\\initial_top");
mod->attributes.erase(ID::top);
mod->attributes.erase(ID::initial_top);
}
}
@ -931,7 +927,7 @@ struct HierarchyPass : public Pass {
for (auto mod : design->modules())
if (set_keep_assert(cache, mod)) {
log("Module %s directly or indirectly contains formal properties -> setting \"keep\" attribute.\n", log_id(mod));
mod->set_bool_attribute("\\keep");
mod->set_bool_attribute(ID::keep);
}
}
@ -941,22 +937,20 @@ struct HierarchyPass : public Pass {
std::map<std::pair<RTLIL::Module*,int>, RTLIL::IdString> pos_map;
std::vector<std::pair<RTLIL::Module*,RTLIL::Cell*>> pos_work;
for (auto &mod_it : design->modules_)
for (auto &cell_it : mod_it.second->cells_) {
RTLIL::Cell *cell = cell_it.second;
if (design->modules_.count(cell->type) == 0)
for (auto mod : design->modules())
for (auto cell : mod->cells()) {
if (design->module(cell->type) == nullptr)
continue;
for (auto &conn : cell->connections())
if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') {
pos_mods.insert(design->modules_.at(cell->type));
pos_work.push_back(std::pair<RTLIL::Module*,RTLIL::Cell*>(mod_it.second, cell));
pos_mods.insert(design->module(cell->type));
pos_work.push_back(std::pair<RTLIL::Module*,RTLIL::Cell*>(mod, cell));
break;
}
}
for (auto module : pos_mods)
for (auto &wire_it : module->wires_) {
RTLIL::Wire *wire = wire_it.second;
for (auto wire : module->wires()) {
if (wire->port_id > 0)
pos_map[std::pair<RTLIL::Module*,int>(module, wire->port_id)] = wire->name;
}
@ -970,7 +964,7 @@ struct HierarchyPass : public Pass {
for (auto &conn : cell->connections())
if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') {
int id = atoi(conn.first.c_str()+1);
std::pair<RTLIL::Module*,int> key(design->modules_.at(cell->type), id);
std::pair<RTLIL::Module*,int> key(design->module(cell->type), id);
if (pos_map.count(key) == 0) {
log(" Failed to map positional argument %d of cell %s.%s (%s).\n",
id, RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
@ -989,8 +983,8 @@ struct HierarchyPass : public Pass {
{
for (auto module : design->modules())
for (auto wire : module->wires())
if (wire->port_input && wire->attributes.count("\\defaultvalue"))
defaults_db[module->name][wire->name] = wire->attributes.at("\\defaultvalue");
if (wire->port_input && wire->attributes.count(ID::defaultvalue))
defaults_db[module->name][wire->name] = wire->attributes.at(ID::defaultvalue);
}
// Process SV implicit wildcard port connections
std::set<Module*> blackbox_derivatives;
@ -1000,7 +994,7 @@ struct HierarchyPass : public Pass {
{
for (auto cell : module->cells())
{
if (!cell->get_bool_attribute(ID(wildcard_port_conns)))
if (!cell->get_bool_attribute(ID::wildcard_port_conns))
continue;
Module *m = design->module(cell->type);
@ -1009,7 +1003,7 @@ struct HierarchyPass : public Pass {
RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
// Need accurate port widths for error checking; so must derive blackboxes with dynamic port widths
if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) {
if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute(ID::dynports)) {
IdString new_m_name = m->derive(design, cell->parameters, true);
if (new_m_name.empty())
continue;
@ -1042,7 +1036,7 @@ struct HierarchyPass : public Pass {
RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
cell->setPort(wire->name, parent_wire);
}
cell->attributes.erase(ID(wildcard_port_conns));
cell->attributes.erase(ID::wildcard_port_conns);
}
}
@ -1077,11 +1071,11 @@ struct HierarchyPass : public Pass {
for (auto wire : module->wires())
{
if (wire->get_bool_attribute("\\wand")) {
if (wire->get_bool_attribute(ID::wand)) {
wand_map[wire] = SigSpec();
wand_wor_index.insert(wire);
}
if (wire->get_bool_attribute("\\wor")) {
if (wire->get_bool_attribute(ID::wor)) {
wor_map[wire] = SigSpec();
wand_wor_index.insert(wire);
}
@ -1192,7 +1186,7 @@ struct HierarchyPass : public Pass {
if (m == nullptr)
continue;
if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) {
if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute(ID::dynports)) {
IdString new_m_name = m->derive(design, cell->parameters, true);
if (new_m_name.empty())
continue;

View file

@ -51,7 +51,7 @@ struct SubmodWorker
RTLIL::Wire *new_wire;
RTLIL::Const is_int_driven;
bool is_int_used, is_ext_driven, is_ext_used;
wire_flags_t(RTLIL::Wire* wire) : new_wire(NULL), is_int_driven(State::S0, GetSize(wire)), is_int_used(false), is_ext_driven(false), is_ext_used(false) { }
wire_flags_t(RTLIL::Wire* wire) : new_wire(nullptr), is_int_driven(State::S0, GetSize(wire)), is_int_used(false), is_ext_driven(false), is_ext_used(false) { }
};
std::map<RTLIL::Wire*, wire_flags_t> wire_flags;
bool flag_found_something;
@ -75,7 +75,7 @@ struct SubmodWorker
void flag_signal(const RTLIL::SigSpec &sig, bool create, bool set_int_driven, bool set_int_used, bool set_ext_driven, bool set_ext_used)
{
for (auto &c : sig.chunks())
if (c.wire != NULL) {
if (c.wire != nullptr) {
flag_wire(c.wire, create, set_int_used, set_ext_driven, set_ext_used);
if (set_int_driven)
for (int i = c.offset; i < c.offset+c.width; i++) {
@ -100,8 +100,7 @@ struct SubmodWorker
flag_signal(conn.second, true, true, true, false, false);
}
}
for (auto &it : module->cells_) {
RTLIL::Cell *cell = it.second;
for (auto cell : module->cells()) {
if (submod.cells.count(cell) > 0)
continue;
if (ct.cell_known(cell->type)) {
@ -176,16 +175,16 @@ struct SubmodWorker
new_wire->start_offset = wire->start_offset;
new_wire->attributes = wire->attributes;
if (!flags.is_int_driven.is_fully_zero()) {
new_wire->attributes.erase(ID(init));
new_wire->attributes.erase(ID::init);
auto sig = sigmap(wire);
for (int i = 0; i < GetSize(sig); i++) {
if (flags.is_int_driven[i] == State::S0)
continue;
if (!sig[i].wire)
continue;
auto it = sig[i].wire->attributes.find(ID(init));
auto it = sig[i].wire->attributes.find(ID::init);
if (it != sig[i].wire->attributes.end()) {
auto jt = new_wire->attributes.insert(std::make_pair(ID(init), Const(State::Sx, GetSize(sig)))).first;
auto jt = new_wire->attributes.insert(std::make_pair(ID::init, Const(State::Sx, GetSize(sig)))).first;
jt->second[i] = it->second[sig[i].offset];
it->second[sig[i].offset] = State::Sx;
}
@ -211,7 +210,7 @@ struct SubmodWorker
RTLIL::Cell *new_cell = new_mod->addCell(cell->name, cell);
for (auto &conn : new_cell->connections_)
for (auto &bit : conn.second)
if (bit.wire != NULL) {
if (bit.wire != nullptr) {
log_assert(wire_flags.count(bit.wire) > 0);
bit.wire = wire_flags.at(bit.wire).new_wire;
}
@ -274,24 +273,23 @@ struct SubmodWorker
if (opt_name.empty())
{
for (auto &it : module->wires_)
it.second->attributes.erase("\\submod");
for (auto wire : module->wires())
wire->attributes.erase(ID::submod);
for (auto &it : module->cells_)
for (auto cell : module->cells())
{
RTLIL::Cell *cell = it.second;
if (cell->attributes.count("\\submod") == 0 || cell->attributes["\\submod"].bits.size() == 0) {
cell->attributes.erase("\\submod");
if (cell->attributes.count(ID::submod) == 0 || cell->attributes[ID::submod].bits.size() == 0) {
cell->attributes.erase(ID::submod);
continue;
}
std::string submod_str = cell->attributes["\\submod"].decode_string();
cell->attributes.erase("\\submod");
std::string submod_str = cell->attributes[ID::submod].decode_string();
cell->attributes.erase(ID::submod);
if (submodules.count(submod_str) == 0) {
submodules[submod_str].name = submod_str;
submodules[submod_str].full_name = module->name.str() + "_" + submod_str;
while (design->modules_.count(submodules[submod_str].full_name) != 0 ||
while (design->module(submodules[submod_str].full_name) != nullptr ||
module->count_id(submodules[submod_str].full_name) != 0)
submodules[submod_str].full_name += "_";
}
@ -301,9 +299,8 @@ struct SubmodWorker
}
else
{
for (auto &it : module->cells_)
for (auto cell : module->cells())
{
RTLIL::Cell *cell = it.second;
if (!design->selected(module, cell))
continue;
submodules[opt_name].name = opt_name;
@ -392,12 +389,12 @@ struct SubmodPass : public Pass {
while (did_something) {
did_something = false;
std::vector<RTLIL::IdString> queued_modules;
for (auto &mod_it : design->modules_)
if (handled_modules.count(mod_it.first) == 0 && design->selected_whole_module(mod_it.first))
queued_modules.push_back(mod_it.first);
for (auto mod : design->modules())
if (handled_modules.count(mod->name) == 0 && design->selected_whole_module(mod->name))
queued_modules.push_back(mod->name);
for (auto &modname : queued_modules)
if (design->modules_.count(modname) != 0) {
SubmodWorker worker(design, design->modules_[modname], copy_mode, hidden_mode);
if (design->module(modname) != nullptr) {
SubmodWorker worker(design, design->module(modname), copy_mode, hidden_mode);
handled_modules.insert(modname);
did_something = true;
}
@ -407,15 +404,13 @@ struct SubmodPass : public Pass {
}
else
{
RTLIL::Module *module = NULL;
for (auto &mod_it : design->modules_) {
if (!design->selected_module(mod_it.first))
continue;
if (module != NULL)
log_cmd_error("More than one module selected: %s %s\n", module->name.c_str(), mod_it.first.c_str());
module = mod_it.second;
RTLIL::Module *module = nullptr;
for (auto mod : design->selected_modules()) {
if (module != nullptr)
log_cmd_error("More than one module selected: %s %s\n", module->name.c_str(), mod->name.c_str());
module = mod;
}
if (module == NULL)
if (module == nullptr)
log("Nothing selected -> do nothing.\n");
else {
Pass::call_on_module(design, module, "opt_clean");

View file

@ -64,7 +64,7 @@ struct UniquifyPass : public Pass {
for (auto module : design->selected_modules())
{
if (!module->get_bool_attribute("\\unique") && !module->get_bool_attribute("\\top"))
if (!module->get_bool_attribute(ID::unique) && !module->get_bool_attribute(ID::top))
continue;
for (auto cell : module->selected_cells())
@ -78,7 +78,7 @@ struct UniquifyPass : public Pass {
if (tmod->get_blackbox_attribute())
continue;
if (tmod->get_bool_attribute("\\unique") && newname == tmod->name)
if (tmod->get_bool_attribute(ID::unique) && newname == tmod->name)
continue;
log("Creating module %s from %s.\n", log_id(newname), log_id(tmod));
@ -86,9 +86,9 @@ struct UniquifyPass : public Pass {
auto smod = tmod->clone();
smod->name = newname;
cell->type = newname;
smod->set_bool_attribute("\\unique");
if (smod->attributes.count("\\hdlname") == 0)
smod->attributes["\\hdlname"] = string(log_id(tmod->name));
smod->set_bool_attribute(ID::unique);
if (smod->attributes.count(ID::hdlname) == 0)
smod->attributes[ID::hdlname] = string(log_id(tmod->name));
design->add(smod);
did_something = true;

View file

@ -105,11 +105,11 @@ struct rules_t
log_error("Bram %s variants %d and %d have different values for 'groups'.\n", log_id(name), variant, other.variant);
if (abits != other.abits)
variant_params["\\CFG_ABITS"] = abits;
variant_params[ID::CFG_ABITS] = abits;
if (dbits != other.dbits)
variant_params["\\CFG_DBITS"] = dbits;
variant_params[ID::CFG_DBITS] = dbits;
if (init != other.init)
variant_params["\\CFG_INIT"] = init;
variant_params[ID::CFG_INIT] = init;
for (int i = 0; i < groups; i++)
{
@ -414,44 +414,44 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram,
log(" Mapping to bram type %s (variant %d):\n", log_id(bram.name), bram.variant);
// bram.dump_config();
int mem_size = cell->getParam("\\SIZE").as_int();
int mem_abits = cell->getParam("\\ABITS").as_int();
int mem_width = cell->getParam("\\WIDTH").as_int();
// int mem_offset = cell->getParam("\\OFFSET").as_int();
int mem_size = cell->getParam(ID::SIZE).as_int();
int mem_abits = cell->getParam(ID::ABITS).as_int();
int mem_width = cell->getParam(ID::WIDTH).as_int();
// int mem_offset = cell->getParam(ID::OFFSET).as_int();
bool cell_init = !SigSpec(cell->getParam("\\INIT")).is_fully_undef();
bool cell_init = !SigSpec(cell->getParam(ID::INIT)).is_fully_undef();
vector<Const> initdata;
if (cell_init) {
Const initparam = cell->getParam("\\INIT");
Const initparam = cell->getParam(ID::INIT);
initdata.reserve(mem_size);
for (int i=0; i < mem_size; i++)
initdata.push_back(initparam.extract(mem_width*i, mem_width, State::Sx));
}
int wr_ports = cell->getParam("\\WR_PORTS").as_int();
auto wr_clken = SigSpec(cell->getParam("\\WR_CLK_ENABLE"));
auto wr_clkpol = SigSpec(cell->getParam("\\WR_CLK_POLARITY"));
int wr_ports = cell->getParam(ID::WR_PORTS).as_int();
auto wr_clken = SigSpec(cell->getParam(ID::WR_CLK_ENABLE));
auto wr_clkpol = SigSpec(cell->getParam(ID::WR_CLK_POLARITY));
wr_clken.extend_u0(wr_ports);
wr_clkpol.extend_u0(wr_ports);
SigSpec wr_en = cell->getPort("\\WR_EN");
SigSpec wr_clk = cell->getPort("\\WR_CLK");
SigSpec wr_data = cell->getPort("\\WR_DATA");
SigSpec wr_addr = cell->getPort("\\WR_ADDR");
SigSpec wr_en = cell->getPort(ID::WR_EN);
SigSpec wr_clk = cell->getPort(ID::WR_CLK);
SigSpec wr_data = cell->getPort(ID::WR_DATA);
SigSpec wr_addr = cell->getPort(ID::WR_ADDR);
int rd_ports = cell->getParam("\\RD_PORTS").as_int();
auto rd_clken = SigSpec(cell->getParam("\\RD_CLK_ENABLE"));
auto rd_clkpol = SigSpec(cell->getParam("\\RD_CLK_POLARITY"));
auto rd_transp = SigSpec(cell->getParam("\\RD_TRANSPARENT"));
int rd_ports = cell->getParam(ID::RD_PORTS).as_int();
auto rd_clken = SigSpec(cell->getParam(ID::RD_CLK_ENABLE));
auto rd_clkpol = SigSpec(cell->getParam(ID::RD_CLK_POLARITY));
auto rd_transp = SigSpec(cell->getParam(ID::RD_TRANSPARENT));
rd_clken.extend_u0(rd_ports);
rd_clkpol.extend_u0(rd_ports);
rd_transp.extend_u0(rd_ports);
SigSpec rd_en = cell->getPort("\\RD_EN");
SigSpec rd_clk = cell->getPort("\\RD_CLK");
SigSpec rd_data = cell->getPort("\\RD_DATA");
SigSpec rd_addr = cell->getPort("\\RD_ADDR");
SigSpec rd_en = cell->getPort(ID::RD_EN);
SigSpec rd_clk = cell->getPort(ID::RD_CLK);
SigSpec rd_data = cell->getPort(ID::RD_DATA);
SigSpec rd_addr = cell->getPort(ID::RD_ADDR);
if (match.shuffle_enable && bram.dbits >= portinfos.at(match.shuffle_enable - 'A').enable*2 && portinfos.at(match.shuffle_enable - 'A').enable > 0 && wr_ports > 0)
{
@ -915,7 +915,7 @@ grow_read_ports:;
else
initparam[i*bram.dbits+j] = padding;
}
c->setParam("\\INIT", initparam);
c->setParam(ID::INIT, initparam);
}
for (auto &pi : portinfos)
@ -1048,14 +1048,14 @@ void handle_cell(Cell *cell, const rules_t &rules)
{
log("Processing %s.%s:\n", log_id(cell->module), log_id(cell));
bool cell_init = !SigSpec(cell->getParam("\\INIT")).is_fully_undef();
bool cell_init = !SigSpec(cell->getParam(ID::INIT)).is_fully_undef();
dict<string, int> match_properties;
match_properties["words"] = cell->getParam("\\SIZE").as_int();
match_properties["abits"] = cell->getParam("\\ABITS").as_int();
match_properties["dbits"] = cell->getParam("\\WIDTH").as_int();
match_properties["wports"] = cell->getParam("\\WR_PORTS").as_int();
match_properties["rports"] = cell->getParam("\\RD_PORTS").as_int();
match_properties["words"] = cell->getParam(ID::SIZE).as_int();
match_properties["abits"] = cell->getParam(ID::ABITS).as_int();
match_properties["dbits"] = cell->getParam(ID::WIDTH).as_int();
match_properties["wports"] = cell->getParam(ID::WR_PORTS).as_int();
match_properties["rports"] = cell->getParam(ID::RD_PORTS).as_int();
match_properties["bits"] = match_properties["words"] * match_properties["dbits"];
match_properties["ports"] = match_properties["wports"] + match_properties["rports"];
@ -1357,7 +1357,7 @@ struct MemoryBramPass : public Pass {
for (auto mod : design->selected_modules())
for (auto cell : mod->selected_cells())
if (cell->type == "$mem")
if (cell->type == ID($mem))
handle_cell(cell, rules);
}
} MemoryBramPass;

View file

@ -25,11 +25,11 @@ PRIVATE_NAMESPACE_BEGIN
bool memcells_cmp(Cell *a, Cell *b)
{
if (a->type == "$memrd" && b->type == "$memrd")
if (a->type == ID($memrd) && b->type == ID($memrd))
return a->name < b->name;
if (a->type == "$memrd" || b->type == "$memrd")
return (a->type == "$memrd") < (b->type == "$memrd");
return a->parameters.at("\\PRIORITY").as_int() < b->parameters.at("\\PRIORITY").as_int();
if (a->type == ID($memrd) || b->type == ID($memrd))
return (a->type == ID($memrd)) < (b->type == ID($memrd));
return a->parameters.at(ID::PRIORITY).as_int() < b->parameters.at(ID::PRIORITY).as_int();
}
Cell *handle_memory(Module *module, RTLIL::Memory *memory)
@ -62,8 +62,8 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
for (auto &cell_it : module->cells_) {
Cell *cell = cell_it.second;
if (cell->type.in("$memrd", "$memwr", "$meminit") && memory->name == cell->parameters["\\MEMID"].decode_string()) {
SigSpec addr = sigmap(cell->getPort("\\ADDR"));
if (cell->type.in(ID($memrd), ID($memwr), ID($meminit)) && memory->name == cell->parameters[ID::MEMID].decode_string()) {
SigSpec addr = sigmap(cell->getPort(ID::ADDR));
for (int i = 0; i < GetSize(addr); i++)
if (addr[i] != State::S0)
addr_bits = std::max(addr_bits, i+1);
@ -90,10 +90,10 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
{
log(" %s (%s)\n", log_id(cell), log_id(cell->type));
if (cell->type == "$meminit")
if (cell->type == ID($meminit))
{
SigSpec addr = sigmap(cell->getPort("\\ADDR"));
SigSpec data = sigmap(cell->getPort("\\DATA"));
SigSpec addr = sigmap(cell->getPort(ID::ADDR));
SigSpec data = sigmap(cell->getPort(ID::DATA));
if (!addr.is_fully_const())
log_error("Non-constant address %s in memory initialization %s.\n", log_signal(addr), log_id(cell));
@ -112,14 +112,14 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
continue;
}
if (cell->type == "$memwr")
if (cell->type == ID($memwr))
{
SigSpec clk = sigmap(cell->getPort("\\CLK"));
SigSpec clk_enable = SigSpec(cell->parameters["\\CLK_ENABLE"]);
SigSpec clk_polarity = SigSpec(cell->parameters["\\CLK_POLARITY"]);
SigSpec addr = sigmap(cell->getPort("\\ADDR"));
SigSpec data = sigmap(cell->getPort("\\DATA"));
SigSpec en = sigmap(cell->getPort("\\EN"));
SigSpec clk = sigmap(cell->getPort(ID::CLK));
SigSpec clk_enable = SigSpec(cell->parameters[ID::CLK_ENABLE]);
SigSpec clk_polarity = SigSpec(cell->parameters[ID::CLK_POLARITY]);
SigSpec addr = sigmap(cell->getPort(ID::ADDR));
SigSpec data = sigmap(cell->getPort(ID::DATA));
SigSpec en = sigmap(cell->getPort(ID::EN));
if (!en.is_fully_zero())
{
@ -142,15 +142,15 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
continue;
}
if (cell->type == "$memrd")
if (cell->type == ID($memrd))
{
SigSpec clk = sigmap(cell->getPort("\\CLK"));
SigSpec clk_enable = SigSpec(cell->parameters["\\CLK_ENABLE"]);
SigSpec clk_polarity = SigSpec(cell->parameters["\\CLK_POLARITY"]);
SigSpec transparent = SigSpec(cell->parameters["\\TRANSPARENT"]);
SigSpec addr = sigmap(cell->getPort("\\ADDR"));
SigSpec data = sigmap(cell->getPort("\\DATA"));
SigSpec en = sigmap(cell->getPort("\\EN"));
SigSpec clk = sigmap(cell->getPort(ID::CLK));
SigSpec clk_enable = SigSpec(cell->parameters[ID::CLK_ENABLE]);
SigSpec clk_polarity = SigSpec(cell->parameters[ID::CLK_POLARITY]);
SigSpec transparent = SigSpec(cell->parameters[ID::TRANSPARENT]);
SigSpec addr = sigmap(cell->getPort(ID::ADDR));
SigSpec data = sigmap(cell->getPort(ID::DATA));
SigSpec en = sigmap(cell->getPort(ID::EN));
if (!en.is_fully_zero())
{
@ -178,13 +178,13 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
std::stringstream sstr;
sstr << "$mem$" << memory->name.str() << "$" << (autoidx++);
Cell *mem = module->addCell(sstr.str(), "$mem");
mem->parameters["\\MEMID"] = Const(memory->name.str());
mem->parameters["\\WIDTH"] = Const(memory->width);
mem->parameters["\\OFFSET"] = Const(memory->start_offset);
mem->parameters["\\SIZE"] = Const(memory->size);
mem->parameters["\\ABITS"] = Const(addr_bits);
mem->parameters["\\INIT"] = init_data;
Cell *mem = module->addCell(sstr.str(), ID($mem));
mem->parameters[ID::MEMID] = Const(memory->name.str());
mem->parameters[ID::WIDTH] = Const(memory->width);
mem->parameters[ID::OFFSET] = Const(memory->start_offset);
mem->parameters[ID::SIZE] = Const(memory->size);
mem->parameters[ID::ABITS] = Const(addr_bits);
mem->parameters[ID::INIT] = init_data;
log_assert(sig_wr_clk.size() == wr_ports);
log_assert(sig_wr_clk_enable.size() == wr_ports && sig_wr_clk_enable.is_fully_const());
@ -193,14 +193,14 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
log_assert(sig_wr_data.size() == wr_ports * memory->width);
log_assert(sig_wr_en.size() == wr_ports * memory->width);
mem->parameters["\\WR_PORTS"] = Const(wr_ports);
mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.as_const() : State::S0;
mem->parameters["\\WR_CLK_POLARITY"] = wr_ports ? sig_wr_clk_polarity.as_const() : State::S0;
mem->parameters[ID::WR_PORTS] = Const(wr_ports);
mem->parameters[ID::WR_CLK_ENABLE] = wr_ports ? sig_wr_clk_enable.as_const() : State::S0;
mem->parameters[ID::WR_CLK_POLARITY] = wr_ports ? sig_wr_clk_polarity.as_const() : State::S0;
mem->setPort("\\WR_CLK", sig_wr_clk);
mem->setPort("\\WR_ADDR", sig_wr_addr);
mem->setPort("\\WR_DATA", sig_wr_data);
mem->setPort("\\WR_EN", sig_wr_en);
mem->setPort(ID::WR_CLK, sig_wr_clk);
mem->setPort(ID::WR_ADDR, sig_wr_addr);
mem->setPort(ID::WR_DATA, sig_wr_data);
mem->setPort(ID::WR_EN, sig_wr_en);
log_assert(sig_rd_clk.size() == rd_ports);
log_assert(sig_rd_clk_enable.size() == rd_ports && sig_rd_clk_enable.is_fully_const());
@ -208,15 +208,15 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
log_assert(sig_rd_addr.size() == rd_ports * addr_bits);
log_assert(sig_rd_data.size() == rd_ports * memory->width);
mem->parameters["\\RD_PORTS"] = Const(rd_ports);
mem->parameters["\\RD_CLK_ENABLE"] = rd_ports ? sig_rd_clk_enable.as_const() : State::S0;
mem->parameters["\\RD_CLK_POLARITY"] = rd_ports ? sig_rd_clk_polarity.as_const() : State::S0;
mem->parameters["\\RD_TRANSPARENT"] = rd_ports ? sig_rd_transparent.as_const() : State::S0;
mem->parameters[ID::RD_PORTS] = Const(rd_ports);
mem->parameters[ID::RD_CLK_ENABLE] = rd_ports ? sig_rd_clk_enable.as_const() : State::S0;
mem->parameters[ID::RD_CLK_POLARITY] = rd_ports ? sig_rd_clk_polarity.as_const() : State::S0;
mem->parameters[ID::RD_TRANSPARENT] = rd_ports ? sig_rd_transparent.as_const() : State::S0;
mem->setPort("\\RD_CLK", sig_rd_clk);
mem->setPort("\\RD_ADDR", sig_rd_addr);
mem->setPort("\\RD_DATA", sig_rd_data);
mem->setPort("\\RD_EN", sig_rd_en);
mem->setPort(ID::RD_CLK, sig_rd_clk);
mem->setPort(ID::RD_ADDR, sig_rd_addr);
mem->setPort(ID::RD_DATA, sig_rd_data);
mem->setPort(ID::RD_EN, sig_rd_en);
// Copy attributes from RTLIL memory to $mem
for (auto attr : memory->attributes)

View file

@ -39,10 +39,10 @@ struct MemoryDffWorker
MemoryDffWorker(Module *module) : module(module), sigmap(module)
{
for (auto wire : module->wires()) {
if (wire->attributes.count("\\init") == 0)
if (wire->attributes.count(ID::init) == 0)
continue;
SigSpec sig = sigmap(wire);
Const initval = wire->attributes.at("\\init");
Const initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(sig) && i < GetSize(initval); i++)
if (initval[i] == State::S0 || initval[i] == State::S1)
init_bits.insert(sig[i]);
@ -66,8 +66,8 @@ struct MemoryDffWorker
if (after && forward_merged_dffs.count(cell))
continue;
SigSpec this_clk = cell->getPort("\\CLK");
bool this_clk_polarity = cell->parameters["\\CLK_POLARITY"].as_bool();
SigSpec this_clk = cell->getPort(ID::CLK);
bool this_clk_polarity = cell->parameters[ID::CLK_POLARITY].as_bool();
if (invbits.count(this_clk)) {
this_clk = invbits.at(this_clk);
@ -81,10 +81,10 @@ struct MemoryDffWorker
continue;
}
RTLIL::SigSpec q_norm = cell->getPort(after ? "\\D" : "\\Q");
RTLIL::SigSpec q_norm = cell->getPort(after ? ID::D : ID::Q);
sigmap.apply(q_norm);
RTLIL::SigSpec d = q_norm.extract(bit, &cell->getPort(after ? "\\Q" : "\\D"));
RTLIL::SigSpec d = q_norm.extract(bit, &cell->getPort(after ? ID::Q : ID::D));
if (d.size() != 1)
continue;
@ -113,19 +113,19 @@ struct MemoryDffWorker
bool clk_polarity = 0;
candidate_dffs.clear();
RTLIL::SigSpec sig_addr = cell->getPort("\\ADDR");
RTLIL::SigSpec sig_addr = cell->getPort(ID::ADDR);
if (!find_sig_before_dff(sig_addr, clk, clk_polarity)) {
log("no (compatible) $dff for address input found.\n");
return;
}
RTLIL::SigSpec sig_data = cell->getPort("\\DATA");
RTLIL::SigSpec sig_data = cell->getPort(ID::DATA);
if (!find_sig_before_dff(sig_data, clk, clk_polarity)) {
log("no (compatible) $dff for data input found.\n");
return;
}
RTLIL::SigSpec sig_en = cell->getPort("\\EN");
RTLIL::SigSpec sig_en = cell->getPort(ID::EN);
if (!find_sig_before_dff(sig_en, clk, clk_polarity)) {
log("no (compatible) $dff for enable input found.\n");
return;
@ -136,12 +136,12 @@ struct MemoryDffWorker
for (auto cell : candidate_dffs)
forward_merged_dffs.insert(cell);
cell->setPort("\\CLK", clk);
cell->setPort("\\ADDR", sig_addr);
cell->setPort("\\DATA", sig_data);
cell->setPort("\\EN", sig_en);
cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
cell->setPort(ID::CLK, clk);
cell->setPort(ID::ADDR, sig_addr);
cell->setPort(ID::DATA, sig_data);
cell->setPort(ID::EN, sig_en);
cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1);
cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity);
log("merged $dff to cell.\n");
return;
@ -161,10 +161,10 @@ struct MemoryDffWorker
RTLIL::SigSpec new_sig = module->addWire(sstr.str(), sig.size());
for (auto cell : module->cells())
if (cell->type == "$dff") {
RTLIL::SigSpec new_q = cell->getPort("\\Q");
if (cell->type == ID($dff)) {
RTLIL::SigSpec new_q = cell->getPort(ID::Q);
new_q.replace(sig, new_sig);
cell->setPort("\\Q", new_q);
cell->setPort(ID::Q, new_q);
}
}
@ -175,7 +175,7 @@ struct MemoryDffWorker
bool clk_polarity = 0;
RTLIL::SigSpec clk_data = RTLIL::SigSpec(RTLIL::State::Sx);
RTLIL::SigSpec sig_data = cell->getPort("\\DATA");
RTLIL::SigSpec sig_data = cell->getPort(ID::DATA);
for (auto bit : sigmap(sig_data))
if (sigbit_users_count[bit] > 1)
@ -189,9 +189,9 @@ struct MemoryDffWorker
do {
bool enable_invert = mux_cells_a.count(sig_data) != 0;
Cell *mux = enable_invert ? mux_cells_a.at(sig_data) : mux_cells_b.at(sig_data);
check_q.push_back(sigmap(mux->getPort(enable_invert ? "\\B" : "\\A")));
sig_data = sigmap(mux->getPort("\\Y"));
en.append(enable_invert ? module->LogicNot(NEW_ID, mux->getPort("\\S")) : mux->getPort("\\S"));
check_q.push_back(sigmap(mux->getPort(enable_invert ? ID::B : ID::A)));
sig_data = sigmap(mux->getPort(ID::Y));
en.append(enable_invert ? module->LogicNot(NEW_ID, mux->getPort(ID::S)) : mux->getPort(ID::S));
} while (mux_cells_a.count(sig_data) || mux_cells_b.count(sig_data));
for (auto bit : sig_data)
@ -202,12 +202,12 @@ struct MemoryDffWorker
std::all_of(check_q.begin(), check_q.end(), [&](const SigSpec &cq) {return cq == sig_data; }))
{
disconnect_dff(sig_data);
cell->setPort("\\CLK", clk_data);
cell->setPort("\\EN", en.size() > 1 ? module->ReduceAnd(NEW_ID, en) : en);
cell->setPort("\\DATA", sig_data);
cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
cell->parameters["\\TRANSPARENT"] = RTLIL::Const(0);
cell->setPort(ID::CLK, clk_data);
cell->setPort(ID::EN, en.size() > 1 ? module->ReduceAnd(NEW_ID, en) : en);
cell->setPort(ID::DATA, sig_data);
cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1);
cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity);
cell->parameters[ID::TRANSPARENT] = RTLIL::Const(0);
log("merged data $dff with rd enable to cell.\n");
return;
}
@ -217,12 +217,12 @@ struct MemoryDffWorker
if (find_sig_before_dff(sig_data, clk_data, clk_polarity, true) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx))
{
disconnect_dff(sig_data);
cell->setPort("\\CLK", clk_data);
cell->setPort("\\EN", State::S1);
cell->setPort("\\DATA", sig_data);
cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
cell->parameters["\\TRANSPARENT"] = RTLIL::Const(0);
cell->setPort(ID::CLK, clk_data);
cell->setPort(ID::EN, State::S1);
cell->setPort(ID::DATA, sig_data);
cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1);
cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity);
cell->parameters[ID::TRANSPARENT] = RTLIL::Const(0);
log("merged data $dff to cell.\n");
return;
}
@ -230,16 +230,16 @@ struct MemoryDffWorker
skip_ff_after_read_merging:;
RTLIL::SigSpec clk_addr = RTLIL::SigSpec(RTLIL::State::Sx);
RTLIL::SigSpec sig_addr = cell->getPort("\\ADDR");
RTLIL::SigSpec sig_addr = cell->getPort(ID::ADDR);
if (find_sig_before_dff(sig_addr, clk_addr, clk_polarity) &&
clk_addr != RTLIL::SigSpec(RTLIL::State::Sx))
{
cell->setPort("\\CLK", clk_addr);
cell->setPort("\\EN", State::S1);
cell->setPort("\\ADDR", sig_addr);
cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
cell->parameters["\\TRANSPARENT"] = RTLIL::Const(1);
cell->setPort(ID::CLK, clk_addr);
cell->setPort(ID::EN, State::S1);
cell->setPort(ID::ADDR, sig_addr);
cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1);
cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity);
cell->parameters[ID::TRANSPARENT] = RTLIL::Const(1);
log("merged address $dff to cell.\n");
return;
}
@ -256,18 +256,18 @@ struct MemoryDffWorker
}
for (auto cell : module->cells()) {
if (cell->type == "$dff")
if (cell->type == ID($dff))
dff_cells.push_back(cell);
if (cell->type == "$mux") {
mux_cells_a[sigmap(cell->getPort("\\A"))] = cell;
mux_cells_b[sigmap(cell->getPort("\\B"))] = cell;
if (cell->type == ID($mux)) {
mux_cells_a[sigmap(cell->getPort(ID::A))] = cell;
mux_cells_b[sigmap(cell->getPort(ID::B))] = cell;
}
if (cell->type.in("$not", "$_NOT_") || (cell->type == "$logic_not" && GetSize(cell->getPort("\\A")) == 1)) {
SigSpec sig_a = cell->getPort("\\A");
SigSpec sig_y = cell->getPort("\\Y");
if (cell->type == "$not")
sig_a.extend_u0(GetSize(sig_y), cell->getParam("\\A_SIGNED").as_bool());
if (cell->type == "$logic_not")
if (cell->type.in(ID($not), ID($_NOT_)) || (cell->type == ID($logic_not) && GetSize(cell->getPort(ID::A)) == 1)) {
SigSpec sig_a = cell->getPort(ID::A);
SigSpec sig_y = cell->getPort(ID::Y);
if (cell->type == ID($not))
sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool());
if (cell->type == ID($logic_not))
sig_y.extend_u0(1);
for (int i = 0; i < GetSize(sig_y); i++)
invbits[sig_y[i]] = sig_a[i];
@ -279,12 +279,12 @@ struct MemoryDffWorker
}
for (auto cell : module->selected_cells())
if (cell->type == "$memwr" && !cell->parameters["\\CLK_ENABLE"].as_bool())
if (cell->type == ID($memwr) && !cell->parameters[ID::CLK_ENABLE].as_bool())
handle_wr_cell(cell);
if (!flag_wr_only)
for (auto cell : module->selected_cells())
if (cell->type == "$memrd" && !cell->parameters["\\CLK_ENABLE"].as_bool())
if (cell->type == ID($memrd) && !cell->parameters[ID::CLK_ENABLE].as_bool())
handle_rd_cell(cell);
}
};

View file

@ -81,15 +81,15 @@ struct MemoryMapWorker
std::set<int> static_ports;
std::map<int, RTLIL::SigSpec> static_cells_map;
int wr_ports = cell->parameters["\\WR_PORTS"].as_int();
int rd_ports = cell->parameters["\\RD_PORTS"].as_int();
int wr_ports = cell->parameters[ID::WR_PORTS].as_int();
int rd_ports = cell->parameters[ID::RD_PORTS].as_int();
int mem_size = cell->parameters["\\SIZE"].as_int();
int mem_width = cell->parameters["\\WIDTH"].as_int();
int mem_offset = cell->parameters["\\OFFSET"].as_int();
int mem_abits = cell->parameters["\\ABITS"].as_int();
int mem_size = cell->parameters[ID::SIZE].as_int();
int mem_width = cell->parameters[ID::WIDTH].as_int();
int mem_offset = cell->parameters[ID::OFFSET].as_int();
int mem_abits = cell->parameters[ID::ABITS].as_int();
SigSpec init_data = cell->getParam("\\INIT");
SigSpec init_data = cell->getParam(ID::INIT);
init_data.extend_u0(mem_size*mem_width, true);
// delete unused memory cell
@ -99,22 +99,22 @@ struct MemoryMapWorker
}
// all write ports must share the same clock
RTLIL::SigSpec clocks = cell->getPort("\\WR_CLK");
RTLIL::Const clocks_pol = cell->parameters["\\WR_CLK_POLARITY"];
RTLIL::Const clocks_en = cell->parameters["\\WR_CLK_ENABLE"];
RTLIL::SigSpec clocks = cell->getPort(ID::WR_CLK);
RTLIL::Const clocks_pol = cell->parameters[ID::WR_CLK_POLARITY];
RTLIL::Const clocks_en = cell->parameters[ID::WR_CLK_ENABLE];
clocks_pol.bits.resize(wr_ports);
clocks_en.bits.resize(wr_ports);
RTLIL::SigSpec refclock;
RTLIL::State refclock_pol = RTLIL::State::Sx;
for (int i = 0; i < clocks.size(); i++) {
RTLIL::SigSpec wr_en = cell->getPort("\\WR_EN").extract(i * mem_width, mem_width);
RTLIL::SigSpec wr_en = cell->getPort(ID::WR_EN).extract(i * mem_width, mem_width);
if (wr_en.is_fully_const() && !wr_en.as_bool()) {
static_ports.insert(i);
continue;
}
if (clocks_en.bits[i] != RTLIL::State::S1) {
RTLIL::SigSpec wr_addr = cell->getPort("\\WR_ADDR").extract(i*mem_abits, mem_abits);
RTLIL::SigSpec wr_data = cell->getPort("\\WR_DATA").extract(i*mem_width, mem_width);
RTLIL::SigSpec wr_addr = cell->getPort(ID::WR_ADDR).extract(i*mem_abits, mem_abits);
RTLIL::SigSpec wr_data = cell->getPort(ID::WR_DATA).extract(i*mem_width, mem_width);
if (wr_addr.is_fully_const()) {
// FIXME: Actually we should check for wr_en.is_fully_const() also and
// create a $adff cell with this ports wr_en input as reset pin when wr_en
@ -155,21 +155,21 @@ struct MemoryMapWorker
}
else
{
RTLIL::Cell *c = module->addCell(genid(cell->name, "", i), "$dff");
c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"];
RTLIL::Cell *c = module->addCell(genid(cell->name, "", i), ID($dff));
c->parameters[ID::WIDTH] = cell->parameters[ID::WIDTH];
if (clocks_pol.bits.size() > 0) {
c->parameters["\\CLK_POLARITY"] = RTLIL::Const(clocks_pol.bits[0]);
c->setPort("\\CLK", clocks.extract(0, 1));
c->parameters[ID::CLK_POLARITY] = RTLIL::Const(clocks_pol.bits[0]);
c->setPort(ID::CLK, clocks.extract(0, 1));
} else {
c->parameters["\\CLK_POLARITY"] = RTLIL::Const(RTLIL::State::S1);
c->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::S0));
c->parameters[ID::CLK_POLARITY] = RTLIL::Const(RTLIL::State::S1);
c->setPort(ID::CLK, RTLIL::SigSpec(RTLIL::State::S0));
}
RTLIL::Wire *w_in = module->addWire(genid(cell->name, "", i, "$d"), mem_width);
data_reg_in.push_back(RTLIL::SigSpec(w_in));
c->setPort("\\D", data_reg_in.back());
c->setPort(ID::D, data_reg_in.back());
std::string w_out_name = stringf("%s[%d]", cell->parameters["\\MEMID"].decode_string().c_str(), i);
std::string w_out_name = stringf("%s[%d]", cell->parameters[ID::MEMID].decode_string().c_str(), i);
if (module->wires_.count(w_out_name) > 0)
w_out_name = genid(cell->name, "", i, "$q");
@ -177,10 +177,10 @@ struct MemoryMapWorker
SigSpec w_init = init_data.extract(i*mem_width, mem_width);
if (!w_init.is_fully_undef())
w_out->attributes["\\init"] = w_init.as_const();
w_out->attributes[ID::init] = w_init.as_const();
data_reg_out.push_back(RTLIL::SigSpec(w_out));
c->setPort("\\Q", data_reg_out.back());
c->setPort(ID::Q, data_reg_out.back());
}
}
@ -188,55 +188,55 @@ struct MemoryMapWorker
int count_dff = 0, count_mux = 0, count_wrmux = 0;
for (int i = 0; i < cell->parameters["\\RD_PORTS"].as_int(); i++)
for (int i = 0; i < cell->parameters[ID::RD_PORTS].as_int(); i++)
{
RTLIL::SigSpec rd_addr = cell->getPort("\\RD_ADDR").extract(i*mem_abits, mem_abits);
RTLIL::SigSpec rd_addr = cell->getPort(ID::RD_ADDR).extract(i*mem_abits, mem_abits);
if (mem_offset)
rd_addr = module->Sub(NEW_ID, rd_addr, SigSpec(mem_offset, GetSize(rd_addr)));
std::vector<RTLIL::SigSpec> rd_signals;
rd_signals.push_back(cell->getPort("\\RD_DATA").extract(i*mem_width, mem_width));
rd_signals.push_back(cell->getPort(ID::RD_DATA).extract(i*mem_width, mem_width));
if (cell->parameters["\\RD_CLK_ENABLE"].bits[i] == RTLIL::State::S1)
if (cell->parameters[ID::RD_CLK_ENABLE].bits[i] == RTLIL::State::S1)
{
RTLIL::Cell *dff_cell = nullptr;
if (cell->parameters["\\RD_TRANSPARENT"].bits[i] == RTLIL::State::S1)
if (cell->parameters[ID::RD_TRANSPARENT].bits[i] == RTLIL::State::S1)
{
dff_cell = module->addCell(genid(cell->name, "$rdreg", i), "$dff");
dff_cell->parameters["\\WIDTH"] = RTLIL::Const(mem_abits);
dff_cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]);
dff_cell->setPort("\\CLK", cell->getPort("\\RD_CLK").extract(i, 1));
dff_cell->setPort("\\D", rd_addr);
dff_cell = module->addCell(genid(cell->name, "$rdreg", i), ID($dff));
dff_cell->parameters[ID::WIDTH] = RTLIL::Const(mem_abits);
dff_cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(cell->parameters[ID::RD_CLK_POLARITY].bits[i]);
dff_cell->setPort(ID::CLK, cell->getPort(ID::RD_CLK).extract(i, 1));
dff_cell->setPort(ID::D, rd_addr);
count_dff++;
RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$q"), mem_abits);
dff_cell->setPort("\\Q", RTLIL::SigSpec(w));
dff_cell->setPort(ID::Q, RTLIL::SigSpec(w));
rd_addr = RTLIL::SigSpec(w);
}
else
{
dff_cell = module->addCell(genid(cell->name, "$rdreg", i), "$dff");
dff_cell->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"];
dff_cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]);
dff_cell->setPort("\\CLK", cell->getPort("\\RD_CLK").extract(i, 1));
dff_cell->setPort("\\Q", rd_signals.back());
dff_cell = module->addCell(genid(cell->name, "$rdreg", i), ID($dff));
dff_cell->parameters[ID::WIDTH] = cell->parameters[ID::WIDTH];
dff_cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(cell->parameters[ID::RD_CLK_POLARITY].bits[i]);
dff_cell->setPort(ID::CLK, cell->getPort(ID::RD_CLK).extract(i, 1));
dff_cell->setPort(ID::Q, rd_signals.back());
count_dff++;
RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$d"), mem_width);
rd_signals.clear();
rd_signals.push_back(RTLIL::SigSpec(w));
dff_cell->setPort("\\D", rd_signals.back());
dff_cell->setPort(ID::D, rd_signals.back());
}
SigBit en_bit = cell->getPort("\\RD_EN").extract(i);
SigBit en_bit = cell->getPort(ID::RD_EN).extract(i);
if (en_bit != State::S1) {
SigSpec new_d = module->Mux(genid(cell->name, "$rdenmux", i),
dff_cell->getPort("\\Q"), dff_cell->getPort("\\D"), en_bit);
dff_cell->setPort("\\D", new_d);
dff_cell->getPort(ID::Q), dff_cell->getPort(ID::D), en_bit);
dff_cell->setPort(ID::D, new_d);
}
}
@ -246,17 +246,17 @@ struct MemoryMapWorker
for (size_t k = 0; k < rd_signals.size(); k++)
{
RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdmux", i, "", j, "", k), "$mux");
c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"];
c->setPort("\\Y", rd_signals[k]);
c->setPort("\\S", rd_addr.extract(mem_abits-j-1, 1));
RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdmux", i, "", j, "", k), ID($mux));
c->parameters[ID::WIDTH] = cell->parameters[ID::WIDTH];
c->setPort(ID::Y, rd_signals[k]);
c->setPort(ID::S, rd_addr.extract(mem_abits-j-1, 1));
count_mux++;
c->setPort("\\A", module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$a"), mem_width));
c->setPort("\\B", module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$b"), mem_width));
c->setPort(ID::A, module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$a"), mem_width));
c->setPort(ID::B, module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$b"), mem_width));
next_rd_signals.push_back(c->getPort("\\A"));
next_rd_signals.push_back(c->getPort("\\B"));
next_rd_signals.push_back(c->getPort(ID::A));
next_rd_signals.push_back(c->getPort(ID::B));
}
next_rd_signals.swap(rd_signals);
@ -275,11 +275,11 @@ struct MemoryMapWorker
RTLIL::SigSpec sig = data_reg_out[i];
for (int j = 0; j < cell->parameters["\\WR_PORTS"].as_int(); j++)
for (int j = 0; j < cell->parameters[ID::WR_PORTS].as_int(); j++)
{
RTLIL::SigSpec wr_addr = cell->getPort("\\WR_ADDR").extract(j*mem_abits, mem_abits);
RTLIL::SigSpec wr_data = cell->getPort("\\WR_DATA").extract(j*mem_width, mem_width);
RTLIL::SigSpec wr_en = cell->getPort("\\WR_EN").extract(j*mem_width, mem_width);
RTLIL::SigSpec wr_addr = cell->getPort(ID::WR_ADDR).extract(j*mem_abits, mem_abits);
RTLIL::SigSpec wr_data = cell->getPort(ID::WR_DATA).extract(j*mem_width, mem_width);
RTLIL::SigSpec wr_en = cell->getPort(ID::WR_EN).extract(j*mem_width, mem_width);
if (mem_offset)
wr_addr = module->Sub(NEW_ID, wr_addr, SigSpec(mem_offset, GetSize(wr_addr)));
@ -303,27 +303,27 @@ struct MemoryMapWorker
if (wr_bit != State::S1)
{
RTLIL::Cell *c = module->addCell(genid(cell->name, "$wren", i, "", j, "", wr_offset), "$and");
c->parameters["\\A_SIGNED"] = RTLIL::Const(0);
c->parameters["\\B_SIGNED"] = RTLIL::Const(0);
c->parameters["\\A_WIDTH"] = RTLIL::Const(1);
c->parameters["\\B_WIDTH"] = RTLIL::Const(1);
c->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
c->setPort("\\A", w);
c->setPort("\\B", wr_bit);
RTLIL::Cell *c = module->addCell(genid(cell->name, "$wren", i, "", j, "", wr_offset), ID($and));
c->parameters[ID::A_SIGNED] = RTLIL::Const(0);
c->parameters[ID::B_SIGNED] = RTLIL::Const(0);
c->parameters[ID::A_WIDTH] = RTLIL::Const(1);
c->parameters[ID::B_WIDTH] = RTLIL::Const(1);
c->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
c->setPort(ID::A, w);
c->setPort(ID::B, wr_bit);
w = module->addWire(genid(cell->name, "$wren", i, "", j, "", wr_offset, "$y"));
c->setPort("\\Y", RTLIL::SigSpec(w));
c->setPort(ID::Y, RTLIL::SigSpec(w));
}
RTLIL::Cell *c = module->addCell(genid(cell->name, "$wrmux", i, "", j, "", wr_offset), "$mux");
c->parameters["\\WIDTH"] = wr_width;
c->setPort("\\A", sig.extract(wr_offset, wr_width));
c->setPort("\\B", wr_data.extract(wr_offset, wr_width));
c->setPort("\\S", RTLIL::SigSpec(w));
RTLIL::Cell *c = module->addCell(genid(cell->name, "$wrmux", i, "", j, "", wr_offset), ID($mux));
c->parameters[ID::WIDTH] = wr_width;
c->setPort(ID::A, sig.extract(wr_offset, wr_width));
c->setPort(ID::B, wr_data.extract(wr_offset, wr_width));
c->setPort(ID::S, RTLIL::SigSpec(w));
w = module->addWire(genid(cell->name, "$wrmux", i, "", j, "", wr_offset, "$y"), wr_width);
c->setPort("\\Y", w);
c->setPort(ID::Y, w);
sig.replace(wr_offset, w);
wr_offset += wr_width;
@ -343,7 +343,7 @@ struct MemoryMapWorker
{
std::vector<RTLIL::Cell*> cells;
for (auto cell : module->selected_cells())
if (cell->type == "$mem" && design->selected(module, cell))
if (cell->type == ID($mem))
cells.push_back(cell);
for (auto cell : cells)
handle_cell(cell);

View file

@ -47,18 +47,18 @@ struct MemoryMemxPass : public Pass {
vector<Cell*> mem_port_cells;
for (auto cell : module->selected_cells())
if (cell->type.in("$memrd", "$memwr"))
if (cell->type.in(ID($memrd), ID($memwr)))
mem_port_cells.push_back(cell);
for (auto cell : mem_port_cells)
{
IdString memid = cell->getParam("\\MEMID").decode_string();
IdString memid = cell->getParam(ID::MEMID).decode_string();
RTLIL::Memory *mem = module->memories.at(memid);
int lowest_addr = mem->start_offset;
int highest_addr = mem->start_offset + mem->size - 1;
SigSpec addr = cell->getPort("\\ADDR");
SigSpec addr = cell->getPort(ID::ADDR);
addr.extend_u0(32);
SigSpec addr_ok = module->Nex(NEW_ID, module->ReduceXor(NEW_ID, addr), module->ReduceXor(NEW_ID, {addr, State::S1}));
@ -66,23 +66,23 @@ struct MemoryMemxPass : public Pass {
addr_ok = module->LogicAnd(NEW_ID, addr_ok, module->Ge(NEW_ID, addr, lowest_addr));
addr_ok = module->LogicAnd(NEW_ID, addr_ok, module->Le(NEW_ID, addr, highest_addr));
if (cell->type == "$memrd")
if (cell->type == ID($memrd))
{
if (cell->getParam("\\CLK_ENABLE").as_bool())
if (cell->getParam(ID::CLK_ENABLE).as_bool())
log_error("Cell %s.%s (%s) has an enabled clock. Clocked $memrd cells are not supported by memory_memx!\n",
log_id(module), log_id(cell), log_id(cell->type));
SigSpec rdata = cell->getPort("\\DATA");
SigSpec rdata = cell->getPort(ID::DATA);
Wire *raw_rdata = module->addWire(NEW_ID, GetSize(rdata));
module->addMux(NEW_ID, SigSpec(State::Sx, GetSize(rdata)), raw_rdata, addr_ok, rdata);
cell->setPort("\\DATA", raw_rdata);
cell->setPort(ID::DATA, raw_rdata);
}
if (cell->type == "$memwr")
if (cell->type == ID($memwr))
{
SigSpec en = cell->getPort("\\EN");
SigSpec en = cell->getPort(ID::EN);
en = module->And(NEW_ID, en, addr_ok.repeat(GetSize(en)));
cell->setPort("\\EN", en);
cell->setPort(ID::EN, en);
}
}
}

View file

@ -52,19 +52,19 @@ struct MemoryNordffPass : public Pass {
for (auto module : design->selected_modules())
for (auto cell : vector<Cell*>(module->selected_cells()))
{
if (cell->type != "$mem")
if (cell->type != ID($mem))
continue;
int rd_ports = cell->getParam("\\RD_PORTS").as_int();
int abits = cell->getParam("\\ABITS").as_int();
int width = cell->getParam("\\WIDTH").as_int();
int rd_ports = cell->getParam(ID::RD_PORTS).as_int();
int abits = cell->getParam(ID::ABITS).as_int();
int width = cell->getParam(ID::WIDTH).as_int();
SigSpec rd_addr = cell->getPort("\\RD_ADDR");
SigSpec rd_data = cell->getPort("\\RD_DATA");
SigSpec rd_clk = cell->getPort("\\RD_CLK");
SigSpec rd_en = cell->getPort("\\RD_EN");
Const rd_clk_enable = cell->getParam("\\RD_CLK_ENABLE");
Const rd_clk_polarity = cell->getParam("\\RD_CLK_POLARITY");
SigSpec rd_addr = cell->getPort(ID::RD_ADDR);
SigSpec rd_data = cell->getPort(ID::RD_DATA);
SigSpec rd_clk = cell->getPort(ID::RD_CLK);
SigSpec rd_en = cell->getPort(ID::RD_EN);
Const rd_clk_enable = cell->getParam(ID::RD_CLK_ENABLE);
Const rd_clk_polarity = cell->getParam(ID::RD_CLK_POLARITY);
for (int i = 0; i < rd_ports; i++)
{
@ -72,11 +72,11 @@ struct MemoryNordffPass : public Pass {
if (clk_enable)
{
bool clk_polarity = cell->getParam("\\RD_CLK_POLARITY")[i] == State::S1;
bool transparent = cell->getParam("\\RD_TRANSPARENT")[i] == State::S1;
bool clk_polarity = cell->getParam(ID::RD_CLK_POLARITY)[i] == State::S1;
bool transparent = cell->getParam(ID::RD_TRANSPARENT)[i] == State::S1;
SigSpec clk = cell->getPort("\\RD_CLK")[i] ;
SigSpec en = cell->getPort("\\RD_EN")[i];
SigSpec clk = cell->getPort(ID::RD_CLK)[i] ;
SigSpec en = cell->getPort(ID::RD_EN)[i];
Cell *c;
if (transparent)
@ -108,12 +108,12 @@ struct MemoryNordffPass : public Pass {
rd_clk_polarity[i] = State::S1;
}
cell->setPort("\\RD_ADDR", rd_addr);
cell->setPort("\\RD_DATA", rd_data);
cell->setPort("\\RD_CLK", rd_clk);
cell->setPort("\\RD_EN", rd_en);
cell->setParam("\\RD_CLK_ENABLE", rd_clk_enable);
cell->setParam("\\RD_CLK_POLARITY", rd_clk_polarity);
cell->setPort(ID::RD_ADDR, rd_addr);
cell->setPort(ID::RD_DATA, rd_data);
cell->setPort(ID::RD_CLK, rd_clk);
cell->setPort(ID::RD_EN, rd_en);
cell->setParam(ID::RD_CLK_ENABLE, rd_clk_enable);
cell->setParam(ID::RD_CLK_POLARITY, rd_clk_polarity);
}
}
} MemoryNordffPass;

View file

@ -27,11 +27,11 @@ PRIVATE_NAMESPACE_BEGIN
bool memcells_cmp(RTLIL::Cell *a, RTLIL::Cell *b)
{
if (a->type == "$memrd" && b->type == "$memrd")
if (a->type == ID($memrd) && b->type == ID($memrd))
return a->name < b->name;
if (a->type == "$memrd" || b->type == "$memrd")
return (a->type == "$memrd") < (b->type == "$memrd");
return a->parameters.at("\\PRIORITY").as_int() < b->parameters.at("\\PRIORITY").as_int();
if (a->type == ID($memrd) || b->type == ID($memrd))
return (a->type == ID($memrd)) < (b->type == ID($memrd));
return a->parameters.at(ID::PRIORITY).as_int() < b->parameters.at(ID::PRIORITY).as_int();
}
struct MemoryShareWorker
@ -64,18 +64,18 @@ struct MemoryShareWorker
RTLIL::Cell *cell = sig_to_mux.at(sig).first;
int bit_idx = sig_to_mux.at(sig).second;
std::vector<RTLIL::SigBit> sig_a = sigmap(cell->getPort("\\A"));
std::vector<RTLIL::SigBit> sig_b = sigmap(cell->getPort("\\B"));
std::vector<RTLIL::SigBit> sig_s = sigmap(cell->getPort("\\S"));
std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort("\\Y"));
std::vector<RTLIL::SigBit> sig_a = sigmap(cell->getPort(ID::A));
std::vector<RTLIL::SigBit> sig_b = sigmap(cell->getPort(ID::B));
std::vector<RTLIL::SigBit> sig_s = sigmap(cell->getPort(ID::S));
std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort(ID::Y));
log_assert(sig_y.at(bit_idx) == sig);
for (int i = 0; i < int(sig_s.size()); i++)
if (state.count(sig_s[i]) && state.at(sig_s[i]) == true) {
if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), state, conditions)) {
RTLIL::SigSpec new_b = cell->getPort("\\B");
RTLIL::SigSpec new_b = cell->getPort(ID::B);
new_b.replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx);
cell->setPort("\\B", new_b);
cell->setPort(ID::B, new_b);
}
return false;
}
@ -90,9 +90,9 @@ struct MemoryShareWorker
new_state[sig_s[i]] = true;
if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), new_state, conditions)) {
RTLIL::SigSpec new_b = cell->getPort("\\B");
RTLIL::SigSpec new_b = cell->getPort(ID::B);
new_b.replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx);
cell->setPort("\\B", new_b);
cell->setPort(ID::B, new_b);
}
}
@ -101,9 +101,9 @@ struct MemoryShareWorker
new_state[sig_s[i]] = false;
if (find_data_feedback(async_rd_bits, sig_a.at(bit_idx), new_state, conditions)) {
RTLIL::SigSpec new_a = cell->getPort("\\A");
RTLIL::SigSpec new_a = cell->getPort(ID::A);
new_a.replace(bit_idx, RTLIL::State::Sx);
cell->setPort("\\A", new_a);
cell->setPort(ID::A, new_a);
}
return false;
@ -120,8 +120,8 @@ struct MemoryShareWorker
for (auto &cond : conditions) {
RTLIL::SigSpec sig1, sig2;
for (auto &it : cond) {
sig1.append_bit(it.first);
sig2.append_bit(it.second ? RTLIL::State::S1 : RTLIL::State::S0);
sig1.append(it.first);
sig2.append(it.second ? RTLIL::State::S1 : RTLIL::State::S0);
}
terms.append(module->Ne(NEW_ID, sig1, sig2));
created_conditions++;
@ -155,12 +155,12 @@ struct MemoryShareWorker
{
bool ignore_data_port = false;
if (cell->type.in("$mux", "$pmux"))
if (cell->type.in(ID($mux), ID($pmux)))
{
std::vector<RTLIL::SigBit> sig_a = sigmap(cell->getPort("\\A"));
std::vector<RTLIL::SigBit> sig_b = sigmap(cell->getPort("\\B"));
std::vector<RTLIL::SigBit> sig_s = sigmap(cell->getPort("\\S"));
std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort("\\Y"));
std::vector<RTLIL::SigBit> sig_a = sigmap(cell->getPort(ID::A));
std::vector<RTLIL::SigBit> sig_b = sigmap(cell->getPort(ID::B));
std::vector<RTLIL::SigBit> sig_s = sigmap(cell->getPort(ID::S));
std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort(ID::Y));
non_feedback_nets.insert(sig_s.begin(), sig_s.end());
@ -173,13 +173,13 @@ struct MemoryShareWorker
continue;
}
if (cell->type.in("$memwr", "$memrd") &&
cell->parameters.at("\\MEMID").decode_string() == memid)
if (cell->type.in(ID($memwr), ID($memrd)) &&
cell->parameters.at(ID::MEMID).decode_string() == memid)
ignore_data_port = true;
for (auto conn : cell->connections())
{
if (ignore_data_port && conn.first == "\\DATA")
if (ignore_data_port && conn.first == ID::DATA)
continue;
std::vector<RTLIL::SigBit> bits = sigmap(conn.second);
non_feedback_nets.insert(bits.begin(), bits.end());
@ -204,11 +204,11 @@ struct MemoryShareWorker
for (auto cell : rd_ports)
{
if (cell->parameters.at("\\CLK_ENABLE").as_bool())
if (cell->parameters.at(ID::CLK_ENABLE).as_bool())
continue;
RTLIL::SigSpec sig_addr = sigmap(cell->getPort("\\ADDR"));
std::vector<RTLIL::SigBit> sig_data = sigmap(cell->getPort("\\DATA"));
RTLIL::SigSpec sig_addr = sigmap(cell->getPort(ID::ADDR));
std::vector<RTLIL::SigBit> sig_data = sigmap(cell->getPort(ID::DATA));
for (int i = 0; i < int(sig_data.size()); i++)
if (non_feedback_nets.count(sig_data[i]))
@ -228,14 +228,14 @@ struct MemoryShareWorker
for (auto cell : wr_ports)
{
RTLIL::SigSpec sig_addr = sigmap_xmux(cell->getPort("\\ADDR"));
RTLIL::SigSpec sig_addr = sigmap_xmux(cell->getPort(ID::ADDR));
if (!async_rd_bits.count(sig_addr))
continue;
log(" Analyzing write port %s.\n", log_id(cell));
std::vector<RTLIL::SigBit> cell_data = cell->getPort("\\DATA");
std::vector<RTLIL::SigBit> cell_en = cell->getPort("\\EN");
std::vector<RTLIL::SigBit> cell_data = cell->getPort(ID::DATA);
std::vector<RTLIL::SigBit> cell_en = cell->getPort(ID::EN);
int created_conditions = 0;
for (int i = 0; i < int(cell_data.size()); i++)
@ -250,7 +250,7 @@ struct MemoryShareWorker
if (created_conditions) {
log(" Added enable logic for %d different cases.\n", created_conditions);
cell->setPort("\\EN", cell_en);
cell->setPort(ID::EN, cell_en);
}
}
}
@ -284,8 +284,8 @@ struct MemoryShareWorker
std::pair<RTLIL::SigBit, RTLIL::SigBit> key(v_bits[i], v_mask_bits[i]);
if (groups.count(key) == 0) {
groups[key].first = grouped_bits.size();
grouped_bits.append_bit(v_bits[i]);
grouped_mask_bits.append_bit(v_mask_bits[i]);
grouped_bits.append(v_bits[i]);
grouped_mask_bits.append(v_mask_bits[i]);
}
groups[key].second.push_back(i);
}
@ -295,7 +295,7 @@ struct MemoryShareWorker
for (int i = 0; i < bits.size(); i++) {
std::pair<RTLIL::SigBit, RTLIL::SigBit> key(v_bits[i], v_mask_bits[i]);
result.append_bit(grouped_result.at(groups.at(key).first));
result.append(grouped_result.at(groups.at(key).first));
}
return result;
@ -326,7 +326,7 @@ struct MemoryShareWorker
for (int i = 0; i < int(v_old_en.size()); i++) {
std::pair<RTLIL::SigBit, RTLIL::SigBit> key(v_old_en[i], v_next_en[i]);
new_merged_en.append_bit(grouped_new_en.at(groups.at(key)));
new_merged_en.append(grouped_new_en.at(groups.at(key)));
}
// Create the new merged_data signal.
@ -368,15 +368,15 @@ struct MemoryShareWorker
for (int i = 0; i < int(wr_ports.size()); i++)
{
RTLIL::Cell *cell = wr_ports.at(i);
RTLIL::SigSpec addr = sigmap_xmux(cell->getPort("\\ADDR"));
RTLIL::SigSpec addr = sigmap_xmux(cell->getPort(ID::ADDR));
if (cell->parameters.at("\\CLK_ENABLE").as_bool() != cache_clk_enable ||
(cache_clk_enable && (sigmap(cell->getPort("\\CLK")) != cache_clk ||
cell->parameters.at("\\CLK_POLARITY").as_bool() != cache_clk_polarity)))
if (cell->parameters.at(ID::CLK_ENABLE).as_bool() != cache_clk_enable ||
(cache_clk_enable && (sigmap(cell->getPort(ID::CLK)) != cache_clk ||
cell->parameters.at(ID::CLK_POLARITY).as_bool() != cache_clk_polarity)))
{
cache_clk_enable = cell->parameters.at("\\CLK_ENABLE").as_bool();
cache_clk_polarity = cell->parameters.at("\\CLK_POLARITY").as_bool();
cache_clk = sigmap(cell->getPort("\\CLK"));
cache_clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool();
cache_clk_polarity = cell->parameters.at(ID::CLK_POLARITY).as_bool();
cache_clk = sigmap(cell->getPort(ID::CLK));
last_port_by_addr.clear();
if (cache_clk_enable)
@ -388,7 +388,7 @@ struct MemoryShareWorker
log(" Port %d (%s) has addr %s.\n", i, log_id(cell), log_signal(addr));
log(" Active bits: ");
std::vector<RTLIL::SigBit> en_bits = sigmap(cell->getPort("\\EN"));
std::vector<RTLIL::SigBit> en_bits = sigmap(cell->getPort(ID::EN));
active_bits_on_port.push_back(std::vector<bool>(en_bits.size()));
for (int k = int(en_bits.size())-1; k >= 0; k--) {
active_bits_on_port[i][k] = en_bits[k].wire != NULL || en_bits[k].data != RTLIL::State::S0;
@ -410,13 +410,13 @@ struct MemoryShareWorker
// Force this ports addr input to addr directly (skip don't care muxes)
cell->setPort("\\ADDR", addr);
cell->setPort(ID::ADDR, addr);
// If any of the ports between `last_i' and `i' write to the same address, this
// will have priority over whatever `last_i` wrote. So we need to revisit those
// ports and mask the EN bits accordingly.
RTLIL::SigSpec merged_en = sigmap(wr_ports[last_i]->getPort("\\EN"));
RTLIL::SigSpec merged_en = sigmap(wr_ports[last_i]->getPort(ID::EN));
for (int j = last_i+1; j < i; j++)
{
@ -431,20 +431,20 @@ struct MemoryShareWorker
found_overlapping_bits_i_j:
log(" Creating collosion-detect logic for port %d.\n", j);
RTLIL::SigSpec is_same_addr = module->addWire(NEW_ID);
module->addEq(NEW_ID, addr, wr_ports[j]->getPort("\\ADDR"), is_same_addr);
merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(wr_ports[j]->getPort("\\EN")));
module->addEq(NEW_ID, addr, wr_ports[j]->getPort(ID::ADDR), is_same_addr);
merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(wr_ports[j]->getPort(ID::EN)));
}
}
// Then we need to merge the (masked) EN and the DATA signals.
RTLIL::SigSpec merged_data = wr_ports[last_i]->getPort("\\DATA");
RTLIL::SigSpec merged_data = wr_ports[last_i]->getPort(ID::DATA);
if (found_overlapping_bits) {
log(" Creating logic for merging DATA and EN ports.\n");
merge_en_data(merged_en, merged_data, sigmap(cell->getPort("\\EN")), sigmap(cell->getPort("\\DATA")));
merge_en_data(merged_en, merged_data, sigmap(cell->getPort(ID::EN)), sigmap(cell->getPort(ID::DATA)));
} else {
RTLIL::SigSpec cell_en = sigmap(cell->getPort("\\EN"));
RTLIL::SigSpec cell_data = sigmap(cell->getPort("\\DATA"));
RTLIL::SigSpec cell_en = sigmap(cell->getPort(ID::EN));
RTLIL::SigSpec cell_data = sigmap(cell->getPort(ID::DATA));
for (int k = 0; k < int(en_bits.size()); k++)
if (!active_bits_on_port[last_i][k]) {
merged_en.replace(k, cell_en.extract(k, 1));
@ -454,14 +454,14 @@ struct MemoryShareWorker
// Connect the new EN and DATA signals and remove the old write port.
cell->setPort("\\EN", merged_en);
cell->setPort("\\DATA", merged_data);
cell->setPort(ID::EN, merged_en);
cell->setPort(ID::DATA, merged_data);
module->remove(wr_ports[last_i]);
wr_ports[last_i] = NULL;
log(" Active bits: ");
std::vector<RTLIL::SigBit> en_bits = sigmap(cell->getPort("\\EN"));
std::vector<RTLIL::SigBit> en_bits = sigmap(cell->getPort(ID::EN));
active_bits_on_port.push_back(std::vector<bool>(en_bits.size()));
for (int k = int(en_bits.size())-1; k >= 0; k--)
log("%c", active_bits_on_port[i][k] ? '1' : '0');
@ -500,7 +500,7 @@ struct MemoryShareWorker
std::set<int> considered_port_pairs;
for (int i = 0; i < int(wr_ports.size()); i++) {
std::vector<RTLIL::SigBit> bits = modwalker.sigmap(wr_ports[i]->getPort("\\EN"));
std::vector<RTLIL::SigBit> bits = modwalker.sigmap(wr_ports[i]->getPort(ID::EN));
for (auto bit : bits)
if (bit == RTLIL::State::S1)
goto port_is_always_active;
@ -519,13 +519,13 @@ struct MemoryShareWorker
{
RTLIL::Cell *cell = wr_ports.at(i);
if (cell->parameters.at("\\CLK_ENABLE").as_bool() != cache_clk_enable ||
(cache_clk_enable && (sigmap(cell->getPort("\\CLK")) != cache_clk ||
cell->parameters.at("\\CLK_POLARITY").as_bool() != cache_clk_polarity)))
if (cell->parameters.at(ID::CLK_ENABLE).as_bool() != cache_clk_enable ||
(cache_clk_enable && (sigmap(cell->getPort(ID::CLK)) != cache_clk ||
cell->parameters.at(ID::CLK_POLARITY).as_bool() != cache_clk_polarity)))
{
cache_clk_enable = cell->parameters.at("\\CLK_ENABLE").as_bool();
cache_clk_polarity = cell->parameters.at("\\CLK_POLARITY").as_bool();
cache_clk = sigmap(cell->getPort("\\CLK"));
cache_clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool();
cache_clk_polarity = cell->parameters.at(ID::CLK_POLARITY).as_bool();
cache_clk = sigmap(cell->getPort(ID::CLK));
}
else if (i > 0 && considered_ports.count(i-1) && considered_ports.count(i))
considered_port_pairs.insert(i);
@ -554,7 +554,7 @@ struct MemoryShareWorker
for (int i = 0; i < int(wr_ports.size()); i++)
if (considered_port_pairs.count(i) || considered_port_pairs.count(i+1))
{
RTLIL::SigSpec sig = modwalker.sigmap(wr_ports[i]->getPort("\\EN"));
RTLIL::SigSpec sig = modwalker.sigmap(wr_ports[i]->getPort(ID::EN));
port_to_sat_variable[i] = ez->expression(ez->OpOr, satgen.importSigSpec(sig));
std::vector<RTLIL::SigBit> bits = sig;
@ -564,7 +564,7 @@ struct MemoryShareWorker
while (!bits_queue.empty())
{
for (auto bit : bits_queue)
if (bit.wire && bit.wire->get_bool_attribute("\\onehot"))
if (bit.wire && bit.wire->get_bool_attribute(ID::onehot))
one_hot_wires.insert(bit.wire);
pool<ModWalker::PortBit> portbits;
@ -609,13 +609,13 @@ struct MemoryShareWorker
log(" Merging port %d into port %d.\n", i-1, i);
port_to_sat_variable.at(i) = ez->OR(port_to_sat_variable.at(i-1), port_to_sat_variable.at(i));
RTLIL::SigSpec last_addr = wr_ports[i-1]->getPort("\\ADDR");
RTLIL::SigSpec last_data = wr_ports[i-1]->getPort("\\DATA");
std::vector<RTLIL::SigBit> last_en = modwalker.sigmap(wr_ports[i-1]->getPort("\\EN"));
RTLIL::SigSpec last_addr = wr_ports[i-1]->getPort(ID::ADDR);
RTLIL::SigSpec last_data = wr_ports[i-1]->getPort(ID::DATA);
std::vector<RTLIL::SigBit> last_en = modwalker.sigmap(wr_ports[i-1]->getPort(ID::EN));
RTLIL::SigSpec this_addr = wr_ports[i]->getPort("\\ADDR");
RTLIL::SigSpec this_data = wr_ports[i]->getPort("\\DATA");
std::vector<RTLIL::SigBit> this_en = modwalker.sigmap(wr_ports[i]->getPort("\\EN"));
RTLIL::SigSpec this_addr = wr_ports[i]->getPort(ID::ADDR);
RTLIL::SigSpec this_data = wr_ports[i]->getPort(ID::DATA);
std::vector<RTLIL::SigBit> this_en = modwalker.sigmap(wr_ports[i]->getPort(ID::EN));
RTLIL::SigBit this_en_active = module->ReduceOr(NEW_ID, this_en);
@ -624,9 +624,9 @@ struct MemoryShareWorker
else
this_addr.extend_u0(GetSize(last_addr));
wr_ports[i]->setParam("\\ABITS", GetSize(this_addr));
wr_ports[i]->setPort("\\ADDR", module->Mux(NEW_ID, last_addr, this_addr, this_en_active));
wr_ports[i]->setPort("\\DATA", module->Mux(NEW_ID, last_data, this_data, this_en_active));
wr_ports[i]->setParam(ID::ABITS, GetSize(this_addr));
wr_ports[i]->setPort(ID::ADDR, module->Mux(NEW_ID, last_addr, this_addr, this_en_active));
wr_ports[i]->setPort(ID::DATA, module->Mux(NEW_ID, last_data, this_data, this_en_active));
std::map<std::pair<RTLIL::SigBit, RTLIL::SigBit>, int> groups_en;
RTLIL::SigSpec grouped_last_en, grouped_this_en, en;
@ -635,8 +635,8 @@ struct MemoryShareWorker
for (int j = 0; j < int(this_en.size()); j++) {
std::pair<RTLIL::SigBit, RTLIL::SigBit> key(last_en[j], this_en[j]);
if (!groups_en.count(key)) {
grouped_last_en.append_bit(last_en[j]);
grouped_this_en.append_bit(this_en[j]);
grouped_last_en.append(last_en[j]);
grouped_this_en.append(this_en[j]);
groups_en[key] = grouped_en->width;
grouped_en->width++;
}
@ -644,7 +644,7 @@ struct MemoryShareWorker
}
module->addMux(NEW_ID, grouped_last_en, grouped_this_en, this_en_active, grouped_en);
wr_ports[i]->setPort("\\EN", en);
wr_ports[i]->setPort(ID::EN, en);
module->remove(wr_ports[i-1]);
wr_ports[i-1] = NULL;
@ -665,34 +665,40 @@ struct MemoryShareWorker
// Setup and run
// -------------
MemoryShareWorker(RTLIL::Design *design, RTLIL::Module *module) :
design(design), module(module), sigmap(module)
MemoryShareWorker(RTLIL::Design *design) : design(design), modwalker(design) {}
void operator()(RTLIL::Module* module)
{
std::map<std::string, std::pair<std::vector<RTLIL::Cell*>, std::vector<RTLIL::Cell*>>> memindex;
this->module = module;
sigmap.set(module);
sig_to_mux.clear();
conditions_logic_cache.clear();
sigmap_xmux = sigmap;
for (auto cell : module->cells())
{
if (cell->type == "$memrd")
memindex[cell->parameters.at("\\MEMID").decode_string()].first.push_back(cell);
if (cell->type == ID($memrd))
memindex[cell->parameters.at(ID::MEMID).decode_string()].first.push_back(cell);
if (cell->type == "$memwr")
memindex[cell->parameters.at("\\MEMID").decode_string()].second.push_back(cell);
if (cell->type == ID($memwr))
memindex[cell->parameters.at(ID::MEMID).decode_string()].second.push_back(cell);
if (cell->type == "$mux")
if (cell->type == ID($mux))
{
RTLIL::SigSpec sig_a = sigmap_xmux(cell->getPort("\\A"));
RTLIL::SigSpec sig_b = sigmap_xmux(cell->getPort("\\B"));
RTLIL::SigSpec sig_a = sigmap_xmux(cell->getPort(ID::A));
RTLIL::SigSpec sig_b = sigmap_xmux(cell->getPort(ID::B));
if (sig_a.is_fully_undef())
sigmap_xmux.add(cell->getPort("\\Y"), sig_b);
sigmap_xmux.add(cell->getPort(ID::Y), sig_b);
else if (sig_b.is_fully_undef())
sigmap_xmux.add(cell->getPort("\\Y"), sig_a);
sigmap_xmux.add(cell->getPort(ID::Y), sig_a);
}
if (cell->type.in("$mux", "$pmux"))
if (cell->type.in(ID($mux), ID($pmux)))
{
std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort("\\Y"));
std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort(ID::Y));
for (int i = 0; i < int(sig_y.size()); i++)
sig_to_mux[sig_y[i]] = std::pair<RTLIL::Cell*, int>(cell, i);
}
@ -706,18 +712,18 @@ struct MemoryShareWorker
}
cone_ct.setup_internals();
cone_ct.cell_types.erase("$mul");
cone_ct.cell_types.erase("$mod");
cone_ct.cell_types.erase("$div");
cone_ct.cell_types.erase("$pow");
cone_ct.cell_types.erase("$shl");
cone_ct.cell_types.erase("$shr");
cone_ct.cell_types.erase("$sshl");
cone_ct.cell_types.erase("$sshr");
cone_ct.cell_types.erase("$shift");
cone_ct.cell_types.erase("$shiftx");
cone_ct.cell_types.erase(ID($mul));
cone_ct.cell_types.erase(ID($mod));
cone_ct.cell_types.erase(ID($div));
cone_ct.cell_types.erase(ID($pow));
cone_ct.cell_types.erase(ID($shl));
cone_ct.cell_types.erase(ID($shr));
cone_ct.cell_types.erase(ID($sshl));
cone_ct.cell_types.erase(ID($sshr));
cone_ct.cell_types.erase(ID($shift));
cone_ct.cell_types.erase(ID($shiftx));
modwalker.setup(design, module, &cone_ct);
modwalker.setup(module, &cone_ct);
for (auto &it : memindex)
consolidate_wr_using_sat(it.first, it.second.second);
@ -755,8 +761,10 @@ struct MemorySharePass : public Pass {
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE {
log_header(design, "Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells).\n");
extra_args(args, 1, design);
MemoryShareWorker msw(design);
for (auto module : design->selected_modules())
MemoryShareWorker(design, module);
msw(module);
}
} MemorySharePass;

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