Parse and elaborate timescale to scopes.
This commit is contained in:
parent
741b17245d
commit
286cef19fb
8
Module.h
8
Module.h
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
12
elaborate.cc
12
elaborate.cc
|
|
@ -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
113
lexor.lex
|
|
@ -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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
27
net_scope.cc
27
net_scope.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
36
netlist.h
36
netlist.h
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
16
pform.cc
16
pform.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue