SystemVerilog has more lax rules for function declarations.
Allow empty parameter lists Allow lists of statements instead of simple statements.
This commit is contained in:
parent
1d02f89a09
commit
f0bf64271b
1
PTask.h
1
PTask.h
|
|
@ -24,6 +24,7 @@
|
|||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include <string>
|
||||
# include <vector>
|
||||
# include <list>
|
||||
class Design;
|
||||
class NetScope;
|
||||
|
|
|
|||
|
|
@ -105,11 +105,11 @@ PBlock::PBlock(BL_TYPE t)
|
|||
|
||||
PBlock::~PBlock()
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < list_.count() ; idx += 1)
|
||||
for (unsigned idx = 0 ; idx < list_.size() ; idx += 1)
|
||||
delete list_[idx];
|
||||
}
|
||||
|
||||
void PBlock::set_statement(const svector<Statement*>&st)
|
||||
void PBlock::set_statement(const vector<Statement*>&st)
|
||||
{
|
||||
list_ = st;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
# include <string>
|
||||
# include <vector>
|
||||
# include <list>
|
||||
# include "ivl_target.h"
|
||||
# include "svector.h"
|
||||
|
|
@ -167,7 +168,7 @@ class PBlock : public PScope, public Statement {
|
|||
|
||||
BL_TYPE bl_type() const { return bl_type_; }
|
||||
|
||||
void set_statement(const svector<Statement*>&st);
|
||||
void set_statement(const std::vector<Statement*>&st);
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
|
|
@ -176,7 +177,7 @@ class PBlock : public PScope, public Statement {
|
|||
|
||||
private:
|
||||
const BL_TYPE bl_type_;
|
||||
svector<Statement*>list_;
|
||||
std::vector<Statement*>list_;
|
||||
};
|
||||
|
||||
class PCallTask : public Statement {
|
||||
|
|
|
|||
|
|
@ -1513,7 +1513,7 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
|||
elaborate_scope_events_(des, my_scope, events);
|
||||
}
|
||||
|
||||
for (unsigned idx = 0 ; idx < list_.count() ; idx += 1)
|
||||
for (unsigned idx = 0 ; idx < list_.size() ; idx += 1)
|
||||
list_[idx] -> elaborate_scope(des, my_scope);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -450,7 +450,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
|||
/* Make sure the function has at least one input port. If it
|
||||
fails this test, print an error message. Keep going so we
|
||||
can find more errors. */
|
||||
if (ports_ == 0) {
|
||||
if (ports_ == 0 && !gn_system_verilog()) {
|
||||
cerr << get_fileline() << ": error: Function " << fname
|
||||
<< " has no ports." << endl;
|
||||
cerr << get_fileline() << ": : Functions must have"
|
||||
|
|
@ -721,7 +721,7 @@ void PBlock::elaborate_sig(Design*des, NetScope*scope) const
|
|||
|
||||
// elaborate_sig in the statements included in the
|
||||
// block. There may be named blocks in there.
|
||||
for (unsigned idx = 0 ; idx < list_.count() ; idx += 1)
|
||||
for (unsigned idx = 0 ; idx < list_.size() ; idx += 1)
|
||||
list_[idx] -> elaborate_sig(des, my_scope);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2562,13 +2562,13 @@ NetProc* PBlock::elaborate(Design*des, NetScope*scope) const
|
|||
// statement. There is no need to keep the block node. Also,
|
||||
// don't elide named blocks, because they might be referenced
|
||||
// elsewhere.
|
||||
if ((list_.count() == 1) && (pscope_name() == 0)) {
|
||||
if ((list_.size() == 1) && (pscope_name() == 0)) {
|
||||
assert(list_[0]);
|
||||
NetProc*tmp = list_[0]->elaborate(des, nscope);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
for (unsigned idx = 0 ; idx < list_.count() ; idx += 1) {
|
||||
for (unsigned idx = 0 ; idx < list_.size() ; idx += 1) {
|
||||
assert(list_[idx]);
|
||||
NetProc*tmp = list_[idx]->elaborate(des, nscope);
|
||||
// If the statement fails to elaborate, then simply
|
||||
|
|
@ -3879,6 +3879,7 @@ void PFunction::elaborate(Design*des, NetScope*scope) const
|
|||
|
||||
assert(def);
|
||||
|
||||
ivl_assert(*this, statement_);
|
||||
NetProc*st = statement_->elaborate(des, scope);
|
||||
if (st == 0) {
|
||||
cerr << statement_->get_fileline() << ": error: Unable to elaborate "
|
||||
|
|
|
|||
88
parse.y
88
parse.y
|
|
@ -310,7 +310,7 @@ static long check_enum_seq_value(const YYLTYPE&loc, verinum *arg, bool zero_ok)
|
|||
|
||||
PEventStatement*event_statement;
|
||||
Statement*statement;
|
||||
svector<Statement*>*statement_list;
|
||||
vector<Statement*>*statement_list;
|
||||
|
||||
PTaskFuncArg function_type;
|
||||
|
||||
|
|
@ -454,7 +454,7 @@ static long check_enum_seq_value(const YYLTYPE&loc, verinum *arg, bool zero_ok)
|
|||
%type <enum_type> enum_data_type
|
||||
|
||||
%type <wires> task_item task_item_list task_item_list_opt
|
||||
%type <wires> task_port_item task_port_decl task_port_decl_list
|
||||
%type <wires> task_port_item task_port_decl task_port_decl_list task_port_decl_list_opt
|
||||
%type <wires> function_item function_item_list
|
||||
|
||||
%type <named_pexpr> port_name parameter_value_byname
|
||||
|
|
@ -1651,6 +1651,16 @@ expr_primary
|
|||
delete[]$1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| hierarchy_identifier '(' ')'
|
||||
{ const vector<PExpr*> empty;
|
||||
PECallFunction*tmp = new PECallFunction(*$1, empty);
|
||||
FILE_NAME(tmp, @1);
|
||||
delete $1;
|
||||
$$ = tmp;
|
||||
if (!gn_system_verilog()) {
|
||||
yyerror(@1, "error: Empty function argument list requires SystemVerilog.");
|
||||
}
|
||||
}
|
||||
|
||||
/* Many of the VAMS built-in functions are available as builtin
|
||||
functions with $system_function equivalents. */
|
||||
|
|
@ -2854,11 +2864,24 @@ module_item
|
|||
{ assert(current_function == 0);
|
||||
current_function = pform_push_function_scope(@1, $4, $2);
|
||||
}
|
||||
function_item_list statement
|
||||
function_item_list statement_list
|
||||
K_endfunction
|
||||
{ current_function->set_ports($7);
|
||||
current_function->set_statement($8);
|
||||
current_function->set_return($3);
|
||||
assert($8 && $8->size() > 0);
|
||||
if ($8->size() == 1) {
|
||||
current_function->set_statement((*$8)[0]);
|
||||
delete $8;
|
||||
} else {
|
||||
PBlock*tmp = new PBlock(PBlock::BL_SEQ);
|
||||
FILE_NAME(tmp, @8);
|
||||
tmp->set_statement( *$8 );
|
||||
current_function->set_statement(tmp);
|
||||
delete $8;
|
||||
if (!gn_system_verilog()) {
|
||||
yyerror(@8, "error: Function body with multiple statements requres SystemVerilog.");
|
||||
}
|
||||
}
|
||||
pform_pop_scope();
|
||||
current_function = 0;
|
||||
delete[]$4;
|
||||
|
|
@ -2868,20 +2891,42 @@ module_item
|
|||
{ assert(current_function == 0);
|
||||
current_function = pform_push_function_scope(@1, $4, $2);
|
||||
}
|
||||
'(' task_port_decl_list ')' ';'
|
||||
'(' task_port_decl_list_opt ')' ';'
|
||||
block_item_decls_opt
|
||||
statement
|
||||
statement_list
|
||||
K_endfunction
|
||||
{ current_function->set_ports($7);
|
||||
current_function->set_statement($11);
|
||||
current_function->set_return($3);
|
||||
assert($11 && $11->size() > 0);
|
||||
if ($11->size() == 1) {
|
||||
current_function->set_statement((*$11)[0]);
|
||||
delete $11;
|
||||
} else {
|
||||
PBlock*tmp = new PBlock(PBlock::BL_SEQ);
|
||||
FILE_NAME(tmp, @11);
|
||||
tmp->set_statement( *$11 );
|
||||
current_function->set_statement(tmp);
|
||||
delete $11;
|
||||
if (!gn_system_verilog()) {
|
||||
yyerror(@11, "error: Function body with multiple statements requres SystemVerilog.");
|
||||
}
|
||||
}
|
||||
pform_pop_scope();
|
||||
current_function = 0;
|
||||
delete[]$4;
|
||||
if ($7==0 && !gn_system_verilog()) {
|
||||
yyerror(@7, "error: Empty parenthesis syntax requires SystemVerilog.");
|
||||
}
|
||||
}
|
||||
| K_function automatic_opt function_range_or_type_opt IDENTIFIER error K_endfunction
|
||||
{
|
||||
{ /* */
|
||||
if (current_function) {
|
||||
pform_pop_scope();
|
||||
current_function = 0;
|
||||
}
|
||||
assert(current_function == 0);
|
||||
yyerror(@1, "error: Syntax error defining function.");
|
||||
yyerrok;
|
||||
delete[]$4;
|
||||
}
|
||||
|
||||
|
|
@ -4582,17 +4627,17 @@ compressed_statement
|
|||
;
|
||||
|
||||
statement_list
|
||||
: statement_list statement
|
||||
{ svector<Statement*>*tmp = new svector<Statement*>(*$1, $2);
|
||||
delete $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| statement
|
||||
{ svector<Statement*>*tmp = new svector<Statement*>(1);
|
||||
(*tmp)[0] = $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
: statement_list statement
|
||||
{ vector<Statement*>*tmp = $1;
|
||||
tmp->push_back($2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| statement
|
||||
{ vector<Statement*>*tmp = new vector<Statement*>(1);
|
||||
tmp->at(0) = $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
statement_or_null
|
||||
: statement
|
||||
|
|
@ -5007,6 +5052,11 @@ task_port_decl
|
|||
}
|
||||
;
|
||||
|
||||
task_port_decl_list_opt
|
||||
: task_port_decl_list { $$ = $1; }
|
||||
| { $$ = 0; }
|
||||
;
|
||||
|
||||
task_port_decl_list
|
||||
: task_port_decl_list ',' task_port_decl
|
||||
{ svector<PWire*>*tmp = new svector<PWire*>(*$1, *$3);
|
||||
|
|
|
|||
|
|
@ -591,7 +591,7 @@ void PBlock::dump(ostream&out, unsigned ind) const
|
|||
dump_wires_(out, ind+2);
|
||||
}
|
||||
|
||||
for (unsigned idx = 0 ; idx < list_.count() ; idx += 1) {
|
||||
for (unsigned idx = 0 ; idx < list_.size() ; idx += 1) {
|
||||
if (list_[idx])
|
||||
list_[idx]->dump(out, ind+2);
|
||||
else
|
||||
|
|
|
|||
Loading…
Reference in New Issue