aboutsummaryrefslogtreecommitdiffstats
path: root/frontends/ast/genrtlil.cc
diff options
context:
space:
mode:
authorRuben Undheim <ruben.undheim@gmail.com>2018-10-11 23:33:31 +0200
committerRuben Undheim <ruben.undheim@gmail.com>2018-10-12 21:11:36 +0200
commit75009ada3c2a4bcd38c52c8fb871c9e8c1f2e6b1 (patch)
treee8d3be5d6134dbf4fc26b47f9481f80a4bdfc4c7 /frontends/ast/genrtlil.cc
parent9850de405a11fe93e4562c86be0a0830b83c2785 (diff)
downloadyosys-75009ada3c2a4bcd38c52c8fb871c9e8c1f2e6b1.tar.gz
yosys-75009ada3c2a4bcd38c52c8fb871c9e8c1f2e6b1.tar.bz2
yosys-75009ada3c2a4bcd38c52c8fb871c9e8c1f2e6b1.zip
Synthesis support for SystemVerilog interfaces
This time doing the changes mostly in AST before RTLIL generation
Diffstat (limited to 'frontends/ast/genrtlil.cc')
-rw-r--r--frontends/ast/genrtlil.cc48
1 files changed, 46 insertions, 2 deletions
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index c9345ff08..1dd1a9130 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -854,6 +854,22 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
case AST_GENCASE:
case AST_PACKAGE:
break;
+ case AST_INTERFACEPORT: {
+ // If a port in a module with unknown type is found, mark it as "is_interface=true"
+ // 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", filename.c_str(), linenum);
+ wire->start_offset = 0;
+ wire->port_id = port_id;
+ wire->port_input = true;
+ wire->port_output = true;
+ wire->set_bool_attribute("\\is_interface");
+ wire->upto = 0;
+ }
+ break;
+ case AST_INTERFACEPORTTYPE:
+ break;
// remember the parameter, needed for example in techmap
case AST_PARAMETER:
@@ -949,6 +965,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
{
RTLIL::Wire *wire = NULL;
RTLIL::SigChunk chunk;
+ bool is_interface = false;
int add_undef_bits_msb = 0;
int add_undef_bits_lsb = 0;
@@ -969,15 +986,41 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
chunk = RTLIL::Const(id2ast->children[0]->bits);
goto use_const_chunk;
}
- else if (!id2ast || (id2ast->type != AST_WIRE && id2ast->type != AST_AUTOWIRE &&
- id2ast->type != AST_MEMORY) || current_module->wires_.count(str) == 0)
+ 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"))
+ is_interface = true;
+ // Ignore
+ }
+ // If an identifier is found that is not already known, assume that it is an interface:
+ else if (1) { // FIXME: Check if sv_mode first?
+ is_interface = true;
+ }
+ else {
log_file_error(filename, linenum, "Identifier `%s' doesn't map to any signal!\n",
str.c_str());
+ }
if (id2ast->type == AST_MEMORY)
log_file_error(filename, linenum, "Identifier `%s' does map to an unexpanded memory!\n",
str.c_str());
+ // If identifier is an interface, create a RTLIL::SigSpec object and set is_interface to true.
+ // 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 {
+ dummy_wire = current_module->addWire(dummy_wire_name);
+ dummy_wire->set_bool_attribute("\\is_interface");
+ }
+ RTLIL::SigSpec tmp = RTLIL::SigSpec(dummy_wire);
+ return tmp;
+ }
+
wire = current_module->wires_[str];
chunk.wire = wire;
chunk.width = wire->width;
@@ -1423,6 +1466,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
RTLIL::Cell *cell = current_module->addCell(str, "");
cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
+ cell->set_bool_attribute("\\module_not_derived");
for (auto it = children.begin(); it != children.end(); it++) {
AstNode *child = *it;