Catch memory word parameters to tasks.
This commit is contained in:
parent
1f7090135b
commit
08e9a114a2
|
|
@ -18,7 +18,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.47 2000/04/26 20:53:21 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.48 2000/04/28 16:50:53 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
|
@ -77,7 +77,7 @@ 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 \
|
||||
verinum.o verireal.o target.o targets.o util.o Module.o PDelays.o PEvent.o \
|
||||
PExpr.o PGate.o \
|
||||
PTask.o PFunction.o PWire.o Statement.o \
|
||||
$(FF) $(TT)
|
||||
|
|
|
|||
104
elaborate.cc
104
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.162 2000/04/23 03:45:24 steve Exp $"
|
||||
#ident "$Id: elaborate.cc,v 1.163 2000/04/28 16:50:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
# include "PEvent.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
# include "util.h"
|
||||
|
||||
// Urff, I don't like this global variable. I *will* figure out a
|
||||
// way to get rid of it. But, for now the PGModule::elaborate method
|
||||
|
|
@ -41,6 +41,7 @@
|
|||
static const map<string,Module*>* modlist = 0;
|
||||
static const map<string,PUdp*>* udplist = 0;
|
||||
|
||||
|
||||
/*
|
||||
* Elaborate a source wire. The "wire" is the declaration of wires,
|
||||
* registers, ports and memories. The parser has already merged the
|
||||
|
|
@ -50,6 +51,21 @@ static const map<string,PUdp*>* udplist = 0;
|
|||
*/
|
||||
void PWire::elaborate(Design*des, NetScope*scope) const
|
||||
{
|
||||
/* The parser may produce hierarchical names for wires. I here
|
||||
follow the scopes down to the base where I actually want to
|
||||
elaborate the NetNet object. */
|
||||
string basename = name_;
|
||||
for (;;) {
|
||||
string p = parse_first_name(basename);
|
||||
if (basename == "") {
|
||||
basename = p;
|
||||
break;
|
||||
}
|
||||
|
||||
scope = scope->child(p);
|
||||
assert(scope);
|
||||
}
|
||||
|
||||
const string path = scope->name();
|
||||
NetNet::Type wtype = type_;
|
||||
if (wtype == NetNet::IMPLICIT)
|
||||
|
|
@ -100,7 +116,7 @@ void PWire::elaborate(Design*des, NetScope*scope) const
|
|||
cerr << get_line() << ": error: Inconsistent width, "
|
||||
"[" << mnum[idx] << ":" << lnum[idx] << "]"
|
||||
" vs. [" << mnum[0] << ":" << lnum[0] << "]"
|
||||
" for signal ``" << name_ << "''" << endl;
|
||||
" for signal ``" << basename << "''" << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
|
@ -130,13 +146,13 @@ void PWire::elaborate(Design*des, NetScope*scope) const
|
|||
long rnum = rval->as_long();
|
||||
delete lval;
|
||||
delete rval;
|
||||
NetMemory*sig = new NetMemory(path+"."+name_, wid, lnum, rnum);
|
||||
NetMemory*sig = new NetMemory(path+"."+basename, wid, lnum, rnum);
|
||||
sig->set_attributes(attributes);
|
||||
des->add_memory(sig);
|
||||
|
||||
} else {
|
||||
|
||||
NetNet*sig = new NetNet(scope, path + "." + name_, wtype, msb, lsb);
|
||||
NetNet*sig = new NetNet(scope, path + "." +basename, wtype, msb, lsb);
|
||||
sig->set_line(*this);
|
||||
sig->port_type(port_type_);
|
||||
sig->set_attributes(attributes);
|
||||
|
|
@ -745,6 +761,12 @@ NetProc* PAssign::assign_to_memory_(NetMemory*mem, PExpr*ix,
|
|||
assert(rv);
|
||||
|
||||
rv->set_width(mem->width());
|
||||
if (ix == 0) {
|
||||
cerr << get_line() << ": internal error: No index in lval "
|
||||
<< "of assignment to memory?" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(ix);
|
||||
NetNet*idx = ix->elaborate_net(des, path, 0, 0, 0, 0);
|
||||
assert(idx);
|
||||
|
|
@ -884,6 +906,10 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const
|
|||
const PEIdent*id = dynamic_cast<const PEIdent*>(lval());
|
||||
if (id == 0) break;
|
||||
|
||||
NetNet*net = des->find_signal(path, id->name());
|
||||
if (net && (net->scope() == scope))
|
||||
break;
|
||||
|
||||
if (NetMemory*mem = des->find_memory(path, id->name()))
|
||||
return assign_to_memory_(mem, id->msb_, des, path);
|
||||
|
||||
|
|
@ -927,7 +953,7 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const
|
|||
delete rv;
|
||||
rv = tmp;
|
||||
}
|
||||
|
||||
|
||||
NetAssign*cur;
|
||||
|
||||
/* Rewrite delayed assignments as assignments that are
|
||||
|
|
@ -1434,10 +1460,13 @@ NetProc* PCallTask::elaborate_usr(Design*des, const string&path) const
|
|||
|
||||
NetBlock*block = new NetBlock(NetBlock::SEQU);
|
||||
|
||||
|
||||
/* Generate assignment statement statements for the input and
|
||||
INOUT ports of the task. These are managed by writing
|
||||
assignments with the task port the l-value and the passed
|
||||
expression the r-value. */
|
||||
expression the r-value. We know by definition that the port
|
||||
is a reg type, so this elaboration is pretty obvious. */
|
||||
|
||||
for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
|
||||
|
||||
NetNet*port = def->port(idx);
|
||||
|
|
@ -1457,27 +1486,67 @@ NetProc* PCallTask::elaborate_usr(Design*des, const string&path) const
|
|||
cur = new NetUTask(def);
|
||||
block->append(cur);
|
||||
|
||||
/* Generate assignment statement statements for the output and
|
||||
INOUT ports of the task. The l-value in this case is the
|
||||
|
||||
/* Generate assignment statements for the output and INOUT
|
||||
ports of the task. The l-value in this case is the
|
||||
expression passed as a parameter, and the r-value is the
|
||||
port to be copied out. */
|
||||
port to be copied out.
|
||||
|
||||
We know by definition that the r-value of this copy-out is
|
||||
the port, which is a reg. The l-value, however, may be any
|
||||
expression that can be a target to a procedural
|
||||
assignment, including a memory word. */
|
||||
|
||||
for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
|
||||
|
||||
NetNet*port = def->port(idx);
|
||||
|
||||
/* Skip input ports. */
|
||||
assert(port->port_type() != NetNet::NOT_A_PORT);
|
||||
if (port->port_type() == NetNet::PINPUT)
|
||||
continue;
|
||||
|
||||
const PEIdent*id;
|
||||
NetNet*val = 0;
|
||||
NetMemory*mem = 0;
|
||||
if ( (id = dynamic_cast<const PEIdent*>(parms_[idx])) )
|
||||
des->find_symbol(scope, id->name(), val, mem);
|
||||
|
||||
/* Catch the case of memory words passed as an out
|
||||
parameter. Generate an assignment to memory instead
|
||||
of a normal assignment. */
|
||||
if (mem != 0) {
|
||||
assert(id->msb_);
|
||||
NetNet*ix = id->msb_->elaborate_net(des, path,
|
||||
0, 0, 0, 0);
|
||||
assert(ix);
|
||||
|
||||
NetExpr*rv = new NetESignal(port);
|
||||
if (rv->expr_width() < mem->width())
|
||||
rv = pad_to_width(rv, mem->width());
|
||||
|
||||
NetAssignMem*am = new NetAssignMem(mem, ix, rv);
|
||||
am->set_line(*this);
|
||||
block->append(am);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* Elaborate the parameter expression as a net so that
|
||||
it can be used as an l-value. Then check that the
|
||||
parameter width match up. */
|
||||
NetNet*val = parms_[idx]->elaborate_net(des, path,
|
||||
0, 0, 0, 0);
|
||||
parameter width match up.
|
||||
|
||||
XXXX FIXME XXXX This goes nuts if the parameter is a
|
||||
memory word. that must be handled by generating
|
||||
NetAssignMem objects instead. */
|
||||
if (val == 0)
|
||||
val = parms_[idx]->elaborate_net(des, path,
|
||||
0, 0, 0, 0);
|
||||
assert(val);
|
||||
|
||||
|
||||
/* Make an expression out of the actual task port. If
|
||||
the port is smaller then the expression to redeive
|
||||
the port is smaller then the expression to receive
|
||||
the result, then expand the port by padding with
|
||||
zeros. */
|
||||
NetESignal*sig = new NetESignal(port);
|
||||
|
|
@ -2031,6 +2100,9 @@ NetProc* PRepeat::elaborate(Design*des, const string&path) const
|
|||
*/
|
||||
void PTask::elaborate_1(Design*des, const string&path) const
|
||||
{
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
/* Translate the wires that are ports to NetNet pointers by
|
||||
presuming that the name is already elaborated, and look it
|
||||
up in the design. Then save that pointer for later use by
|
||||
|
|
@ -2040,6 +2112,7 @@ void PTask::elaborate_1(Design*des, const string&path) const
|
|||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||
NetNet*tmp = des->find_signal(path, (*ports_)[idx]->name());
|
||||
|
||||
assert(tmp->scope() == scope);
|
||||
ports[idx] = tmp;
|
||||
}
|
||||
|
||||
|
|
@ -2268,6 +2341,9 @@ Design* elaborate(const map<string,Module*>&modules,
|
|||
|
||||
/*
|
||||
* $Log: elaborate.cc,v $
|
||||
* Revision 1.163 2000/04/28 16:50:53 steve
|
||||
* Catch memory word parameters to tasks.
|
||||
*
|
||||
* Revision 1.162 2000/04/23 03:45:24 steve
|
||||
* Add support for the procedural release statement.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.4 2000/04/10 05:26:06 steve Exp $"
|
||||
#ident "$Id: net_design.cc,v 1.5 2000/04/28 16:50:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -26,22 +26,9 @@
|
|||
*/
|
||||
|
||||
# include "netlist.h"
|
||||
# include "util.h"
|
||||
# include <strstream>
|
||||
|
||||
static string parse_first_name(string&path)
|
||||
{
|
||||
unsigned pos = path.find('.');
|
||||
if (pos > path.length()) {
|
||||
string res = path;
|
||||
path = "";
|
||||
return res;
|
||||
}
|
||||
|
||||
string res = path.substr(0, pos);
|
||||
path = path.substr(pos+1, path.length());
|
||||
return res;
|
||||
}
|
||||
|
||||
static string parse_last_name(string&path)
|
||||
{
|
||||
unsigned pos = path.rfind('.');
|
||||
|
|
@ -365,6 +352,47 @@ NetMemory* Design::find_memory(const string&path, const string&name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void Design::find_symbol(const NetScope*scope, const string&key,
|
||||
NetNet*&sig, NetMemory*&mem)
|
||||
{
|
||||
sig = 0;
|
||||
mem = 0;
|
||||
|
||||
for (;;) {
|
||||
/* Form the full heirarchical name for lookups. */
|
||||
string fulname = scope? (scope->name() + "." + key) : key;
|
||||
|
||||
/* Is this a signal? If so, we are done. */
|
||||
if (signals_) {
|
||||
NetNet*cur = signals_;
|
||||
do {
|
||||
if (cur->name() == fulname) {
|
||||
sig = cur;
|
||||
return;
|
||||
}
|
||||
|
||||
cur = cur->sig_prev_;
|
||||
} while (cur != signals_);
|
||||
}
|
||||
|
||||
/* Is this a memory? If so, we are again done. */
|
||||
map<string,NetMemory*>::const_iterator cur
|
||||
= memories_.find(fulname);
|
||||
|
||||
if (cur != memories_.end()) {
|
||||
mem = (*cur).second;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Neither a signal nor memory are found, so go up a
|
||||
scope level and try again. */
|
||||
if (scope == 0)
|
||||
return;
|
||||
|
||||
scope = scope->parent();
|
||||
}
|
||||
}
|
||||
|
||||
void Design::add_function(const string&key, NetFuncDef*def)
|
||||
{
|
||||
funcs_[key] = def;
|
||||
|
|
@ -548,6 +576,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
|
|||
|
||||
/*
|
||||
* $Log: net_design.cc,v $
|
||||
* Revision 1.5 2000/04/28 16:50:53 steve
|
||||
* Catch memory word parameters to tasks.
|
||||
*
|
||||
* Revision 1.4 2000/04/10 05:26:06 steve
|
||||
* All events now use the NetEvent class.
|
||||
*
|
||||
|
|
|
|||
10
netlist.h
10
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.130 2000/04/23 21:17:31 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.131 2000/04/28 16:50:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -2333,6 +2333,11 @@ class Design {
|
|||
void add_memory(NetMemory*);
|
||||
NetMemory* find_memory(const string&path, const string&name);
|
||||
|
||||
/* This is a more general lookup that finds the named signal
|
||||
or memory, whichever is first in the search path. */
|
||||
void find_symbol(const NetScope*,const string&key,
|
||||
NetNet*&sig, NetMemory*&mem);
|
||||
|
||||
// Functions
|
||||
void add_function(const string&n, NetFuncDef*);
|
||||
NetFuncDef* find_function(const string&path, const string&key);
|
||||
|
|
@ -2446,6 +2451,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.131 2000/04/28 16:50:53 steve
|
||||
* Catch memory word parameters to tasks.
|
||||
*
|
||||
* Revision 1.130 2000/04/23 21:17:31 steve
|
||||
* Better comments about bufif devices.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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: util.cc,v 1.1 2000/04/28 16:50:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "util.h"
|
||||
|
||||
string parse_first_name(string&path)
|
||||
{
|
||||
unsigned pos = path.find('.');
|
||||
if (pos > path.length()) {
|
||||
string res = path;
|
||||
path = "";
|
||||
return res;
|
||||
}
|
||||
|
||||
string res = path.substr(0, pos);
|
||||
path = path.substr(pos+1, path.length());
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: util.cc,v $
|
||||
* Revision 1.1 2000/04/28 16:50:53 steve
|
||||
* Catch memory word parameters to tasks.
|
||||
*
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue