diff --git a/tgt-vlog95/event.c b/tgt-vlog95/event.c index cc8b169c9..8454a3727 100644 --- a/tgt-vlog95/event.c +++ b/tgt-vlog95/event.c @@ -65,7 +65,7 @@ void emit_event(ivl_scope_t scope, ivl_statement_t stmt) if (first) first = 0; else fprintf(vlog_out, " or "); emit_scope_module_path(scope, ev_scope); - fprintf(vlog_out, "%s", ivl_event_basename(event)); + emit_id(ivl_event_basename(event)); } } } diff --git a/tgt-vlog95/expr.c b/tgt-vlog95/expr.c index ede1c7da3..698aa6349 100644 --- a/tgt-vlog95/expr.c +++ b/tgt-vlog95/expr.c @@ -73,7 +73,7 @@ static void emit_expr_array(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { ivl_signal_t sig = ivl_expr_signal(expr); emit_scope_call_path(scope, ivl_signal_scope(sig)); - fprintf(vlog_out, "%s", ivl_signal_basename(sig)); + emit_id(ivl_signal_basename(sig)); } static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) @@ -220,12 +220,23 @@ static void emit_expr_event(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) assert(! ivl_event_npos(event)); assert(! ivl_event_nneg(event)); emit_scope_call_path(scope, ev_scope); - fprintf(vlog_out, "%s", ivl_event_basename(event)); + emit_id(ivl_event_basename(event)); +} + +static void emit_expr_scope_piece(ivl_scope_t scope) +{ + ivl_scope_t parent = ivl_scope_parent(scope); + /* If this scope has a parent then emit it first. */ + if (parent) { + emit_expr_scope_piece(parent); + fprintf(vlog_out, "."); + } + emit_id(ivl_scope_basename(scope)); } static void emit_expr_scope(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { - fprintf(vlog_out, "%s", ivl_scope_name(ivl_expr_scope(expr))); + emit_expr_scope_piece(ivl_expr_scope(expr)); } static unsigned emit_param_name_in_scope(ivl_scope_t scope, ivl_expr_t expr) @@ -258,7 +269,7 @@ static unsigned emit_param_name_in_scope(ivl_scope_t scope, ivl_expr_t expr) break; } } - fprintf(vlog_out, "%s", ivl_parameter_basename(par)); + emit_id(ivl_parameter_basename(par)); return 1; } } @@ -418,11 +429,10 @@ static void emit_expr_select(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) /* * This routine is used to emit both system and user functions. */ -static void emit_expr_func(ivl_scope_t scope, ivl_expr_t expr, const char* name) +static void emit_expr_func(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { unsigned count = ivl_expr_parms(expr); - fprintf(vlog_out, "%s", name); - if (count != 0) { + if (count) { unsigned idx; fprintf(vlog_out, "("); count -= 1; @@ -435,16 +445,11 @@ static void emit_expr_func(ivl_scope_t scope, ivl_expr_t expr, const char* name) } } -static void emit_expr_sfunc(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) -{ - emit_expr_func(scope, expr, ivl_expr_name(expr)); -} - static void emit_expr_signal(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { ivl_signal_t sig = ivl_expr_signal(expr); emit_scope_call_path(scope, ivl_signal_scope(sig)); - fprintf(vlog_out, "%s", ivl_signal_basename(sig)); + emit_id(ivl_signal_basename(sig)); if (ivl_signal_dimensions(sig)) { int lsb = ivl_signal_array_base(sig); int msb = lsb + ivl_signal_array_count(sig); @@ -465,13 +470,6 @@ static void emit_expr_ternary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) fprintf(vlog_out, ")"); } -static void emit_expr_ufunc(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) -{ - ivl_scope_t ufunc_def = ivl_expr_def(expr); - emit_scope_module_path(scope, ufunc_def); - emit_expr_func(scope, expr, ivl_scope_tname(ufunc_def)); -} - static void emit_expr_unary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { char *oper = "invalid"; @@ -551,7 +549,8 @@ void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) emit_expr_select(scope, expr, wid); break; case IVL_EX_SFUNC: - emit_expr_sfunc(scope, expr, wid); + fprintf(vlog_out, "%s", ivl_expr_name(expr)); + emit_expr_func(scope, expr, wid); break; case IVL_EX_SIGNAL: emit_expr_signal(scope, expr, wid); @@ -563,7 +562,8 @@ void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) emit_expr_ternary(scope, expr, wid); break; case IVL_EX_UFUNC: - emit_expr_ufunc(scope, expr, wid); + emit_scope_path(scope, ivl_expr_def(expr)); + emit_expr_func(scope, expr, wid); break; case IVL_EX_UNARY: emit_expr_unary(scope, expr, wid); diff --git a/tgt-vlog95/logic_lpm.c b/tgt-vlog95/logic_lpm.c index 764fb93bd..7e932762e 100644 --- a/tgt-vlog95/logic_lpm.c +++ b/tgt-vlog95/logic_lpm.c @@ -232,6 +232,55 @@ static ivl_nexus_t get_lpm_output(ivl_scope_t scope, ivl_lpm_t lpm) static void emit_logic_as_ca(ivl_scope_t scope, ivl_net_logic_t nlogic); static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm); +void emit_nexus_port_driver_as_ca(ivl_scope_t scope, ivl_nexus_t nex) +{ + unsigned idx, count = ivl_nexus_ptrs(nex); + ivl_lpm_t lpm = 0; + ivl_net_const_t net_const = 0; + ivl_net_logic_t net_logic = 0; + ivl_signal_t sig = 0; + for (idx = 0; idx < count; idx += 1) { + ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); + if ((ivl_nexus_ptr_drive1(nex_ptr) == IVL_DR_HiZ) && + (ivl_nexus_ptr_drive0(nex_ptr) == IVL_DR_HiZ)) continue; + ivl_lpm_t t_lpm = ivl_nexus_ptr_lpm(nex_ptr); + ivl_net_const_t t_net_const = ivl_nexus_ptr_con(nex_ptr); + ivl_net_logic_t t_net_logic = ivl_nexus_ptr_log(nex_ptr); + ivl_signal_t t_sig = ivl_nexus_ptr_sig(nex_ptr); + if (t_lpm) { + assert(! lpm); + lpm = t_lpm; + } + if (t_net_const) { + assert(! net_const); + net_const = t_net_const; + } + if (t_net_logic) { + assert(! net_logic); + net_logic = t_net_logic; + } + if (t_sig) { + assert(! sig); + sig = t_sig; + } + } + if (lpm) { + assert(! net_const); + assert(! net_logic); + assert(! sig); + emit_lpm_as_ca(scope, lpm); + } else if (net_const) { + assert( !net_logic); + assert(! sig); + emit_const_nexus(scope, net_const); + } else if (net_logic) { + assert(! sig); + emit_logic_as_ca(scope, net_logic); + } else if (sig) { + emit_nexus_as_ca(scope, ivl_signal_nex(sig, 0)); + } else assert(0); +} + void emit_nexus_as_ca(ivl_scope_t scope, ivl_nexus_t nex) { /* If there is no nexus then there is nothing to print. */ @@ -240,6 +289,7 @@ void emit_nexus_as_ca(ivl_scope_t scope, ivl_nexus_t nex) if (is_local_nexus(scope, nex)) { unsigned idx, count = ivl_nexus_ptrs(nex); unsigned must_be_sig = 0; + unsigned out_of_scope_drive = 0; ivl_lpm_t lpm = 0; ivl_net_const_t net_const = 0; ivl_net_logic_t net_logic = 0; @@ -263,6 +313,10 @@ void emit_nexus_as_ca(ivl_scope_t scope, ivl_nexus_t nex) lpm = t_lpm; } if (t_net_const) { + if (scope != ivl_const_scope(t_net_const)) { +// HERE: Need to verify that this is not a parameter + out_of_scope_drive = 1; + } assert(! net_const); net_const = t_net_const; } @@ -285,7 +339,15 @@ void emit_nexus_as_ca(ivl_scope_t scope, ivl_nexus_t nex) assert( !net_logic); assert(! sig); assert(! must_be_sig); - emit_const_nexus(scope, net_const); + if (out_of_scope_drive) { +// HERE: An out of scope const drive that is not a parameter is really a +// port so look for and emit the local signal name (nexus_is_signal +// may work). The is_local_nexus code also needs to be changed to +// not emit the port expressions as a CA. Make sure this works +// correctly if the parameter is passed as a port argument. +// For now report this as missing. + fprintf(vlog_out, ""); + } else emit_const_nexus(scope, net_const); } else if (net_logic) { assert(! sig); assert(! must_be_sig); @@ -385,8 +447,9 @@ static void emit_lpm_array(ivl_scope_t scope, ivl_lpm_t lpm) { ivl_signal_t sig = ivl_lpm_array(lpm); emit_scope_module_path(scope, ivl_signal_scope(sig)); - fprintf(vlog_out, "%s[", ivl_signal_basename(sig)); -// HERE: Need to remove the scale to match array base. + emit_id(ivl_signal_basename(sig)); + fprintf(vlog_out, "["); +// HERE: Need to remove the scale to match array base instead of adding it back. emit_nexus_as_ca(scope, ivl_lpm_select(lpm)); fprintf(vlog_out, " + %d]", ivl_signal_array_base(sig)); } @@ -488,7 +551,7 @@ static void emit_lpm_part_select(ivl_scope_t scope, ivl_lpm_t lpm) if (base) fprintf(vlog_out, " >> %d)", base); return; } - fprintf(vlog_out, "%s", ivl_signal_basename(sig)); + emit_id(ivl_signal_basename(sig)); if (ivl_signal_dimensions(sig)) { array_word += ivl_signal_array_base(sig); fprintf(vlog_out, "[%d]", array_word); @@ -538,16 +601,19 @@ static void emit_lpm_part_select(ivl_scope_t scope, ivl_lpm_t lpm) } // HERE: No support for trigger. Is this actually needed? -static void emit_lpm_func(ivl_scope_t scope, ivl_lpm_t lpm, const char *name) +static void emit_lpm_func(ivl_scope_t scope, ivl_lpm_t lpm) { - unsigned idx, count= ivl_lpm_size(lpm); - fprintf(vlog_out, "%s(", name);; - for (idx = count-1; idx > 0; idx -= 1) { - emit_nexus_as_ca(scope, ivl_lpm_data(lpm, idx)); - fprintf(vlog_out, ", "); + unsigned count = ivl_lpm_size(lpm); + if (count) { + unsigned idx; + fprintf(vlog_out, "("); + for (idx = count-1; idx > 0; idx -= 1) { + emit_nexus_as_ca(scope, ivl_lpm_data(lpm, idx)); + fprintf(vlog_out, ", "); + } + emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0)); + fprintf(vlog_out, ")"); } - emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0)); - fprintf(vlog_out, ")"); } static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm) @@ -692,7 +758,8 @@ static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm) fprintf(vlog_out, "}}"); break; case IVL_LPM_SFUNC: - emit_lpm_func(scope, lpm, ivl_lpm_string(lpm)); + fprintf(vlog_out, "%s", ivl_lpm_string(lpm)); + emit_lpm_func(scope, lpm); break; case IVL_LPM_SHIFTL: fprintf(vlog_out, "("); @@ -720,7 +787,8 @@ static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm) fprintf(vlog_out, ")"); break; case IVL_LPM_UFUNC: - emit_lpm_func(scope, lpm, ivl_scope_name(ivl_lpm_define(lpm))); + emit_scope_path(scope, ivl_lpm_define(lpm)); + emit_lpm_func(scope, lpm); break; default: fprintf(vlog_out, ""); @@ -966,8 +1034,8 @@ static ivl_signal_t get_output_from_nexus(ivl_scope_t scope, ivl_nexus_t nex, tmp_idx += ivl_signal_array_base(sig); fprintf(stderr, "[%"PRId64"]", tmp_idx); } - fprintf(stderr, ") found for nexus "); - fprintf(stderr, "(%s", ivl_signal_basename(use_sig)); + fprintf(stderr, ") found for nexus (%s", + ivl_signal_basename(use_sig)); if (is_array) fprintf(stderr, "[%"PRId64"]", *array_idx); fprintf(stderr, ")\n"); } else { @@ -994,7 +1062,7 @@ static void emit_lpm_part_pv(ivl_scope_t scope, ivl_lpm_t lpm) &array_word); assert(sig); assert(ivl_lpm_data(lpm, 1) == 0); - fprintf(vlog_out, "%s", ivl_signal_basename(sig)); + emit_id(ivl_signal_basename(sig)); if (ivl_signal_dimensions(sig)) { fprintf(vlog_out, "[%"PRId64"]", array_word); } @@ -1083,7 +1151,7 @@ static void emit_bufz(ivl_scope_t scope, ivl_net_logic_t nlogic) static void emit_and_save_udp_name(ivl_net_logic_t nlogic){ ivl_udp_t udp = ivl_logic_udp(nlogic); assert(udp); - fprintf(vlog_out, "%s", ivl_udp_name(udp)); + emit_id(ivl_udp_name(udp)); add_udp_to_list(udp); } @@ -1235,6 +1303,7 @@ void emit_logic(ivl_scope_t scope, ivl_net_logic_t nlogic) // remove this and rebuild the instance array. For now we just strip // this encoding and create an zero based range. Need to skip the // local names _s. +// This can also be an escaped id. name = ivl_logic_basename(nlogic); if (name && *name) { char *fixed_name = strdup(name); @@ -1246,7 +1315,8 @@ void emit_logic(ivl_scope_t scope, ivl_net_logic_t nlogic) } fixed_name[lp] = 0; } - fprintf(vlog_out, " %s", fixed_name); + fprintf(vlog_out, " "); + emit_id(fixed_name); free(fixed_name); if (width > 1) { fprintf(vlog_out, " [%u:0]", width-1); @@ -1373,7 +1443,9 @@ void emit_signal_net_const_as_ca(ivl_scope_t scope, ivl_signal_t sig) ivl_const_delay(net_const, 1), ivl_const_delay(net_const, 2), 3); - fprintf(vlog_out, " %s = ", ivl_signal_basename(sig)); + fprintf(vlog_out, " "); + emit_id(ivl_signal_basename(sig)); + fprintf(vlog_out, " = "); emit_const_nexus(scope, net_const); fprintf(vlog_out, ";"); emit_sig_file_line(sig); diff --git a/tgt-vlog95/misc.c b/tgt-vlog95/misc.c index af296ffd1..0cf1c1489 100644 --- a/tgt-vlog95/misc.c +++ b/tgt-vlog95/misc.c @@ -16,6 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +# include # include # include # include "config.h" @@ -454,8 +455,8 @@ static unsigned find_signal_in_nexus(ivl_scope_t scope, ivl_nexus_t nex) tmp_idx += ivl_signal_array_base(sig); fprintf(stderr, "[%"PRId64"]", tmp_idx); } - fprintf(stderr, ") found for nexus "); - fprintf(stderr, "(%s", ivl_signal_basename(use_sig)); + fprintf(stderr, ") found for nexus (%s", + ivl_signal_basename(use_sig)); if (is_array) fprintf(stderr, "[%"PRId64"]", array_idx); fprintf(stderr, ")\n"); } else { @@ -475,7 +476,7 @@ static unsigned find_signal_in_nexus(ivl_scope_t scope, ivl_nexus_t nex) } if (use_sig) { - fprintf(vlog_out, "%s", ivl_signal_basename(use_sig)); + emit_id(ivl_signal_basename(use_sig)); if (is_array) fprintf(vlog_out, "[%"PRId64"]", array_idx); return 1; } @@ -530,12 +531,16 @@ static unsigned find_const_nexus(ivl_scope_t scope, ivl_nexus_t nex) // HERE: Does this work correctly with an array reference created from @*? void emit_name_of_nexus(ivl_scope_t scope, ivl_nexus_t nex) { + ivl_scope_t mod_scope; /* First look in the local scope for the nexus name. */ if (find_signal_in_nexus(scope, nex)) return; /* If the signal was not found in the passed scope then look in * the module scope if the passed scope was not the module scope. */ - if (find_signal_in_nexus(get_module_scope(scope), nex)) return; + mod_scope = get_module_scope(scope); + if (mod_scope != scope) { + if (find_signal_in_nexus(mod_scope, nex)) return; + } /* If there is no signals driving this then look for a constant. */ if (find_const_nexus(scope, nex)) return; @@ -564,6 +569,19 @@ ivl_scope_t get_module_scope(ivl_scope_t scope) return scope; } +static void emit_scope_piece(ivl_scope_t scope, ivl_scope_t call_scope) +{ + ivl_scope_t parent = ivl_scope_parent(call_scope); + /* If we are not at the top of the scope (parent != 0) and the two + * scopes do not match then print the parent scope. */ + if ((parent != 0) && (scope != parent)) { + emit_scope_piece(scope, parent); + } + /* Print the base scope. */ + emit_id(ivl_scope_basename(call_scope)); + fprintf(vlog_out, "."); +} + /* * This routine emits the appropriate string to call the call_scope from the * given scope. If the module scopes for the two match then do nothing. If @@ -577,28 +595,8 @@ void emit_scope_module_path(ivl_scope_t scope, ivl_scope_t call_scope) ivl_scope_t mod_scope = get_module_scope(scope); ivl_scope_t call_mod_scope = get_module_scope(call_scope); - if (mod_scope != call_mod_scope) { - /* Trim off the top of the call name if it exactly matches - * the module scope of the caller. */ - char *sc_name = strdup(ivl_scope_name(mod_scope)); - const char *sc_ptr = sc_name; - char *call_name = strdup(ivl_scope_name(call_mod_scope)); - const char *call_ptr = call_name; - while ((*sc_ptr == *call_ptr) && - (*sc_ptr != 0) && (*call_ptr != 0)) { - sc_ptr += 1; - call_ptr += 1; - } - if (*sc_ptr == 0) { - assert(*call_ptr == '.'); - call_ptr += 1; - } else { - call_ptr = call_name; - } - fprintf(vlog_out, "%s.", call_ptr); - free(sc_name); - free(call_name); - } + if (mod_scope == call_mod_scope) return; + emit_scope_piece(mod_scope, call_mod_scope); } /* This is the same as emit_scope_module_path() except we need to add down @@ -609,47 +607,35 @@ void emit_scope_call_path(ivl_scope_t scope, ivl_scope_t call_scope) ivl_scope_t call_mod_scope = get_module_scope(call_scope); if (mod_scope != call_mod_scope) { - /* Trim off the top of the call name if it exactly matches - * the module scope of the caller. */ - char *sc_name = strdup(ivl_scope_name(mod_scope)); - const char *sc_ptr = sc_name; - char *call_name = strdup(ivl_scope_name(call_mod_scope)); - const char *call_ptr = call_name; - while ((*sc_ptr == *call_ptr) && - (*sc_ptr != 0) && (*call_ptr != 0)) { - sc_ptr += 1; - call_ptr += 1; - } - if (*sc_ptr == 0) { - assert(*call_ptr == '.'); - call_ptr += 1; - } else { - call_ptr = call_name; - } - fprintf(vlog_out, "%s.", call_ptr); - free(sc_name); - free(call_name); + emit_scope_piece(mod_scope, call_mod_scope); } else if (scope != call_scope) { - /* Look for a down reference that is local to the module scope. */ - char *sc_name = strdup(ivl_scope_name(scope)); - const char *sc_ptr = sc_name; - char *call_name = strdup(ivl_scope_name(call_scope)); - const char *call_ptr = call_name; - while ((*sc_ptr == *call_ptr) && - (*sc_ptr != 0) && (*call_ptr != 0)) { - sc_ptr += 1; - call_ptr += 1; + ivl_scope_t parent; + /* We only emit a scope path if the scope is a parent of the + * call scope. */ + for (parent = ivl_scope_parent(call_scope); + parent != 0; + parent = ivl_scope_parent(parent)) { + if (parent == scope) { + emit_scope_piece(scope, call_scope); + return; + } } - if (*sc_ptr == 0) { - assert(*call_ptr == '.'); - call_ptr += 1; - fprintf(vlog_out, "%s.", call_ptr); - } - free(sc_name); - free(call_name); } } +static void emit_scope_path_piece(ivl_scope_t scope, ivl_scope_t call_scope) +{ + ivl_scope_t parent = ivl_scope_parent(call_scope); + /* If we are not at the top of the scope (parent != 0) and the two + * scopes do not match then print the parent scope. */ + if ((parent != 0) && (scope != parent)) { + emit_scope_path_piece(scope, parent); + fprintf(vlog_out, "."); + } + /* Print the base scope. */ + emit_id(ivl_scope_basename(call_scope)); +} + /* * This routine emits the appropriate string to call the call_scope from the * given scope. If the module scopes for the two match then just return the @@ -664,27 +650,32 @@ void emit_scope_path(ivl_scope_t scope, ivl_scope_t call_scope) ivl_scope_t call_mod_scope = get_module_scope(call_scope); if (mod_scope == call_mod_scope) { - fprintf(vlog_out, "%s", ivl_scope_basename(call_scope)); + emit_id(ivl_scope_basename(call_scope)); } else { - /* Trim off the top of the call name if it exactly matches - * the module scope of the caller. */ - char *sc_name = strdup(ivl_scope_name(mod_scope)); - const char *sc_ptr = sc_name; - char *call_name = strdup(ivl_scope_name(call_scope)); - const char *call_ptr = call_name; - while ((*sc_ptr == *call_ptr) && - (*sc_ptr != 0) && (*call_ptr != 0)) { - sc_ptr += 1; - call_ptr += 1; - } - if (*sc_ptr == 0) { - assert(*call_ptr == '.'); - call_ptr += 1; - } else { - call_ptr = call_name; - } - fprintf(vlog_out, "%s", call_ptr); - free(sc_name); - free(call_name); + emit_scope_path_piece(mod_scope, call_scope); } } + +static unsigned is_escaped(const char *id) +{ + assert(id); + /* The first digit must be alpha or '_' to be a normal id. */ + if (isalpha((int)id[0]) || id[0] == '_') { + unsigned idx; + for (idx = 1; id[idx] != '\0'; idx += 1) { + if (! (isalnum((int)id[idx]) || + id[idx] == '_' || id[idx] == '$')) { + return 1; + } + } + /* We looked at all the digits, so this is a normal id. */ + return 0; + } + return 1; +} + +void emit_id(const char *id) +{ + if (is_escaped(id)) fprintf(vlog_out, "\\%s ", id); + else fprintf(vlog_out, "%s", id); +} diff --git a/tgt-vlog95/numbers.c b/tgt-vlog95/numbers.c index b89d6d8b5..ecf72dcc2 100644 --- a/tgt-vlog95/numbers.c +++ b/tgt-vlog95/numbers.c @@ -51,7 +51,7 @@ static int32_t get_int32_from_bits(const char *bits, unsigned nbits, else if (bits[idx] != '0') { *result_type = -1; /* If the value is entirely x/z then return -2 or -3. */ - if ((idx == 0) && (trim_wid == 1)) { + if (trim_wid == 1) { if (bits[idx] == 'x') *result_type -= 1; *result_type -= 1; } @@ -190,7 +190,7 @@ uint64_t get_uint64_from_number(ivl_expr_t expr, int *result_type) else if (bits[idx] != '0') { *result_type = -1; /* If the value is entirely x/z then return -2 or -3. */ - if ((idx == 0) && (trim_wid == 1)) { + if (trim_wid == 1) { if (bits[idx] == 'x') *result_type -= 1; *result_type -= 1; } @@ -236,7 +236,7 @@ int64_t get_int64_from_number(ivl_expr_t expr, int *result_type) else if (bits[idx] != '0') { *result_type = -1; /* If the value is entirely x/z then return -2 or -3. */ - if ((idx == 0) && (trim_wid == 1)) { + if (trim_wid == 1) { if (bits[idx] == 'x') *result_type -= 1; *result_type -= 1; } diff --git a/tgt-vlog95/scope.c b/tgt-vlog95/scope.c index ac5660764..ae2914378 100644 --- a/tgt-vlog95/scope.c +++ b/tgt-vlog95/scope.c @@ -76,14 +76,21 @@ void emit_sig_file_line(ivl_signal_t sig) } } +static void emit_sig_id(ivl_signal_t sig) +{ + emit_id(ivl_signal_basename(sig)); + fprintf(vlog_out, ";"); + emit_sig_file_line(sig); + fprintf(vlog_out, "\n"); +} + void emit_var_def(ivl_signal_t sig) { if (ivl_signal_local(sig)) return; fprintf(vlog_out, "%*c", indent, ' '); if (ivl_signal_integer(sig)) { - fprintf(vlog_out, "integer %s;", ivl_signal_basename(sig)); - emit_sig_file_line(sig); - fprintf(vlog_out, "\n"); + fprintf(vlog_out, "integer "); + emit_sig_id(sig); if (ivl_signal_dimensions(sig) > 0) { fprintf(stderr, "%s:%u: vlog95 error: Integer arrays (%s) " "are not supported.\n", ivl_signal_file(sig), @@ -92,9 +99,8 @@ void emit_var_def(ivl_signal_t sig) vlog_errors += 1; } } else if (ivl_signal_data_type(sig) == IVL_VT_REAL) { - fprintf(vlog_out, "real %s;", ivl_signal_basename(sig)); - emit_sig_file_line(sig); - fprintf(vlog_out, "\n"); + fprintf(vlog_out, "real "); + emit_sig_id(sig); if (ivl_signal_dimensions(sig) > 0) { fprintf(stderr, "%s:%u: vlog95 error: Real arrays (%s) " "are not supported.\n", ivl_signal_file(sig), @@ -105,9 +111,9 @@ void emit_var_def(ivl_signal_t sig) } else { int msb = ivl_signal_msb(sig); int lsb = ivl_signal_lsb(sig); - fprintf(vlog_out, "reg"); - if (msb != 0 || lsb != 0) fprintf(vlog_out, " [%d:%d]", msb, lsb); - fprintf(vlog_out, " %s", ivl_signal_basename(sig)); + fprintf(vlog_out, "reg "); + if (msb != 0 || lsb != 0) fprintf(vlog_out, "[%d:%d] ", msb, lsb); + emit_id(ivl_signal_basename(sig)); if (ivl_signal_dimensions(sig) > 0) { unsigned wd_count = ivl_signal_array_count(sig); int first = ivl_signal_array_base(sig); @@ -178,23 +184,24 @@ void emit_net_def(ivl_scope_t scope, ivl_signal_t sig) if (ivl_signal_local(sig)) return; fprintf(vlog_out, "%*c", indent, ' '); if (ivl_signal_data_type(sig) == IVL_VT_REAL){ - fprintf(vlog_out, "wire %s;\n", ivl_signal_basename(sig)); + fprintf(vlog_out, "wire "); + emit_sig_id(sig); fprintf(stderr, "%s:%u: vlog95 error: Real nets (%s) are " "not supported.\n", ivl_signal_file(sig), ivl_signal_lineno(sig), ivl_signal_basename(sig)); vlog_errors += 1; } else if (ivl_signal_signed(sig)) { - fprintf(vlog_out, "wire"); - if (msb != 0 || lsb != 0) fprintf(vlog_out, " [%d:%d]", msb, lsb); - fprintf(vlog_out, " %s;\n", ivl_signal_basename(sig)); + fprintf(vlog_out, "wire "); + if (msb != 0 || lsb != 0) fprintf(vlog_out, "[%d:%d] ", msb, lsb); + emit_sig_id(sig); fprintf(stderr, "%s:%u: vlog95 error: Signed nets (%s) are " "not supported.\n", ivl_signal_file(sig), ivl_signal_lineno(sig), ivl_signal_basename(sig)); vlog_errors += 1; } else if (ivl_signal_dimensions(sig) > 0) { - fprintf(vlog_out, "wire"); - if (msb != 0 || lsb != 0) fprintf(vlog_out, " [%d:%d]", msb, lsb); - fprintf(vlog_out, " %s;\n", ivl_signal_basename(sig)); + fprintf(vlog_out, "wire "); + if (msb != 0 || lsb != 0) fprintf(vlog_out, "[%d:%d] ", msb, lsb); + emit_sig_id(sig); fprintf(stderr, "%s:%u: vlog95 error: Array nets (%s) are " "not supported.\n", ivl_signal_file(sig), ivl_signal_lineno(sig), ivl_signal_basename(sig)); @@ -205,59 +212,58 @@ void emit_net_def(ivl_scope_t scope, ivl_signal_t sig) case IVL_SIT_UWIRE: // HERE: Need to add support for supply nets. Probably supply strength // with a constant 0/1 driver for all the bits. - fprintf(vlog_out, "wire"); + fprintf(vlog_out, "wire "); break; case IVL_SIT_TRI0: - fprintf(vlog_out, "tri0"); + fprintf(vlog_out, "tri0 "); break; case IVL_SIT_TRI1: - fprintf(vlog_out, "tri1"); + fprintf(vlog_out, "tri1 "); break; case IVL_SIT_TRIAND: - fprintf(vlog_out, "wand"); + fprintf(vlog_out, "wand "); break; case IVL_SIT_TRIOR: - fprintf(vlog_out, "wor"); + fprintf(vlog_out, "wor "); break; default: - fprintf(vlog_out, ""); + fprintf(vlog_out, " "); fprintf(stderr, "%s:%u: vlog95 error: Unknown net type " "(%d).\n", ivl_signal_file(sig), ivl_signal_lineno(sig), (int)ivl_signal_type(sig)); vlog_errors += 1; break; } - if (msb != 0 || lsb != 0) fprintf(vlog_out, " [%d:%d]", msb, lsb); - fprintf(vlog_out, " %s;", ivl_signal_basename(sig)); - emit_sig_file_line(sig); - fprintf(vlog_out, "\n"); + if (msb != 0 || lsb != 0) fprintf(vlog_out, "[%d:%d] ", msb, lsb); + emit_sig_id(sig); /* A constant driving a net does not create an lpm or logic * element in the design so save them from the definition. */ save_net_constants(scope, sig); } } -static char *get_mangled_name(ivl_scope_t scope, unsigned root) +static void emit_mangled_name(ivl_scope_t scope, unsigned root) { - char *name; /* If the module has parameters and it's not a root module then it - * may not be unique so we create a mangled name version instead. */ + * may not be unique so we create a mangled name version instead. + * The mangled name is of the form: + * []. */ if (ivl_scope_params(scope) && ! root) { - unsigned idx; + char *name; size_t len = strlen(ivl_scope_name(scope)) + - strlen(ivl_scope_tname(scope)) + 2; + strlen(ivl_scope_tname(scope)) + 3; name = (char *)malloc(len); (void) strcpy(name, ivl_scope_tname(scope)); - (void) strcat(name, "_"); + (void) strcat(name, "["); (void) strcat(name, ivl_scope_name(scope)); + (void) strcat(name, "]"); assert(name[len-1] == 0); - for (idx = 0; idx < len; idx += 1) { - if (name[idx] == '.') name[idx] = '_'; - } + /* Emit the mangled name as an escaped identifier. */ + fprintf(vlog_out, "\\%s ", name); + free(name); } else { - name = strdup(ivl_scope_tname(scope)); + emit_id(ivl_scope_tname(scope)); } - return name; } /* @@ -279,8 +285,9 @@ void emit_scope_variables(ivl_scope_t scope) for (idx = 0; idx < count; idx += 1) { ivl_parameter_t par = ivl_scope_param(scope, idx); ivl_expr_t pex = ivl_parameter_expr(par); - fprintf(vlog_out, "%*cparameter %s = ", indent, ' ', - ivl_parameter_basename(par)); + fprintf(vlog_out, "%*cparameter ", indent, ' '); + emit_id(ivl_parameter_basename(par)); + fprintf(vlog_out, " = "); emit_expr(scope, pex, 0); fprintf(vlog_out, ";"); if (emit_file_line) { @@ -317,8 +324,9 @@ void emit_scope_variables(ivl_scope_t scope) if (ivl_event_nany(event)) continue; if (ivl_event_npos(event)) continue; if (ivl_event_nneg(event)) continue; - fprintf(vlog_out, "%*cevent %s;", indent, ' ', - ivl_event_basename(event)); + fprintf(vlog_out, "%*cevent ", indent, ' '); + emit_id(ivl_event_basename(event)); + fprintf(vlog_out, ";"); if (emit_file_line) { fprintf(vlog_out, " /* %s:%u */", ivl_event_file(event), @@ -345,65 +353,166 @@ static void emit_module_ports(ivl_scope_t scope) if (count == 0) return; - fprintf(stderr, "%s:%u: vlog95 sorry: Modules with port are not " - "currently supported.\n", ivl_scope_file(scope), - ivl_scope_lineno(scope)); - vlog_errors += 1; fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_scope_mod_port(scope, 0)); for (idx = 1; idx < count; idx += 1) { fprintf(vlog_out, ", "); emit_nexus_as_ca(scope, ivl_scope_mod_port(scope, idx)); -// HERE: Save the signals that are connected to the nexi and use those -// in the port_def code below. } fprintf(vlog_out, ")"); } +static ivl_signal_t get_port_from_nexus(ivl_scope_t scope, ivl_nexus_t nex) +{ + assert(nex); + unsigned idx, count = ivl_nexus_ptrs(nex); + ivl_signal_t sig = 0; + for (idx = 0; idx < count; idx += 1) { + ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); + ivl_signal_t t_sig = ivl_nexus_ptr_sig(nex_ptr); + if (t_sig) { + if (ivl_signal_scope(t_sig) != scope) continue; + assert(! sig); + sig = t_sig; + } + } + return sig; +} + +static void emit_sig_type(ivl_signal_t sig) +{ + ivl_signal_type_t type = ivl_signal_type(sig); + assert(ivl_signal_dimensions(sig) == 0); + /* Check to see if we have a variable (reg) or a net. */ + if (type == IVL_SIT_REG) { + if (ivl_signal_integer(sig)) { + fprintf(vlog_out, " integer"); + } else if (ivl_signal_data_type(sig) == IVL_VT_REAL) { + fprintf(vlog_out, " real"); + } else { + int msb = ivl_signal_msb(sig); + int lsb = ivl_signal_lsb(sig); + if (msb != 0 || lsb != 0) { + fprintf(vlog_out, " [%d:%d]", msb, lsb); + } + if (ivl_signal_signed(sig)) { + fprintf(stderr, "%s:%u: vlog95 error: Signed ports " + "(%s) are not supported.\n", + ivl_signal_file(sig), + ivl_signal_lineno(sig), + ivl_signal_basename(sig)); + vlog_errors += 1; + } + } + } else { + assert(type == IVL_SIT_TRI); + if (ivl_signal_data_type(sig) == IVL_VT_REAL) { + fprintf(stderr, "%s:%u: vlog95 error: Real net ports (%s) " + "are not supported.\n", + ivl_signal_file(sig), + ivl_signal_lineno(sig), + ivl_signal_basename(sig)); + vlog_errors += 1; + } else { + int msb = ivl_signal_msb(sig); + int lsb = ivl_signal_lsb(sig); + if (ivl_signal_signed(sig)) { + fprintf(stderr, "%s:%u: vlog95 error: Signed net ports " + "(%s) are not supported.\n", + ivl_signal_file(sig), + ivl_signal_lineno(sig), + ivl_signal_basename(sig)); + vlog_errors += 1; + } + if (msb != 0 || lsb != 0) { + fprintf(vlog_out, " [%d:%d]", msb, lsb); + } + } + } +} + +static void emit_port(ivl_signal_t port) +{ + assert(port); + fprintf(vlog_out, "%*c", indent, ' '); + switch (ivl_signal_port(port)) { + case IVL_SIP_INPUT: + fprintf(vlog_out, "input"); + break; + case IVL_SIP_OUTPUT: + fprintf(vlog_out, "output"); + break; + case IVL_SIP_INOUT: + fprintf(vlog_out, "inout"); + break; + default: + fprintf(vlog_out, ""); + fprintf(stderr, "%s:%u: vlog95 error: Unknown port direction (%d) " + "for signal %s.\n", ivl_signal_file(port), + ivl_signal_lineno(port), (int)ivl_signal_port(port), + ivl_signal_basename(port)); + vlog_errors += 1; + break; + } + emit_sig_type(port); + fprintf(vlog_out, " "); + emit_id(ivl_signal_basename(port)); + fprintf(vlog_out, ";"); + emit_sig_file_line(port); + fprintf(vlog_out, "\n"); +} + static void emit_module_port_defs(ivl_scope_t scope) { unsigned idx, count = ivl_scope_ports(scope); for (idx = 0; idx < count; idx += 1) { - ivl_nexus_t port = ivl_scope_mod_port(scope, idx); - fprintf(vlog_out, "%*c", indent, ' '); -// HERE: Need port type/size information. - emit_nexus_as_ca(scope, port); -// emit_sig_file_line(port); - fprintf(vlog_out, " \n"); + ivl_nexus_t nex = ivl_scope_mod_port(scope, idx); + ivl_signal_t port = get_port_from_nexus(scope, nex); + if (port) emit_port(port); + else { + fprintf(vlog_out, ""); + fprintf(stderr, "%s:%u: vlog95 error: Could not find signal " + "definition for port (%u) of module %s.\n", + ivl_scope_file(scope), ivl_scope_lineno(scope), + idx + 1, ivl_scope_basename(scope)); + vlog_errors += 1; + } } if (count) fprintf(vlog_out, "\n"); } +static void emit_module_call_expr(ivl_scope_t scope, unsigned idx) +{ + ivl_nexus_t nex = ivl_scope_mod_port(scope, idx); + ivl_signal_t port = get_port_from_nexus(scope, nex); + /* For an input port we need to emit the driving expression. */ + if (ivl_signal_port(port) == IVL_SIP_INPUT) { + emit_nexus_port_driver_as_ca(ivl_scope_parent(scope), + ivl_signal_nex(port, 0)); + /* For an output we need to emit the signal the output is driving. */ + } else { + emit_nexus_as_ca(ivl_scope_parent(scope), ivl_signal_nex(port, 0)); + } +} + +static void emit_module_call_expressions(ivl_scope_t scope) +{ + unsigned idx, count = ivl_scope_ports(scope); + if (count == 0) return; + emit_module_call_expr(scope, 0); + for (idx = 1; idx < count; idx += 1) { + fprintf(vlog_out, ", "); + emit_module_call_expr(scope, idx); + } +} + static void emit_task_func_port_defs(ivl_scope_t scope) { unsigned idx, count = ivl_scope_ports(scope); unsigned start = ivl_scope_type(scope) == IVL_SCT_FUNCTION; for (idx = start; idx < count; idx += 1) { ivl_signal_t port = ivl_scope_port(scope, idx); - fprintf(vlog_out, "%*c", indent, ' '); - switch (ivl_signal_port(port)) { - case IVL_SIP_INPUT: - fprintf(vlog_out, "input"); - break; - case IVL_SIP_OUTPUT: - fprintf(vlog_out, "output"); - break; - case IVL_SIP_INOUT: - fprintf(vlog_out, "inout"); - break; - default: - fprintf(vlog_out, ""); - fprintf(stderr, "%s:%u: vlog95 error: Unknown port " - "direction (%d) for signal %s.\n", - ivl_signal_file(port), ivl_signal_lineno(port), - (int)ivl_signal_port(port), - ivl_signal_basename(port)); - vlog_errors += 1; - break; - } - fprintf(vlog_out, " %s;", ivl_signal_basename(port)); - emit_sig_file_line(port); - fprintf(vlog_out, " \n"); + emit_port(port); } if (count) fprintf(vlog_out, "\n"); } @@ -454,25 +563,25 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent) ivl_scope_type_t sc_type = ivl_scope_type(scope); unsigned is_auto = ivl_scope_is_auto(scope); unsigned idx, count; - char *name; /* Output the scope definition. */ switch (sc_type) { case IVL_SCT_MODULE: assert(!is_auto); - name = get_mangled_name(scope, !parent && !emitting_scopes); /* This is an instantiation. */ if (parent) { assert(indent != 0); /* If the module has parameters then it may not be unique * so we create a mangled name version instead. */ - fprintf(vlog_out, "\n%*c%s %s(", indent, ' ', name, - ivl_scope_basename(scope)); -// HERE: Still need to add port information. + fprintf(vlog_out, "\n%*c", indent, ' '); + emit_mangled_name(scope, !parent && !emitting_scopes); + fprintf(vlog_out, " "); + emit_id(ivl_scope_basename(scope)); + fprintf(vlog_out, "("); + emit_module_call_expressions(scope); fprintf(vlog_out, ");"); emit_scope_file_line(scope); fprintf(vlog_out, "\n"); - free(name); num_scopes_to_emit += 1; scopes_to_emit = realloc(scopes_to_emit, num_scopes_to_emit * sizeof(ivl_scope_t)); @@ -491,8 +600,8 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent) "file %s at line %u. */\n", ivl_scope_def_file(scope), ivl_scope_def_lineno(scope)); - fprintf(vlog_out, "module %s", name); - free(name); + fprintf(vlog_out, "module "); + emit_mangled_name(scope, !parent && !emitting_scopes); emit_module_ports(scope); break; case IVL_SCT_FUNCTION: @@ -501,7 +610,8 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent) assert(ivl_scope_ports(scope) >= 2); /* The function return information is the zero port. */ emit_func_return(ivl_scope_port(scope, 0)); - fprintf(vlog_out, " %s", ivl_scope_tname(scope)); + fprintf(vlog_out, " "); + emit_id(ivl_scope_tname(scope)); if (is_auto) { fprintf(stderr, "%s:%u: vlog95 error: Automatic functions " "(%s) are not supported.\n", ivl_scope_file(scope), @@ -511,8 +621,8 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent) break; case IVL_SCT_TASK: assert(indent != 0); - fprintf(vlog_out, "\n%*ctask %s", indent, ' ', - ivl_scope_tname(scope)); + fprintf(vlog_out, "\n%*ctask ", indent, ' '); + emit_id(ivl_scope_tname(scope)); if (is_auto) { fprintf(stderr, "%s:%u: vlog95 error: Automatic tasks " "(%s) are not supported.\n", ivl_scope_file(scope), @@ -583,7 +693,9 @@ int emit_scope(ivl_scope_t scope, ivl_scope_t parent) switch (sc_type) { case IVL_SCT_MODULE: assert(indent == 0); - fprintf(vlog_out, "endmodule /* %s */\n", ivl_scope_tname(scope)); + fprintf(vlog_out, "endmodule /* "); + emit_mangled_name(scope, !parent && !emitting_scopes); + fprintf(vlog_out, " */\n"); if (ivl_scope_is_cell(scope)) { fprintf(vlog_out, "`endcelldefine\n"); } diff --git a/tgt-vlog95/stmt.c b/tgt-vlog95/stmt.c index b09c4cfaf..96eac0654 100644 --- a/tgt-vlog95/stmt.c +++ b/tgt-vlog95/stmt.c @@ -91,7 +91,7 @@ static void emit_stmt_lval_name(ivl_scope_t scope, ivl_lval_t lval, { ivl_expr_t array_idx = ivl_lval_idx(lval); emit_scope_call_path(scope, ivl_signal_scope(sig)); - fprintf(vlog_out, "%s", ivl_signal_basename(sig)); + emit_id(ivl_signal_basename(sig)); if (array_idx) { int msb, lsb; assert(ivl_signal_dimensions(sig)); @@ -767,8 +767,8 @@ static void emit_stmt_block(ivl_scope_t scope, ivl_statement_t stmt) static void emit_stmt_block_named(ivl_scope_t scope, ivl_statement_t stmt) { ivl_scope_t my_scope = ivl_stmt_block_scope(stmt); - fprintf(vlog_out, "%*cbegin: %s", get_indent(), ' ', - ivl_scope_basename(my_scope)); + fprintf(vlog_out, "%*cbegin: ", get_indent(), ' '); + emit_id(ivl_scope_basename(my_scope)); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); emit_stmt_block_body(scope, stmt); @@ -778,23 +778,23 @@ static void emit_stmt_block_named(ivl_scope_t scope, ivl_statement_t stmt) static void emit_stmt_case(ivl_scope_t scope, ivl_statement_t stmt) { - char *name; + char *case_type; unsigned idx, default_case, count = ivl_stmt_case_count(stmt); switch(ivl_statement_type(stmt)) { case IVL_ST_CASE: case IVL_ST_CASER: - name = "case"; + case_type = "case"; break; case IVL_ST_CASEX: - name = "casex"; + case_type = "casex"; break; case IVL_ST_CASEZ: - name = "casez"; + case_type = "casez"; break; default: assert(0); } - fprintf(vlog_out, "%*c%s (", get_indent(), ' ', name); + fprintf(vlog_out, "%*c%s (", get_indent(), ' ', case_type); emit_expr(scope, ivl_stmt_cond_expr(stmt), 0); fprintf(vlog_out, ")"); emit_stmt_file_line(stmt); @@ -949,8 +949,8 @@ static void emit_stmt_fork(ivl_scope_t scope, ivl_statement_t stmt) static void emit_stmt_fork_named(ivl_scope_t scope, ivl_statement_t stmt) { ivl_scope_t my_scope = ivl_stmt_block_scope(stmt); - fprintf(vlog_out, "%*cfork: %s", get_indent(), ' ', - ivl_scope_basename(my_scope)); + fprintf(vlog_out, "%*cfork: ", get_indent(), ' '); + emit_id(ivl_scope_basename(my_scope)); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); emit_stmt_block_body(scope, stmt); diff --git a/tgt-vlog95/udp.c b/tgt-vlog95/udp.c index 29a9acb30..e95d44135 100644 --- a/tgt-vlog95/udp.c +++ b/tgt-vlog95/udp.c @@ -183,24 +183,30 @@ static void emit_udp(ivl_udp_t udp) fprintf(vlog_out, "/* This primitive was originally defined in " "file %s at line %u. */\n", ivl_udp_file(udp), ivl_udp_lineno(udp)); - fprintf(vlog_out, "primitive %s (", ivl_udp_name(udp)); - fprintf(vlog_out, "%s", ivl_udp_port(udp, 0)); + fprintf(vlog_out, "primitive "); + emit_id(ivl_udp_name(udp)); + fprintf(vlog_out, " ("); + emit_id(ivl_udp_port(udp, 0)); count = ivl_udp_nin(udp); for (idx = 1; idx <= count; idx += 1) { - fprintf(vlog_out, ", %s", ivl_udp_port(udp, idx)); + fprintf(vlog_out, ", "); + emit_id(ivl_udp_port(udp, idx)); } fprintf(vlog_out, ");\n"); - fprintf(vlog_out, "%*coutput %s;\n", indent_incr, ' ', - ivl_udp_port(udp, 0)); + fprintf(vlog_out, "%*coutput ", indent_incr, ' '); + emit_id(ivl_udp_port(udp, 0)); + fprintf(vlog_out, ";\n"); for (idx = 1; idx <= count; idx += 1) { - fprintf(vlog_out, "%*cinput %s;\n", indent_incr, ' ', - ivl_udp_port(udp, idx)); + fprintf(vlog_out, "%*cinput ", indent_incr, ' '); + emit_id(ivl_udp_port(udp, idx)); + fprintf(vlog_out, ";\n"); } if (ivl_udp_sequ(udp)) { char init = ivl_udp_init(udp); fprintf(vlog_out, "\n"); - fprintf(vlog_out, "%*creg %s;\n", indent_incr, ' ', - ivl_udp_port(udp, 0)); + fprintf(vlog_out, "%*creg ", indent_incr, ' '); + emit_id(ivl_udp_port(udp, 0)); + fprintf(vlog_out, ";\n"); switch (init) { case '0': case '1': @@ -209,8 +215,9 @@ static void emit_udp(ivl_udp_t udp) init = 'x'; break; } - fprintf(vlog_out, "%*cinitial %s = 1'b%c;\n", - indent_incr, ' ', ivl_udp_port(udp, 0), init); + fprintf(vlog_out, "%*cinitial ", indent_incr, ' '); + emit_id(ivl_udp_port(udp, 0)); + fprintf(vlog_out, " = 1'b%c;\n", init); } fprintf(vlog_out, "\n"); fprintf(vlog_out, "%*ctable\n", indent_incr, ' '); diff --git a/tgt-vlog95/vlog95_priv.h b/tgt-vlog95/vlog95_priv.h index 97c832150..2698be1a8 100644 --- a/tgt-vlog95/vlog95_priv.h +++ b/tgt-vlog95/vlog95_priv.h @@ -81,6 +81,7 @@ extern void emit_scope_call_path(ivl_scope_t scope, ivl_scope_t call_scope); extern void emit_scope_module_path(ivl_scope_t scope, ivl_scope_t call_scope); extern void emit_name_of_nexus(ivl_scope_t scope, ivl_nexus_t nex); extern void emit_nexus_as_ca(ivl_scope_t scope, ivl_nexus_t nex); +extern void emit_nexus_port_driver_as_ca(ivl_scope_t scope, ivl_nexus_t nex); extern void emit_const_nexus(ivl_scope_t scope, ivl_net_const_t const_net); extern void emit_signal_net_const_as_ca(ivl_scope_t scope, ivl_signal_t sig); extern void emit_icarus_generated_udps(); @@ -89,6 +90,7 @@ extern void add_udp_to_list(ivl_udp_t udp); extern void emit_udp_list(); extern void emit_sig_file_line(ivl_signal_t sig); +extern void emit_id(const char *id); extern void emit_real_number(double value); extern void emit_number(const char *bits, unsigned nbits, unsigned is_signed, const char *file, unsigned lineno);