X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=frontends%2Fverific%2Fverific.cc;h=a22a8a93d7d80de1f9aa9d9abbaf38ec9e7b59da;hb=8f1a32064639fa17d67bda508df941c8846a0664;hp=ae5815f8e496f3efb78487423c05b01a52753f5e;hpb=cd044a2bb6adf7a5e00d4a6c075e9489d852d733;p=yosys.git diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index ae5815f8e..a22a8a93d 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -149,13 +149,13 @@ RTLIL::IdString VerificImporter::new_verific_id(Verific::DesignObj *obj) return s; } -void VerificImporter::import_attributes(dict &attributes, DesignObj *obj) +void VerificImporter::import_attributes(dict &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) { @@ -163,6 +163,68 @@ void VerificImporter::import_attributes(dict &att 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 'b + 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 'b.\n", v); + attributes.emplace(stringf("\\enum_value_%s", p+2), RTLIL::escape_id(k)); + } + else if (nl->IsFromVhdl()) { + // Expect "" + 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 \"\".\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) @@ -738,7 +800,7 @@ void VerificImporter::merge_past_ffs_clock(pool &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 +826,7 @@ void VerificImporter::merge_past_ffs_clock(pool &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 +845,8 @@ void VerificImporter::merge_past_ffs(pool &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 +884,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)); } @@ -845,7 +907,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se 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; @@ -872,7 +934,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se 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; @@ -912,6 +974,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se 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) { @@ -952,17 +1015,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); } } } @@ -1021,7 +1084,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se 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; } @@ -1046,7 +1109,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se 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; @@ -1079,7 +1142,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 +1196,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 +1207,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) @@ -1199,64 +1262,63 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se 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; @@ -1431,7 +1493,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> cell_port_conns; @@ -1514,10 +1576,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 +1590,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 +1714,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; } @@ -2118,6 +2180,9 @@ struct VerificPass : public Pass { 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);