mirror of
https://github.com/steveicarus/iverilog.git
synced 2026-08-22 05:47:31 +02:00
Parse more constant expressions.
This commit is contained in:
@@ -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.11 1999/03/16 04:44:45 steve Exp $"
|
#ident "$Id: lexor.lex,v 1.12 1999/05/06 04:09:28 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//# define YYSTYPE lexval
|
//# define YYSTYPE lexval
|
||||||
@@ -44,6 +44,10 @@ static verinum*make_sized_binary(const char*txt);
|
|||||||
static verinum*make_sized_dec(const char*txt);
|
static verinum*make_sized_dec(const char*txt);
|
||||||
static verinum*make_sized_octal(const char*txt);
|
static verinum*make_sized_octal(const char*txt);
|
||||||
static verinum*make_sized_hex(const char*txt);
|
static verinum*make_sized_hex(const char*txt);
|
||||||
|
static verinum*make_unsized_binary(const char*txt);
|
||||||
|
static verinum*make_unsized_dec(const char*txt);
|
||||||
|
static verinum*make_unsized_octal(const char*txt);
|
||||||
|
static verinum*make_unsized_hex(const char*txt);
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@@ -73,7 +77,7 @@ static verinum*make_sized_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(); }
|
||||||
@@ -130,6 +134,11 @@ static verinum*make_sized_hex(const char*txt);
|
|||||||
[0-9][0-9_]*\'[hH][0-9a-fA-Fxz_]+ { yylval.number = make_sized_hex(yytext);
|
[0-9][0-9_]*\'[hH][0-9a-fA-Fxz_]+ { yylval.number = make_sized_hex(yytext);
|
||||||
return NUMBER; }
|
return NUMBER; }
|
||||||
|
|
||||||
|
\'[bB][0-1xz_]+ { yylval.number = make_unsized_binary(yytext); return NUMBER; }
|
||||||
|
\'[oO][0-7xz_]+ { yylval.number = make_unsized_octal(yytext); return NUMBER; }
|
||||||
|
\'[hH][0-9a-fA-Fxz_]+ { yylval.number = make_unsized_hex(yytext);
|
||||||
|
return NUMBER; }
|
||||||
|
|
||||||
[0-9][0-9_]* {
|
[0-9][0-9_]* {
|
||||||
/* Handle the special case of the unsized decimal number. */
|
/* Handle the special case of the unsized decimal number. */
|
||||||
unsigned long value = 0;
|
unsigned long value = 0;
|
||||||
@@ -298,18 +307,13 @@ static int check_identifier(const char*name)
|
|||||||
return IDENTIFIER;
|
return IDENTIFIER;
|
||||||
}
|
}
|
||||||
|
|
||||||
static verinum*make_sized_binary(const char*txt)
|
static verinum*make_binary_with_size(unsigned size, const char*ptr)
|
||||||
{
|
{
|
||||||
char*ptr;
|
|
||||||
unsigned size = strtoul(txt,&ptr,10);
|
|
||||||
assert(*ptr == '\'');
|
|
||||||
ptr += 1;
|
|
||||||
assert(tolower(*ptr) == 'b');
|
assert(tolower(*ptr) == 'b');
|
||||||
|
|
||||||
verinum::V*bits = new verinum::V[size];
|
verinum::V*bits = new verinum::V[size];
|
||||||
|
|
||||||
unsigned idx = 0;
|
unsigned idx = 0;
|
||||||
char*eptr = ptr + strlen(ptr) - 1;
|
const char*eptr = ptr + strlen(ptr) - 1;
|
||||||
while ((eptr > ptr) && (idx < size)) {
|
while ((eptr > ptr) && (idx < size)) {
|
||||||
|
|
||||||
if (*eptr == '_') {
|
if (*eptr == '_') {
|
||||||
@@ -336,7 +340,6 @@ static verinum*make_sized_binary(const char*txt)
|
|||||||
|
|
||||||
eptr -= 1;
|
eptr -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zero-extend binary number, except that z or x is extended
|
// Zero-extend binary number, except that z or x is extended
|
||||||
// if it is the highest supplied digit.
|
// if it is the highest supplied digit.
|
||||||
while (idx < size) {
|
while (idx < size) {
|
||||||
@@ -359,6 +362,24 @@ static verinum*make_sized_binary(const char*txt)
|
|||||||
return new verinum(bits, size);
|
return new verinum(bits, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static verinum*make_sized_binary(const char*txt)
|
||||||
|
{
|
||||||
|
char*ptr;
|
||||||
|
unsigned size = strtoul(txt,&ptr,10);
|
||||||
|
assert(*ptr == '\'');
|
||||||
|
ptr += 1;
|
||||||
|
assert(tolower(*ptr) == 'b');
|
||||||
|
|
||||||
|
return make_binary_with_size(size, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static verinum*make_unsized_binary(const char*txt)
|
||||||
|
{
|
||||||
|
assert(*txt == '\'');
|
||||||
|
txt += 1;
|
||||||
|
return make_binary_with_size(64, txt);
|
||||||
|
}
|
||||||
|
|
||||||
static verinum*make_sized_octal(const char*txt)
|
static verinum*make_sized_octal(const char*txt)
|
||||||
{
|
{
|
||||||
char*ptr;
|
char*ptr;
|
||||||
@@ -410,6 +431,11 @@ static verinum*make_sized_octal(const char*txt)
|
|||||||
return new verinum(bits, size);
|
return new verinum(bits, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static verinum*make_unsized_octal(const char*txt)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
static verinum*make_sized_hex(const char*txt)
|
static verinum*make_sized_hex(const char*txt)
|
||||||
{
|
{
|
||||||
char*ptr;
|
char*ptr;
|
||||||
@@ -479,6 +505,11 @@ static verinum*make_sized_hex(const char*txt)
|
|||||||
return new verinum(bits, size);
|
return new verinum(bits, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static verinum*make_unsized_hex(const char*txt)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Making a deciman number is much easier then the other base numbers
|
* Making a deciman number is much easier then the other base numbers
|
||||||
* because there are no z or x values to worry about.
|
* because there are no z or x values to worry about.
|
||||||
|
|||||||
@@ -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.20 1999/05/05 03:27:15 steve Exp $"
|
#ident "$Id: parse.y,v 1.21 1999/05/06 04:09:28 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "parse_misc.h"
|
# include "parse_misc.h"
|
||||||
@@ -170,6 +170,10 @@ 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
|
const_expression
|
||||||
: NUMBER
|
: NUMBER
|
||||||
{ verinum*tmp = $1;
|
{ verinum*tmp = $1;
|
||||||
@@ -184,6 +188,23 @@ const_expression
|
|||||||
{ $$ = new PEString(*$1);
|
{ $$ = new PEString(*$1);
|
||||||
delete $1;
|
delete $1;
|
||||||
}
|
}
|
||||||
|
| 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
|
||||||
|
{ $$ = new PEBinary('-', $1, $3);
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
delay
|
delay
|
||||||
@@ -277,6 +298,10 @@ expression
|
|||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
| '(' expression ')'
|
| '(' expression ')'
|
||||||
{ $$ = $2; }
|
{ $$ = $2; }
|
||||||
|
| '{' expression_list '}'
|
||||||
|
{ yyerror(@1, "Sorry, concatenation operator not supported.");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
| '~' expression %prec UNARY_PREC
|
| '~' expression %prec UNARY_PREC
|
||||||
{ $$ = new PEUnary('~', $2);
|
{ $$ = new PEUnary('~', $2);
|
||||||
}
|
}
|
||||||
@@ -507,8 +532,16 @@ list_of_variables
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
/* An lvalue is the expression that can go on the left side of an
|
||||||
|
assignment. This rule handles only procedural assignments. */
|
||||||
lvalue
|
lvalue
|
||||||
: identifier { $$ = $1; }
|
: identifier { $$ = $1; }
|
||||||
|
| identifier '[' expression ']'
|
||||||
|
{ yyerror(@2, "Sorry, bit/memory selects "
|
||||||
|
"not supported in lvalue.");
|
||||||
|
$$ = $1;
|
||||||
|
delete $3;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
module
|
module
|
||||||
|
|||||||
@@ -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.12 1999/05/02 23:25:32 steve Exp $"
|
#ident "$Id: pform.cc,v 1.13 1999/05/06 04:09:28 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "pform.h"
|
# include "pform.h"
|
||||||
@@ -426,8 +426,14 @@ static void pform_set_net_range(const string&name, list<PExpr*>*range)
|
|||||||
PExpr*msb = *idx;
|
PExpr*msb = *idx;
|
||||||
idx ++;
|
idx ++;
|
||||||
PExpr*lsb = *idx;
|
PExpr*lsb = *idx;
|
||||||
if (! (cur->msb->is_the_same(msb) && cur->lsb->is_the_same(lsb)))
|
if (msb == 0) {
|
||||||
|
VLerror(yylloc, "failed to parse msb of range.");
|
||||||
|
} else if (lsb == 0) {
|
||||||
|
VLerror(yylloc, "failed to parse lsb of range.");
|
||||||
|
} else if (! (cur->msb->is_the_same(msb) &&
|
||||||
|
cur->lsb->is_the_same(lsb))) {
|
||||||
VLerror(yylloc, "net ranges are not identical.");
|
VLerror(yylloc, "net ranges are not identical.");
|
||||||
|
}
|
||||||
delete msb;
|
delete msb;
|
||||||
delete lsb;
|
delete lsb;
|
||||||
}
|
}
|
||||||
@@ -438,6 +444,13 @@ 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()
|
||||||
@@ -535,6 +548,9 @@ int pform_parse(const char*path, map<string,Module*>&modules,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pform.cc,v $
|
* $Log: pform.cc,v $
|
||||||
|
* Revision 1.13 1999/05/06 04:09:28 steve
|
||||||
|
* Parse more constant expressions.
|
||||||
|
*
|
||||||
* Revision 1.12 1999/05/02 23:25:32 steve
|
* Revision 1.12 1999/05/02 23:25:32 steve
|
||||||
* Enforce module instance names.
|
* Enforce module instance names.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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.9 1999/04/19 01:59:37 steve Exp $"
|
#ident "$Id: pform.h,v 1.10 1999/05/06 04:09:28 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
@@ -107,6 +107,7 @@ 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_assignment(string*t, PExpr*e);
|
extern Statement* pform_make_assignment(string*t, PExpr*e);
|
||||||
@@ -140,6 +141,9 @@ extern void pform_dump(ostream&out, Module*mod);
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pform.h,v $
|
* $Log: pform.h,v $
|
||||||
|
* Revision 1.10 1999/05/06 04:09:28 steve
|
||||||
|
* Parse more constant expressions.
|
||||||
|
*
|
||||||
* Revision 1.9 1999/04/19 01:59:37 steve
|
* Revision 1.9 1999/04/19 01:59:37 steve
|
||||||
* Add memories to the parse and elaboration phases.
|
* Add memories to the parse and elaboration phases.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user