diff --git a/tgt-vlog95/misc.c b/tgt-vlog95/misc.c index 8787c0302..5076bd4c6 100644 --- a/tgt-vlog95/misc.c +++ b/tgt-vlog95/misc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2014 Cary R. (cygcary@yahoo.com) + * Copyright (C) 2011-2016 Cary R. (cygcary@yahoo.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -872,7 +872,8 @@ void emit_scope_path(ivl_scope_t scope, ivl_scope_t call_scope) /* Check to see if this is a root scope task or function. */ if (ivl_scope_parent(call_scope) == 0) { - fprintf(vlog_out, "ivl_root_scope."); + fprintf(vlog_out, "ivl_root_scope_%s.", + ivl_scope_basename(call_scope)); mod_scope = 0; call_mod_scope = 0; } else { @@ -938,3 +939,30 @@ void get_sig_msb_lsb(ivl_signal_t sig, int *msb, int *lsb) break; } } + +const char*get_time_const(int time_value) +{ + switch (time_value) { + case 2: return "100s"; + case 1: return "10s"; + case 0: return "1s"; + case -1: return "100ms"; + case -2: return "10ms"; + case -3: return "1ms"; + case -4: return "100us"; + case -5: return "10us"; + case -6: return "1us"; + case -7: return "100ns"; + case -8: return "10ns"; + case -9: return "1ns"; + case -10: return "100ps"; + case -11: return "10ps"; + case -12: return "1ps"; + case -13: return "100fs"; + case -14: return "10fs"; + case -15: return "1fs"; + default: + fprintf(stderr, "Invalid time constant value %d.\n", time_value); + return "N/A"; + } +} diff --git a/tgt-vlog95/scope.c b/tgt-vlog95/scope.c index fc7ce0dfd..ee0372b80 100644 --- a/tgt-vlog95/scope.c +++ b/tgt-vlog95/scope.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2015 Cary R. (cygcary@yahoo.com) + * Copyright (C) 2010-2016 Cary R. (cygcary@yahoo.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,33 +24,6 @@ const char *func_rtn_name = 0; -static const char*get_time_const(int time_value) -{ - switch (time_value) { - case 2: return "100s"; - case 1: return "10s"; - case 0: return "1s"; - case -1: return "100ms"; - case -2: return "10ms"; - case -3: return "1ms"; - case -4: return "100us"; - case -5: return "10us"; - case -6: return "1us"; - case -7: return "100ns"; - case -8: return "10ns"; - case -9: return "1ns"; - case -10: return "100ps"; - case -11: return "10ps"; - case -12: return "1ps"; - case -13: return "100fs"; - case -14: return "10fs"; - case -15: return "1fs"; - default: - fprintf(stderr, "Invalid time constant value %d.\n", time_value); - return "N/A"; - } -} - static void emit_func_return(ivl_signal_t sig) { if (ivl_signal_dimensions(sig) > 0) { diff --git a/tgt-vlog95/vlog95.c b/tgt-vlog95/vlog95.c index 4841cb522..1890d76b6 100644 --- a/tgt-vlog95/vlog95.c +++ b/tgt-vlog95/vlog95.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2013 Cary R. (cygcary@yahoo.com) + * Copyright (C) 2010-2016 Cary R. (cygcary@yahoo.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -60,7 +60,6 @@ int target_design(ivl_design_t des) { ivl_scope_t *roots; unsigned nroots, idx; - unsigned has_root_scope = 0; const char*path = ivl_design_flag(des, "-o"); /* Set the indent spacing with the -pspacing flag passed to iverilog * (e.g. -pspacing=4). The default is 2 spaces. */ @@ -190,23 +189,27 @@ int target_design(ivl_design_t des) switch(ivl_scope_type(roots[idx])) { case IVL_SCT_FUNCTION: case IVL_SCT_TASK: - if (! has_root_scope) { - fprintf(vlog_out, "module ivl_root_scope;\n"); - indent += indent_incr; - has_root_scope = 1; - } + /* Create a separate module for each task/function. + This allows us to handle different timescales. */ + fprintf(vlog_out, "\n`timescale %s/%s\n", + get_time_const(ivl_scope_time_units(roots[idx])), + get_time_const(ivl_scope_time_precision(roots[idx]))); + fprintf(vlog_out, "module ivl_root_scope_%s;\n", + ivl_scope_basename(roots[idx])); + indent += indent_incr; + /* Say this task/function has a parent so the * definition is emitted correctly. */ emit_scope(roots[idx], roots[idx]); + + indent -= indent_incr; + assert(indent == 0); + fprintf(vlog_out, "endmodule /* ivl_root_scope_%p */\n", + roots[idx]); break; default: break; } - } - if (has_root_scope) { - indent -= indent_incr; - assert(indent == 0); - fprintf(vlog_out, "endmodule /* ivl_root_scope */\n"); } /* Emit the rest of the scope objects. */ for (idx = 0; idx < nroots; idx += 1) emit_scope(roots[idx], 0); diff --git a/tgt-vlog95/vlog95_priv.h b/tgt-vlog95/vlog95_priv.h index fb632d95e..913fd0424 100644 --- a/tgt-vlog95/vlog95_priv.h +++ b/tgt-vlog95/vlog95_priv.h @@ -1,7 +1,7 @@ #ifndef IVL_vlog95_priv_H #define IVL_vlog95_priv_H /* - * Copyright (C) 2010-2014 Cary R. (cygcary@yahoo.com) + * Copyright (C) 2010-2016 Cary R. (cygcary@yahoo.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -145,6 +145,11 @@ extern char * get_package_name(ivl_scope_t scope); */ extern void get_sig_msb_lsb(ivl_signal_t sig, int *msb, int *lsb); +/* + * Convert a timescale value to a string. + */ +extern const char*get_time_const(int time_value); + /* * Cleanup functions. */