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; }
|
\n { cflloc.first_line += 1; }
|
||||||
|
|
||||||
|
|
||||||
"+parameter+" { BEGIN(PLUS_ARGS); return TOK_PARAMETER; }
|
|
||||||
|
|
||||||
"+define+" { BEGIN(PLUS_ARGS); return TOK_DEFINE; }
|
"+define+" { BEGIN(PLUS_ARGS); return TOK_DEFINE; }
|
||||||
|
|
||||||
"+incdir+" { BEGIN(PLUS_ARGS); return TOK_INCDIR; }
|
"+incdir+" { BEGIN(PLUS_ARGS); return TOK_INCDIR; }
|
||||||
|
|
||||||
|
"+integer-width+" { BEGIN(PLUS_ARGS); return TOK_INTEGER_WIDTH; }
|
||||||
|
|
||||||
"+libdir+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR; }
|
"+libdir+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR; }
|
||||||
|
|
||||||
"+libdir-nocase+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR_NOCASE; }
|
"+libdir-nocase+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR_NOCASE; }
|
||||||
|
|
||||||
"+libext+" { BEGIN(PLUS_ARGS); return TOK_LIBEXT; }
|
"+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. */
|
/* If it is not any known plus-flag, return the generic form. */
|
||||||
"+"[^\n \t\b\f\r+]* {
|
"+"[^\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_Da TOK_Dc TOK_Dv TOK_Dy
|
||||||
%token TOK_DEFINE TOK_INCDIR TOK_LIBDIR TOK_LIBDIR_NOCASE TOK_LIBEXT TOK_PARAMETER
|
%token TOK_DEFINE TOK_INCDIR TOK_INTEGER_WIDTH TOK_LIBDIR TOK_LIBDIR_NOCASE
|
||||||
%token TOK_INTEGER_WIDTH
|
%token TOK_LIBEXT TOK_PARAMETER TOK_TIMESCALE
|
||||||
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
|
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
@ -142,6 +142,15 @@ item
|
||||||
free(tmp);
|
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
|
| TOK_DEFINE TOK_PLUSARG
|
||||||
{ process_define($2);
|
{ process_define($2);
|
||||||
free($2);
|
free($2);
|
||||||
|
|
|
||||||
|
|
@ -43,5 +43,8 @@ extern void process_define(const char*name);
|
||||||
|
|
||||||
/* Add a new parameter definition */
|
/* Add a new parameter definition */
|
||||||
extern void process_parameter(const char*name);
|
extern void process_parameter(const char*name);
|
||||||
|
|
||||||
|
/* Set the default timescale for the simulator. */
|
||||||
|
extern void process_timescale(const char*ts_string);
|
||||||
|
|
||||||
#endif
|
#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
|
.SH NAME
|
||||||
iverilog - Icarus Verilog compiler
|
iverilog - Icarus Verilog compiler
|
||||||
|
|
||||||
|
|
@ -425,9 +425,16 @@ command line. The value part of the token is optional.
|
||||||
|
|
||||||
.TP 8
|
.TP 8
|
||||||
.B +parameter+\fINAME\fP=\fIvalue\fP
|
.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.
|
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
|
.TP 8
|
||||||
.B +toupper-filename
|
.B +toupper-filename
|
||||||
This token causes file names after this in the command file to be
|
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);
|
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
|
* 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
|
* file, or a file name on the command line. Look to see if there is a
|
||||||
|
|
|
||||||
137
main.cc
137
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, Module*m);
|
||||||
static void find_module_mention(map<perm_string,bool>&check_map, PGenerate*s);
|
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
|
* Read the contents of a config file. This file is a temporary
|
||||||
* configuration file made by the compiler driver to carry the bulky
|
* 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>
|
* warnings:<string>
|
||||||
* Warning flag letters.
|
* Warning flag letters.
|
||||||
*/
|
*/
|
||||||
|
bool had_timescale = false;
|
||||||
static void read_iconfig_file(const char*ipath)
|
static void read_iconfig_file(const char*ipath)
|
||||||
{
|
{
|
||||||
char buf[8*1024];
|
char buf[8*1024];
|
||||||
|
|
@ -560,8 +682,19 @@ static void read_iconfig_file(const char*ipath)
|
||||||
flag_errors += 1;
|
flag_errors += 1;
|
||||||
}
|
}
|
||||||
} else if (strcmp(buf,"defparam") == 0) {
|
} else if (strcmp(buf,"defparam") == 0) {
|
||||||
parm_to_defparam_list(cp);
|
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);
|
fclose(ifile);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue