Parse parameter value ranges into pform.
Handle parameter value ranges as far as the pform. The +-inf expressions are not handled yet, nor is the single value exclude, but the other cases are handled.
This commit is contained in:
parent
cbf96d73ee
commit
2172c8a503
22
Module.h
22
Module.h
|
|
@ -75,16 +75,29 @@ class Module : public PScope, public LineInfo {
|
|||
|
||||
NetNet::Type default_nettype;
|
||||
|
||||
struct range_t {
|
||||
// True if this is an exclude
|
||||
bool exclude_flag;
|
||||
// lower bound
|
||||
bool low_open_flag;
|
||||
PExpr*low_expr;
|
||||
// upper bound
|
||||
bool high_open_flag;
|
||||
PExpr*high_expr;
|
||||
// Next range description in list
|
||||
struct range_t*next;
|
||||
};
|
||||
|
||||
/* The module has parameters that are evaluated when the
|
||||
module is elaborated. During parsing, I put the parameters
|
||||
into this map. */
|
||||
struct param_expr_t {
|
||||
struct param_expr_t : public LineInfo {
|
||||
PExpr*expr;
|
||||
PExpr*msb;
|
||||
PExpr*lsb;
|
||||
perm_string file;
|
||||
unsigned lineno;
|
||||
bool signed_flag;
|
||||
// If there are range constrants, list them here
|
||||
range_t*range;
|
||||
};
|
||||
map<perm_string,param_expr_t>parameters;
|
||||
map<perm_string,param_expr_t>localparams;
|
||||
|
|
@ -158,8 +171,7 @@ class Module : public PScope, public LineInfo {
|
|||
map<perm_string,PFunction*> funcs_;
|
||||
|
||||
static void elaborate_parm_item_(perm_string name, const param_expr_t&cur,
|
||||
Design*des, NetScope*scope,
|
||||
perm_string file, unsigned lineno);
|
||||
Design*des, NetScope*scope);
|
||||
|
||||
private: // Not implemented
|
||||
Module(const Module&);
|
||||
|
|
|
|||
|
|
@ -45,8 +45,7 @@
|
|||
# include <assert.h>
|
||||
|
||||
void Module::elaborate_parm_item_(perm_string name, const param_expr_t&cur,
|
||||
Design*des, NetScope*scope,
|
||||
perm_string file, unsigned lineno)
|
||||
Design*des, NetScope*scope)
|
||||
{
|
||||
PExpr*ex = cur.expr;
|
||||
assert(ex);
|
||||
|
|
@ -81,8 +80,8 @@ void Module::elaborate_parm_item_(perm_string name, const param_expr_t&cur,
|
|||
signed_flag = val->has_sign();
|
||||
}
|
||||
|
||||
val = scope->set_parameter(name, val,
|
||||
msb, lsb, signed_flag, file, lineno);
|
||||
val = scope->set_parameter(name, val, msb, lsb, signed_flag,
|
||||
cur.get_file(), cur.get_lineno());
|
||||
assert(val);
|
||||
delete val;
|
||||
}
|
||||
|
|
@ -121,7 +120,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
|||
tmp->cast_signed( (*cur).second.signed_flag );
|
||||
|
||||
scope->set_parameter((*cur).first, tmp, 0, 0, false,
|
||||
(*cur).second.file, (*cur).second.lineno);
|
||||
(*cur).second.get_file(),
|
||||
(*cur).second.get_lineno());
|
||||
}
|
||||
|
||||
for (mparm_it_t cur = localparams.begin()
|
||||
|
|
@ -133,7 +133,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
|||
tmp->cast_signed( (*cur).second.signed_flag );
|
||||
|
||||
scope->set_parameter((*cur).first, tmp, 0, 0, false,
|
||||
(*cur).second.file, (*cur).second.lineno);
|
||||
(*cur).second.get_file(),
|
||||
(*cur).second.get_lineno());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -145,8 +146,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
|||
for (mparm_it_t cur = parameters.begin()
|
||||
; cur != parameters.end() ; cur ++) {
|
||||
|
||||
elaborate_parm_item_((*cur).first, (*cur).second, des, scope,
|
||||
(*cur).second.file, (*cur).second.lineno);
|
||||
elaborate_parm_item_((*cur).first, (*cur).second, des, scope);
|
||||
}
|
||||
|
||||
/* run parameter replacements that were collected from the
|
||||
|
|
@ -178,8 +178,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
|||
for (mparm_it_t cur = localparams.begin()
|
||||
; cur != localparams.end() ; cur ++) {
|
||||
|
||||
elaborate_parm_item_((*cur).first, (*cur).second, des, scope,
|
||||
(*cur).second.file, (*cur).second.lineno);
|
||||
elaborate_parm_item_((*cur).first, (*cur).second, des, scope);
|
||||
}
|
||||
|
||||
// Run through the defparams for this module, elaborate the
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ hypot, GN_KEYWORDS_VAMS_2_3, K_hypot
|
|||
idt_nature, GN_KEYWORDS_VAMS_2_3, K_idt_nature
|
||||
if, GN_KEYWORDS_1364_1995, K_if
|
||||
ifnone, GN_KEYWORDS_1364_1995, K_ifnone
|
||||
inf, GN_KEYWORDS_VAMS_2_3, K_inf
|
||||
initial, GN_KEYWORDS_1364_1995, K_initial
|
||||
inout, GN_KEYWORDS_1364_1995, K_inout
|
||||
input, GN_KEYWORDS_1364_1995, K_input
|
||||
|
|
|
|||
65
parse.y
65
parse.y
|
|
@ -156,6 +156,7 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
|
|||
svector<lgate>*gates;
|
||||
|
||||
Module::port_t *mport;
|
||||
Module::range_t* value_range;
|
||||
svector<Module::port_t*>*mports;
|
||||
|
||||
named_pexpr_t*named_pexpr;
|
||||
|
|
@ -213,7 +214,7 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
|
|||
%token K_endprimitive K_endspecify K_endtable K_endtask K_event
|
||||
%token K_exclude K_exp K_floor K_flow K_from
|
||||
%token K_for K_force K_forever K_fork K_function K_generate K_genvar
|
||||
%token K_ground K_highz0 K_highz1 K_hypot K_idt_nature K_if K_ifnone
|
||||
%token K_ground K_highz0 K_highz1 K_hypot K_idt_nature K_if K_ifnone K_inf
|
||||
%token K_initial K_inout K_input K_integer K_join K_large K_ln K_localparam
|
||||
%token K_log K_logic K_macromodule K_max
|
||||
%token K_medium K_min K_module K_nand K_nature K_negedge
|
||||
|
|
@ -235,6 +236,7 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
|
|||
|
||||
%token KK_attribute
|
||||
|
||||
%type <flag> from_exclude
|
||||
%type <number> number
|
||||
%type <flag> signed_opt udp_reg_opt edge_operator
|
||||
%type <drive> drive_strength drive_strength_opt dr_strength0 dr_strength1
|
||||
|
|
@ -256,6 +258,9 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
|
|||
%type <mport> port port_opt port_reference port_reference_list
|
||||
%type <mport> port_declaration
|
||||
%type <mports> list_of_ports module_port_list_opt list_of_port_declarations
|
||||
%type <value_range> parameter_value_range parameter_value_ranges
|
||||
%type <value_range> parameter_value_ranges_opt
|
||||
%type <expr> value_range_expression
|
||||
|
||||
%type <wires> task_item task_item_list task_item_list_opt
|
||||
%type <wires> task_port_item task_port_decl task_port_decl_list
|
||||
|
|
@ -2375,22 +2380,43 @@ parameter_assign_list
|
|||
;
|
||||
|
||||
parameter_assign
|
||||
: IDENTIFIER '=' expression
|
||||
{ PExpr*tmp = $3;
|
||||
if (!pform_expression_is_constant(tmp)) {
|
||||
yyerror(@3, "error: parameter value "
|
||||
"must be a constant expression.");
|
||||
delete tmp;
|
||||
tmp = 0;
|
||||
} else {
|
||||
pform_set_parameter(lex_strings.make($1),
|
||||
active_signed,
|
||||
active_range, tmp,
|
||||
@1.text, @1.first_line);
|
||||
}
|
||||
delete[]$1;
|
||||
}
|
||||
;
|
||||
: IDENTIFIER '=' expression parameter_value_ranges_opt
|
||||
{ PExpr*tmp = $3;
|
||||
pform_set_parameter(@1, lex_strings.make($1),
|
||||
active_signed, active_range, tmp, $4);
|
||||
delete[]$1;
|
||||
}
|
||||
;
|
||||
|
||||
parameter_value_ranges_opt : parameter_value_ranges { $$ = $1; } | { $$ = 0; } ;
|
||||
|
||||
parameter_value_ranges
|
||||
: parameter_value_ranges parameter_value_range
|
||||
{ $$ = $2; $$->next = $1; }
|
||||
| parameter_value_range
|
||||
{ $$ = $1; $$->next = 0; }
|
||||
;
|
||||
|
||||
parameter_value_range
|
||||
: from_exclude '[' value_range_expression ':' value_range_expression ']'
|
||||
{ $$ = pform_parameter_value_range($1, false, $3, false, $5); }
|
||||
| from_exclude '[' value_range_expression ':' value_range_expression ')'
|
||||
{ $$ = pform_parameter_value_range($1, false, $3, true, $5); }
|
||||
| from_exclude '(' value_range_expression ':' value_range_expression ']'
|
||||
{ $$ = pform_parameter_value_range($1, true, $3, false, $5); }
|
||||
| from_exclude '(' value_range_expression ':' value_range_expression ')'
|
||||
{ $$ = pform_parameter_value_range($1, true, $3, true, $5); }
|
||||
/* | K_exclude expression */
|
||||
;
|
||||
|
||||
value_range_expression
|
||||
: expression { $$ = $1; }
|
||||
| K_inf { $$ = 0; }
|
||||
| '+' K_inf { $$ = 0; }
|
||||
| '-' K_inf { $$ = 0; }
|
||||
;
|
||||
|
||||
from_exclude : K_from { $$ = false; } | K_exclude { $$ = true; } ;
|
||||
|
||||
/* Localparam assignments and assignment lists are broken into
|
||||
separate BNF so that I can call slightly different parameter
|
||||
|
|
@ -2406,10 +2432,9 @@ localparam_assign
|
|||
delete tmp;
|
||||
tmp = 0;
|
||||
} else {
|
||||
pform_set_localparam(lex_strings.make($1),
|
||||
pform_set_localparam(@1, lex_strings.make($1),
|
||||
active_signed,
|
||||
active_range, tmp,
|
||||
@1.text, @1.first_line);
|
||||
active_range, tmp);
|
||||
}
|
||||
delete[]$1;
|
||||
}
|
||||
|
|
|
|||
61
pform.cc
61
pform.cc
|
|
@ -1634,50 +1634,69 @@ void pform_set_reg_idx(perm_string name, PExpr*l, PExpr*r)
|
|||
cur->set_memory_idx(l, r);
|
||||
}
|
||||
|
||||
void pform_set_parameter(perm_string name, bool signed_flag,
|
||||
Module::range_t* pform_parameter_value_range(bool exclude_flag,
|
||||
bool low_open, PExpr*low_expr,
|
||||
bool hig_open, PExpr*hig_expr)
|
||||
{
|
||||
Module::range_t*tmp = new Module::range_t;
|
||||
tmp->exclude_flag = exclude_flag;
|
||||
tmp->low_open_flag = low_open;
|
||||
tmp->low_expr = low_expr;
|
||||
tmp->high_open_flag = hig_open;
|
||||
tmp->high_expr = hig_expr;
|
||||
tmp->next = 0;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void pform_set_parameter(const struct vlltype&loc,
|
||||
perm_string name, bool signed_flag,
|
||||
svector<PExpr*>*range, PExpr*expr,
|
||||
const char*file, unsigned lineno)
|
||||
Module::range_t*value_range)
|
||||
{
|
||||
assert(expr);
|
||||
pform_cur_module->parameters[name].expr = expr;
|
||||
Module::param_expr_t&parm = pform_cur_module->parameters[name];
|
||||
FILE_NAME(&parm, loc);
|
||||
|
||||
parm.expr = expr;
|
||||
|
||||
if (range) {
|
||||
assert(range->count() == 2);
|
||||
assert((*range)[0]);
|
||||
assert((*range)[1]);
|
||||
pform_cur_module->parameters[name].msb = (*range)[0];
|
||||
pform_cur_module->parameters[name].lsb = (*range)[1];
|
||||
parm.msb = (*range)[0];
|
||||
parm.lsb = (*range)[1];
|
||||
} else {
|
||||
pform_cur_module->parameters[name].msb = 0;
|
||||
pform_cur_module->parameters[name].lsb = 0;
|
||||
parm.msb = 0;
|
||||
parm.lsb = 0;
|
||||
}
|
||||
pform_cur_module->parameters[name].signed_flag = signed_flag;
|
||||
pform_cur_module->parameters[name].file = filename_strings.make(file);
|
||||
pform_cur_module->parameters[name].lineno = lineno;
|
||||
parm.signed_flag = signed_flag;
|
||||
parm.range = value_range;
|
||||
|
||||
pform_cur_module->param_names.push_back(name);
|
||||
}
|
||||
|
||||
void pform_set_localparam(perm_string name, bool signed_flag,
|
||||
svector<PExpr*>*range, PExpr*expr,
|
||||
const char*file, unsigned lineno)
|
||||
void pform_set_localparam(const struct vlltype&loc,
|
||||
perm_string name, bool signed_flag,
|
||||
svector<PExpr*>*range, PExpr*expr)
|
||||
{
|
||||
assert(expr);
|
||||
pform_cur_module->localparams[name].expr = expr;
|
||||
Module::param_expr_t&parm = pform_cur_module->localparams[name];
|
||||
FILE_NAME(&parm, loc);
|
||||
|
||||
parm.expr = expr;
|
||||
|
||||
if (range) {
|
||||
assert(range->count() == 2);
|
||||
assert((*range)[0]);
|
||||
assert((*range)[1]);
|
||||
pform_cur_module->localparams[name].msb = (*range)[0];
|
||||
pform_cur_module->localparams[name].lsb = (*range)[1];
|
||||
parm.msb = (*range)[0];
|
||||
parm.lsb = (*range)[1];
|
||||
} else {
|
||||
pform_cur_module->localparams[name].msb = 0;
|
||||
pform_cur_module->localparams[name].lsb = 0;
|
||||
parm.msb = 0;
|
||||
parm.lsb = 0;
|
||||
}
|
||||
pform_cur_module->localparams[name].signed_flag = signed_flag;
|
||||
pform_cur_module->localparams[name].file = filename_strings.make(file);
|
||||
pform_cur_module->localparams[name].lineno = lineno;
|
||||
parm.signed_flag = signed_flag;
|
||||
parm.range = 0;
|
||||
}
|
||||
|
||||
void pform_set_specparam(perm_string name, PExpr*expr)
|
||||
|
|
|
|||
16
pform.h
16
pform.h
|
|
@ -266,16 +266,20 @@ extern void pform_set_attrib(perm_string name, perm_string key,
|
|||
extern void pform_set_type_attrib(perm_string name, const string&key,
|
||||
char*value);
|
||||
|
||||
extern void pform_set_parameter(perm_string name,
|
||||
extern Module::range_t* pform_parameter_value_range(bool exclude_flag,
|
||||
bool low_open, PExpr*low_expr,
|
||||
bool hig_open, PExpr*hig_expr);
|
||||
|
||||
extern void pform_set_parameter(const struct vlltype&loc,
|
||||
perm_string name,
|
||||
bool signed_flag,
|
||||
svector<PExpr*>*range,
|
||||
PExpr*expr,
|
||||
const char*file, unsigned lineno);
|
||||
extern void pform_set_localparam(perm_string name,
|
||||
PExpr*expr, Module::range_t*value_range);
|
||||
extern void pform_set_localparam(const struct vlltype&loc,
|
||||
perm_string name,
|
||||
bool signed_flag,
|
||||
svector<PExpr*>*range,
|
||||
PExpr*expr,
|
||||
const char*file, unsigned lineno);
|
||||
PExpr*expr);
|
||||
extern void pform_set_defparam(const pform_name_t&name, PExpr*expr);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1002,9 +1002,34 @@ void Module::dump(ostream&out) const
|
|||
<< *(*cur).second.lsb << "] ";
|
||||
out << (*cur).first << " = ";
|
||||
if ((*cur).second.expr)
|
||||
out << *(*cur).second.expr << ";" << endl;
|
||||
out << *(*cur).second.expr;
|
||||
else
|
||||
out << "/* ERROR */;" << endl;
|
||||
out << "/* ERROR */";
|
||||
for (Module::range_t*tmp = (*cur).second.range
|
||||
; tmp ; tmp = tmp->next) {
|
||||
if (tmp->exclude_flag)
|
||||
out << " exclude ";
|
||||
else
|
||||
out << " from ";
|
||||
if (tmp->low_open_flag)
|
||||
out << "(";
|
||||
else
|
||||
out << "[";
|
||||
if (tmp->low_expr)
|
||||
out << *(tmp->low_expr);
|
||||
else
|
||||
out << "<>";
|
||||
out << ":";
|
||||
if (tmp->high_expr)
|
||||
out << *(tmp->high_expr);
|
||||
else
|
||||
out << "<>";
|
||||
if (tmp->high_open_flag)
|
||||
out << ")";
|
||||
else
|
||||
out << "]";
|
||||
}
|
||||
out << ";" << endl;
|
||||
}
|
||||
|
||||
for (parm_iter_t cur = localparams.begin()
|
||||
|
|
|
|||
Loading…
Reference in New Issue