Redo constant expression detection to happen
after parsing. Parse more operators and expressions.
This commit is contained in:
parent
c677afd8e3
commit
10ffaeda90
34
PExpr.cc
34
PExpr.cc
|
|
@ -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
19
PExpr.h
|
|
@ -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*>
|
||||||
|
|
|
||||||
14
elaborate.cc
14
elaborate.cc
|
|
@ -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*>
|
||||||
|
|
|
||||||
|
|
@ -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(); }
|
||||||
|
|
|
||||||
13
netlist.cc
13
netlist.cc
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
19
netlist.h
19
netlist.h
|
|
@ -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
170
parse.y
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
20
pform.cc
20
pform.cc
|
|
@ -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
11
pform.h
|
|
@ -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*>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue