summaryrefslogtreecommitdiff
path: root/frontends
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2014-03-16 17:05:05 +0100
committerClifford Wolf <clifford@clifford.at>2014-03-16 17:05:05 +0100
commitacda74c12cd39ae1a17d15f472728b49ad584e91 (patch)
treedd1efddfb05a4cb6a9612af53fa4e7472b0e7ba1 /frontends
parent7545510edcc1d9ab14e53cae285f1ef0dfb3d7d4 (diff)
Added support for memories to verific bindings
Diffstat (limited to 'frontends')
-rw-r--r--frontends/verific/test_navre.ys1
-rw-r--r--frontends/verific/verific.cc86
2 files changed, 86 insertions, 1 deletions
diff --git a/frontends/verific/test_navre.ys b/frontends/verific/test_navre.ys
index 9e11cde0..6f63761a 100644
--- a/frontends/verific/test_navre.ys
+++ b/frontends/verific/test_navre.ys
@@ -1,6 +1,7 @@
verific -vlog2k ../../../yosys-bigsim/softusb_navre/rtl/softusb_navre.v
verific -import softusb_navre
+memory softusb_navre
flatten softusb_navre
rename softusb_navre gate
diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc
index bf24c823..8b42ca8c 100644
--- a/frontends/verific/verific.cc
+++ b/frontends/verific/verific.cc
@@ -408,12 +408,14 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::set<Netlist*
std::map<Net*, RTLIL::SigBit> net_map;
+ SetIter si;
MapIter mi, mi2;
Port *port;
PortBus *portbus;
Net *net;
NetBus *netbus;
Instance *inst;
+ PortRef *pr;
FOREACH_PORT_OF_NETLIST(nl, mi, port)
{
@@ -479,6 +481,33 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::set<Netlist*
FOREACH_NET_OF_NETLIST(nl, mi, net)
{
+ if (net->IsRamNet())
+ {
+ RTLIL::Memory *memory = new RTLIL::Memory;
+ memory->name = RTLIL::escape_id(net->Name());
+ log_assert(module->count_id(memory->name) == 0);
+ module->memories[memory->name] = memory;
+
+ int number_of_bits = net->Size();
+ int bits_in_word = number_of_bits;
+ FOREACH_PORTREF_OF_NET(net, si, pr) {
+ if (pr->GetInst()->Type() == OPER_READ_PORT) {
+ bits_in_word = std::min<int>(bits_in_word, pr->GetInst()->OutputSize());
+ continue;
+ }
+ if (pr->GetInst()->Type() == OPER_WRITE_PORT || pr->GetInst()->Type() == OPER_CLOCKED_WRITE_PORT) {
+ bits_in_word = std::min<int>(bits_in_word, pr->GetInst()->Input2Size());
+ continue;
+ }
+ log_error("Verific RamNet %s is connected to unsupported instance type %s (%s).\n",
+ net->Name(), pr->GetInst()->View()->Owner()->Name(), pr->GetInst()->Name());
+ }
+
+ memory->width = bits_in_word;
+ memory->size = number_of_bits / bits_in_word;
+ continue;
+ }
+
if (net_map.count(net)) {
// log(" skipping net %s.\n", net->Name());
continue;
@@ -569,6 +598,62 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::set<Netlist*
continue;
}
+ if (inst->Type() == OPER_READ_PORT)
+ {
+ RTLIL::Memory *memory = module->memories.at(RTLIL::escape_id(inst->GetInput()->Name()));
+ if (memory->width != int(inst->OutputSize()))
+ log_error("Import of asymetric memories from Verific is not supported yet: %s %s\n", inst->Name(), inst->GetInput()->Name());
+
+ RTLIL::SigSpec addr = operatorInput1(inst, net_map);
+ RTLIL::SigSpec data = operatorOutput(inst, net_map, module);
+
+ RTLIL::Cell *cell = new RTLIL::Cell;
+ cell->name = RTLIL::escape_id(inst->Name());
+ cell->type = "$memrd";
+ cell->parameters["\\MEMID"] = memory->name;
+ cell->parameters["\\CLK_ENABLE"] = false;
+ cell->parameters["\\CLK_POLARITY"] = true;
+ cell->parameters["\\TRANSPARENT"] = false;
+ cell->parameters["\\ABITS"] = addr.width;
+ cell->parameters["\\WIDTH"] = data.width;
+ cell->connections["\\CLK"] = RTLIL::State::S0;
+ cell->connections["\\ADDR"] = addr;
+ cell->connections["\\DATA"] = data;
+ module->add(cell);
+ 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()));
+ if (memory->width != int(inst->Input2Size()))
+ log_error("Import of asymetric memories from Verific is not supported yet: %s %s\n", inst->Name(), inst->GetInput()->Name());
+
+ RTLIL::SigSpec addr = operatorInput1(inst, net_map);
+ RTLIL::SigSpec data = operatorInput2(inst, net_map);
+
+ RTLIL::Cell *cell = new RTLIL::Cell;
+ cell->name = RTLIL::escape_id(inst->Name());
+ cell->type = "$memwr";
+ cell->parameters["\\MEMID"] = memory->name;
+ cell->parameters["\\CLK_ENABLE"] = false;
+ cell->parameters["\\CLK_POLARITY"] = true;
+ cell->parameters["\\PRIORITY"] = 0;
+ cell->parameters["\\ABITS"] = addr.width;
+ cell->parameters["\\WIDTH"] = data.width;
+ cell->connections["\\EN"] = net_map.at(inst->GetControl());
+ cell->connections["\\CLK"] = RTLIL::State::S0;
+ cell->connections["\\ADDR"] = addr;
+ cell->connections["\\DATA"] = data;
+ module->add(cell);
+
+ if (inst->Type() == OPER_CLOCKED_WRITE_PORT) {
+ cell->parameters["\\CLK_ENABLE"] = true;
+ cell->connections["\\CLK"] = net_map.at(inst->GetClock());
+ }
+ continue;
+ }
+
if (!mode_gates) {
if (import_netlist_instance_cells(module, net_map, inst))
continue;
@@ -589,7 +674,6 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::set<Netlist*
cell->type = inst->IsOperator() ? std::string("$verific$") + inst->View()->Owner()->Name() : RTLIL::escape_id(inst->View()->Owner()->Name());
module->add(cell);
- PortRef *pr ;
FOREACH_PORTREF_OF_INST(inst, mi2, pr) {
// log(" .%s(%s)\n", pr->GetPort()->Name(), pr->GetNet()->Name());
const char *port_name = pr->GetPort()->Name();