Elaborate fork-join_none and fork-join_any statements.

This commit is contained in:
Stephen Williams 2012-05-19 17:34:13 -07:00
parent c0f35cbe62
commit 6a57764e0e
12 changed files with 102 additions and 25 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2008,2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2008,2010,2012 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -114,6 +114,13 @@ PBlock::~PBlock()
delete list_[idx];
}
void PBlock::set_join_type(PBlock::BL_TYPE type)
{
assert(bl_type_ == BL_PAR);
assert(type == BL_JOIN_NONE || type==BL_JOIN_ANY);
bl_type_ = type;
}
void PBlock::set_statement(const vector<Statement*>&st)
{
list_ = st;

View File

@ -1,7 +1,7 @@
#ifndef __Statement_H
#define __Statement_H
/*
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2008,2012 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -165,7 +165,7 @@ class PAssignNB : public PAssign_ {
class PBlock : public PScope, public Statement {
public:
enum BL_TYPE { BL_SEQ, BL_PAR };
enum BL_TYPE { BL_SEQ, BL_PAR, BL_JOIN_NONE, BL_JOIN_ANY };
// If the block has a name, it is a scope and also has a parent.
explicit PBlock(perm_string n, LexicalScope*parent, BL_TYPE t);
@ -175,6 +175,10 @@ class PBlock : public PScope, public Statement {
BL_TYPE bl_type() const { return bl_type_; }
// If the bl_type() is BL_PAR, it is possible to replace it
// with JOIN_NONE or JOIN_ANY. This is to help the parser.
void set_join_type(BL_TYPE);
void set_statement(const std::vector<Statement*>&st);
virtual void dump(ostream&out, unsigned ind) const;
@ -183,7 +187,7 @@ class PBlock : public PScope, public Statement {
virtual void elaborate_sig(Design*des, NetScope*scope) const;
private:
const BL_TYPE bl_type_;
BL_TYPE bl_type_;
std::vector<Statement*>list_;
};

View File

@ -40,6 +40,12 @@ static ostream& operator<< (ostream&o, NetBlock::Type t)
case NetBlock::PARA:
o << "fork";
break;
case NetBlock::PARA_JOIN_NONE:
o << "fork-join_none";
break;
case NetBlock::PARA_JOIN_ANY:
o << "fork-join_any";
break;
}
return o;
}

View File

@ -1564,7 +1564,9 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
<< "Elaborate block scope " << use_name
<< " within " << scope_path(scope) << endl;
my_scope = new NetScope(scope, use_name, bl_type_==BL_PAR
// The scope type is begin-end or fork-join. The
// sub-types of fork-join are not interesting to the scope.
my_scope = new NetScope(scope, use_name, bl_type_!=BL_SEQ
? NetScope::FORK_JOIN
: NetScope::BEGIN_END);
my_scope->set_line(get_file(), get_lineno());

View File

@ -2633,9 +2633,21 @@ NetProc* PBlock::elaborate(Design*des, NetScope*scope) const
{
assert(scope);
NetBlock::Type type = (bl_type_==PBlock::BL_PAR)
? NetBlock::PARA
: NetBlock::SEQU;
NetBlock::Type type;
switch (bl_type_) {
case PBlock::BL_SEQ:
type = NetBlock::SEQU;
break;
case PBlock::BL_PAR:
type = NetBlock::PARA;
break;
case PBlock::BL_JOIN_NONE:
type = NetBlock::PARA_JOIN_NONE;
break;
case PBlock::BL_JOIN_ANY:
type = NetBlock::PARA_JOIN_ANY;
break;
}
NetScope*nscope = 0;
if (pscope_name() != 0) {

View File

@ -1,7 +1,7 @@
#ifndef __ivl_target_H
#define __ivl_target_H
/*
* Copyright (c) 2000-2011 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2012 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -406,6 +406,8 @@ typedef enum ivl_statement_type_e {
IVL_ST_FORCE = 14,
IVL_ST_FOREVER = 15,
IVL_ST_FORK = 16,
IVL_ST_FORK_JOIN_ANY = 28,
IVL_ST_FORK_JOIN_NONE = 29,
IVL_ST_FREE = 26,
IVL_ST_RELEASE = 17,
IVL_ST_REPEAT = 18,
@ -2069,11 +2071,11 @@ extern unsigned ivl_stmt_lineno(ivl_statement_t net);
* triggers. The statement waits even if the sub-statement is nul.
*/
/* IVL_ST_BLOCK, IVL_ST_FORK */
/* IVL_ST_BLOCK, IVL_ST_FORK, IVL_ST_FORK_JOIN_ANY, IVL_ST_FORK_JOIN_NONE */
extern unsigned ivl_stmt_block_count(ivl_statement_t net);
/* IVL_ST_BLOCK, IVL_ST_FORK */
/* IVL_ST_BLOCK, IVL_ST_FORK, IVL_ST_FORK_JOIN_ANY, IVL_ST_FORK_JOIN_NONE */
extern ivl_scope_t ivl_stmt_block_scope(ivl_statement_t net);
/* IVL_ST_BLOCK, IVL_ST_FORK */
/* IVL_ST_BLOCK, IVL_ST_FORK, IVL_ST_FORK_JOIN_ANY, IVL_ST_FORK_JOIN_NONE */
extern ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net, unsigned i);
/* IVL_ST_UTASK IVL_ST_DISABLE */
extern ivl_scope_t ivl_stmt_call(ivl_statement_t net);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2011 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2012 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -257,7 +257,7 @@ NexusSet* NetBlock::nex_input(bool rem_out)
if (last_ == 0)
return new NexusSet;
if (type_ == PARA) {
if (type_ != SEQU) {
cerr << get_fileline() << ": internal error: Sorry, "
<< "I don't know how to synthesize fork/join blocks."
<< endl;

View File

@ -2491,7 +2491,7 @@ class NetAssignNB : public NetAssignBase {
class NetBlock : public NetProc {
public:
enum Type { SEQU, PARA };
enum Type { SEQU, PARA, PARA_JOIN_ANY, PARA_JOIN_NONE };
NetBlock(Type t, NetScope*subscope);
~NetBlock();

13
parse.y
View File

@ -356,6 +356,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
PGBuiltin::Type gatetype;
NetNet::PortType porttype;
ivl_variable_type_t vartype;
PBlock::BL_TYPE join_keyword;
PWire*wire;
svector<PWire*>*wires;
@ -574,6 +575,8 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
%type <statement> analog_statement
%type <join_keyword> join_keyword
%type <letter> spec_polarity
%type <perm_strings> specify_path_identifiers
@ -1084,10 +1087,11 @@ integer_vector_type /* IEEE1800-2005: A.2.2.1 */
join_keyword /* IEEE1800-2005: A.6.3 */
: K_join
{ $$ = PBlock::BL_PAR; }
| K_join_none
{ yyerror(@1, "sorry: join_none not supported."); }
{ $$ = PBlock::BL_JOIN_NONE; }
| K_join_any
{ yyerror(@1, "sorry: join_any not supported."); }
{ $$ = PBlock::BL_JOIN_ANY; }
;
jump_statement /* IEEE1800-2005: A.6.5 */
@ -5335,12 +5339,12 @@ statement_item /* This is roughly statement_item in the LRM */
code generator can do the right thing. */
| K_fork join_keyword
{ PBlock*tmp = new PBlock(PBlock::BL_PAR);
{ PBlock*tmp = new PBlock($2);
FILE_NAME(tmp, @1);
$$ = tmp;
}
| K_fork statement_or_null_list join_keyword
{ PBlock*tmp = new PBlock(PBlock::BL_PAR);
{ PBlock*tmp = new PBlock($3);
FILE_NAME(tmp, @1);
tmp->set_statement(*$2);
delete $2;
@ -5357,6 +5361,7 @@ statement_item /* This is roughly statement_item in the LRM */
assert(! current_block_stack.empty());
PBlock*tmp = current_block_stack.top();
current_block_stack.pop();
tmp->set_join_type($7);
if ($6) tmp->set_statement(*$6);
delete[]$3;
delete $6;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2011 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2012 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -2271,6 +2271,8 @@ extern "C" ivl_scope_t ivl_stmt_block_scope(ivl_statement_t net)
switch (net->type_) {
case IVL_ST_BLOCK:
case IVL_ST_FORK:
case IVL_ST_FORK_JOIN_ANY:
case IVL_ST_FORK_JOIN_NONE:
return net->u_.block_.scope;
default:
assert(0);
@ -2283,6 +2285,8 @@ extern "C" unsigned ivl_stmt_block_count(ivl_statement_t net)
switch (net->type_) {
case IVL_ST_BLOCK:
case IVL_ST_FORK:
case IVL_ST_FORK_JOIN_ANY:
case IVL_ST_FORK_JOIN_NONE:
return net->u_.block_.nstmt_;
default:
assert(0);
@ -2296,6 +2300,8 @@ extern "C" ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net,
switch (net->type_) {
case IVL_ST_BLOCK:
case IVL_ST_FORK:
case IVL_ST_FORK_JOIN_ANY:
case IVL_ST_FORK_JOIN_NONE:
return net->u_.block_.stmt_ + i;
default:
assert(0);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2011 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2012 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -386,9 +386,20 @@ bool dll_target::proc_block(const NetBlock*net)
it, so fill in the block fields of the existing statement,
and generate the contents for the statement array. */
stmt_cur_->type_ = (net->type() == NetBlock::SEQU)
? IVL_ST_BLOCK
: IVL_ST_FORK;
switch (net->type()) {
case NetBlock::SEQU:
stmt_cur_->type_ = IVL_ST_BLOCK;
break;
case NetBlock::PARA:
stmt_cur_->type_ = IVL_ST_FORK;
break;
case NetBlock::PARA_JOIN_ANY:
stmt_cur_->type_ = IVL_ST_FORK_JOIN_ANY;
break;
case NetBlock::PARA_JOIN_NONE:
stmt_cur_->type_ = IVL_ST_FORK_JOIN_NONE;
break;
}
stmt_cur_->u_.block_.nstmt_ = count;
stmt_cur_->u_.block_.stmt_ = (struct ivl_statement_s*)
calloc(count, sizeof(struct ivl_statement_s));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2004-2007 Stephen Williams (steve@icarus.com)
* Copyright (c) 2004-2007,2012 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -329,6 +329,28 @@ void show_statement(ivl_statement_t net, unsigned ind)
break;
}
case IVL_ST_FORK_JOIN_ANY: {
unsigned cnt = ivl_stmt_block_count(net);
fprintf(out, "%*sfork\n", ind, "");
for (idx = 0 ; idx < cnt ; idx += 1) {
ivl_statement_t cur = ivl_stmt_block_stmt(net, idx);
show_statement(cur, ind+4);
}
fprintf(out, "%*sjoin_any\n", ind, "");
break;
}
case IVL_ST_FORK_JOIN_NONE: {
unsigned cnt = ivl_stmt_block_count(net);
fprintf(out, "%*sfork\n", ind, "");
for (idx = 0 ; idx < cnt ; idx += 1) {
ivl_statement_t cur = ivl_stmt_block_stmt(net, idx);
show_statement(cur, ind+4);
}
fprintf(out, "%*sjoin_none\n", ind, "");
break;
}
case IVL_ST_FREE:
fprintf(out, "%*sfree automatic storage ...\n", ind, "");
break;