Add support for SystemVerilog return statements.
This commit is contained in:
parent
dca6171f5f
commit
1b178d56b7
12
Statement.cc
12
Statement.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2008,2010,2012 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2008,2010,2012-2013 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -329,6 +329,16 @@ PRepeat::~PRepeat()
|
||||||
delete statement_;
|
delete statement_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PReturn::PReturn(PExpr*e)
|
||||||
|
: expr_(e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PReturn::~PReturn()
|
||||||
|
{
|
||||||
|
delete expr_;
|
||||||
|
}
|
||||||
|
|
||||||
PTrigger::PTrigger(const pform_name_t&e)
|
PTrigger::PTrigger(const pform_name_t&e)
|
||||||
: event_(e)
|
: event_(e)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
13
Statement.h
13
Statement.h
|
|
@ -462,6 +462,19 @@ class PRelease : public Statement {
|
||||||
PExpr*lval_;
|
PExpr*lval_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PReturn : public Statement {
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PReturn(PExpr*e);
|
||||||
|
~PReturn();
|
||||||
|
|
||||||
|
NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||||
|
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
PExpr*expr_;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The PTrigger statement sends a trigger to a named event. Take the
|
* The PTrigger statement sends a trigger to a named event. Take the
|
||||||
* name here.
|
* name here.
|
||||||
|
|
|
||||||
63
elaborate.cc
63
elaborate.cc
|
|
@ -4443,6 +4443,69 @@ NetProc* PRepeat::elaborate(Design*des, NetScope*scope) const
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetProc* PReturn::elaborate(Design*des, NetScope*scope) const
|
||||||
|
{
|
||||||
|
NetScope*target = scope;
|
||||||
|
for (;;) {
|
||||||
|
if (target == 0) {
|
||||||
|
cerr << get_fileline() << ": error: "
|
||||||
|
<< "Return statement is not in a function." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target->type() == NetScope::FUNC)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (target->type() == NetScope::TASK) {
|
||||||
|
cerr << get_fileline() << ": error: "
|
||||||
|
<< "Cannot \"return\" from tasks." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target->type()==NetScope::BEGIN_END) {
|
||||||
|
target = target->parent();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
cerr << get_fileline() << ": error: "
|
||||||
|
<< "Cannot \"return\" from this scope: " << scope_path(target) << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't yet support void functions, so require an
|
||||||
|
// expression for the return statement.
|
||||||
|
if (expr_ == 0) {
|
||||||
|
cerr << get_fileline() << ": error: "
|
||||||
|
<< "Return from " << scope_path(target)
|
||||||
|
<< " requires a return value expression." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetNet*res = target->find_signal(target->basename());
|
||||||
|
ivl_variable_type_t lv_type = res->data_type();
|
||||||
|
unsigned long wid = res->vector_width();
|
||||||
|
NetAssign_*lv = new NetAssign_(res);
|
||||||
|
|
||||||
|
NetExpr*val = elaborate_rval_expr(des, scope, lv_type, wid, expr_);
|
||||||
|
|
||||||
|
NetBlock*proc = new NetBlock(NetBlock::SEQU, 0);
|
||||||
|
proc->set_line( *this );
|
||||||
|
|
||||||
|
NetAssign*assn = new NetAssign(lv, val);
|
||||||
|
assn->set_line( *this );
|
||||||
|
proc->append(assn);
|
||||||
|
|
||||||
|
NetDisable*disa = new NetDisable(target);
|
||||||
|
disa->set_line( *this );
|
||||||
|
proc->append( disa );
|
||||||
|
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A task definition is elaborated by elaborating the statement that
|
* A task definition is elaborated by elaborating the statement that
|
||||||
* it contains, and connecting its ports to NetNet objects. The
|
* it contains, and connecting its ports to NetNet objects. The
|
||||||
|
|
|
||||||
10
parse.y
10
parse.y
|
|
@ -1229,12 +1229,14 @@ jump_statement /* IEEE1800-2005: A.6.5 */
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
| K_return ';'
|
| K_return ';'
|
||||||
{ yyerror(@1, "sorry: return statements not supported.");
|
{ PReturn*tmp = new PReturn(0);
|
||||||
$$ = 0;
|
FILE_NAME(tmp, @1);
|
||||||
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_return expression ';'
|
| K_return expression ';'
|
||||||
{ yyerror(@1, "sorry: return statements not supported.");
|
{ PReturn*tmp = new PReturn($2);
|
||||||
$$ = 0;
|
FILE_NAME(tmp, @1);
|
||||||
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2012 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2013 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -928,6 +928,13 @@ void PRepeat::dump(ostream&out, unsigned ind) const
|
||||||
statement_->dump(out, ind+3);
|
statement_->dump(out, ind+3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PReturn::dump(ostream&fd, unsigned ind) const
|
||||||
|
{
|
||||||
|
fd << setw(ind) << "" << "return (";
|
||||||
|
if (expr_) fd << *expr_;
|
||||||
|
fd << ")" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
void PTask::dump(ostream&out, unsigned ind) const
|
void PTask::dump(ostream&out, unsigned ind) const
|
||||||
{
|
{
|
||||||
out << setw(ind) << "" << "task ";
|
out << setw(ind) << "" << "task ";
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2004-2012 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2004-2013 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -153,6 +153,12 @@ static void show_stmt_delayx(ivl_statement_t net, unsigned ind)
|
||||||
show_statement(ivl_stmt_sub_stmt(net), ind+2);
|
show_statement(ivl_stmt_sub_stmt(net), ind+2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void show_stmt_disable(ivl_statement_t net, unsigned ind)
|
||||||
|
{
|
||||||
|
ivl_scope_t scope = ivl_stmt_call(net);
|
||||||
|
fprintf(out, "%*sdisable %s\n", ind, "", ivl_scope_basename(scope));
|
||||||
|
}
|
||||||
|
|
||||||
static void show_stmt_force(ivl_statement_t net, unsigned ind)
|
static void show_stmt_force(ivl_statement_t net, unsigned ind)
|
||||||
{
|
{
|
||||||
unsigned idx;
|
unsigned idx;
|
||||||
|
|
@ -378,6 +384,10 @@ void show_statement(ivl_statement_t net, unsigned ind)
|
||||||
show_stmt_delayx(net, ind);
|
show_stmt_delayx(net, ind);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IVL_ST_DISABLE:
|
||||||
|
show_stmt_disable(net, ind);
|
||||||
|
break;
|
||||||
|
|
||||||
case IVL_ST_FORCE:
|
case IVL_ST_FORCE:
|
||||||
show_stmt_force(net, ind);
|
show_stmt_force(net, ind);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue