Parse and elaborate timescale to scopes.

This commit is contained in:
steve 2000-07-22 22:09:03 +00:00
parent 741b17245d
commit 286cef19fb
9 changed files with 248 additions and 14 deletions

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Module.h,v 1.19 2000/05/16 04:05:15 steve Exp $"
#ident "$Id: Module.h,v 1.20 2000/07/22 22:09:03 steve Exp $"
#endif
# include <list>
@ -84,6 +84,9 @@ class Module {
/* Keep a table of named events declared in the module. */
map<string,PEvent*>events;
/* These are the timescale for this module. The default is
set by the `timescale directive. */
int time_unit, time_precision;
const string&get_name() const { return name_; }
@ -136,6 +139,9 @@ class Module {
/*
* $Log: Module.h,v $
* Revision 1.20 2000/07/22 22:09:03 steve
* Parse and elaborate timescale to scopes.
*
* Revision 1.19 2000/05/16 04:05:15 steve
* Module ports are really special PEIdent
* expressions, because a name can be used

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: design_dump.cc,v 1.90 2000/07/14 06:12:57 steve Exp $"
#ident "$Id: design_dump.cc,v 1.91 2000/07/22 22:09:03 steve Exp $"
#endif
/*
@ -679,6 +679,9 @@ void NetScope::dump(ostream&o) const
}
o << endl;
o << " timescale = 10e" << time_unit() << " / 10e"
<< time_precision() << endl;
/* Dump the parameters for this scope. */
{
map<string,NetExpr*>::const_iterator pp;
@ -935,6 +938,7 @@ void NetEUnary::dump(ostream&o) const
void Design::dump(ostream&o) const
{
o << "DESIGN TIME PRECISION: 10e" << get_precision() << endl;
o << "SCOPES:" << endl;
root_scope_->dump(o);
@ -977,6 +981,9 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.91 2000/07/22 22:09:03 steve
* Parse and elaborate timescale to scopes.
*
* Revision 1.90 2000/07/14 06:12:57 steve
* Move inital value handling from NetNet to Nexus
* objects. This allows better propogation of inital

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_scope.cc,v 1.4 2000/04/09 17:44:30 steve Exp $"
#ident "$Id: elab_scope.cc,v 1.5 2000/07/22 22:09:03 steve Exp $"
#endif
/*
@ -209,7 +209,10 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
// Create the new scope as a MODULE with my name.
NetScope*my_scope = new NetScope(sc, get_name(), NetScope::MODULE);
// Set time units and precision.
my_scope->time_unit(mod->time_unit);
my_scope->time_precision(mod->time_precision);
des->set_precision(mod->time_precision);
// This call actually arranges for the description of the
// module type to process this instance and handle parameters
@ -415,6 +418,9 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
/*
* $Log: elab_scope.cc,v $
* Revision 1.5 2000/07/22 22:09:03 steve
* Parse and elaborate timescale to scopes.
*
* Revision 1.4 2000/04/09 17:44:30 steve
* Catch event declarations during scope elaborate.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elaborate.cc,v 1.178 2000/07/14 06:12:57 steve Exp $"
#ident "$Id: elaborate.cc,v 1.179 2000/07/22 22:09:03 steve Exp $"
#endif
/*
@ -1611,13 +1611,15 @@ NetProc* PDelayStatement::elaborate(Design*des, const string&path) const
}
assert(num);
/* Convert the delay in the units of the scope to the
precision of the design as a whole. */
unsigned long val = des->scale_to_precision(num->as_ulong(), scope);
/* If there is a statement, then elaborate it and create a
NetPDelay statement to contain it. Note that we create a
NetPDelay statement even if the value is 0 because #0 does
in fact have a well defined meaning in Verilog. */
unsigned long val = num->as_ulong();
if (statement_) {
NetProc*stmt = statement_->elaborate(des, path);
return new NetPDelay(val, stmt);
@ -2425,6 +2427,9 @@ Design* elaborate(const map<string,Module*>&modules,
// Make the root scope, then scan the pform looking for scopes
// and parameters.
NetScope*scope = des->make_root_scope(root);
scope->time_unit(rmod->time_unit);
scope->time_precision(rmod->time_precision);
des->set_precision(rmod->time_precision);
if (! rmod->elaborate_scope(des, scope)) {
delete des;
return 0;
@ -2472,6 +2477,9 @@ Design* elaborate(const map<string,Module*>&modules,
/*
* $Log: elaborate.cc,v $
* Revision 1.179 2000/07/22 22:09:03 steve
* Parse and elaborate timescale to scopes.
*
* Revision 1.178 2000/07/14 06:12:57 steve
* Move inital value handling from NetNet to Nexus
* objects. This allows better propogation of inital

113
lexor.lex
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: lexor.lex,v 1.45 2000/06/27 04:36:29 steve Exp $"
#ident "$Id: lexor.lex,v 1.46 2000/07/22 22:09:03 steve Exp $"
#endif
//# define YYSTYPE lexval
@ -39,6 +39,8 @@ extern string vl_file;
# define yylval VLlval
extern YYLTYPE yylloc;
extern void pform_set_timescale(int, int);
static void reset_lexor();
static void line_directive();
static void line_directive2();
@ -53,6 +55,8 @@ static verinum*make_unsized_dec(const char*txt);
static verinum*make_unsized_octal(const char*txt);
static verinum*make_unsized_hex(const char*txt);
static void process_timescale(const char*txt);
static int comment_enter;
%}
@ -218,10 +222,8 @@ W [ \t\b\f\r]+
/* Notice and handle the timescale directive. */
`timescale { BEGIN(PPTIMESCALE); }
<PPTIMESCALE>. { ; }
<PPTIMESCALE>.* { process_timescale(yytext); }
<PPTIMESCALE>\n {
cerr << yylloc.text << ":" << yylloc.first_line
<< ": Sorry, `timescale not supported." << endl;
yylloc.first_line += 1;
BEGIN(0); }
@ -815,6 +817,109 @@ static verinum*make_unsized_dec(const char*txt)
return make_dec_with_size(INTEGER_WIDTH, false, txt+1);
}
/*
* The timescale parameter has the form:
* " <num> xs / <num> xs"
*/
static void process_timescale(const char*txt)
{
unsigned num;
const char*cp = txt + strspn(txt, " \t");
char*tmp;
const char*ctmp;
int unit = 0;
int prec = 0;
num = strtoul(cp, &tmp, 10);
if (num == 0) {
VLerror(yylloc, "Invalid timescale string.");
return;
}
while (num >= 10) {
unit += 1;
num /= 10;
}
if (num != 1) {
VLerror(yylloc, "Invalid timescale unit number.");
return;
}
cp = tmp;
cp += strspn(cp, " \t");
ctmp = cp + strcspn(cp, " \t/");
if (strncmp("s", cp, ctmp-cp) == 0) {
unit -= 0;
} else if (strncmp("ms", cp, ctmp-cp) == 0) {
unit -= 3;
} else if (strncmp("us", cp, ctmp-cp) == 0) {
unit -= 6;
} else if (strncmp("ns", cp, ctmp-cp) == 0) {
unit -= 9;
} else if (strncmp("ps", cp, ctmp-cp) == 0) {
unit -= 12;
} else if (strncmp("fs", cp, ctmp-cp) == 0) {
unit -= 15;
} else {
VLerror(yylloc, "Invalid timescale unit of measurement");
return;
}
cp = ctmp;
cp += strspn(cp, " \t/");
num = strtoul(cp, &tmp, 10);
if (num == 0) {
VLerror(yylloc, "Invalid timescale string.");
return;
}
assert(num);
while (num >= 10) {
prec += 1;
num /= 10;
}
if (num != 1) {
VLerror(yylloc, "Invalid timescale precision number.");
return;
}
cp = tmp;
cp += strspn(cp, " \t");
ctmp = cp + strcspn(cp, " \t");
if (strncmp("s", cp, ctmp-cp) == 0) {
prec -= 0;
} else if (strncmp("ms", cp, ctmp-cp) == 0) {
prec -= 3;
} else if (strncmp("us", cp, ctmp-cp) == 0) {
prec -= 6;
} else if (strncmp("ns", cp, ctmp-cp) == 0) {
prec -= 9;
} else if (strncmp("ps", cp, ctmp-cp) == 0) {
prec -= 12;
} else if (strncmp("fs", cp, ctmp-cp) == 0) {
prec -= 15;
} else {
VLerror(yylloc, "Invalid timescale precision units of measurement");
return;
}
pform_set_timescale(unit, prec);
}
static int yywrap()
{

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_design.cc,v 1.10 2000/07/16 04:56:08 steve Exp $"
#ident "$Id: net_design.cc,v 1.11 2000/07/22 22:09:03 steve Exp $"
#endif
/*
@ -47,6 +47,7 @@ Design:: Design()
: errors(0), root_scope_(0), nodes_(0), procs_(0), lcounter_(0)
{
procs_idx_ = 0;
des_precision_ = 0;
}
Design::~Design()
@ -61,6 +62,31 @@ string Design::local_symbol(const string&path)
return path + "." + res.str();
}
void Design::set_precision(int val)
{
if (val < des_precision_)
des_precision_ = val;
}
int Design::get_precision() const
{
return des_precision_;
}
unsigned long Design::scale_to_precision(unsigned long val,
const NetScope*scope) const
{
int units = scope->time_unit();
assert( units > des_precision_ );
while (units > des_precision_) {
units -= 1;
val *= 10;
}
return val;
}
NetScope* Design::make_root_scope(const string&root)
{
assert(root_scope_ == 0);
@ -471,6 +497,9 @@ void Design::delete_process(NetProcTop*top)
/*
* $Log: net_design.cc,v $
* Revision 1.11 2000/07/22 22:09:03 steve
* Parse and elaborate timescale to scopes.
*
* Revision 1.10 2000/07/16 04:56:08 steve
* Handle some edge cases during node scans.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_scope.cc,v 1.6 2000/05/02 03:13:31 steve Exp $"
#ident "$Id: net_scope.cc,v 1.7 2000/07/22 22:09:03 steve Exp $"
#endif
# include "netlist.h"
@ -46,6 +46,8 @@ NetScope::NetScope(NetScope*up, const string&n, NetScope::TYPE t)
memories_ = 0;
signals_ = 0;
events_ = 0;
time_unit_ = up->time_unit();
time_prec_ = up->time_precision();
sib_ = up_->sub_;
up_->sub_ = this;
}
@ -93,6 +95,26 @@ NetScope::TYPE NetScope::type() const
return type_;
}
void NetScope::time_unit(int val)
{
time_unit_ = val;
}
void NetScope::time_precision(int val)
{
time_prec_ = val;
}
int NetScope::time_unit() const
{
return time_unit_;
}
int NetScope::time_precision() const
{
return time_prec_;
}
string NetScope::basename() const
{
return name_;
@ -281,6 +303,9 @@ string NetScope::local_symbol()
/*
* $Log: net_scope.cc,v $
* Revision 1.7 2000/07/22 22:09:03 steve
* Parse and elaborate timescale to scopes.
*
* Revision 1.6 2000/05/02 03:13:31 steve
* Move memories to the NetScope object.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: netlist.h,v 1.147 2000/07/16 04:56:08 steve Exp $"
#ident "$Id: netlist.h,v 1.148 2000/07/22 22:09:04 steve Exp $"
#endif
/*
@ -2461,6 +2461,20 @@ class NetScope {
TYPE type() const;
/* Scopes have their own time units and time precision. The
unit and precision are given as power of 10, i.e. -3 is
units of milliseconds.
If a NetScope is created with a parent scope, the new scope
will initially inherit the unit and precision of the
parent scope. */
void time_unit(int);
void time_precision(int);
int time_unit() const;
int time_precision() const;
/* The name of the scope is the fully qualified hierarchical
name, whereas the basename is just my name within my parent
scope. */
@ -2492,6 +2506,8 @@ class NetScope {
TYPE type_;
string name_;
signed char time_unit_, time_prec_;
map<string,NetExpr*>parameters_;
map<string,NetExpr*>localparams_;
@ -2531,6 +2547,19 @@ class Design {
NetScope* make_root_scope(const string&name);
NetScope* find_root_scope();
/* Attempt to set the precision to the specified value. If the
precision is already more precise, the keep the precise
setting. This is intended to hold the simulation precision
for use throughout the entire design. */
void set_precision(int val);
int get_precision() const;
/* This function takes a delay value and a scope, and returns
the delay value scaled to the precision of the design. */
unsigned long scale_to_precision(unsigned long, const NetScope*)const;
/* look up a scope. If no starting scope is passed, then the
path name string is taken as an absolute scope
name. Otherwise, the scope is located starting at the
@ -2613,6 +2642,8 @@ class Design {
map<string,string> flags_;
int des_precision_;
unsigned lcounter_;
private: // not implemented
@ -2660,6 +2691,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.148 2000/07/22 22:09:04 steve
* Parse and elaborate timescale to scopes.
*
* Revision 1.147 2000/07/16 04:56:08 steve
* Handle some edge cases during node scans.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: pform.cc,v 1.61 2000/05/23 16:03:13 steve Exp $"
#ident "$Id: pform.cc,v 1.62 2000/07/22 22:09:04 steve Exp $"
#endif
# include "compiler.h"
@ -39,6 +39,8 @@ string vl_file = "";
extern int VLparse();
static Module*pform_cur_module = 0;
static int pform_time_unit = 0;
static int pform_time_prec = 0;
/*
* The scope stack and the following functions handle the processing
@ -53,6 +55,13 @@ struct scope_name_t {
};
static scope_name_t*scope_stack = 0;
void pform_set_timescale(int unit, int prec)
{
assert(unit >= prec);
pform_time_unit = unit;
pform_time_prec = prec;
}
void pform_push_scope(const string&name)
{
scope_name_t*cur = new scope_name_t;
@ -110,6 +119,8 @@ void pform_startmodule(const string&name, svector<Module::port_t*>*ports)
}
pform_cur_module = new Module(name, ports);
pform_cur_module->time_unit = pform_time_unit;
pform_cur_module->time_precision = pform_time_prec;
delete ports;
}
@ -874,6 +885,9 @@ int pform_parse(const char*path, map<string,Module*>&modules,
/*
* $Log: pform.cc,v $
* Revision 1.62 2000/07/22 22:09:04 steve
* Parse and elaborate timescale to scopes.
*
* Revision 1.61 2000/05/23 16:03:13 steve
* Better parsing of expressions lists will empty expressoins.
*