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;
|
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
|
/* The module has parameters that are evaluated when the
|
||||||
module is elaborated. During parsing, I put the parameters
|
module is elaborated. During parsing, I put the parameters
|
||||||
into this map. */
|
into this map. */
|
||||||
struct param_expr_t {
|
struct param_expr_t : public LineInfo {
|
||||||
PExpr*expr;
|
PExpr*expr;
|
||||||
PExpr*msb;
|
PExpr*msb;
|
||||||
PExpr*lsb;
|
PExpr*lsb;
|
||||||
perm_string file;
|
|
||||||
unsigned lineno;
|
|
||||||
bool signed_flag;
|
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>parameters;
|
||||||
map<perm_string,param_expr_t>localparams;
|
map<perm_string,param_expr_t>localparams;
|
||||||
|
|
@ -158,8 +171,7 @@ class Module : public PScope, public LineInfo {
|
||||||
map<perm_string,PFunction*> funcs_;
|
map<perm_string,PFunction*> funcs_;
|
||||||
|
|
||||||
static void elaborate_parm_item_(perm_string name, const param_expr_t&cur,
|
static void elaborate_parm_item_(perm_string name, const param_expr_t&cur,
|
||||||
Design*des, NetScope*scope,
|
Design*des, NetScope*scope);
|
||||||
perm_string file, unsigned lineno);
|
|
||||||
|
|
||||||
private: // Not implemented
|
private: // Not implemented
|
||||||
Module(const Module&);
|
Module(const Module&);
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,7 @@
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
|
|
||||||
void Module::elaborate_parm_item_(perm_string name, const param_expr_t&cur,
|
void Module::elaborate_parm_item_(perm_string name, const param_expr_t&cur,
|
||||||
Design*des, NetScope*scope,
|
Design*des, NetScope*scope)
|
||||||
perm_string file, unsigned lineno)
|
|
||||||
{
|
{
|
||||||
PExpr*ex = cur.expr;
|
PExpr*ex = cur.expr;
|
||||||
assert(ex);
|
assert(ex);
|
||||||
|
|
@ -81,8 +80,8 @@ void Module::elaborate_parm_item_(perm_string name, const param_expr_t&cur,
|
||||||
signed_flag = val->has_sign();
|
signed_flag = val->has_sign();
|
||||||
}
|
}
|
||||||
|
|
||||||
val = scope->set_parameter(name, val,
|
val = scope->set_parameter(name, val, msb, lsb, signed_flag,
|
||||||
msb, lsb, signed_flag, file, lineno);
|
cur.get_file(), cur.get_lineno());
|
||||||
assert(val);
|
assert(val);
|
||||||
delete val;
|
delete val;
|
||||||
}
|
}
|
||||||
|
|
@ -121,7 +120,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
||||||
tmp->cast_signed( (*cur).second.signed_flag );
|
tmp->cast_signed( (*cur).second.signed_flag );
|
||||||
|
|
||||||
scope->set_parameter((*cur).first, tmp, 0, 0, false,
|
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()
|
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 );
|
tmp->cast_signed( (*cur).second.signed_flag );
|
||||||
|
|
||||||
scope->set_parameter((*cur).first, tmp, 0, 0, false,
|
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()
|
for (mparm_it_t cur = parameters.begin()
|
||||||
; cur != parameters.end() ; cur ++) {
|
; cur != parameters.end() ; cur ++) {
|
||||||
|
|
||||||
elaborate_parm_item_((*cur).first, (*cur).second, des, scope,
|
elaborate_parm_item_((*cur).first, (*cur).second, des, scope);
|
||||||
(*cur).second.file, (*cur).second.lineno);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* run parameter replacements that were collected from the
|
/* 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()
|
for (mparm_it_t cur = localparams.begin()
|
||||||
; cur != localparams.end() ; cur ++) {
|
; cur != localparams.end() ; cur ++) {
|
||||||
|
|
||||||
elaborate_parm_item_((*cur).first, (*cur).second, des, scope,
|
elaborate_parm_item_((*cur).first, (*cur).second, des, scope);
|
||||||
(*cur).second.file, (*cur).second.lineno);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run through the defparams for this module, elaborate the
|
// 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
|
idt_nature, GN_KEYWORDS_VAMS_2_3, K_idt_nature
|
||||||
if, GN_KEYWORDS_1364_1995, K_if
|
if, GN_KEYWORDS_1364_1995, K_if
|
||||||
ifnone, GN_KEYWORDS_1364_1995, K_ifnone
|
ifnone, GN_KEYWORDS_1364_1995, K_ifnone
|
||||||
|
inf, GN_KEYWORDS_VAMS_2_3, K_inf
|
||||||
initial, GN_KEYWORDS_1364_1995, K_initial
|
initial, GN_KEYWORDS_1364_1995, K_initial
|
||||||
inout, GN_KEYWORDS_1364_1995, K_inout
|
inout, GN_KEYWORDS_1364_1995, K_inout
|
||||||
input, GN_KEYWORDS_1364_1995, K_input
|
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;
|
svector<lgate>*gates;
|
||||||
|
|
||||||
Module::port_t *mport;
|
Module::port_t *mport;
|
||||||
|
Module::range_t* value_range;
|
||||||
svector<Module::port_t*>*mports;
|
svector<Module::port_t*>*mports;
|
||||||
|
|
||||||
named_pexpr_t*named_pexpr;
|
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_endprimitive K_endspecify K_endtable K_endtask K_event
|
||||||
%token K_exclude K_exp K_floor K_flow K_from
|
%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_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_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_log K_logic K_macromodule K_max
|
||||||
%token K_medium K_min K_module K_nand K_nature K_negedge
|
%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
|
%token KK_attribute
|
||||||
|
|
||||||
|
%type <flag> from_exclude
|
||||||
%type <number> number
|
%type <number> number
|
||||||
%type <flag> signed_opt udp_reg_opt edge_operator
|
%type <flag> signed_opt udp_reg_opt edge_operator
|
||||||
%type <drive> drive_strength drive_strength_opt dr_strength0 dr_strength1
|
%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 port_opt port_reference port_reference_list
|
||||||
%type <mport> port_declaration
|
%type <mport> port_declaration
|
||||||
%type <mports> list_of_ports module_port_list_opt list_of_port_declarations
|
%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_item task_item_list task_item_list_opt
|
||||||
%type <wires> task_port_item task_port_decl task_port_decl_list
|
%type <wires> task_port_item task_port_decl task_port_decl_list
|
||||||
|
|
@ -2375,22 +2380,43 @@ parameter_assign_list
|
||||||
;
|
;
|
||||||
|
|
||||||
parameter_assign
|
parameter_assign
|
||||||
: IDENTIFIER '=' expression
|
: IDENTIFIER '=' expression parameter_value_ranges_opt
|
||||||
{ PExpr*tmp = $3;
|
{ PExpr*tmp = $3;
|
||||||
if (!pform_expression_is_constant(tmp)) {
|
pform_set_parameter(@1, lex_strings.make($1),
|
||||||
yyerror(@3, "error: parameter value "
|
active_signed, active_range, tmp, $4);
|
||||||
"must be a constant expression.");
|
delete[]$1;
|
||||||
delete tmp;
|
}
|
||||||
tmp = 0;
|
;
|
||||||
} else {
|
|
||||||
pform_set_parameter(lex_strings.make($1),
|
parameter_value_ranges_opt : parameter_value_ranges { $$ = $1; } | { $$ = 0; } ;
|
||||||
active_signed,
|
|
||||||
active_range, tmp,
|
parameter_value_ranges
|
||||||
@1.text, @1.first_line);
|
: parameter_value_ranges parameter_value_range
|
||||||
}
|
{ $$ = $2; $$->next = $1; }
|
||||||
delete[]$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
|
/* Localparam assignments and assignment lists are broken into
|
||||||
separate BNF so that I can call slightly different parameter
|
separate BNF so that I can call slightly different parameter
|
||||||
|
|
@ -2406,10 +2432,9 @@ localparam_assign
|
||||||
delete tmp;
|
delete tmp;
|
||||||
tmp = 0;
|
tmp = 0;
|
||||||
} else {
|
} else {
|
||||||
pform_set_localparam(lex_strings.make($1),
|
pform_set_localparam(@1, lex_strings.make($1),
|
||||||
active_signed,
|
active_signed,
|
||||||
active_range, tmp,
|
active_range, tmp);
|
||||||
@1.text, @1.first_line);
|
|
||||||
}
|
}
|
||||||
delete[]$1;
|
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);
|
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,
|
svector<PExpr*>*range, PExpr*expr,
|
||||||
const char*file, unsigned lineno)
|
Module::range_t*value_range)
|
||||||
{
|
{
|
||||||
assert(expr);
|
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) {
|
if (range) {
|
||||||
assert(range->count() == 2);
|
assert(range->count() == 2);
|
||||||
assert((*range)[0]);
|
assert((*range)[0]);
|
||||||
assert((*range)[1]);
|
assert((*range)[1]);
|
||||||
pform_cur_module->parameters[name].msb = (*range)[0];
|
parm.msb = (*range)[0];
|
||||||
pform_cur_module->parameters[name].lsb = (*range)[1];
|
parm.lsb = (*range)[1];
|
||||||
} else {
|
} else {
|
||||||
pform_cur_module->parameters[name].msb = 0;
|
parm.msb = 0;
|
||||||
pform_cur_module->parameters[name].lsb = 0;
|
parm.lsb = 0;
|
||||||
}
|
}
|
||||||
pform_cur_module->parameters[name].signed_flag = signed_flag;
|
parm.signed_flag = signed_flag;
|
||||||
pform_cur_module->parameters[name].file = filename_strings.make(file);
|
parm.range = value_range;
|
||||||
pform_cur_module->parameters[name].lineno = lineno;
|
|
||||||
|
|
||||||
pform_cur_module->param_names.push_back(name);
|
pform_cur_module->param_names.push_back(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_set_localparam(perm_string name, bool signed_flag,
|
void pform_set_localparam(const struct vlltype&loc,
|
||||||
svector<PExpr*>*range, PExpr*expr,
|
perm_string name, bool signed_flag,
|
||||||
const char*file, unsigned lineno)
|
svector<PExpr*>*range, PExpr*expr)
|
||||||
{
|
{
|
||||||
assert(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) {
|
if (range) {
|
||||||
assert(range->count() == 2);
|
assert(range->count() == 2);
|
||||||
assert((*range)[0]);
|
assert((*range)[0]);
|
||||||
assert((*range)[1]);
|
assert((*range)[1]);
|
||||||
pform_cur_module->localparams[name].msb = (*range)[0];
|
parm.msb = (*range)[0];
|
||||||
pform_cur_module->localparams[name].lsb = (*range)[1];
|
parm.lsb = (*range)[1];
|
||||||
} else {
|
} else {
|
||||||
pform_cur_module->localparams[name].msb = 0;
|
parm.msb = 0;
|
||||||
pform_cur_module->localparams[name].lsb = 0;
|
parm.lsb = 0;
|
||||||
}
|
}
|
||||||
pform_cur_module->localparams[name].signed_flag = signed_flag;
|
parm.signed_flag = signed_flag;
|
||||||
pform_cur_module->localparams[name].file = filename_strings.make(file);
|
parm.range = 0;
|
||||||
pform_cur_module->localparams[name].lineno = lineno;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_set_specparam(perm_string name, PExpr*expr)
|
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,
|
extern void pform_set_type_attrib(perm_string name, const string&key,
|
||||||
char*value);
|
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,
|
bool signed_flag,
|
||||||
svector<PExpr*>*range,
|
svector<PExpr*>*range,
|
||||||
PExpr*expr,
|
PExpr*expr, Module::range_t*value_range);
|
||||||
const char*file, unsigned lineno);
|
extern void pform_set_localparam(const struct vlltype&loc,
|
||||||
extern void pform_set_localparam(perm_string name,
|
perm_string name,
|
||||||
bool signed_flag,
|
bool signed_flag,
|
||||||
svector<PExpr*>*range,
|
svector<PExpr*>*range,
|
||||||
PExpr*expr,
|
PExpr*expr);
|
||||||
const char*file, unsigned lineno);
|
|
||||||
extern void pform_set_defparam(const pform_name_t&name, 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 << "] ";
|
<< *(*cur).second.lsb << "] ";
|
||||||
out << (*cur).first << " = ";
|
out << (*cur).first << " = ";
|
||||||
if ((*cur).second.expr)
|
if ((*cur).second.expr)
|
||||||
out << *(*cur).second.expr << ";" << endl;
|
out << *(*cur).second.expr;
|
||||||
else
|
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()
|
for (parm_iter_t cur = localparams.begin()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue