return s;
}
-void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &attributes, DesignObj *obj)
+void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &attributes, DesignObj *obj, Netlist *nl)
{
MapIter mi;
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) {
continue;
attributes[RTLIL::escape_id(attr->Key())] = RTLIL::Const(std::string(attr->Value()));
}
+
+ if (nl) {
+ auto type_range = nl->GetTypeRange(obj->Name());
+ if (!type_range)
+ return;
+ if (!type_range->IsTypeEnum())
+ return;
+ if (nl->IsFromVhdl() && strcmp(type_range->GetTypeName(), "STD_LOGIC") == 0)
+ return;
+ auto type_name = type_range->GetTypeName();
+ if (!type_name)
+ return;
+ attributes.emplace(ID::wiretype, RTLIL::escape_id(type_name));
+
+ MapIter mi;
+ const char *k, *v;
+ FOREACH_MAP_ITEM(type_range->GetEnumIdMap(), mi, &k, &v) {
+ if (nl->IsFromVerilog()) {
+ // Expect <decimal>'b<binary>
+ auto p = strchr(v, '\'');
+ if (p) {
+ if (*(p+1) != 'b')
+ p = nullptr;
+ else
+ for (auto q = p+2; *q != '\0'; q++)
+ if (*q != '0' && *q != '1') {
+ p = nullptr;
+ break;
+ }
+ }
+ if (p == nullptr)
+ log_error("Expected TypeRange value '%s' to be of form <decimal>'b<binary>.\n", v);
+ attributes.emplace(stringf("\\enum_value_%s", p+2), RTLIL::escape_id(k));
+ }
+ else if (nl->IsFromVhdl()) {
+ // Expect "<binary>"
+ auto p = v;
+ if (p) {
+ if (*p != '"')
+ p = nullptr;
+ else {
+ auto *q = p+1;
+ for (; *q != '"'; q++)
+ if (*q != '0' && *q != '1') {
+ p = nullptr;
+ break;
+ }
+ if (p && *(q+1) != '\0')
+ p = nullptr;
+ }
+ }
+ if (p == nullptr)
+ log_error("Expected TypeRange value '%s' to be of form \"<binary>\".\n", v);
+ auto l = strlen(p);
+ auto q = (char*)malloc(l+1-2);
+ strncpy(q, p+1, l-2);
+ q[l-2] = '\0';
+ attributes.emplace(stringf("\\enum_value_%s", q), RTLIL::escape_id(k));
+ free(q);
+ }
+ }
+ }
}
RTLIL::SigSpec VerificImporter::operatorInput(Instance *inst)
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);
}
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);
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);
}
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));
}
log(" importing port %s.\n", port->Name());
RTLIL::Wire *wire = module->addWire(RTLIL::escape_id(port->Name()));
- import_attributes(wire->attributes, port);
+ import_attributes(wire->attributes, port, nl);
wire->port_id = nl->IndexOf(port) + 1;
RTLIL::Wire *wire = module->addWire(RTLIL::escape_id(portbus->Name()), portbus->Size());
wire->start_offset = min(portbus->LeftIndex(), portbus->RightIndex());
- import_attributes(wire->attributes, portbus);
+ import_attributes(wire->attributes, portbus, nl);
if (portbus->GetDir() == DIR_INOUT || portbus->GetDir() == DIR_IN)
wire->port_input = true;
module->memories[memory->name] = memory;
int number_of_bits = net->Size();
+ number_of_bits = 1 << ceil_log2(number_of_bits);
int bits_in_word = number_of_bits;
FOREACH_PORTREF_OF_NET(net, si, pr) {
if (pr->GetInst()->Type() == OPER_READ_PORT) {
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);
}
}
}
log(" importing net %s as %s.\n", net->Name(), log_id(wire_name));
RTLIL::Wire *wire = module->addWire(wire_name);
- import_attributes(wire->attributes, net);
+ import_attributes(wire->attributes, net, nl);
net_map[net] = wire;
}
RTLIL::Wire *wire = module->addWire(wire_name, netbus->Size());
wire->start_offset = min(netbus->LeftIndex(), netbus->RightIndex());
- import_attributes(wire->attributes, netbus);
+ import_attributes(wire->attributes, netbus, nl);
RTLIL::Const initval = Const(State::Sx, GetSize(wire));
bool initval_valid = false;
}
if (initval_valid)
- wire->attributes["\\init"] = initval;
+ wire->attributes[ID::init] = initval;
}
else
{
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);
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)
if (inst->Type() == OPER_READ_PORT)
{
- RTLIL::Memory *memory = module->memories.at(RTLIL::escape_id(inst->GetInput()->Name()));
+ RTLIL::Memory *memory = module->memories.at(RTLIL::escape_id(inst->GetInput()->Name()), nullptr);
+ if (!memory)
+ log_error("Memory net '%s' missing, possibly no driver, use verific -flatten.\n", inst->GetInput()->Name());
+
int numchunks = int(inst->OutputSize()) / memory->width;
int chunksbits = ceil_log2(numchunks);
- if ((numchunks * memory->width) != int(inst->OutputSize()) || (numchunks & (numchunks - 1)) != 0)
- log_error("Import of asymmetric memories of this type is not supported yet: %s %s\n", inst->Name(), inst->GetInput()->Name());
-
for (int i = 0; i < numchunks; i++)
{
RTLIL::SigSpec addr = {operatorInput1(inst), RTLIL::Const(i, chunksbits)};
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;
}
if (inst->Type() == OPER_WRITE_PORT || inst->Type() == OPER_CLOCKED_WRITE_PORT)
{
- RTLIL::Memory *memory = module->memories.at(RTLIL::escape_id(inst->GetOutput()->Name()));
+ RTLIL::Memory *memory = module->memories.at(RTLIL::escape_id(inst->GetOutput()->Name()), nullptr);
+ if (!memory)
+ log_error("Memory net '%s' missing, possibly no driver, use verific -flatten.\n", inst->GetInput()->Name());
int numchunks = int(inst->Input2Size()) / memory->width;
int chunksbits = ceil_log2(numchunks);
- if ((numchunks * memory->width) != int(inst->Input2Size()) || (numchunks & (numchunks - 1)) != 0)
- log_error("Import of asymmetric memories of this type is not supported yet: %s %s\n", inst->Name(), inst->GetOutput()->Name());
-
for (int i = 0; i < numchunks; i++)
{
RTLIL::SigSpec addr = {operatorInput1(inst), RTLIL::Const(i, chunksbits)};
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;
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;
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)
}
if (initval.is_fully_undef())
- wire->attributes.erase("\\init");
+ wire->attributes.erase(ID::init);
}
}
}
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;
}
RuntimeFlags::SetVar("vhdl_support_variable_slice", 1);
RuntimeFlags::SetVar("vhdl_ignore_assertion_statements", 0);
+ RuntimeFlags::SetVar("veri_preserve_assignments", 1);
+ RuntimeFlags::SetVar("vhdl_preserve_assignments", 1);
+
// Workaround for VIPER #13851
RuntimeFlags::SetVar("veri_create_name_for_unnamed_gen_block", 1);