Add +timescale to the command file.
This patch adds a +timescale command to the command file syntax that can be used to set the default time scale of the simulation.
This commit is contained in:
parent
d2dd0daa3c
commit
3cef85b06b
|
|
@ -72,19 +72,21 @@ int cmdfile_stack_ptr = 0;
|
|||
\n { cflloc.first_line += 1; }
|
||||
|
||||
|
||||
"+parameter+" { BEGIN(PLUS_ARGS); return TOK_PARAMETER; }
|
||||
|
||||
"+define+" { BEGIN(PLUS_ARGS); return TOK_DEFINE; }
|
||||
|
||||
"+incdir+" { BEGIN(PLUS_ARGS); return TOK_INCDIR; }
|
||||
|
||||
"+integer-width+" { BEGIN(PLUS_ARGS); return TOK_INTEGER_WIDTH; }
|
||||
|
||||
"+libdir+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR; }
|
||||
|
||||
"+libdir-nocase+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR_NOCASE; }
|
||||
|
||||
"+libext+" { BEGIN(PLUS_ARGS); return TOK_LIBEXT; }
|
||||
|
||||
"+integer-width+" { BEGIN(PLUS_ARGS); return TOK_INTEGER_WIDTH; }
|
||||
"+parameter+" { BEGIN(PLUS_ARGS); return TOK_PARAMETER; }
|
||||
|
||||
"+timescale+" { BEGIN(PLUS_ARGS); return TOK_TIMESCALE; }
|
||||
|
||||
/* If it is not any known plus-flag, return the generic form. */
|
||||
"+"[^\n \t\b\f\r+]* {
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ static void translate_file_name(char*text)
|
|||
};
|
||||
|
||||
%token TOK_Da TOK_Dc TOK_Dv TOK_Dy
|
||||
%token TOK_DEFINE TOK_INCDIR TOK_LIBDIR TOK_LIBDIR_NOCASE TOK_LIBEXT TOK_PARAMETER
|
||||
%token TOK_INTEGER_WIDTH
|
||||
%token TOK_DEFINE TOK_INCDIR TOK_INTEGER_WIDTH TOK_LIBDIR TOK_LIBDIR_NOCASE
|
||||
%token TOK_LIBEXT TOK_PARAMETER TOK_TIMESCALE
|
||||
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
|
||||
|
||||
%%
|
||||
|
|
@ -142,6 +142,15 @@ item
|
|||
free(tmp);
|
||||
}
|
||||
|
||||
/* The +timescale token is used to set the default timescale for
|
||||
the simulator. */
|
||||
| TOK_TIMESCALE TOK_PLUSARG
|
||||
{ char*tmp = substitutions($2);
|
||||
process_timescale(tmp);
|
||||
free($2);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
| TOK_DEFINE TOK_PLUSARG
|
||||
{ process_define($2);
|
||||
free($2);
|
||||
|
|
|
|||
|
|
@ -44,4 +44,7 @@ extern void process_define(const char*name);
|
|||
/* Add a new parameter definition */
|
||||
extern void process_parameter(const char*name);
|
||||
|
||||
/* Set the default timescale for the simulator. */
|
||||
extern void process_timescale(const char*ts_string);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.TH iverilog 1 "October 28th, 2009" "" "Version %M.%m.%n %E"
|
||||
.TH iverilog 1 "December 29th, 2009" "" "Version %M.%m.%n %E"
|
||||
.SH NAME
|
||||
iverilog - Icarus Verilog compiler
|
||||
|
||||
|
|
@ -425,9 +425,16 @@ command line. The value part of the token is optional.
|
|||
|
||||
.TP 8
|
||||
.B +parameter+\fINAME\fP=\fIvalue\fP
|
||||
The \fB+default+\fP token is the same as the \fB\-P\fP option on the
|
||||
The \fB+parameter+\fP token is the same as the \fB\-P\fP option on the
|
||||
command line.
|
||||
|
||||
.TP 8
|
||||
.B +timescale+\fIvalue\fP
|
||||
The \fB+timescale+\fP token is used to set the default timescale for
|
||||
the simulation. This is the time units and precision before any
|
||||
`timescale directive or after a `resetall directive. The default is
|
||||
1s/1s.
|
||||
|
||||
.TP 8
|
||||
.B +toupper-filename
|
||||
This token causes file names after this in the command file to be
|
||||
|
|
|
|||
|
|
@ -582,6 +582,11 @@ void process_parameter(const char*name)
|
|||
fprintf(iconfig_file,"defparam:%s\n", name);
|
||||
}
|
||||
|
||||
void process_timescale(const char*ts_string)
|
||||
{
|
||||
fprintf(iconfig_file, "timescale:%s\n", ts_string);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called while processing a file name in a command
|
||||
* file, or a file name on the command line. Look to see if there is a
|
||||
|
|
|
|||
133
main.cc
133
main.cc
|
|
@ -312,6 +312,127 @@ static void parm_to_flagmap(const string&flag)
|
|||
static void find_module_mention(map<perm_string,bool>&check_map, Module*m);
|
||||
static void find_module_mention(map<perm_string,bool>&check_map, PGenerate*s);
|
||||
|
||||
/*
|
||||
* Convert a string to a time unit or precision.
|
||||
*
|
||||
* Returns true on failure.
|
||||
*/
|
||||
static bool get_ts_const(const char*&cp, int&res, bool is_units)
|
||||
{
|
||||
/* Check for the 1 digit. */
|
||||
if (*cp != '1') {
|
||||
if (is_units) {
|
||||
cerr << "Error: Invalid +timescale units constant "
|
||||
"(1st digit)." << endl;
|
||||
} else {
|
||||
cerr << "Error: Invalid +timescale precision constant "
|
||||
"(1st digit)." << endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
cp += 1;
|
||||
|
||||
/* Check the number of zeros after the 1. */
|
||||
res = strspn(cp, "0");
|
||||
if (res > 2) {
|
||||
if (is_units) {
|
||||
cerr << "Error: Invalid +timescale units constant "
|
||||
"(number of zeros)." << endl;
|
||||
} else {
|
||||
cerr << "Error: Invalid +timescale precision constant "
|
||||
"(number of zeros)." << endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
cp += res;
|
||||
|
||||
/* Now process the scaling string. */
|
||||
if (strncmp("s", cp, 1) == 0) {
|
||||
res -= 0;
|
||||
cp += 1;
|
||||
return false;
|
||||
|
||||
} else if (strncmp("ms", cp, 2) == 0) {
|
||||
res -= 3;
|
||||
cp += 2;
|
||||
return false;
|
||||
|
||||
} else if (strncmp("us", cp, 2) == 0) {
|
||||
res -= 6;
|
||||
cp += 2;
|
||||
return false;
|
||||
|
||||
} else if (strncmp("ns", cp, 2) == 0) {
|
||||
res -= 9;
|
||||
cp += 2;
|
||||
return false;
|
||||
|
||||
} else if (strncmp("ps", cp, 2) == 0) {
|
||||
res -= 12;
|
||||
cp += 2;
|
||||
return false;
|
||||
|
||||
} else if (strncmp("fs", cp, 2) == 0) {
|
||||
res -= 15;
|
||||
cp += 2;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (is_units) {
|
||||
cerr << "Error: Invalid +timescale units scale." << endl;
|
||||
} else {
|
||||
cerr << "Error: Invalid +timescale precision scale." << endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a string with the following form (no space allowed):
|
||||
*
|
||||
* num = < '1' | '10' | '100' >
|
||||
* scale = < 's' | 'ms' | 'us' | 'ns' | 'ps' | 'fs' >
|
||||
*
|
||||
* "<num> <scale> '/' <num> <scale>
|
||||
*
|
||||
* and set the default time units and precision if successful.
|
||||
*
|
||||
* Return true if we have an error processing the timescale string.
|
||||
*/
|
||||
static bool set_default_timescale(const char*ts_string)
|
||||
{
|
||||
/* Because this came from a command file we can not have embedded
|
||||
* space in this string. */
|
||||
const char*cp = ts_string;
|
||||
int units = 0;
|
||||
int prec = 0;
|
||||
|
||||
/* Get the time units. */
|
||||
if (get_ts_const(cp, units, true)) return true;
|
||||
|
||||
/* Skip the '/'. */
|
||||
if (*cp != '/') {
|
||||
cerr << "Error: +timescale separator '/' is missing." << endl;
|
||||
return true;
|
||||
}
|
||||
cp += 1;
|
||||
|
||||
/* Get the time precision. */
|
||||
if (get_ts_const(cp, prec, false)) return true;
|
||||
|
||||
/* The time unit must be greater than or equal to the precision. */
|
||||
if (units < prec) {
|
||||
cerr << "Error: +timescale unit must not be less than the "
|
||||
"precision." << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* We have valid units and precision so set the global defaults. */
|
||||
def_ts_units = units;
|
||||
def_ts_prec = prec;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the contents of a config file. This file is a temporary
|
||||
* configuration file made by the compiler driver to carry the bulky
|
||||
|
|
@ -384,6 +505,7 @@ static void find_module_mention(map<perm_string,bool>&check_map, PGenerate*s);
|
|||
* warnings:<string>
|
||||
* Warning flag letters.
|
||||
*/
|
||||
bool had_timescale = false;
|
||||
static void read_iconfig_file(const char*ipath)
|
||||
{
|
||||
char buf[8*1024];
|
||||
|
|
@ -561,6 +683,17 @@ static void read_iconfig_file(const char*ipath)
|
|||
}
|
||||
} else if (strcmp(buf,"defparam") == 0) {
|
||||
parm_to_defparam_list(cp);
|
||||
} else if (strcmp(buf,"timescale") == 0) {
|
||||
if (had_timescale) {
|
||||
cerr << "Command File: Warning: default timescale "
|
||||
"is being set multiple times." << endl;
|
||||
cerr << " : using the last valid "
|
||||
"+timescale found." << endl;
|
||||
}
|
||||
if (set_default_timescale(cp)) {
|
||||
cerr << " : with +timescale+" << cp << "+" << endl;
|
||||
flag_errors += 1;
|
||||
} else had_timescale = true;
|
||||
}
|
||||
}
|
||||
fclose(ifile);
|
||||
|
|
|
|||
Loading…
Reference in New Issue