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 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "PExpr.h" # include "PExpr.h"
# include "Module.h"
# include <typeinfo> # include <typeinfo>
PExpr::~PExpr() PExpr::~PExpr()
@ -32,6 +33,21 @@ bool PExpr::is_the_same(const PExpr*that) const
return typeid(this) == typeid(that); 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 bool PENumber::is_the_same(const PExpr*that) const
{ {
const PENumber*obj = dynamic_cast<const PENumber*>(that); 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_; return *value_ == *obj->value_;
} }
bool PENumber::is_constant(Module*) const
{
return true;
}
bool PEString::is_constant(Module*) const
{
return true;
}
/* /*
* $Log: PExpr.cc,v $ * $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 * Revision 1.2 1998/11/11 00:01:51 steve
* Check net ranges in declarations. * 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 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include <string> # include <string>
@ -28,6 +28,7 @@
# include "LineInfo.h" # include "LineInfo.h"
class Design; class Design;
class Module;
class NetNet; class NetNet;
class NetExpr; class NetExpr;
@ -57,6 +58,12 @@ class PExpr : public LineInfo {
// this expression. This method is used for comparing // this expression. This method is used for comparing
// expressions that must be structurally "identical". // expressions that must be structurally "identical".
virtual bool is_the_same(const PExpr*that) const; 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&); ostream& operator << (ostream&, const PExpr&);
@ -99,6 +106,7 @@ class PEIdent : public PExpr {
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, const string&path) const; virtual NetNet* elaborate_net(Design*des, const string&path) const;
virtual NetExpr*elaborate_expr(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; verinum* eval_const(const Design*des, const string&path) const;
// XXXX // XXXX
@ -132,6 +140,7 @@ class PENumber : public PExpr {
virtual verinum* eval_const(const Design*des, const string&path) const; virtual verinum* eval_const(const Design*des, const string&path) const;
virtual bool is_the_same(const PExpr*that) const; virtual bool is_the_same(const PExpr*that) const;
virtual bool is_constant(Module*) const;
private: private:
verinum*const value_; verinum*const value_;
@ -147,6 +156,8 @@ class PEString : public PExpr {
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const; virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
virtual bool is_constant(Module*) const;
private: private:
const string text_; const string text_;
}; };
@ -185,6 +196,12 @@ class PEBinary : public PExpr {
/* /*
* $Log: PExpr.h,v $ * $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 * Revision 1.8 1999/05/10 00:16:57 steve
* Parse and elaborate the concatenate operator * Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*> * in structural contexts, Replace vector<PExpr*>

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #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 NetExpr* PENumber::elaborate_expr(Design*des, const string&path) const
{ {
assert(value_); 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 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 NetExpr* PExpr::elaborate_expr(Design*des, const string&path) const
{ {
cerr << "Cannot elaborate expression: " << *this << endl; cerr << "Cannot elaborate expression: " << *this << endl;
return new NetEConst(verinum()); return 0;
} }
NetExpr* PEUnary::elaborate_expr(Design*des, const string&path) const 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 $ * $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 * Revision 1.25 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator * Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*> * in structural contexts, Replace vector<PExpr*>

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
//# define YYSTYPE lexval //# define YYSTYPE lexval
@ -68,6 +68,8 @@ static verinum*make_unsized_hex(const char*txt);
<CCOMMENT>\n { yylloc.first_line += 1; yymore(); } <CCOMMENT>\n { yylloc.first_line += 1; yymore(); }
<CCOMMENT>"*/" { BEGIN(0); } <CCOMMENT>"*/" { BEGIN(0); }
"<<" { return K_LS; }
">>" { return K_RS; }
"<=" { return K_LE; } "<=" { return K_LE; }
">=" { return K_GE; } ">=" { return K_GE; }
"==" { return K_EQ; } "==" { return K_EQ; }
@ -77,7 +79,7 @@ static verinum*make_unsized_hex(const char*txt);
"||" { return K_LOR; } "||" { return K_LOR; }
"&&" { return K_LAND; } "&&" { return K_LAND; }
[}{;:\[\],()#=.@&!<|^~+*/-] { return yytext[0]; } [}{;:\[\],()#=.@&!?<>%|^~+*/-] { return yytext[0]; }
\" { BEGIN(CSTRING); } \" { BEGIN(CSTRING); }
<CSTRING>\\\" { yymore(); } <CSTRING>\\\" { yymore(); }

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include <cassert> # include <cassert>
@ -507,6 +507,11 @@ NetEConst::~NetEConst()
void NetEConst::set_width(unsigned w) 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()); assert(w <= value_.len());
value_ = verinum(value_, w); value_ = verinum(value_, w);
expr_width(w); expr_width(w);
@ -1054,6 +1059,12 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/* /*
* $Log: netlist.cc,v $ * $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 * Revision 1.25 1999/05/13 04:02:09 steve
* More precise handling of verinum bit lengths. * 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 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
/* /*
@ -327,7 +327,7 @@ class NetMemory {
* being referenced, so can handle garbage collection. Also, this * being referenced, so can handle garbage collection. Also, this
* trick can be used to replace subexpressions. * trick can be used to replace subexpressions.
*/ */
class NetExpr { class NetExpr : public LineInfo {
public: public:
explicit NetExpr(unsigned w =0) : width_(w), reflist_(0) { } explicit NetExpr(unsigned w =0) : width_(w), reflist_(0) { }
virtual ~NetExpr() =0; virtual ~NetExpr() =0;
@ -881,15 +881,22 @@ class NetProcTop : public LineInfo {
* *
* ^ -- Bit-wise exclusive OR * ^ -- Bit-wise exclusive OR
* + -- Arithmetic add * + -- Arithmetic add
* - -- Arighmetic minus * - -- Arithmetic minus
* * -- Arithmetic multiply
* / -- Arithmetic divide
* % -- Arithmetic modulus
* & -- Bit-wise AND * & -- Bit-wise AND
* | -- Bit-wise OR * | -- Bit-wise OR
* e -- Logical equality (==) * e -- Logical equality (==)
* E -- Case equality (===) * E -- Case equality (===)
* L -- Less or equal
* G -- Greater or equal
* n -- Logical inequality (!=) * n -- Logical inequality (!=)
* N -- Case inequality (!==) * N -- Case inequality (!==)
* a -- Logical AND (&&) * a -- Logical AND (&&)
* o -- Logical OR (||) * o -- Logical OR (||)
* l -- Left shift (<<)
* r -- Right shift (>>)
*/ */
class NetEBinary : public NetExpr { class NetEBinary : public NetExpr {
@ -1178,6 +1185,12 @@ extern ostream& operator << (ostream&, NetNet::Type);
/* /*
* $Log: netlist.h,v $ * $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 * Revision 1.30 1999/05/12 04:03:19 steve
* emit NetAssignMem objects in vvm target. * 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 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "parse_misc.h" # include "parse_misc.h"
@ -61,7 +61,7 @@ extern void lex_end_table();
%token <text> IDENTIFIER PORTNAME SYSTEM_IDENTIFIER STRING %token <text> IDENTIFIER PORTNAME SYSTEM_IDENTIFIER STRING
%token <number> NUMBER %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_LOR K_LAND
%token K_always K_and K_assign K_begin K_buf K_bufif0 K_bufif1 K_case %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 %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 <gate> gate_instance
%type <gates> gate_instance_list %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 <expr> lavalue lpvalue
%type <exprs> expression_list %type <exprs> expression_list
@ -122,7 +122,9 @@ extern void lex_end_table();
%left '&' %left '&'
%left K_EQ K_NE K_CEQ K_CNE %left K_EQ K_NE K_CEQ K_CNE
%left K_GE K_LE '<' '>' %left K_GE K_LE '<' '>'
%left K_LS K_RS
%left '+' '-' %left '+' '-'
%left '*' '/' '%'
%left UNARY_PREC %left UNARY_PREC
%% %%
@ -132,11 +134,6 @@ source_file
| source_file description | source_file description
; ;
bitsel
: '[' const_expression ']'
{ $$ = $2; }
;
case_item case_item
: expression ':' statement_opt : expression ':' statement_opt
{ PCase::Item*tmp = new PCase::Item; { 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 delay
: '#' NUMBER : '#' NUMBER
{ verinum*tmp = $2; { verinum*tmp = $2;
@ -332,6 +283,15 @@ expression
| expression '^' expression | expression '^' expression
{ $$ = new PEBinary('^', $1, $3); { $$ = new PEBinary('^', $1, $3);
} }
| expression '*' expression
{ $$ = new PEBinary('*', $1, $3);
}
| expression '/' expression
{ $$ = new PEBinary('/', $1, $3);
}
| expression '%' expression
{ $$ = new PEBinary('%', $1, $3);
}
| expression '+' expression | expression '+' expression
{ $$ = new PEBinary('+', $1, $3); { $$ = new PEBinary('+', $1, $3);
} }
@ -350,12 +310,24 @@ expression
| expression '>' expression | expression '>' expression
{ $$ = new PEBinary('>', $1, $3); { $$ = 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 | expression K_EQ expression
{ $$ = new PEBinary('e', $1, $3); { $$ = new PEBinary('e', $1, $3);
} }
| expression K_CEQ expression | expression K_CEQ expression
{ $$ = new PEBinary('E', $1, $3); { $$ = 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 | expression K_NE expression
{ $$ = new PEBinary('n', $1, $3); { $$ = new PEBinary('n', $1, $3);
} }
@ -396,7 +368,10 @@ expr_primary
yyerror(@1, "XXXX No number value in primary?"); yyerror(@1, "XXXX No number value in primary?");
$$ = 0; $$ = 0;
} else { } else {
$$ = new PENumber($1); PENumber*tmp = new PENumber($1);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
} }
} }
| STRING | STRING
@ -579,9 +554,16 @@ lavalue
delete $1; delete $1;
$$ = tmp; $$ = tmp;
} }
| IDENTIFIER bitsel | IDENTIFIER '[' expression ']'
{ PEIdent*tmp = new PEIdent(*$1); { 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_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
delete $1; delete $1;
@ -623,6 +605,14 @@ lpvalue
$$ = tmp; $$ = tmp;
} }
| identifier '[' expression ':' expression ']'
{ yyerror(@1, "Sorry, part selects"
" not supported in lvalue.");
$$ = 0;
delete $1;
delete $3;
delete $5;
}
| '{' expression_list '}' | '{' expression_list '}'
{ yyerror(@1, "Sorry, concatenation expressions" { yyerror(@1, "Sorry, concatenation expressions"
" not supported in lvalue."); " not supported in lvalue.");
@ -721,14 +711,25 @@ net_type
; ;
parameter_assign parameter_assign
: IDENTIFIER '=' const_expression : IDENTIFIER '=' expression
{ pform_set_parameter(*$1, $3); { 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; delete $1;
} }
; ;
parameter_assign_list parameter_assign_list
: parameter_assign : parameter_assign
| range parameter_assign
{ yyerror(@1, "Ranges in parameter definition "
"are not supported.");
delete $1;
}
| parameter_assign_list ',' parameter_assign | parameter_assign_list ',' parameter_assign
; ;
@ -738,12 +739,25 @@ port
$$->port_type = NetNet::PIMPLICIT; $$->port_type = NetNet::PIMPLICIT;
delete $1; delete $1;
} }
| IDENTIFIER '[' const_expression ':' const_expression ']' | IDENTIFIER '[' expression ':' expression ']'
{ $$ = new PWire(*$1, NetNet::IMPLICIT); { PWire*tmp = new PWire(*$1, NetNet::IMPLICIT);
$$->port_type = NetNet::PIMPLICIT; tmp->port_type = NetNet::PIMPLICIT;
$$->msb = $3; if (!pform_expression_is_constant($3)) {
$$->lsb = $5; 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; delete $1;
$$ = tmp;
} }
| IDENTIFIER '[' error ']' | IDENTIFIER '[' error ']'
{ yyerror(@1, "invalid port bit select"); { yyerror(@1, "invalid port bit select");
@ -754,10 +768,14 @@ port
; ;
port_name port_name
: PORTNAME '(' IDENTIFIER ')' : PORTNAME '(' expression ')'
{ delete $1; { delete $1;
delete $3; delete $3;
} }
| PORTNAME '(' error ')'
{ yyerror(@3, "invalid port connection expression.");
delete $1;
}
| PORTNAME '(' ')' | PORTNAME '(' ')'
{ delete $1; { delete $1;
} }
@ -775,10 +793,20 @@ port_type
; ;
range range
: '[' const_expression ':' const_expression ']' : '[' expression ':' expression ']'
{ svector<PExpr*>*tmp = new svector<PExpr*> (2); { svector<PExpr*>*tmp = new svector<PExpr*> (2);
(*tmp)[0] = $2; if (!pform_expression_is_constant($2)) {
(*tmp)[1] = $4; 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; $$ = tmp;
} }
; ;
@ -798,8 +826,12 @@ register_variable
{ pform_makewire(*$1, NetNet::REG); { pform_makewire(*$1, NetNet::REG);
$$ = $1; $$ = $1;
} }
| IDENTIFIER '[' const_expression ':' const_expression ']' | IDENTIFIER '[' expression ':' expression ']'
{ pform_makewire(*$1, NetNet::REG); { 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); pform_set_reg_idx(*$1, $3, $5);
$$ = $1; $$ = $1;
} }

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "pform.h" # include "pform.h"
@ -82,6 +82,11 @@ void pform_endmodule(const string&name)
cur_module = 0; 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, void pform_make_udp(string*name, list<string>*parms,
list<PWire*>*decl, list<string>*table, list<PWire*>*decl, list<string>*table,
Statement*init_expr) Statement*init_expr)
@ -421,13 +426,6 @@ void pform_set_parameter(const string&name, PExpr*expr)
cur_module->parameters[name] = 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) void pform_set_port_type(list<string>*names, NetNet::PortType pt)
{ {
for (list<string>::const_iterator cur = names->begin() 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 $ * $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 * Revision 1.17 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator * Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*> * 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 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "netlist.h" # 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, extern void pform_set_type_attrib(const string&name, const string&key,
const string&value); const string&value);
extern void pform_set_parameter(const string&name, PExpr*expr); 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 PProcess* pform_make_behavior(PProcess::Type, Statement*);
extern Statement* pform_make_block(PBlock::BL_TYPE, list<Statement*>*); extern Statement* pform_make_block(PBlock::BL_TYPE, list<Statement*>*);
extern Statement* pform_make_calltask(string*t, svector<PExpr*>* =0); extern Statement* pform_make_calltask(string*t, svector<PExpr*>* =0);
extern list<PWire*>* pform_make_udp_input_ports(list<string>*); 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 * The makegate function creates a new gate (which need not have a
* name) and connects it to the specified wires. * name) and connects it to the specified wires.
@ -139,6 +140,12 @@ extern void pform_dump(ostream&out, Module*mod);
/* /*
* $Log: pform.h,v $ * $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 * Revision 1.13 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator * Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*> * in structural contexts, Replace vector<PExpr*>