From c64b8900ca6cfa6b2100f0d46db9ac1f23f86ffa Mon Sep 17 00:00:00 2001 From: Cary R Date: Thu, 17 Oct 2013 19:33:57 -0700 Subject: [PATCH] Add support for disable fork to the compiler. --- design_dump.cc | 6 ++++-- elaborate.cc | 16 ++++++++++++++++ parse.y | 6 ++++++ pform_dump.cc | 6 ++++-- t-dll-proc.cc | 6 +++++- tgt-stub/statement.c | 6 +++++- tgt-vlog95/stmt.c | 21 ++++++++++++++++----- tgt-vvp/vvp_process.c | 12 +++++++++--- 8 files changed, 65 insertions(+), 14 deletions(-) diff --git a/design_dump.cc b/design_dump.cc index 77a4aa662..5fff01054 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -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 diff --git a/elaborate.cc b/elaborate.cc index 2e1ba1895..c90ca3421 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -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 spath = eval_scope_path(des, scope, scope_); NetScope*target = des->find_scope(scope, spath); diff --git a/parse.y b/parse.y index cb773627c..606dc2deb 100644 --- a/parse.y +++ b/parse.y @@ -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); diff --git a/pform_dump.cc b/pform_dump.cc index 18299c434..d0426e136 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -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 diff --git a/t-dll-proc.cc b/t-dll-proc.cc index 18c8ab3a1..449cb4326 100644 --- a/t-dll-proc.cc +++ b/t-dll-proc.cc @@ -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; } diff --git a/tgt-stub/statement.c b/tgt-stub/statement.c index 73f2ae2e0..2e027b559 100644 --- a/tgt-stub/statement.c +++ b/tgt-stub/statement.c @@ -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) diff --git a/tgt-vlog95/stmt.c b/tgt-vlog95/stmt.c index 5b998a53b..6a30637ee 100644 --- a/tgt-vlog95/stmt.c +++ b/tgt-vlog95/stmt.c @@ -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"); diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index fc0078499..740fc4080 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -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; }