Redo constant expression detection to happen

after parsing.

 Parse more operators and expressions.
This commit is contained in:
steve 1999-05-16 05:08:42 +00:00
parent c677afd8e3
commit 10ffaeda90
9 changed files with 216 additions and 90 deletions

View File

@ -17,10 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: PExpr.cc,v 1.2 1998/11/11 00:01:51 steve Exp $"
#ident "$Id: PExpr.cc,v 1.3 1999/05/16 05:08:42 steve Exp $"
#endif
# include "PExpr.h"
# include "Module.h"
# include <typeinfo>
PExpr::~PExpr()
@ -32,6 +33,21 @@ bool PExpr::is_the_same(const PExpr*that) const
return typeid(this) == typeid(that);
}
bool PExpr::is_constant(Module*) const
{
return false;
}
/*
* An identifier can be in a constant expresion if (and only if) it is
* a parameter.
*/
bool PEIdent::is_constant(Module*mod) const
{
map<string,PExpr*>::const_iterator cur = mod->parameters.find(text_);
return cur != mod->parameters.end();
}
bool PENumber::is_the_same(const PExpr*that) const
{
const PENumber*obj = dynamic_cast<const PENumber*>(that);
@ -41,8 +57,24 @@ bool PENumber::is_the_same(const PExpr*that) const
return *value_ == *obj->value_;
}
bool PENumber::is_constant(Module*) const
{
return true;
}
bool PEString::is_constant(Module*) const
{
return true;
}
/*
* $Log: PExpr.cc,v $
* Revision 1.3 1999/05/16 05:08:42 steve
* Redo constant expression detection to happen
* after parsing.
*
* Parse more operators and expressions.
*
* Revision 1.2 1998/11/11 00:01:51 steve
* Check net ranges in declarations.
*

19
PExpr.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: PExpr.h,v 1.8 1999/05/10 00:16:57 steve Exp $"
#ident "$Id: PExpr.h,v 1.9 1999/05/16 05:08:42 steve Exp $"
#endif
# include <string>
@ -28,6 +28,7 @@
# include "LineInfo.h"
class Design;
class Module;
class NetNet;
class NetExpr;
@ -57,6 +58,12 @@ class PExpr : public LineInfo {
// this expression. This method is used for comparing
// expressions that must be structurally "identical".
virtual bool is_the_same(const PExpr*that) const;
// Return true if this expression is a valid constant
// expression. the Module pointer is needed to find parameter
// identifiers and any other module specific interpretations
// of expresions.
virtual bool is_constant(Module*) const;
};
ostream& operator << (ostream&, const PExpr&);
@ -99,6 +106,7 @@ class PEIdent : public PExpr {
virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, const string&path) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
virtual bool is_constant(Module*) const;
verinum* eval_const(const Design*des, const string&path) const;
// XXXX
@ -132,6 +140,7 @@ class PENumber : public PExpr {
virtual verinum* eval_const(const Design*des, const string&path) const;
virtual bool is_the_same(const PExpr*that) const;
virtual bool is_constant(Module*) const;
private:
verinum*const value_;
@ -147,6 +156,8 @@ class PEString : public PExpr {
virtual void dump(ostream&) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
virtual bool is_constant(Module*) const;
private:
const string text_;
};
@ -185,6 +196,12 @@ class PEBinary : public PExpr {
/*
* $Log: PExpr.h,v $
* Revision 1.9 1999/05/16 05:08:42 steve
* Redo constant expression detection to happen
* after parsing.
*
* Parse more operators and expressions.
*
* Revision 1.8 1999/05/10 00:16:57 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: elaborate.cc,v 1.25 1999/05/10 00:16:58 steve Exp $"
#ident "$Id: elaborate.cc,v 1.26 1999/05/16 05:08:42 steve Exp $"
#endif
/*
@ -724,7 +724,9 @@ NetExpr* PEBinary::elaborate_expr(Design*des, const string&path) const
NetExpr* PENumber::elaborate_expr(Design*des, const string&path) const
{
assert(value_);
return new NetEConst(*value_);
NetEConst*tmp = new NetEConst(*value_);
tmp->set_line(*this);
return tmp;
}
NetExpr* PEString::elaborate_expr(Design*des, const string&path) const
@ -789,7 +791,7 @@ NetExpr*PEIdent::elaborate_expr(Design*des, const string&path) const
NetExpr* PExpr::elaborate_expr(Design*des, const string&path) const
{
cerr << "Cannot elaborate expression: " << *this << endl;
return new NetEConst(verinum());
return 0;
}
NetExpr* PEUnary::elaborate_expr(Design*des, const string&path) const
@ -1148,6 +1150,12 @@ Design* elaborate(const map<string,Module*>&modules,
/*
* $Log: elaborate.cc,v $
* Revision 1.26 1999/05/16 05:08:42 steve
* Redo constant expression detection to happen
* after parsing.
*
* Parse more operators and expressions.
*
* Revision 1.25 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: lexor.lex,v 1.14 1999/05/13 04:02:09 steve Exp $"
#ident "$Id: lexor.lex,v 1.15 1999/05/16 05:08:42 steve Exp $"
#endif
//# define YYSTYPE lexval
@ -68,6 +68,8 @@ static verinum*make_unsized_hex(const char*txt);
<CCOMMENT>\n { yylloc.first_line += 1; yymore(); }
<CCOMMENT>"*/" { BEGIN(0); }
"<<" { return K_LS; }
">>" { return K_RS; }
"<=" { return K_LE; }
">=" { return K_GE; }
"==" { return K_EQ; }
@ -77,7 +79,7 @@ static verinum*make_unsized_hex(const char*txt);
"||" { return K_LOR; }
"&&" { return K_LAND; }
[}{;:\[\],()#=.@&!<|^~+*/-] { return yytext[0]; }
[}{;:\[\],()#=.@&!?<>%|^~+*/-] { return yytext[0]; }
\" { BEGIN(CSTRING); }
<CSTRING>\\\" { yymore(); }

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: netlist.cc,v 1.25 1999/05/13 04:02:09 steve Exp $"
#ident "$Id: netlist.cc,v 1.26 1999/05/16 05:08:42 steve Exp $"
#endif
# include <cassert>
@ -507,6 +507,11 @@ NetEConst::~NetEConst()
void NetEConst::set_width(unsigned w)
{
if (w > value_.len()) {
cerr << get_line() << ": Cannot expand " << *this
<< " to " << w << " bits." << endl;
assert(0);
}
assert(w <= value_.len());
value_ = verinum(value_, w);
expr_width(w);
@ -1054,6 +1059,12 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/*
* $Log: netlist.cc,v $
* Revision 1.26 1999/05/16 05:08:42 steve
* Redo constant expression detection to happen
* after parsing.
*
* Parse more operators and expressions.
*
* Revision 1.25 1999/05/13 04:02:09 steve
* More precise handling of verinum bit lengths.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: netlist.h,v 1.30 1999/05/12 04:03:19 steve Exp $"
#ident "$Id: netlist.h,v 1.31 1999/05/16 05:08:42 steve Exp $"
#endif
/*
@ -327,7 +327,7 @@ class NetMemory {
* being referenced, so can handle garbage collection. Also, this
* trick can be used to replace subexpressions.
*/
class NetExpr {
class NetExpr : public LineInfo {
public:
explicit NetExpr(unsigned w =0) : width_(w), reflist_(0) { }
virtual ~NetExpr() =0;
@ -881,15 +881,22 @@ class NetProcTop : public LineInfo {
*
* ^ -- Bit-wise exclusive OR
* + -- Arithmetic add
* - -- Arighmetic minus
* - -- Arithmetic minus
* * -- Arithmetic multiply
* / -- Arithmetic divide
* % -- Arithmetic modulus
* & -- Bit-wise AND
* | -- Bit-wise OR
* e -- Logical equality (==)
* E -- Case equality (===)
* L -- Less or equal
* G -- Greater or equal
* n -- Logical inequality (!=)
* N -- Case inequality (!==)
* a -- Logical AND (&&)
* o -- Logical OR (||)
* l -- Left shift (<<)
* r -- Right shift (>>)
*/
class NetEBinary : public NetExpr {
@ -1178,6 +1185,12 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.31 1999/05/16 05:08:42 steve
* Redo constant expression detection to happen
* after parsing.
*
* Parse more operators and expressions.
*
* Revision 1.30 1999/05/12 04:03:19 steve
* emit NetAssignMem objects in vvm target.
*

170
parse.y
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: parse.y,v 1.25 1999/05/10 00:16:58 steve Exp $"
#ident "$Id: parse.y,v 1.26 1999/05/16 05:08:42 steve Exp $"
#endif
# include "parse_misc.h"
@ -61,7 +61,7 @@ extern void lex_end_table();
%token <text> IDENTIFIER PORTNAME SYSTEM_IDENTIFIER STRING
%token <number> NUMBER
%token K_LE K_GE K_EQ K_NE K_CEQ K_CNE
%token K_LE K_GE K_EQ K_NE K_CEQ K_CNE K_LS K_RS
%token K_LOR K_LAND
%token K_always K_and K_assign K_begin K_buf K_bufif0 K_bufif1 K_case
%token K_casex K_casez K_cmos K_deassign K_default K_defparam K_disable
@ -101,7 +101,7 @@ extern void lex_end_table();
%type <gate> gate_instance
%type <gates> gate_instance_list
%type <expr> bitsel delay delay_opt expression expr_primary const_expression
%type <expr> delay delay_opt expression expr_primary
%type <expr> lavalue lpvalue
%type <exprs> expression_list
@ -122,7 +122,9 @@ extern void lex_end_table();
%left '&'
%left K_EQ K_NE K_CEQ K_CNE
%left K_GE K_LE '<' '>'
%left K_LS K_RS
%left '+' '-'
%left '*' '/' '%'
%left UNARY_PREC
%%
@ -132,11 +134,6 @@ source_file
| source_file description
;
bitsel
: '[' const_expression ']'
{ $$ = $2; }
;
case_item
: expression ':' statement_opt
{ PCase::Item*tmp = new PCase::Item;
@ -171,52 +168,6 @@ case_items
}
;
/* const_expressions are restricted expressions that have guaranteed
known values at compile time. I treat them differently at parse
time so that I can tack correctness checking onto the parse
process. */
const_expression
: NUMBER
{ verinum*tmp = $1;
if (tmp == 0) {
yyerror(@1, "XXXX internal error: const_expression.");
$$ = 0;
} else {
PENumber*tmp = new PENumber($1);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
}
}
| STRING
{ PEString*tmp = new PEString(*$1);
tmp->set_file(@2.text);
tmp->set_lineno(@2.first_line);
delete $1;
$$ = tmp;
}
| IDENTIFIER
{ if (!pform_is_parameter(*$1)) {
yyerror(@1, "Identifier in constant expression"
" must be a parameter name.");
delete $1;
$$ = 0;
} else {
PEIdent*tmp = new PEIdent(*$1);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
delete $1;
}
}
| const_expression '-' const_expression
{ PEBinary*tmp = new PEBinary('-', $1, $3);
tmp->set_file(@2.text);
tmp->set_lineno(@2.first_line);
$$ = tmp;
}
;
delay
: '#' NUMBER
{ verinum*tmp = $2;
@ -332,6 +283,15 @@ expression
| expression '^' expression
{ $$ = new PEBinary('^', $1, $3);
}
| expression '*' expression
{ $$ = new PEBinary('*', $1, $3);
}
| expression '/' expression
{ $$ = new PEBinary('/', $1, $3);
}
| expression '%' expression
{ $$ = new PEBinary('%', $1, $3);
}
| expression '+' expression
{ $$ = new PEBinary('+', $1, $3);
}
@ -350,12 +310,24 @@ expression
| expression '>' expression
{ $$ = new PEBinary('>', $1, $3);
}
| expression K_LS expression
{ $$ = new PEBinary('l', $1, $3);
}
| expression K_RS expression
{ $$ = new PEBinary('r', $1, $3);
}
| expression K_EQ expression
{ $$ = new PEBinary('e', $1, $3);
}
| expression K_CEQ expression
{ $$ = new PEBinary('E', $1, $3);
}
| expression K_LE expression
{ $$ = new PEBinary('L', $1, $3);
}
| expression K_GE expression
{ $$ = new PEBinary('G', $1, $3);
}
| expression K_NE expression
{ $$ = new PEBinary('n', $1, $3);
}
@ -396,7 +368,10 @@ expr_primary
yyerror(@1, "XXXX No number value in primary?");
$$ = 0;
} else {
$$ = new PENumber($1);
PENumber*tmp = new PENumber($1);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
}
}
| STRING
@ -579,9 +554,16 @@ lavalue
delete $1;
$$ = tmp;
}
| IDENTIFIER bitsel
| IDENTIFIER '[' expression ']'
{ PEIdent*tmp = new PEIdent(*$1);
tmp->msb_ = $2;
PExpr*sel = $3;
if (! pform_expression_is_constant(sel)) {
yyerror(@2, "Bit select in lvalue must "
"contain a constant expression.");
delete sel;
} else {
tmp->msb_ = sel;
}
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $1;
@ -623,6 +605,14 @@ lpvalue
$$ = tmp;
}
| identifier '[' expression ':' expression ']'
{ yyerror(@1, "Sorry, part selects"
" not supported in lvalue.");
$$ = 0;
delete $1;
delete $3;
delete $5;
}
| '{' expression_list '}'
{ yyerror(@1, "Sorry, concatenation expressions"
" not supported in lvalue.");
@ -721,14 +711,25 @@ net_type
;
parameter_assign
: IDENTIFIER '=' const_expression
{ pform_set_parameter(*$1, $3);
: IDENTIFIER '=' expression
{ PExpr*tmp = $3;
if (!pform_expression_is_constant(tmp)) {
yyerror(@3, "parameter value must be constant.");
delete tmp;
tmp = 0;
}
pform_set_parameter(*$1, tmp);
delete $1;
}
;
parameter_assign_list
: parameter_assign
| range parameter_assign
{ yyerror(@1, "Ranges in parameter definition "
"are not supported.");
delete $1;
}
| parameter_assign_list ',' parameter_assign
;
@ -738,12 +739,25 @@ port
$$->port_type = NetNet::PIMPLICIT;
delete $1;
}
| IDENTIFIER '[' const_expression ':' const_expression ']'
{ $$ = new PWire(*$1, NetNet::IMPLICIT);
$$->port_type = NetNet::PIMPLICIT;
$$->msb = $3;
$$->lsb = $5;
| IDENTIFIER '[' expression ':' expression ']'
{ PWire*tmp = new PWire(*$1, NetNet::IMPLICIT);
tmp->port_type = NetNet::PIMPLICIT;
if (!pform_expression_is_constant($3)) {
yyerror(@3, "msb expression of port bit select "
"must be constant.");
delete $3;
} else {
tmp->msb = $3;
}
if (!pform_expression_is_constant($5)) {
yyerror(@3, "lsb expression of port bit select "
"must be constant.");
delete $5;
} else {
tmp->msb = $5;
}
delete $1;
$$ = tmp;
}
| IDENTIFIER '[' error ']'
{ yyerror(@1, "invalid port bit select");
@ -754,10 +768,14 @@ port
;
port_name
: PORTNAME '(' IDENTIFIER ')'
: PORTNAME '(' expression ')'
{ delete $1;
delete $3;
}
| PORTNAME '(' error ')'
{ yyerror(@3, "invalid port connection expression.");
delete $1;
}
| PORTNAME '(' ')'
{ delete $1;
}
@ -775,10 +793,20 @@ port_type
;
range
: '[' const_expression ':' const_expression ']'
: '[' expression ':' expression ']'
{ svector<PExpr*>*tmp = new svector<PExpr*> (2);
(*tmp)[0] = $2;
(*tmp)[1] = $4;
if (!pform_expression_is_constant($2)) {
yyerror(@2, "msb of range must be constant.");
delete $2;
} else {
(*tmp)[0] = $2;
}
if (!pform_expression_is_constant($4)) {
yyerror(@4, "msb of range must be constant.");
delete $4;
} else {
(*tmp)[1] = $4;
}
$$ = tmp;
}
;
@ -798,8 +826,12 @@ register_variable
{ pform_makewire(*$1, NetNet::REG);
$$ = $1;
}
| IDENTIFIER '[' const_expression ':' const_expression ']'
| IDENTIFIER '[' expression ':' expression ']'
{ pform_makewire(*$1, NetNet::REG);
if (! pform_expression_is_constant($3))
yyerror(@3, "msb of register range must be constant.");
if (! pform_expression_is_constant($5))
yyerror(@3, "lsb of register range must be constant.");
pform_set_reg_idx(*$1, $3, $5);
$$ = $1;
}

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: pform.cc,v 1.17 1999/05/10 00:16:58 steve Exp $"
#ident "$Id: pform.cc,v 1.18 1999/05/16 05:08:42 steve Exp $"
#endif
# include "pform.h"
@ -82,6 +82,11 @@ void pform_endmodule(const string&name)
cur_module = 0;
}
bool pform_expression_is_constant(const PExpr*ex)
{
return ex->is_constant(cur_module);
}
void pform_make_udp(string*name, list<string>*parms,
list<PWire*>*decl, list<string>*table,
Statement*init_expr)
@ -421,13 +426,6 @@ void pform_set_parameter(const string&name, PExpr*expr)
cur_module->parameters[name] = expr;
}
bool pform_is_parameter(const string&name)
{
map<string,PExpr*>::const_iterator cur =
cur_module->parameters.find(name);
return cur != cur_module->parameters.end();
}
void pform_set_port_type(list<string>*names, NetNet::PortType pt)
{
for (list<string>::const_iterator cur = names->begin()
@ -518,6 +516,12 @@ int pform_parse(const char*path, map<string,Module*>&modules,
/*
* $Log: pform.cc,v $
* Revision 1.18 1999/05/16 05:08:42 steve
* Redo constant expression detection to happen
* after parsing.
*
* Parse more operators and expressions.
*
* Revision 1.17 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>

11
pform.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: pform.h,v 1.13 1999/05/10 00:16:58 steve Exp $"
#ident "$Id: pform.h,v 1.14 1999/05/16 05:08:42 steve Exp $"
#endif
# include "netlist.h"
@ -107,13 +107,14 @@ extern void pform_set_attrib(const string&name, const string&key,
extern void pform_set_type_attrib(const string&name, const string&key,
const string&value);
extern void pform_set_parameter(const string&name, PExpr*expr);
extern bool pform_is_parameter(const string&name);
extern PProcess* pform_make_behavior(PProcess::Type, Statement*);
extern Statement* pform_make_block(PBlock::BL_TYPE, list<Statement*>*);
extern Statement* pform_make_calltask(string*t, svector<PExpr*>* =0);
extern list<PWire*>* pform_make_udp_input_ports(list<string>*);
extern bool pform_expression_is_constant(const PExpr*);
/*
* The makegate function creates a new gate (which need not have a
* name) and connects it to the specified wires.
@ -139,6 +140,12 @@ extern void pform_dump(ostream&out, Module*mod);
/*
* $Log: pform.h,v $
* Revision 1.14 1999/05/16 05:08:42 steve
* Redo constant expression detection to happen
* after parsing.
*
* Parse more operators and expressions.
*
* Revision 1.13 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>