Support SystemVerilog size cast.
This commit is contained in:
parent
873a447b5c
commit
557e331ce1
9
PExpr.cc
9
PExpr.cc
|
|
@ -98,6 +98,15 @@ bool PEBinary::has_aa_term(Design*des, NetScope*scope) const
|
|||
return left_->has_aa_term(des, scope) || right_->has_aa_term(des, scope);
|
||||
}
|
||||
|
||||
PECastSize::PECastSize(unsigned si, PExpr*b)
|
||||
: size_(si), base_(b)
|
||||
{
|
||||
}
|
||||
|
||||
PECastSize::~PECastSize()
|
||||
{
|
||||
}
|
||||
|
||||
PEBComp::PEBComp(char op, PExpr*l, PExpr*r)
|
||||
: PEBinary(op, l, r)
|
||||
{
|
||||
|
|
|
|||
23
PExpr.h
23
PExpr.h
|
|
@ -706,6 +706,29 @@ class PECallFunction : public PExpr {
|
|||
width_mode_t&mode);
|
||||
};
|
||||
|
||||
/*
|
||||
* Support the SystemVerilog cast to size.
|
||||
*/
|
||||
class PECastSize : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PECastSize(unsigned expr_wid, PExpr*base);
|
||||
~PECastSize();
|
||||
|
||||
void dump(ostream &out) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
|
||||
private:
|
||||
unsigned size_;
|
||||
PExpr* base_;
|
||||
};
|
||||
|
||||
/*
|
||||
* This class is used for error recovery. All methods do nothing and return
|
||||
* null or default values.
|
||||
|
|
|
|||
20
elab_expr.cc
20
elab_expr.cc
|
|
@ -1423,6 +1423,26 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned PECastSize::test_width(Design*des, NetScope*scope, width_mode_t&)
|
||||
{
|
||||
expr_width_ = size_;
|
||||
|
||||
width_mode_t tmp_mode = PExpr::SIZED;
|
||||
base_->test_width(des, scope, tmp_mode);
|
||||
|
||||
return size_;
|
||||
}
|
||||
|
||||
NetExpr* PECastSize::elaborate_expr(Design*des, NetScope*scope,
|
||||
unsigned, unsigned) const
|
||||
{
|
||||
NetExpr*sub = base_->elaborate_expr(des, scope, base_->expr_width(), NO_FLAGS);
|
||||
NetESelect*sel = new NetESelect(sub, 0, size_);
|
||||
sel->set_line(*this);
|
||||
|
||||
return sel;
|
||||
}
|
||||
|
||||
unsigned PEConcat::test_width(Design*des, NetScope*scope, width_mode_t&)
|
||||
{
|
||||
expr_width_ = 0;
|
||||
|
|
|
|||
|
|
@ -688,6 +688,8 @@ TU [munpf]
|
|||
<< endl;
|
||||
error_count += 1; }
|
||||
|
||||
. { return yytext[0]; }
|
||||
|
||||
/* Final catchall. something got lost or mishandled. */
|
||||
/* XXX Should we tell the user something about the lexical state? */
|
||||
|
||||
|
|
|
|||
113
parse.y
113
parse.y
|
|
@ -1600,29 +1600,29 @@ expression_list_proper
|
|||
;
|
||||
|
||||
expr_primary
|
||||
: number
|
||||
{ assert($1);
|
||||
PENumber*tmp = new PENumber($1);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| REALTIME
|
||||
{ PEFNumber*tmp = new PEFNumber($1);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| STRING
|
||||
{ PEString*tmp = new PEString($1);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| SYSTEM_IDENTIFIER
|
||||
{ perm_string tn = lex_strings.make($1);
|
||||
PECallFunction*tmp = new PECallFunction(tn);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
delete[]$1;
|
||||
}
|
||||
: number
|
||||
{ assert($1);
|
||||
PENumber*tmp = new PENumber($1);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| REALTIME
|
||||
{ PEFNumber*tmp = new PEFNumber($1);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| STRING
|
||||
{ PEString*tmp = new PEString($1);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| SYSTEM_IDENTIFIER
|
||||
{ perm_string tn = lex_strings.make($1);
|
||||
PECallFunction*tmp = new PECallFunction(tn);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
delete[]$1;
|
||||
}
|
||||
|
||||
/* The hierarchy_identifier rule matches simple identifiers as well as
|
||||
indexed arrays and part selects */
|
||||
|
|
@ -1836,35 +1836,50 @@ expr_primary
|
|||
|
||||
/* Parenthesized expressions are primaries. */
|
||||
|
||||
| '(' expr_mintypmax ')'
|
||||
{ $$ = $2; }
|
||||
| '(' expr_mintypmax ')'
|
||||
{ $$ = $2; }
|
||||
|
||||
/* Various kinds of concatenation expressions. */
|
||||
|
||||
| '{' expression_list_proper '}'
|
||||
{ PEConcat*tmp = new PEConcat(*$2);
|
||||
FILE_NAME(tmp, @1);
|
||||
delete $2;
|
||||
$$ = tmp;
|
||||
}
|
||||
| '{' expression '{' expression_list_proper '}' '}'
|
||||
{ PExpr*rep = $2;
|
||||
PEConcat*tmp = new PEConcat(*$4, rep);
|
||||
FILE_NAME(tmp, @1);
|
||||
delete $4;
|
||||
$$ = tmp;
|
||||
}
|
||||
| '{' expression '{' expression_list_proper '}' error '}'
|
||||
{ PExpr*rep = $2;
|
||||
PEConcat*tmp = new PEConcat(*$4, rep);
|
||||
FILE_NAME(tmp, @1);
|
||||
delete $4;
|
||||
$$ = tmp;
|
||||
yyerror(@5, "error: Syntax error between internal '}' "
|
||||
"and closing '}' of repeat concatenation.");
|
||||
yyerrok;
|
||||
}
|
||||
;
|
||||
| '{' expression_list_proper '}'
|
||||
{ PEConcat*tmp = new PEConcat(*$2);
|
||||
FILE_NAME(tmp, @1);
|
||||
delete $2;
|
||||
$$ = tmp;
|
||||
}
|
||||
| '{' expression '{' expression_list_proper '}' '}'
|
||||
{ PExpr*rep = $2;
|
||||
PEConcat*tmp = new PEConcat(*$4, rep);
|
||||
FILE_NAME(tmp, @1);
|
||||
delete $4;
|
||||
$$ = tmp;
|
||||
}
|
||||
| '{' expression '{' expression_list_proper '}' error '}'
|
||||
{ PExpr*rep = $2;
|
||||
PEConcat*tmp = new PEConcat(*$4, rep);
|
||||
FILE_NAME(tmp, @1);
|
||||
delete $4;
|
||||
$$ = tmp;
|
||||
yyerror(@5, "error: Syntax error between internal '}' "
|
||||
"and closing '}' of repeat concatenation.");
|
||||
yyerrok;
|
||||
}
|
||||
|
||||
/* Cast expressions are primaries */
|
||||
|
||||
| DEC_NUMBER '\'' '(' expression ')'
|
||||
{ PExpr*base = $4;
|
||||
if (gn_system_verilog()) {
|
||||
PECastSize*tmp = new PECastSize($1->as_ulong(), base);
|
||||
FILE_NAME(tmp, @1);
|
||||
delete $1;
|
||||
$$ = tmp;
|
||||
} else {
|
||||
yyerror(@1, "error: Size cast requires SystemVerilog.");
|
||||
$$ = base;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
/* A function_item_list borrows the task_port_item run to match
|
||||
declarations of ports. We check later to make sure there are no
|
||||
|
|
|
|||
|
|
@ -197,6 +197,13 @@ void PECallFunction::dump(ostream &out) const
|
|||
out << ")";
|
||||
}
|
||||
|
||||
void PECastSize::dump(ostream &out) const
|
||||
{
|
||||
out << size_ << "'(";
|
||||
base_->dump(out);
|
||||
out << ")";
|
||||
}
|
||||
|
||||
void PEEvent::dump(ostream&out) const
|
||||
{
|
||||
switch (type_) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue