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:
Stephen Williams 2008-05-12 21:26:38 -07:00
parent cbf96d73ee
commit 2172c8a503
7 changed files with 149 additions and 64 deletions

View File

@ -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&);

View File

@ -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

View File

@ -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
View File

@ -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;
}

View File

@ -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
View File

@ -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);
/*

View File

@ -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()