mirror of
https://github.com/YosysHQ/yosys
synced 2026-01-05 18:42:46 +00:00
Merge branch 'master' of github.com:YosysHQ/yosys into firrtl_backend_fileinfo
This commit is contained in:
commit
9edf8869c1
228 changed files with 8971 additions and 6952 deletions
8
Makefile
8
Makefile
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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> ¶ms)
|
||||
{
|
||||
for (auto ¶m : 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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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++) {
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ¶m : 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");
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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> ¶meters, 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> ¶meters, 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> ¶meters, 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 ¶m : 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;
|
||||
|
|
|
|||
|
|
@ -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> ¶meters, bool mayfail) YS_OVERRIDE;
|
||||
RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, 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> ¶meters, 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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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'));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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> ¶meters, 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 $<
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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 ¯o_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 ¯o_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);
|
||||
|
|
|
|||
77
frontends/verilog/preproc.h
Normal file
77
frontends/verilog/preproc.h
Normal 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
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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_$\.]* {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
213
kernel/constids.inc
Normal 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)
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
1226
kernel/rtlil.cc
1226
kernel/rtlil.cc
File diff suppressed because it is too large
Load diff
363
kernel/rtlil.h
363
kernel/rtlil.h
|
|
@ -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> ¶meters, bool mayfail = false);
|
||||
virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, 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)
|
||||
|
|
|
|||
112
kernel/satgen.h
112
kernel/satgen.h
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
OBJS += passes/cmds/exec.o
|
||||
OBJS += passes/cmds/add.o
|
||||
OBJS += passes/cmds/delete.o
|
||||
OBJS += passes/cmds/design.o
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ struct BlackboxPass : public Pass {
|
|||
|
||||
module->remove(remove_wires);
|
||||
|
||||
module->set_bool_attribute("\\blackbox");
|
||||
module->set_bool_attribute(ID::blackbox);
|
||||
}
|
||||
}
|
||||
} BlackboxPass;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
205
passes/cmds/exec.cc
Normal 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
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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]));
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ¶ : i2.second->parameters)
|
||||
for (auto ¶ : 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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue