mirror of https://github.com/YosysHQ/yosys.git
Added defparam support to Verilog/AST frontend
This commit is contained in:
parent
3b294b3912
commit
56432a920f
|
@ -72,6 +72,7 @@ std::string AST::type2str(AstNodeType type)
|
|||
X(AST_AUTOWIRE)
|
||||
X(AST_PARAMETER)
|
||||
X(AST_LOCALPARAM)
|
||||
X(AST_DEFPARAM)
|
||||
X(AST_PARASET)
|
||||
X(AST_ARGUMENT)
|
||||
X(AST_RANGE)
|
||||
|
@ -327,7 +328,7 @@ void AstNode::dumpVlog(FILE *f, std::string indent)
|
|||
fprintf(f, ");\n");
|
||||
|
||||
for (auto child : children)
|
||||
if (child->type == AST_PARAMETER || child->type == AST_LOCALPARAM)
|
||||
if (child->type == AST_PARAMETER || child->type == AST_LOCALPARAM || child->type == AST_DEFPARAM)
|
||||
child->dumpVlog(f, indent + " ");
|
||||
else
|
||||
rem_children1.push_back(child);
|
||||
|
|
|
@ -50,6 +50,7 @@ namespace AST
|
|||
AST_AUTOWIRE,
|
||||
AST_PARAMETER,
|
||||
AST_LOCALPARAM,
|
||||
AST_DEFPARAM,
|
||||
AST_PARASET,
|
||||
AST_ARGUMENT,
|
||||
AST_RANGE,
|
||||
|
|
|
@ -531,6 +531,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint)
|
|||
case AST_AUTOWIRE:
|
||||
case AST_PARAMETER:
|
||||
case AST_LOCALPARAM:
|
||||
case AST_DEFPARAM:
|
||||
case AST_GENVAR:
|
||||
case AST_GENFOR:
|
||||
case AST_GENBLOCK:
|
||||
|
|
|
@ -103,7 +103,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage)
|
|||
}
|
||||
|
||||
// activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.)
|
||||
if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX)
|
||||
if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX)
|
||||
const_fold = true;
|
||||
if (type == AST_IDENTIFIER && current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM))
|
||||
const_fold = true;
|
||||
|
@ -163,7 +163,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage)
|
|||
}
|
||||
wires_are_incompatible:
|
||||
if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR ||
|
||||
node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK) {
|
||||
node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_CELL) {
|
||||
backup_scope[node->str] = current_scope[node->str];
|
||||
current_scope[node->str] = node;
|
||||
}
|
||||
|
@ -224,6 +224,22 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage)
|
|||
if (type == AST_MODULE)
|
||||
current_scope.clear();
|
||||
|
||||
// convert defparam nodes to cell parameters
|
||||
if (type == AST_DEFPARAM && !str.empty()) {
|
||||
size_t pos = str.rfind('.');
|
||||
if (pos == std::string::npos)
|
||||
log_error("Defparam `%s' does not contain a dot (module/parameter seperator) at %s:%d!\n",
|
||||
RTLIL::id2cstr(str.c_str()), filename.c_str(), linenum);
|
||||
std::string modname = str.substr(0, pos), paraname = "\\" + str.substr(pos+1);
|
||||
if (current_scope.count(modname) == 0 || current_scope.at(modname)->type != AST_CELL)
|
||||
log_error("Can't find cell for defparam `%s . %s` at %s:%d!\n", RTLIL::id2cstr(modname), RTLIL::id2cstr(paraname), filename.c_str(), linenum);
|
||||
AstNode *cell = current_scope.at(modname), *paraset = clone();
|
||||
cell->children.insert(cell->children.begin() + 1, paraset);
|
||||
paraset->type = AST_PARASET;
|
||||
paraset->str = paraname;
|
||||
str.clear();
|
||||
}
|
||||
|
||||
// resolve constant prefixes
|
||||
if (type == AST_PREFIX) {
|
||||
if (children[0]->type != AST_CONSTANT) {
|
||||
|
|
|
@ -95,6 +95,7 @@ namespace VERILOG_FRONTEND {
|
|||
"endtask" { return TOK_ENDTASK; }
|
||||
"parameter" { return TOK_PARAMETER; }
|
||||
"localparam" { return TOK_LOCALPARAM; }
|
||||
"defparam" { return TOK_DEFPARAM; }
|
||||
"assign" { return TOK_ASSIGN; }
|
||||
"always" { return TOK_ALWAYS; }
|
||||
"initial" { return TOK_INITIAL; }
|
||||
|
@ -184,7 +185,7 @@ supply1 { return TOK_SUPPLY1; }
|
|||
"$signed" { return TOK_TO_SIGNED; }
|
||||
"$unsigned" { return TOK_TO_UNSIGNED; }
|
||||
|
||||
[a-zA-Z_$][a-zA-Z0-9_\.$]* {
|
||||
[a-zA-Z_$][a-zA-Z0-9_$]* {
|
||||
frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext);
|
||||
return TOK_ID;
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ static void free_attr(std::map<std::string, AstNode*> *al)
|
|||
|
||||
%token <string> TOK_STRING TOK_ID TOK_CONST TOK_PRIMITIVE
|
||||
%token ATTR_BEGIN ATTR_END DEFATTR_BEGIN DEFATTR_END
|
||||
%token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM
|
||||
%token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM
|
||||
%token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG
|
||||
%token TOK_INTEGER TOK_SIGNED TOK_ASSIGN TOK_ALWAYS TOK_INITIAL
|
||||
%token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR
|
||||
|
@ -106,7 +106,7 @@ static void free_attr(std::map<std::string, AstNode*> *al)
|
|||
%token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED
|
||||
|
||||
%type <ast> wire_type range expr basic_expr concat_list rvalue lvalue lvalue_concat_list
|
||||
%type <string> opt_label tok_prim_wrapper
|
||||
%type <string> opt_label tok_prim_wrapper hierarchical_id
|
||||
%type <boolean> opt_signed
|
||||
%type <al> attr
|
||||
|
||||
|
@ -176,19 +176,32 @@ attr_list:
|
|||
attr_list ',' attr_assign;
|
||||
|
||||
attr_assign:
|
||||
TOK_ID {
|
||||
hierarchical_id {
|
||||
if (attr_list.count(*$1) != 0)
|
||||
delete attr_list[*$1];
|
||||
attr_list[*$1] = AstNode::mkconst_int(0, false, 0);
|
||||
delete $1;
|
||||
} |
|
||||
TOK_ID '=' expr {
|
||||
hierarchical_id '=' expr {
|
||||
if (attr_list.count(*$1) != 0)
|
||||
delete attr_list[*$1];
|
||||
attr_list[*$1] = $3;
|
||||
delete $1;
|
||||
};
|
||||
|
||||
hierarchical_id:
|
||||
TOK_ID {
|
||||
$$ = $1;
|
||||
} |
|
||||
hierarchical_id '.' TOK_ID {
|
||||
if ($3->substr(0, 1) == "\\")
|
||||
*$1 += "." + $3->substr(1);
|
||||
else
|
||||
*$1 += "." + *$3;
|
||||
delete $3;
|
||||
$$ = $1;
|
||||
};
|
||||
|
||||
module:
|
||||
attr TOK_MODULE TOK_ID {
|
||||
AstNode *mod = new AstNode(AST_MODULE);
|
||||
|
@ -309,7 +322,7 @@ module_body:
|
|||
/* empty */;
|
||||
|
||||
module_body_stmt:
|
||||
task_func_decl | param_decl | localparam_decl | wire_decl | assign_stmt | cell_stmt |
|
||||
task_func_decl | param_decl | localparam_decl | defparam_decl | wire_decl | assign_stmt | cell_stmt |
|
||||
always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr;
|
||||
|
||||
task_func_decl:
|
||||
|
@ -389,6 +402,23 @@ single_localparam_decl:
|
|||
delete $2;
|
||||
};
|
||||
|
||||
defparam_decl:
|
||||
TOK_DEFPARAM defparam_decl_list ';';
|
||||
|
||||
defparam_decl_list:
|
||||
single_defparam_decl | defparam_decl_list ',' single_defparam_decl;
|
||||
|
||||
single_defparam_decl:
|
||||
range hierarchical_id '=' expr {
|
||||
AstNode *node = new AstNode(AST_DEFPARAM);
|
||||
node->str = *$2;
|
||||
node->children.push_back($4);
|
||||
if ($1 != NULL)
|
||||
node->children.push_back($1);
|
||||
ast_stack.back()->children.push_back(node);
|
||||
delete $2;
|
||||
};
|
||||
|
||||
wire_decl:
|
||||
attr wire_type range {
|
||||
albuf = $1;
|
||||
|
@ -671,7 +701,7 @@ simple_behavioral_stmt:
|
|||
behavioral_stmt:
|
||||
defattr |
|
||||
simple_behavioral_stmt ';' |
|
||||
TOK_ID attr {
|
||||
hierarchical_id attr {
|
||||
AstNode *node = new AstNode(AST_TCALL);
|
||||
node->str = *$1;
|
||||
delete $1;
|
||||
|
@ -808,12 +838,12 @@ case_expr_list:
|
|||
};
|
||||
|
||||
rvalue:
|
||||
TOK_ID '[' expr ']' '.' rvalue {
|
||||
hierarchical_id '[' expr ']' '.' rvalue {
|
||||
$$ = new AstNode(AST_PREFIX, $3, $6);
|
||||
$$->str = *$1;
|
||||
delete $1;
|
||||
} |
|
||||
TOK_ID range {
|
||||
hierarchical_id range {
|
||||
$$ = new AstNode(AST_IDENTIFIER, $2);
|
||||
$$->str = *$1;
|
||||
delete $1;
|
||||
|
@ -931,7 +961,7 @@ basic_expr:
|
|||
$$->str = str;
|
||||
delete $1;
|
||||
} |
|
||||
TOK_ID attr {
|
||||
hierarchical_id attr {
|
||||
AstNode *node = new AstNode(AST_FCALL);
|
||||
node->str = *$1;
|
||||
delete $1;
|
||||
|
|
|
@ -23,6 +23,22 @@ endmodule
|
|||
|
||||
// -----------------------------------
|
||||
|
||||
module test3(a, b, x, y);
|
||||
|
||||
input [7:0] a, b;
|
||||
output [7:0] x, y;
|
||||
|
||||
inc inc_a (.in(a), .out(x));
|
||||
inc inc_b (b, y);
|
||||
|
||||
defparam inc_a.step = 3;
|
||||
defparam inc_b.step = 7;
|
||||
defparam inc_b.width = 4;
|
||||
|
||||
endmodule
|
||||
|
||||
// -----------------------------------
|
||||
|
||||
module inc(in, out);
|
||||
|
||||
parameter width = 8;
|
||||
|
|
Loading…
Reference in New Issue