aboutsummaryrefslogtreecommitdiffstats
path: root/frontends/ast
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2019-05-06 20:57:15 +0200
committerGitHub <noreply@github.com>2019-05-06 20:57:15 +0200
commit752553d8e91643228714e04d9887d32f5d47870a (patch)
treee7e427b9e6558800b6131022c880af8ccc053845 /frontends/ast
parent1706798f4e595266a8758ae6d0ff9d978299de10 (diff)
parent8c6e94d57c430fc516dbcfbde312dbd7c860477b (diff)
downloadyosys-752553d8e91643228714e04d9887d32f5d47870a.tar.gz
yosys-752553d8e91643228714e04d9887d32f5d47870a.tar.bz2
yosys-752553d8e91643228714e04d9887d32f5d47870a.zip
Merge pull request #946 from YosysHQ/clifford/specify
Add specify parser
Diffstat (limited to 'frontends/ast')
-rw-r--r--frontends/ast/ast.cc6
-rw-r--r--frontends/ast/genrtlil.cc25
2 files changed, 30 insertions, 1 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index 9f88b08c1..5623541b2 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -951,6 +951,9 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
continue;
if (child->type == AST_PARAMETER || child->type == AST_LOCALPARAM)
continue;
+ if (child->type == AST_CELL && child->children.size() > 0 && child->children[0]->type == AST_CELLTYPE &&
+ (child->children[0]->str == "$specify2" || child->children[0]->str == "$specify3" || child->children[0]->str == "$specrule"))
+ continue;
blackbox_module = false;
break;
}
@@ -1035,6 +1038,9 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
child->delete_children();
child->children.push_back(AstNode::mkconst_int(0, false, 0));
new_children.push_back(child);
+ } else if (child->type == AST_CELL && child->children.size() > 0 && child->children[0]->type == AST_CELLTYPE &&
+ (child->children[0]->str == "$specify2" || child->children[0]->str == "$specify3" || child->children[0]->str == "$specrule")) {
+ new_children.push_back(child);
} else {
delete child;
}
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index d4515babf..379fed641 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -1492,10 +1492,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
continue;
}
if (child->type == AST_PARASET) {
+ int extra_const_flags = 0;
IdString paraname = child->str.empty() ? stringf("$%d", ++para_counter) : child->str;
if (child->children[0]->type == AST_REALVALUE) {
log_file_warning(filename, linenum, "Replacing floating point parameter %s.%s = %f with string.\n",
log_id(cell), log_id(paraname), child->children[0]->realvalue);
+ extra_const_flags = RTLIL::CONST_FLAG_REAL;
auto strnode = AstNode::mkconst_str(stringf("%f", child->children[0]->realvalue));
strnode->cloneInto(child->children[0]);
delete strnode;
@@ -1504,6 +1506,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
log_file_error(filename, linenum, "Parameter %s.%s with non-constant value!\n",
log_id(cell), log_id(paraname));
cell->parameters[paraname] = child->children[0]->asParaConst();
+ cell->parameters[paraname].flags |= extra_const_flags;
continue;
}
if (child->type == AST_ARGUMENT) {
@@ -1523,9 +1526,29 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
for (auto &attr : attributes) {
if (attr.second->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
+ log_file_error(filename, linenum, "Attribute `%s' with non-constant value.\n", attr.first.c_str());
cell->attributes[attr.first] = attr.second->asAttrConst();
}
+ if (cell->type.in("$specify2", "$specify3")) {
+ int src_width = GetSize(cell->getPort("\\SRC"));
+ int dst_width = GetSize(cell->getPort("\\DST"));
+ bool full = cell->getParam("\\FULL").as_bool();
+ if (!full && src_width != dst_width)
+ log_file_error(filename, linenum, "Parallel specify SRC width does not match DST width.\n");
+ if (cell->type == "$specify3") {
+ int dat_width = GetSize(cell->getPort("\\DAT"));
+ if (dat_width != dst_width)
+ log_file_error(filename, linenum, "Specify DAT width does not match DST width.\n");
+ }
+ cell->setParam("\\SRC_WIDTH", Const(src_width));
+ cell->setParam("\\DST_WIDTH", Const(dst_width));
+ }
+ 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));
+ }
}
break;