Simulate named event trigger and waits.
This commit is contained in:
parent
b62a7ace5c
commit
30e8289239
|
|
@ -18,7 +18,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.42 2000/04/01 19:31:57 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.43 2000/04/04 03:20:15 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
|
@ -72,7 +72,8 @@ FF = nobufz.o nodangle.o propinit.o synth.o xnfio.o xnfsyn.o
|
|||
O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
|
||||
elab_net.o elab_pexpr.o elab_scope.o emit.o eval.o eval_tree.o \
|
||||
expr_synth.o functor.o lexor.o lexor_keyword.o mangle.o netlist.o \
|
||||
net_design.o net_udp.o nexus_from_link.o pad_to_width.o \
|
||||
net_design.o net_event.o net_scope.o net_udp.o nexus_from_link.o \
|
||||
pad_to_width.o \
|
||||
parse.o parse_misc.o pform.o pform_dump.o \
|
||||
set_width.o \
|
||||
verinum.o verireal.o target.o targets.o Module.o PDelays.o PEvent.o \
|
||||
|
|
|
|||
9
PEvent.h
9
PEvent.h
|
|
@ -19,12 +19,14 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PEvent.h,v 1.1 2000/04/01 19:31:57 steve Exp $"
|
||||
#ident "$Id: PEvent.h,v 1.2 2000/04/04 03:20:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include <string>
|
||||
class ostream;
|
||||
class Design;
|
||||
class NetScope;
|
||||
|
||||
/*
|
||||
* The PEvent class represents event objects. These are things that
|
||||
|
|
@ -38,6 +40,8 @@ class PEvent : public LineInfo {
|
|||
|
||||
string name() const;
|
||||
|
||||
void elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
|
||||
|
|
@ -48,6 +52,9 @@ class PEvent : public LineInfo {
|
|||
|
||||
/*
|
||||
* $Log: PEvent.h,v $
|
||||
* Revision 1.2 2000/04/04 03:20:15 steve
|
||||
* Simulate named event trigger and waits.
|
||||
*
|
||||
* Revision 1.1 2000/04/01 19:31:57 steve
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.72 2000/04/02 04:26:06 steve Exp $"
|
||||
#ident "$Id: design_dump.cc,v 1.73 2000/04/04 03:20:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -527,6 +527,22 @@ void NetCondit::dump(ostream&o, unsigned ind) const
|
|||
}
|
||||
}
|
||||
|
||||
void NetEvTrig::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "-> " << event_->name() << "; "
|
||||
<< "// " << get_line() << endl;
|
||||
}
|
||||
|
||||
void NetEvWait::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "@" << event_->name()
|
||||
<< " // " << get_line() << endl;
|
||||
if (statement_)
|
||||
statement_->dump(o, ind+2);
|
||||
else
|
||||
o << setw(ind+2) << "" << "/* noop */ ;" << endl;
|
||||
}
|
||||
|
||||
void NetForever::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "forever" << endl;
|
||||
|
|
@ -648,6 +664,12 @@ void NetScope::dump(ostream&o) const
|
|||
}
|
||||
}
|
||||
|
||||
/* Dump the events in this scope. */
|
||||
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_) {
|
||||
o << " event " << cur->name() << "; "
|
||||
<< "// " << cur->get_line() << endl;
|
||||
}
|
||||
|
||||
/* Dump any sub-scopes. */
|
||||
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
|
||||
cur->dump(o);
|
||||
|
|
@ -906,6 +928,9 @@ void Design::dump(ostream&o) const
|
|||
|
||||
/*
|
||||
* $Log: design_dump.cc,v $
|
||||
* Revision 1.73 2000/04/04 03:20:15 steve
|
||||
* Simulate named event trigger and waits.
|
||||
*
|
||||
* Revision 1.72 2000/04/02 04:26:06 steve
|
||||
* Remove the useless sref template.
|
||||
*
|
||||
|
|
|
|||
66
elaborate.cc
66
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.153 2000/04/01 22:14:19 steve Exp $"
|
||||
#ident "$Id: elaborate.cc,v 1.154 2000/04/04 03:20:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
# include <typeinfo>
|
||||
# include <strstream>
|
||||
# include "pform.h"
|
||||
# include "PEvent.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
|
|
@ -47,6 +48,13 @@ string Design::local_symbol(const string&path)
|
|||
static const map<string,Module*>* modlist = 0;
|
||||
static const map<string,PUdp*>* udplist = 0;
|
||||
|
||||
void PEvent::elaborate(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetEvent*ev = new NetEvent(name_);
|
||||
ev->set_line(*this);
|
||||
scope->add_event(ev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Elaborate a source wire. The "wire" is the declaration of wires,
|
||||
* registers, ports and memories. The parser has already merged the
|
||||
|
|
@ -1540,6 +1548,30 @@ NetProc* PDelayStatement::elaborate(Design*des, const string&path) const
|
|||
NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
|
||||
NetProc*enet) const
|
||||
{
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
/* Handle as a special case the block on an event. In this
|
||||
case I generate a NetEvWait object to represent me.
|
||||
|
||||
XXXX Do I want to move all event handling to NetEvent style
|
||||
event support? I think I do. */
|
||||
|
||||
if ((expr_.count() == 1) && (expr_[0]->expr() == 0)) {
|
||||
string ename = expr_[0]->name();
|
||||
NetEvent*ev = scope->find_event(ename);
|
||||
if (ev == 0) {
|
||||
cerr << get_line() << ": error: no such named event "
|
||||
<< "``" << ename << "''." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEvWait*pr = new NetEvWait(ev, enet);
|
||||
pr->set_line(*this);
|
||||
return pr;
|
||||
}
|
||||
|
||||
|
||||
/* Create a single NetPEvent, and a unique NetNEvent for each
|
||||
conjuctive event. An NetNEvent can have many pins only if
|
||||
|
|
@ -1837,10 +1869,20 @@ void PTask::elaborate_2(Design*des, const string&path) const
|
|||
|
||||
NetProc* PTrigger::elaborate(Design*des, const string&path) const
|
||||
{
|
||||
cerr << get_line() << ": sorry: named event trigger not supported."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
NetEvent*ev = scope->find_event(event_);
|
||||
if (ev == 0) {
|
||||
cerr << get_line() << ": error: event <" << event_ << ">"
|
||||
<< " not found." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEvTrig*trig = new NetEvTrig(ev);
|
||||
trig->set_line(*this);
|
||||
return trig;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1856,11 +1898,22 @@ NetProc* PWhile::elaborate(Design*des, const string&path) const
|
|||
return loop;
|
||||
}
|
||||
|
||||
/*
|
||||
* When a module is instantiated, it creates the scope then uses this
|
||||
* method to elaborate the contents of the module.
|
||||
*/
|
||||
bool Module::elaborate(Design*des, NetScope*scope) const
|
||||
{
|
||||
const string path = scope->name();
|
||||
bool result_flag = true;
|
||||
|
||||
// Scan through the named events and elaborate them.
|
||||
for (map<string,PEvent*>::const_iterator et = events.begin()
|
||||
; et != events.end() ; et ++ ) {
|
||||
|
||||
(*et).second->elaborate(des, scope);
|
||||
|
||||
}
|
||||
|
||||
// Get all the explicitly declared wires of the module and
|
||||
// start the signals list with them.
|
||||
|
|
@ -2018,6 +2071,9 @@ Design* elaborate(const map<string,Module*>&modules,
|
|||
|
||||
/*
|
||||
* $Log: elaborate.cc,v $
|
||||
* Revision 1.154 2000/04/04 03:20:15 steve
|
||||
* Simulate named event trigger and waits.
|
||||
*
|
||||
* Revision 1.153 2000/04/01 22:14:19 steve
|
||||
* detect unsupported block on named events.
|
||||
*
|
||||
|
|
|
|||
24
emit.cc
24
emit.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: emit.cc,v 1.36 2000/04/01 21:40:22 steve Exp $"
|
||||
#ident "$Id: emit.cc,v 1.37 2000/04/04 03:20:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -248,6 +248,21 @@ void NetCondit::emit_recurse_else(ostream&o, struct target_t*tgt) const
|
|||
else_->emit_proc(o, tgt);
|
||||
}
|
||||
|
||||
bool NetEvTrig::emit_proc(ostream&o, struct target_t*tgt) const
|
||||
{
|
||||
return tgt->proc_trigger(o, this);
|
||||
}
|
||||
|
||||
bool NetEvWait::emit_proc(ostream&o, struct target_t*tgt) const
|
||||
{
|
||||
return tgt->proc_wait(o, this);
|
||||
}
|
||||
|
||||
bool NetEvWait::emit_recurse(ostream&o, struct target_t*tgt) const
|
||||
{
|
||||
return statement_->emit_proc(o, tgt);
|
||||
}
|
||||
|
||||
void NetForever::emit_recurse(ostream&o, struct target_t*tgt) const
|
||||
{
|
||||
if (statement_)
|
||||
|
|
@ -263,6 +278,10 @@ void NetRepeat::emit_recurse(ostream&o, struct target_t*tgt) const
|
|||
void NetScope::emit_scope(ostream&o, struct target_t*tgt) const
|
||||
{
|
||||
tgt->scope(o, this);
|
||||
|
||||
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_)
|
||||
tgt->event(o, cur);
|
||||
|
||||
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
|
||||
cur->emit_scope(o, tgt);
|
||||
}
|
||||
|
|
@ -407,6 +426,9 @@ bool emit(ostream&o, const Design*des, const char*type)
|
|||
|
||||
/*
|
||||
* $Log: emit.cc,v $
|
||||
* Revision 1.37 2000/04/04 03:20:15 steve
|
||||
* Simulate named event trigger and waits.
|
||||
*
|
||||
* Revision 1.36 2000/04/01 21:40:22 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 2000 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
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: net_event.cc,v 1.1 2000/04/04 03:20:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
||||
NetEvent::NetEvent(const string&n)
|
||||
: name_(n)
|
||||
{
|
||||
scope_ = 0;
|
||||
snext_ = 0;
|
||||
}
|
||||
|
||||
NetEvent::~NetEvent()
|
||||
{
|
||||
}
|
||||
|
||||
string NetEvent::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
string NetEvent::full_name() const
|
||||
{
|
||||
assert(scope_);
|
||||
return scope_->name() + "." + name_;
|
||||
}
|
||||
|
||||
NetEvTrig::NetEvTrig(NetEvent*ev)
|
||||
: event_(ev)
|
||||
{
|
||||
}
|
||||
|
||||
NetEvTrig::~NetEvTrig()
|
||||
{
|
||||
}
|
||||
|
||||
const NetEvent* NetEvTrig::event() const
|
||||
{
|
||||
return event_;
|
||||
}
|
||||
|
||||
NetEvWait::NetEvWait(NetEvent*ev, NetProc*pr)
|
||||
: event_(ev), statement_(pr)
|
||||
{
|
||||
}
|
||||
|
||||
NetEvWait::~NetEvWait()
|
||||
{
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
const NetEvent* NetEvWait::event() const
|
||||
{
|
||||
return event_;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: net_event.cc,v $
|
||||
* Revision 1.1 2000/04/04 03:20:15 steve
|
||||
* Simulate named event trigger and waits.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Copyright (c) 2000 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
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: net_scope.cc,v 1.1 2000/04/04 03:20:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
||||
/*
|
||||
* The NetScope class keeps a scope tree organized. Each node of the
|
||||
* scope tree points to its parent, its right sibling and its leftmost
|
||||
* child. The root node has no parent or siblings. The node stores the
|
||||
* name of the scope. The complete hierarchical name of the scope is
|
||||
* formed by appending the path of scopes from the root to the scope
|
||||
* in question.
|
||||
*/
|
||||
NetScope::NetScope(const string&n)
|
||||
: type_(NetScope::MODULE), name_(n), up_(0), sib_(0), sub_(0)
|
||||
{
|
||||
events_ = 0;
|
||||
}
|
||||
|
||||
NetScope::NetScope(NetScope*up, const string&n, NetScope::TYPE t)
|
||||
: type_(t), name_(n), up_(up), sib_(0), sub_(0)
|
||||
{
|
||||
sib_ = up_->sub_;
|
||||
up_->sub_ = this;
|
||||
}
|
||||
|
||||
NetScope::~NetScope()
|
||||
{
|
||||
assert(sib_ == 0);
|
||||
assert(sub_ == 0);
|
||||
}
|
||||
|
||||
NetExpr* NetScope::set_parameter(const string&key, NetExpr*expr)
|
||||
{
|
||||
NetExpr*&ref = parameters_[key];
|
||||
NetExpr* res = ref;
|
||||
ref = expr;
|
||||
return res;
|
||||
}
|
||||
|
||||
NetExpr* NetScope::set_localparam(const string&key, NetExpr*expr)
|
||||
{
|
||||
NetExpr*&ref = localparams_[key];
|
||||
NetExpr* res = ref;
|
||||
ref = expr;
|
||||
return res;
|
||||
}
|
||||
|
||||
const NetExpr* NetScope::get_parameter(const string&key) const
|
||||
{
|
||||
map<string,NetExpr*>::const_iterator idx;
|
||||
|
||||
idx = parameters_.find(key);
|
||||
if (idx != parameters_.end())
|
||||
return (*idx).second;
|
||||
|
||||
idx = localparams_.find(key);
|
||||
if (idx != localparams_.end())
|
||||
return (*idx).second;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetScope::TYPE NetScope::type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
string NetScope::name() const
|
||||
{
|
||||
if (up_)
|
||||
return up_->name() + "." + name_;
|
||||
else
|
||||
return name_;
|
||||
}
|
||||
|
||||
void NetScope::add_event(NetEvent*ev)
|
||||
{
|
||||
assert(ev->scope_ == 0);
|
||||
ev->scope_ = this;
|
||||
ev->snext_ = events_;
|
||||
events_ = ev;
|
||||
}
|
||||
|
||||
NetEvent* NetScope::find_event(const string&name)
|
||||
{
|
||||
for (NetEvent*cur = events_; cur ; cur = cur->snext_)
|
||||
if (cur->name() == name)
|
||||
return cur;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method locates a child scope by name. The name is the simple
|
||||
* name of the child, no heirarchy is searched.
|
||||
*/
|
||||
NetScope* NetScope::child(const string&name)
|
||||
{
|
||||
if (sub_ == 0) return 0;
|
||||
|
||||
NetScope*cur = sub_;
|
||||
while (cur->name_ != name) {
|
||||
if (cur->sib_ == 0) return 0;
|
||||
cur = cur->sib_;
|
||||
}
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
const NetScope* NetScope::child(const string&name) const
|
||||
{
|
||||
if (sub_ == 0) return 0;
|
||||
|
||||
NetScope*cur = sub_;
|
||||
while (cur->name_ != name) {
|
||||
if (cur->sib_ == 0) return 0;
|
||||
cur = cur->sib_;
|
||||
}
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
NetScope* NetScope::parent()
|
||||
{
|
||||
return up_;
|
||||
}
|
||||
|
||||
const NetScope* NetScope::parent() const
|
||||
{
|
||||
return up_;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: net_scope.cc,v $
|
||||
* Revision 1.1 2000/04/04 03:20:15 steve
|
||||
* Simulate named event trigger and waits.
|
||||
*
|
||||
*/
|
||||
|
||||
117
netlist.cc
117
netlist.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: netlist.cc,v 1.111 2000/04/02 04:26:06 steve Exp $"
|
||||
#ident "$Id: netlist.cc,v 1.112 2000/04/04 03:20:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <cassert>
|
||||
|
|
@ -1760,7 +1760,7 @@ NetNEvent::NetNEvent(const string&ev, unsigned wid, Type e, NetPEvent*pe)
|
|||
{
|
||||
event_ = pe;
|
||||
next_ = pe->src_;
|
||||
pe->src_ = next_;
|
||||
pe->src_ = this;
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
pin(idx).set_name("P", idx);
|
||||
|
|
@ -2359,116 +2359,6 @@ const NetExpr* NetRepeat::expr() const
|
|||
return expr_;
|
||||
}
|
||||
|
||||
/*
|
||||
* The NetScope class keeps a scope tree organized. Each node of the
|
||||
* scope tree points to its parent, its right sibling and its leftmost
|
||||
* child. The root node has no parent or siblings. The node stores the
|
||||
* name of the scope. The complete hierarchical name of the scope is
|
||||
* formed by appending the path of scopes from the root to the scope
|
||||
* in question.
|
||||
*/
|
||||
NetScope::NetScope(const string&n)
|
||||
: type_(NetScope::MODULE), name_(n), up_(0), sib_(0), sub_(0)
|
||||
{
|
||||
}
|
||||
|
||||
NetScope::NetScope(NetScope*up, const string&n, NetScope::TYPE t)
|
||||
: type_(t), name_(n), up_(up), sib_(0), sub_(0)
|
||||
{
|
||||
sib_ = up_->sub_;
|
||||
up_->sub_ = this;
|
||||
}
|
||||
|
||||
NetScope::~NetScope()
|
||||
{
|
||||
assert(sib_ == 0);
|
||||
assert(sub_ == 0);
|
||||
}
|
||||
|
||||
NetExpr* NetScope::set_parameter(const string&key, NetExpr*expr)
|
||||
{
|
||||
NetExpr*&ref = parameters_[key];
|
||||
NetExpr* res = ref;
|
||||
ref = expr;
|
||||
return res;
|
||||
}
|
||||
|
||||
NetExpr* NetScope::set_localparam(const string&key, NetExpr*expr)
|
||||
{
|
||||
NetExpr*&ref = localparams_[key];
|
||||
NetExpr* res = ref;
|
||||
ref = expr;
|
||||
return res;
|
||||
}
|
||||
|
||||
const NetExpr* NetScope::get_parameter(const string&key) const
|
||||
{
|
||||
map<string,NetExpr*>::const_iterator idx;
|
||||
|
||||
idx = parameters_.find(key);
|
||||
if (idx != parameters_.end())
|
||||
return (*idx).second;
|
||||
|
||||
idx = localparams_.find(key);
|
||||
if (idx != localparams_.end())
|
||||
return (*idx).second;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetScope::TYPE NetScope::type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
string NetScope::name() const
|
||||
{
|
||||
if (up_)
|
||||
return up_->name() + "." + name_;
|
||||
else
|
||||
return name_;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method locates a child scope by name. The name is the simple
|
||||
* name of the child, no heirarchy is searched.
|
||||
*/
|
||||
NetScope* NetScope::child(const string&name)
|
||||
{
|
||||
if (sub_ == 0) return 0;
|
||||
|
||||
NetScope*cur = sub_;
|
||||
while (cur->name_ != name) {
|
||||
if (cur->sib_ == 0) return 0;
|
||||
cur = cur->sib_;
|
||||
}
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
const NetScope* NetScope::child(const string&name) const
|
||||
{
|
||||
if (sub_ == 0) return 0;
|
||||
|
||||
NetScope*cur = sub_;
|
||||
while (cur->name_ != name) {
|
||||
if (cur->sib_ == 0) return 0;
|
||||
cur = cur->sib_;
|
||||
}
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
NetScope* NetScope::parent()
|
||||
{
|
||||
return up_;
|
||||
}
|
||||
|
||||
const NetScope* NetScope::parent() const
|
||||
{
|
||||
return up_;
|
||||
}
|
||||
|
||||
NetTaskDef::NetTaskDef(const string&n, const svector<NetNet*>&po)
|
||||
: name_(n), proc_(0), ports_(po)
|
||||
{
|
||||
|
|
@ -2640,6 +2530,9 @@ bool NetUDP::sequ_glob_(string input, char output)
|
|||
|
||||
/*
|
||||
* $Log: netlist.cc,v $
|
||||
* Revision 1.112 2000/04/04 03:20:15 steve
|
||||
* Simulate named event trigger and waits.
|
||||
*
|
||||
* Revision 1.111 2000/04/02 04:26:06 steve
|
||||
* Remove the useless sref template.
|
||||
*
|
||||
|
|
|
|||
93
netlist.h
93
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.117 2000/04/02 04:26:06 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.118 2000/04/04 03:20:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -1243,6 +1243,84 @@ class NetCondit : public NetProc {
|
|||
NetProc*else_;
|
||||
};
|
||||
|
||||
/*
|
||||
* A NetEvent is an object that represents an event object, that is
|
||||
* objects declared like so in Verilog:
|
||||
*
|
||||
* event foo;
|
||||
*
|
||||
* Once an object of this type exists, behavioral code can wait on the
|
||||
* event or trigger the event. Event waits refer to this object, as do
|
||||
* the event trigger statements.
|
||||
*
|
||||
* The NetEvWait class represents a thread wait for an event. When
|
||||
* this statement is executed, it starts waiting on the
|
||||
* event. Conceptually, it puts itself on the event list for the
|
||||
* referenced event. When the event is triggered, the wit ends its
|
||||
* block and starts the associated statement.
|
||||
*
|
||||
* The NetEvTrig class represents trigger statements. Executing this
|
||||
* statement causes the referenced event to be triggered, which it
|
||||
* turn awakens the waiting threads.
|
||||
*/
|
||||
class NetEvent : public LineInfo {
|
||||
|
||||
friend class NetScope;
|
||||
|
||||
public:
|
||||
explicit NetEvent (const string&n);
|
||||
~NetEvent();
|
||||
|
||||
string name() const;
|
||||
string full_name() const;
|
||||
|
||||
NetScope* scope();
|
||||
const NetScope* scope() const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
|
||||
// The NetScope class uses these to list the events.
|
||||
NetScope*scope_;
|
||||
NetEvent*snext_;
|
||||
|
||||
private: // not implemented
|
||||
NetEvent(const NetEvent&);
|
||||
NetEvent& operator= (const NetEvent&);
|
||||
};
|
||||
|
||||
class NetEvTrig : public NetProc {
|
||||
|
||||
public:
|
||||
explicit NetEvTrig(NetEvent*tgt);
|
||||
~NetEvTrig();
|
||||
|
||||
const NetEvent*event() const;
|
||||
|
||||
virtual bool emit_proc(ostream&, struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
|
||||
private:
|
||||
NetEvent*event_;
|
||||
};
|
||||
|
||||
class NetEvWait : public NetProc {
|
||||
|
||||
public:
|
||||
explicit NetEvWait(NetEvent*tgt, NetProc*st);
|
||||
~NetEvWait();
|
||||
|
||||
const NetEvent*event() const;
|
||||
|
||||
virtual bool emit_proc(ostream&, struct target_t*) const;
|
||||
bool emit_recurse(ostream&, struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
|
||||
private:
|
||||
NetEvent*event_;
|
||||
NetProc*statement_;
|
||||
};
|
||||
|
||||
/*
|
||||
* A forever statement is executed over and over again forever. Or
|
||||
* until its block is disabled.
|
||||
|
|
@ -1365,7 +1443,10 @@ class NetNEvent : public NetNode {
|
|||
public:
|
||||
enum Type { ANYEDGE, POSEDGE, NEGEDGE, POSITIVE };
|
||||
|
||||
// Use this constructor to create NEvent objects that receive
|
||||
// their status from the structural netlist.
|
||||
NetNEvent(const string&ev, unsigned wid, Type e, NetPEvent*pe);
|
||||
|
||||
~NetNEvent();
|
||||
|
||||
Type type() const;
|
||||
|
|
@ -2081,6 +2162,11 @@ class NetScope {
|
|||
NetExpr* set_localparam(const string&name, NetExpr*val);
|
||||
const NetExpr*get_parameter(const string&name) const;
|
||||
|
||||
/* These methods set or access events that live in this
|
||||
scope. */
|
||||
|
||||
void add_event(NetEvent*);
|
||||
NetEvent*find_event(const string&name);
|
||||
|
||||
/* The parent and child() methods allow users of NetScope
|
||||
objects to locate nearby scopes. */
|
||||
|
|
@ -2112,6 +2198,8 @@ class NetScope {
|
|||
map<string,NetExpr*>parameters_;
|
||||
map<string,NetExpr*>localparams_;
|
||||
|
||||
NetEvent*events_;
|
||||
|
||||
NetScope*up_;
|
||||
NetScope*sib_;
|
||||
NetScope*sub_;
|
||||
|
|
@ -2280,6 +2368,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.118 2000/04/04 03:20:15 steve
|
||||
* Simulate named event trigger and waits.
|
||||
*
|
||||
* Revision 1.117 2000/04/02 04:26:06 steve
|
||||
* Remove the useless sref template.
|
||||
*
|
||||
|
|
|
|||
52
t-vvm.cc
52
t-vvm.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: t-vvm.cc,v 1.129 2000/04/02 04:26:07 steve Exp $"
|
||||
#ident "$Id: t-vvm.cc,v 1.130 2000/04/04 03:20:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <iostream>
|
||||
|
|
@ -57,6 +57,7 @@ class target_vvm : public target_t {
|
|||
|
||||
virtual void start_design(ostream&os, const Design*);
|
||||
virtual void scope(ostream&os, const NetScope*);
|
||||
virtual void event(ostream&os, const NetEvent*);
|
||||
virtual void signal(ostream&os, const NetNet*);
|
||||
virtual void memory(ostream&os, const NetMemory*);
|
||||
virtual void task_def(ostream&os, const NetTaskDef*);
|
||||
|
|
@ -93,7 +94,9 @@ class target_vvm : public target_t {
|
|||
virtual void proc_forever(ostream&os, const NetForever*);
|
||||
virtual void proc_repeat(ostream&os, const NetRepeat*);
|
||||
virtual void proc_stask(ostream&os, const NetSTask*);
|
||||
virtual bool proc_trigger(ostream&os, const NetEvTrig*);
|
||||
virtual void proc_utask(ostream&os, const NetUTask*);
|
||||
virtual bool proc_wait(ostream&os, const NetEvWait*);
|
||||
virtual void proc_while(ostream&os, const NetWhile*);
|
||||
virtual void proc_event(ostream&os, const NetPEvent*);
|
||||
virtual void proc_delay(ostream&os, const NetPDelay*);
|
||||
|
|
@ -781,6 +784,13 @@ void target_vvm::scope(ostream&os, const NetScope*scope)
|
|||
type_code << ", \"" << scope->name() << "\");" << endl;
|
||||
}
|
||||
|
||||
void target_vvm::event(ostream&os, const NetEvent*event)
|
||||
{
|
||||
string mname = mangle(event->full_name());
|
||||
os << "static vvm_sync " << mname << "; // "
|
||||
<< event->get_line() << ": event " << event->full_name() << endl;
|
||||
}
|
||||
|
||||
void target_vvm::end_design(ostream&os, const Design*mod)
|
||||
{
|
||||
os << "static struct __vpiStringConst string_table[" <<
|
||||
|
|
@ -2350,6 +2360,19 @@ void target_vvm::proc_stask(ostream&os, const NetSTask*net)
|
|||
defn << " if (vpip_finished()) return false;" << endl;
|
||||
}
|
||||
|
||||
bool target_vvm::proc_trigger(ostream&os, const NetEvTrig*trig)
|
||||
{
|
||||
const NetEvent*ev = trig->event();
|
||||
assert(ev);
|
||||
|
||||
string ename = mangle(ev->full_name());
|
||||
|
||||
defn << " " << ename << ".wakeup(); // "
|
||||
<< trig->get_line() << ": -> " << ev->full_name() << endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void target_vvm::proc_utask(ostream&os, const NetUTask*net)
|
||||
{
|
||||
unsigned out_step = ++thread_step_;
|
||||
|
|
@ -2368,6 +2391,30 @@ void target_vvm::proc_utask(ostream&os, const NetUTask*net)
|
|||
defn << " callee_ = 0;" << endl;
|
||||
}
|
||||
|
||||
bool target_vvm::proc_wait(ostream&os, const NetEvWait*wait)
|
||||
{
|
||||
unsigned out_step = ++thread_step_;
|
||||
|
||||
const NetEvent*ev = wait->event();
|
||||
assert(ev);
|
||||
|
||||
string ename = mangle(ev->full_name());
|
||||
|
||||
defn << " step_ = &" << thread_class_ << "::step_"
|
||||
<< out_step << "_;" << endl;
|
||||
defn << " " << ename << ".wait(this); // "
|
||||
<< wait->get_line() << ": @" << ev->full_name() << "..." << endl;
|
||||
|
||||
defn << " return false;" << endl;
|
||||
defn << "}" << endl;
|
||||
|
||||
os << " bool step_" << out_step << "_();" << endl;
|
||||
defn << "bool " << thread_class_ << "::step_" << out_step
|
||||
<< "_() {" << endl;
|
||||
|
||||
return wait->emit_recurse(os, this);
|
||||
}
|
||||
|
||||
/*
|
||||
* The while loop is implemented by making each iteration one [or
|
||||
* more] basic block and letting the loop condition skip to the block
|
||||
|
|
@ -2531,6 +2578,9 @@ extern const struct target tgt_vvm = {
|
|||
};
|
||||
/*
|
||||
* $Log: t-vvm.cc,v $
|
||||
* Revision 1.130 2000/04/04 03:20:15 steve
|
||||
* Simulate named event trigger and waits.
|
||||
*
|
||||
* Revision 1.129 2000/04/02 04:26:07 steve
|
||||
* Remove the useless sref template.
|
||||
*
|
||||
|
|
|
|||
25
target.cc
25
target.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: target.cc,v 1.32 2000/04/01 21:40:23 steve Exp $"
|
||||
#ident "$Id: target.cc,v 1.33 2000/04/04 03:20:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "target.h"
|
||||
|
|
@ -35,6 +35,12 @@ void target_t::scope(ostream&, const NetScope*)
|
|||
{
|
||||
}
|
||||
|
||||
void target_t::event(ostream&, const NetEvent*ev)
|
||||
{
|
||||
cerr << ev->get_line() << ": error: target (" << typeid(*this).name()
|
||||
<< "): Unhandled event <" << ev->full_name() << ">." << endl;
|
||||
}
|
||||
|
||||
void target_t::signal(ostream&os, const NetNet*)
|
||||
{
|
||||
}
|
||||
|
|
@ -231,6 +237,13 @@ void target_t::proc_repeat(ostream&os, const NetRepeat*)
|
|||
"Unhandled proc_repeat." << endl;
|
||||
}
|
||||
|
||||
bool target_t::proc_trigger(ostream&os, const NetEvTrig*tr)
|
||||
{
|
||||
cerr << tr->get_line() << ": error: target (" << typeid(*this).name()
|
||||
<< "): Unhandled event trigger." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
void target_t::proc_stask(ostream&os, const NetSTask*)
|
||||
{
|
||||
cerr << "target (" << typeid(*this).name() << "): "
|
||||
|
|
@ -243,6 +256,13 @@ void target_t::proc_utask(ostream&os, const NetUTask*)
|
|||
"Unhandled proc_utask." << endl;
|
||||
}
|
||||
|
||||
bool target_t::proc_wait(ostream&os, const NetEvWait*tr)
|
||||
{
|
||||
cerr << tr->get_line() << ": error: target (" << typeid(*this).name()
|
||||
<< "): Unhandled event wait." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
void target_t::proc_while(ostream&os, const NetWhile*net)
|
||||
{
|
||||
cerr << "target (" << typeid(*this).name() << "): "
|
||||
|
|
@ -326,6 +346,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
|
|||
|
||||
/*
|
||||
* $Log: target.cc,v $
|
||||
* Revision 1.33 2000/04/04 03:20:15 steve
|
||||
* Simulate named event trigger and waits.
|
||||
*
|
||||
* Revision 1.32 2000/04/01 21:40:23 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
|
|
|
|||
10
target.h
10
target.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: target.h,v 1.31 2000/04/01 21:40:23 steve Exp $"
|
||||
#ident "$Id: target.h,v 1.32 2000/04/04 03:20:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -59,6 +59,9 @@ struct target_t {
|
|||
anything else is called. */
|
||||
virtual void scope(ostream&os, const NetScope*);
|
||||
|
||||
/* Output an event object. Called for each named event in the scope. */
|
||||
virtual void event(ostream&os, const NetEvent*);
|
||||
|
||||
/* Output a signal (called for each signal) */
|
||||
virtual void signal(ostream&os, const NetNet*);
|
||||
|
||||
|
|
@ -104,8 +107,10 @@ struct target_t {
|
|||
virtual void proc_condit(ostream&os, const NetCondit*);
|
||||
virtual void proc_forever(ostream&os, const NetForever*);
|
||||
virtual void proc_repeat(ostream&os, const NetRepeat*);
|
||||
virtual bool proc_trigger(ostream&os, const NetEvTrig*);
|
||||
virtual void proc_stask(ostream&os, const NetSTask*);
|
||||
virtual void proc_utask(ostream&os, const NetUTask*);
|
||||
virtual bool proc_wait(ostream&os, const NetEvWait*);
|
||||
virtual void proc_while(ostream&os, const NetWhile*);
|
||||
|
||||
virtual void proc_event(ostream&os, const NetPEvent*);
|
||||
|
|
@ -149,6 +154,9 @@ extern const struct target *target_table[];
|
|||
|
||||
/*
|
||||
* $Log: target.h,v $
|
||||
* Revision 1.32 2000/04/04 03:20:15 steve
|
||||
* Simulate named event trigger and waits.
|
||||
*
|
||||
* Revision 1.31 2000/04/01 21:40:23 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue