Add support for disable fork to the compiler.

This commit is contained in:
Cary R 2013-10-17 19:33:57 -07:00
parent 1cd72d375c
commit c64b8900ca
8 changed files with 65 additions and 14 deletions

View File

@ -1036,8 +1036,10 @@ void NetDeassign::dump(ostream&o, unsigned ind) const
void NetDisable::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "disable " << scope_path(target_) << "; "
<< "/* " << get_fileline() << " */" << endl;
o << setw(ind) << "" << "disable ";
if (target_) o << scope_path(target_);
else o << "fork";
o << "; " << "/* " << get_fileline() << " */" << endl;
}
void NetDoWhile::dump(ostream&o, unsigned ind) const

View File

@ -3713,6 +3713,22 @@ NetProc* PDisable::elaborate(Design*des, NetScope*scope) const
{
assert(scope);
/* If the disable scope_ is empty then this is a SystemVerilog
* disable fork statement. */
if (scope_.empty()) {
if (gn_system_verilog()) {
NetDisable*obj = new NetDisable(0);
obj->set_line(*this);
return obj;
} else {
cerr << get_fileline()
<< ": error: 'disable fork' requires SystemVerilog."
<< endl;
des->errors += 1;
return 0;
}
}
list<hname_t> spath = eval_scope_path(des, scope, scope_);
NetScope*target = des->find_scope(scope, spath);

View File

@ -5594,6 +5594,12 @@ statement_item /* This is roughly statement_item in the LRM */
delete $2;
$$ = tmp;
}
| K_disable K_fork ';'
{ pform_name_t tmp_name;
PDisable*tmp = new PDisable(tmp_name);
FILE_NAME(tmp, @1);
$$ = tmp;
}
| K_TRIGGER hierarchy_identifier ';'
{ PTrigger*tmp = new PTrigger(*$2);
FILE_NAME(tmp, @1);

View File

@ -841,8 +841,10 @@ void PDelayStatement::dump(ostream&out, unsigned ind) const
void PDisable::dump(ostream&out, unsigned ind) const
{
out << setw(ind) << "" << "disable " << scope_ << "; /* "
<< get_fileline() << " */" << endl;
out << setw(ind) << "" << "disable ";
if (scope_.empty()) out << scope_;
else out << "fork";
out << "; /* " << get_fileline() << " */" << endl;
}
void PDoWhile::dump(ostream&out, unsigned ind) const

View File

@ -613,7 +613,11 @@ bool dll_target::proc_disable(const NetDisable*net)
FILE_NAME(stmt_cur_, net);
stmt_cur_->type_ = IVL_ST_DISABLE;
stmt_cur_->u_.disable_.scope = lookup_scope_(net->target());
const NetScope* dis_scope = net->target();
/* A normal disable. */
if (dis_scope) stmt_cur_->u_.disable_.scope = lookup_scope_(dis_scope);
/* A SystemVerilog disable fork. */
else stmt_cur_->u_.disable_.scope = 0;
return true;
}

View File

@ -156,7 +156,11 @@ static void show_stmt_delayx(ivl_statement_t net, unsigned ind)
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));
if (scope) {
fprintf(out, "%*sdisable %s\n", ind, "", ivl_scope_basename(scope));
} else {
fprintf(out, "%*sdisable fork\n", ind, "");
}
}
static void show_stmt_force(ivl_statement_t net, unsigned ind)

View File

@ -1068,11 +1068,22 @@ static void emit_stmt_disable(ivl_scope_t scope, ivl_statement_t stmt)
{
ivl_scope_t disable_scope = ivl_stmt_call(stmt);
fprintf(vlog_out, "%*cdisable ", get_indent(), ' ');
/* If this disable is in a function and it is disabling the function
* then emit the appropriate function return name. */
if (func_rtn_name && is_func_disable(scope, disable_scope)) {
fprintf(vlog_out, "%s", func_rtn_name);
} else emit_scope_path(scope, disable_scope);
/* A normal disable statement. */
if (disable_scope) {
/* If this disable is in a function and it is disabling the
* function then emit the appropriate function return name. */
if (func_rtn_name && is_func_disable(scope, disable_scope)) {
fprintf(vlog_out, "%s", func_rtn_name);
} else emit_scope_path(scope, disable_scope);
/* A SystemVerilog disable fork statement cannot be converted. */
} else {
fprintf(vlog_out, "fork");
fprintf(stderr, "%s:%u: vlog95 sorry: disable fork is not "
"currently translated.\n",
ivl_stmt_file(stmt),
ivl_stmt_lineno(stmt));
vlog_errors += 1;
}
fprintf(vlog_out, ";");
emit_stmt_file_line(stmt);
fprintf(vlog_out, "\n");

View File

@ -1359,9 +1359,15 @@ static int show_stmt_disable(ivl_statement_t net, ivl_scope_t sscope)
int rc = 0;
ivl_scope_t target = ivl_stmt_call(net);
show_stmt_file_line(net, "Disable statement.");
fprintf(vvp_out, " %%disable S_%p;\n", target);
/* A normal disable statement. */
if (target) {
show_stmt_file_line(net, "Disable statement.");
fprintf(vvp_out, " %%disable S_%p;\n", target);
/* A SystemVerilog disable fork statement. */
} else {
show_stmt_file_line(net, "Disable fork statement.");
fprintf(vvp_out, " %%disable/fork;\n");
}
return rc;
}