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:
Cary R 2010-01-22 15:26:02 -08:00 committed by Stephen Williams
parent 9afa95dff7
commit 2d1b8e4c81
6 changed files with 167 additions and 10 deletions

View File

@ -4,7 +4,7 @@
%{
/*
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -76,13 +76,15 @@ int cmdfile_stack_ptr = 0;
"+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; }
"+timescale+" { BEGIN(PLUS_ARGS); return TOK_TIMESCALE; }
/* If it is not any known plus-flag, return the generic form. */
"+"[^\n \t\b\f\r+]* {

View File

@ -1,6 +1,6 @@
%{
/*
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -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
%token TOK_INTEGER_WIDTH
%token TOK_DEFINE TOK_INCDIR TOK_INTEGER_WIDTH TOK_LIBDIR TOK_LIBDIR_NOCASE
%token TOK_LIBEXT TOK_TIMESCALE
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
%%
@ -135,6 +135,13 @@ item
free(tmp);
}
| TOK_TIMESCALE TOK_PLUSARG
{ char*tmp = substitutions($2);
process_timescale(tmp);
free($2);
free(tmp);
}
| TOK_DEFINE TOK_PLUSARG
{ process_define($2);
free($2);

View File

@ -1,7 +1,7 @@
#ifndef __globals_H
#define __globals_H
/*
* Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -41,4 +41,7 @@ extern void process_include_dir(const char*name);
/* Add a new -D define. */
extern void process_define(const char*name);
/* Set the default timescale for the simulator. */
extern void process_timescale(const char*ts_string);
#endif

View File

@ -1,4 +1,4 @@
.TH iverilog 1 "October 28th, 2009" "" "Version %M.%m.%n %E"
.TH iverilog 1 "January 22nd, 2010" "" "Version %M.%m.%n %E"
.SH NAME
iverilog - Icarus Verilog compiler
@ -402,6 +402,13 @@ letters are correct. For example, "foo" matches "Foo.v" but not
The \fB+define+\fP token is the same as the \fB\-D\fP option on the
command line. The value part of the token is optional.
.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
@ -472,7 +479,7 @@ Tips on using, debugging, and developing the compiler can be found at
.SH COPYRIGHT
.nf
Copyright \(co 2002\-2009 Stephen Williams
Copyright \(co 2002\-2010 Stephen Williams
This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -568,6 +568,11 @@ void process_define(const char*name)
fprintf(defines_file,"D:%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

135
main.cc
View File

@ -1,6 +1,6 @@
const char COPYRIGHT[] =
"Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)";
"Copyright (c) 1998-2010 Stephen Williams (steve@icarus.com)";
/*
* This source code is free software; you can redistribute it
@ -297,6 +297,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
@ -369,6 +490,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];
@ -542,6 +664,17 @@ static void read_iconfig_file(const char*ipath)
flag_errors += 1;
}
} 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);