Clean up interface of the PWire class,
Properly match wire ranges.
This commit is contained in:
parent
332a2d7ff7
commit
37b60a4c52
|
|
@ -18,7 +18,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.4 1999/06/15 02:50:02 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.5 1999/06/17 05:34:42 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
|
@ -55,7 +55,7 @@ FF = nobufz.o propinit.o sigfold.o stupid.o xnfio.o
|
|||
|
||||
O = main.o cprop.o design_dump.o elaborate.o emit.o eval.o lexor.o mangle.o \
|
||||
netlist.o parse.o parse_misc.o pform.o pform_dump.o verinum.o verireal.o \
|
||||
target.o targets.o Module.o PExpr.o PGate.o Statement.o $(FF) $(TT)
|
||||
target.o targets.o Module.o PExpr.o PGate.o PWire.o Statement.o $(FF) $(TT)
|
||||
|
||||
Makefile: Makefile.in config.status
|
||||
./config.status
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: Module.cc,v 1.1 1998/11/03 23:28:51 steve Exp $"
|
||||
#ident "$Id: Module.cc,v 1.2 1999/06/17 05:34:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "Module.h"
|
||||
|
|
@ -44,7 +44,7 @@ PWire* Module::get_wire(const string&name)
|
|||
; cur != wires_.end()
|
||||
; cur ++ ) {
|
||||
|
||||
if ((*cur)->name == name)
|
||||
if ((*cur)->name() == name)
|
||||
return *cur;
|
||||
}
|
||||
|
||||
|
|
@ -54,6 +54,10 @@ PWire* Module::get_wire(const string&name)
|
|||
|
||||
/*
|
||||
* $Log: Module.cc,v $
|
||||
* Revision 1.2 1999/06/17 05:34:42 steve
|
||||
* Clean up interface of the PWire class,
|
||||
* Properly match wire ranges.
|
||||
*
|
||||
* Revision 1.1 1998/11/03 23:28:51 steve
|
||||
* Introduce verilog to CVS.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (c) 1999 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)
|
||||
#ident "$Id: PWire.cc,v 1.1 1999/06/17 05:34:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "PWire.h"
|
||||
# include <assert.h>
|
||||
|
||||
PWire::PWire(const string&n, NetNet::Type t, NetNet::PortType pt)
|
||||
: name_(n), type_(t), port_type_(pt), lidx_(0), ridx_(0)
|
||||
{
|
||||
}
|
||||
|
||||
NetNet::Type PWire::get_wire_type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
bool PWire::set_wire_type(NetNet::Type t)
|
||||
{
|
||||
assert(t != NetNet::IMPLICIT);
|
||||
|
||||
switch (type_) {
|
||||
case NetNet::IMPLICIT:
|
||||
type_ = t;
|
||||
return true;
|
||||
case NetNet::REG:
|
||||
if (t == NetNet::REG) return true;
|
||||
if (t == NetNet::INTEGER) {type_ = t; return true; }
|
||||
return false;
|
||||
default:
|
||||
if (type_ != t)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
NetNet::PortType PWire::get_port_type() const
|
||||
{
|
||||
return port_type_;
|
||||
}
|
||||
|
||||
bool PWire::set_port_type(NetNet::PortType pt)
|
||||
{
|
||||
assert(pt != NetNet::NOT_A_PORT);
|
||||
assert(pt != NetNet::PIMPLICIT);
|
||||
|
||||
switch (port_type_) {
|
||||
case NetNet::PIMPLICIT:
|
||||
port_type_ = pt;
|
||||
return true;
|
||||
|
||||
case NetNet::NOT_A_PORT:
|
||||
return false;
|
||||
|
||||
default:
|
||||
if (port_type_ != pt)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void PWire::set_range(PExpr*m, PExpr*l)
|
||||
{
|
||||
msb_ = svector<PExpr*>(msb_,m);
|
||||
lsb_ = svector<PExpr*>(lsb_,l);
|
||||
}
|
||||
|
||||
void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
|
||||
{
|
||||
assert(lidx_ == 0);
|
||||
assert(ridx_ == 0);
|
||||
assert((type_ == NetNet::REG) || (type_ == NetNet::INTEGER));
|
||||
lidx_ = ldx;
|
||||
ridx_ = rdx;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PWire.cc,v $
|
||||
* Revision 1.1 1999/06/17 05:34:42 steve
|
||||
* Clean up interface of the PWire class,
|
||||
* Properly match wire ranges.
|
||||
*
|
||||
*/
|
||||
|
||||
46
PWire.h
46
PWire.h
|
|
@ -19,12 +19,13 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: PWire.h,v 1.4 1999/06/02 15:38:46 steve Exp $"
|
||||
#ident "$Id: PWire.h,v 1.5 1999/06/17 05:34:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
# include "LineInfo.h"
|
||||
# include <map>
|
||||
# include "svector.h"
|
||||
class ostream;
|
||||
class PExpr;
|
||||
class Design;
|
||||
|
|
@ -37,22 +38,20 @@ class Design;
|
|||
class PWire : public LineInfo {
|
||||
|
||||
public:
|
||||
PWire(const string&n, NetNet::Type t =NetNet::IMPLICIT)
|
||||
: name(n), type(t), port_type(NetNet::NOT_A_PORT), msb(0),
|
||||
lsb(0), lidx(0), ridx(0)
|
||||
{ }
|
||||
PWire(const string&n, NetNet::Type t, NetNet::PortType pt);
|
||||
|
||||
string name;
|
||||
NetNet::Type type;
|
||||
NetNet::PortType port_type;
|
||||
|
||||
PExpr*msb;
|
||||
PExpr*lsb;
|
||||
const string&name() const { return name_; }
|
||||
|
||||
// If this wire is actually a memory, these indices will give
|
||||
// me the size and address range of the memory.
|
||||
PExpr*lidx;
|
||||
PExpr*ridx;
|
||||
NetNet::Type get_wire_type() const;
|
||||
bool set_wire_type(NetNet::Type);
|
||||
|
||||
NetNet::PortType get_port_type() const;
|
||||
bool set_port_type(NetNet::PortType);
|
||||
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
void set_memory_idx(PExpr*ldx, PExpr*rdx);
|
||||
|
||||
map<string,string> attributes;
|
||||
|
||||
|
|
@ -61,6 +60,21 @@ class PWire : public LineInfo {
|
|||
|
||||
void elaborate(Design*, const string&path) const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
NetNet::Type type_;
|
||||
NetNet::PortType port_type_;
|
||||
|
||||
// These members hold expressions for the bit width of the
|
||||
// wire. If they do not exist, the wire is 1 bit wide.
|
||||
svector<PExpr*>msb_;
|
||||
svector<PExpr*>lsb_;
|
||||
|
||||
// If this wire is actually a memory, these indices will give
|
||||
// me the size and address range of the memory.
|
||||
PExpr*lidx_;
|
||||
PExpr*ridx_;
|
||||
|
||||
private: // not implemented
|
||||
PWire(const PWire&);
|
||||
PWire& operator= (const PWire&);
|
||||
|
|
@ -68,6 +82,10 @@ class PWire : public LineInfo {
|
|||
|
||||
/*
|
||||
* $Log: PWire.h,v $
|
||||
* Revision 1.5 1999/06/17 05:34:42 steve
|
||||
* Clean up interface of the PWire class,
|
||||
* Properly match wire ranges.
|
||||
*
|
||||
* Revision 1.4 1999/06/02 15:38:46 steve
|
||||
* Line information with nets.
|
||||
*
|
||||
|
|
|
|||
86
elaborate.cc
86
elaborate.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: elaborate.cc,v 1.45 1999/06/15 05:38:39 steve Exp $"
|
||||
#ident "$Id: elaborate.cc,v 1.46 1999/06/17 05:34:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -100,70 +100,82 @@ static const map<string,PUdp*>* udplist = 0;
|
|||
*/
|
||||
void PWire::elaborate(Design*des, const string&path) const
|
||||
{
|
||||
NetNet::Type wtype = type;
|
||||
NetNet::Type wtype = type_;
|
||||
if (wtype == NetNet::IMPLICIT)
|
||||
wtype = NetNet::WIRE;
|
||||
|
||||
unsigned wid = 1;
|
||||
|
||||
/* Wires, registers and memories can have a width, expressed
|
||||
as the msb index and lsb index. */
|
||||
if (msb && lsb) {
|
||||
verinum*mval = msb->eval_const(des, path);
|
||||
if (msb_.count()) {
|
||||
svector<long>mnum (msb_.count());
|
||||
svector<long>lnum (msb_.count());
|
||||
|
||||
for (unsigned idx = 0 ; idx < msb_.count() ; idx += 1) {
|
||||
verinum*mval = msb_[idx]->eval_const(des,path);
|
||||
if (mval == 0) {
|
||||
cerr << msb->get_line() << ": Unable to evaluate "
|
||||
"constant expression ``" << *msb << "''." <<
|
||||
endl;
|
||||
cerr << msb_[idx]->get_line() << ": Unable to "
|
||||
"evaluate constant expression ``" <<
|
||||
*msb_[idx] << "''." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
verinum*lval = lsb->eval_const(des, path);
|
||||
verinum*lval = lsb_[idx]->eval_const(des, path);
|
||||
if (mval == 0) {
|
||||
cerr << lsb->get_line() << ": Unable to evaluate "
|
||||
"constant expression ``" << *lsb << "''." <<
|
||||
endl;
|
||||
cerr << lsb_[idx]->get_line() << ": Unable to "
|
||||
"evaluate constant expression ``" <<
|
||||
*lsb_[idx] << "''." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
long mnum = mval->as_long();
|
||||
long lnum = lval->as_long();
|
||||
mnum[idx] = mval->as_long();
|
||||
lnum[idx] = lval->as_long();
|
||||
delete mval;
|
||||
delete lval;
|
||||
|
||||
if (mnum > lnum)
|
||||
wid = mnum - lnum + 1;
|
||||
else
|
||||
wid = lnum - mnum + 1;
|
||||
|
||||
} else if (msb) {
|
||||
verinum*val = msb->eval_const(des, path);
|
||||
assert(val);
|
||||
assert(val->as_ulong() > 0);
|
||||
wid = val->as_ulong();
|
||||
}
|
||||
|
||||
if (lidx || ridx) {
|
||||
for (unsigned idx = 1 ; idx < msb_.count() ; idx += 1) {
|
||||
if ((mnum[idx] != mnum[0]) || (lnum[idx] != lnum[0])) {
|
||||
cerr << get_line() << ": Inconsistent width, "
|
||||
"[" << mnum[idx] << ":" << lnum[idx] << "]"
|
||||
" vs. [" << mnum[0] << ":" << lnum[0] << "]"
|
||||
" for signal ``" << name_ << "''" << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (mnum[0] > lnum[0])
|
||||
wid = mnum[0] - lnum[0] + 1;
|
||||
else
|
||||
wid = lnum[0] - mnum[0] + 1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (lidx_ || ridx_) {
|
||||
assert(lidx_ && ridx_);
|
||||
|
||||
// If the register has indices, then this is a
|
||||
// memory. Create the memory object.
|
||||
verinum*lval = lidx->eval_const(des, path);
|
||||
verinum*lval = lidx_->eval_const(des, path);
|
||||
assert(lval);
|
||||
verinum*rval = ridx->eval_const(des, path);
|
||||
verinum*rval = ridx_->eval_const(des, path);
|
||||
assert(rval);
|
||||
|
||||
long lnum = lval->as_long();
|
||||
long rnum = rval->as_long();
|
||||
delete lval;
|
||||
delete rval;
|
||||
NetMemory*sig = new NetMemory(path+"."+name, wid, lnum, rnum);
|
||||
NetMemory*sig = new NetMemory(path+"."+name_, wid, lnum, rnum);
|
||||
sig->set_attributes(attributes);
|
||||
des->add_memory(sig);
|
||||
|
||||
} else {
|
||||
|
||||
NetNet*sig = new NetNet(path + "." + name, wtype, wid);
|
||||
NetNet*sig = new NetNet(path + "." + name_, wtype, wid);
|
||||
sig->set_line(*this);
|
||||
sig->port_type(port_type);
|
||||
sig->port_type(port_type_);
|
||||
sig->set_attributes(attributes);
|
||||
des->add_signal(sig);
|
||||
}
|
||||
|
|
@ -370,7 +382,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, const string&path) const
|
|||
// for the position that matches the binding name.
|
||||
unsigned pidx = 0;
|
||||
while (pidx < nexp) {
|
||||
if (pins_[idx].name == rmod->ports[pidx]->name)
|
||||
if (pins_[idx].name == rmod->ports[pidx]->name())
|
||||
break;
|
||||
|
||||
pidx += 1;
|
||||
|
|
@ -439,14 +451,14 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, const string&path) const
|
|||
|
||||
assert(sig);
|
||||
NetNet*prt = des->find_signal(my_name + "." +
|
||||
rmod->ports[idx]->name);
|
||||
rmod->ports[idx]->name());
|
||||
assert(prt);
|
||||
|
||||
// Check that the parts have matching pin counts. If
|
||||
// not, they are different widths.
|
||||
if (prt->pin_count() != sig->pin_count()) {
|
||||
cerr << get_line() << ": Port " <<
|
||||
rmod->ports[idx]->name << " of " << type_ <<
|
||||
rmod->ports[idx]->name() << " of " << type_ <<
|
||||
" expects " << prt->pin_count() << " pins, got " <<
|
||||
sig->pin_count() << " from " << sig->name() << endl;
|
||||
des->errors += 1;
|
||||
|
|
@ -1563,6 +1575,10 @@ Design* elaborate(const map<string,Module*>&modules,
|
|||
|
||||
/*
|
||||
* $Log: elaborate.cc,v $
|
||||
* Revision 1.46 1999/06/17 05:34:42 steve
|
||||
* Clean up interface of the PWire class,
|
||||
* Properly match wire ranges.
|
||||
*
|
||||
* Revision 1.45 1999/06/15 05:38:39 steve
|
||||
* Support case expression lists.
|
||||
*
|
||||
|
|
|
|||
25
parse.y
25
parse.y
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: parse.y,v 1.43 1999/06/16 03:13:29 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.44 1999/06/17 05:34:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -1057,38 +1057,31 @@ parameter_assign_list
|
|||
|
||||
port
|
||||
: IDENTIFIER
|
||||
{ $$ = new PWire(*$1, NetNet::IMPLICIT);
|
||||
$$->port_type = NetNet::PIMPLICIT;
|
||||
{ $$ = new PWire(*$1, NetNet::IMPLICIT, NetNet::PIMPLICIT);
|
||||
$$->set_file(@1.text);
|
||||
$$->set_lineno(@1.first_line);
|
||||
delete $1;
|
||||
}
|
||||
| IDENTIFIER '[' expression ':' expression ']'
|
||||
{ PWire*tmp = new PWire(*$1, NetNet::IMPLICIT);
|
||||
tmp->port_type = NetNet::PIMPLICIT;
|
||||
{ PWire*tmp = new PWire(*$1, NetNet::IMPLICIT,
|
||||
NetNet::PIMPLICIT);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
if (!pform_expression_is_constant($3)) {
|
||||
yyerror(@3, "msb expression of port bit select "
|
||||
"must be constant.");
|
||||
delete $3;
|
||||
} else {
|
||||
tmp->msb = $3;
|
||||
}
|
||||
if (!pform_expression_is_constant($5)) {
|
||||
yyerror(@3, "lsb expression of port bit select "
|
||||
"must be constant.");
|
||||
delete $5;
|
||||
} else {
|
||||
tmp->lsb = $5;
|
||||
}
|
||||
tmp->set_range($3, $5);
|
||||
delete $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| IDENTIFIER '[' error ']'
|
||||
{ yyerror(@1, "invalid port bit select");
|
||||
$$ = new PWire(*$1, NetNet::IMPLICIT);
|
||||
$$->port_type = NetNet::PIMPLICIT;
|
||||
$$ = new PWire(*$1, NetNet::IMPLICIT, NetNet::PIMPLICIT);
|
||||
$$->set_file(@1.text);
|
||||
$$->set_lineno(@1.first_line);
|
||||
delete $1;
|
||||
|
|
@ -1583,16 +1576,14 @@ udp_port_decl
|
|||
: K_input list_of_variables ';'
|
||||
{ $$ = pform_make_udp_input_ports($2); }
|
||||
| K_output IDENTIFIER ';'
|
||||
{ PWire*pp = new PWire(*$2);
|
||||
pp->port_type = NetNet::POUTPUT;
|
||||
{ PWire*pp = new PWire(*$2, NetNet::IMPLICIT, NetNet::POUTPUT);
|
||||
svector<PWire*>*tmp = new svector<PWire*>(1);
|
||||
(*tmp)[0] = pp;
|
||||
delete $2;
|
||||
$$ = tmp;
|
||||
}
|
||||
| K_reg IDENTIFIER ';'
|
||||
{ PWire*pp = new PWire(*$2, NetNet::REG);
|
||||
pp->port_type = NetNet::PIMPLICIT;
|
||||
{ PWire*pp = new PWire(*$2, NetNet::REG, NetNet::PIMPLICIT);
|
||||
svector<PWire*>*tmp = new svector<PWire*>(1);
|
||||
(*tmp)[0] = pp;
|
||||
delete $2;
|
||||
|
|
|
|||
122
pform.cc
122
pform.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: pform.cc,v 1.27 1999/06/15 03:44:53 steve Exp $"
|
||||
#ident "$Id: pform.cc,v 1.28 1999/06/17 05:34:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "compiler.h"
|
||||
|
|
@ -91,33 +91,21 @@ void pform_make_udp(string*name, list<string>*parms,
|
|||
assert(parms->size() > 0);
|
||||
|
||||
/* Put the declarations into a map, so that I can check them
|
||||
off with the parameters in the list. I will rebuild a list
|
||||
off with the parameters in the list. If the port is already
|
||||
in the map, merge the port type. I will rebuild a list
|
||||
of parameters for the PUdp object. */
|
||||
map<string,PWire*> defs;
|
||||
for (unsigned idx = 0 ; idx < decl->count() ; idx += 1)
|
||||
for (unsigned idx = 0 ; idx < decl->count() ; idx += 1) {
|
||||
|
||||
if (defs[(*decl)[idx]->name] == 0) {
|
||||
defs[(*decl)[idx]->name] = (*decl)[idx];
|
||||
string pname = (*decl)[idx]->name();
|
||||
PWire*cur = defs[pname];
|
||||
if (PWire*cur = defs[pname]) {
|
||||
bool rc = cur->set_port_type((*decl)[idx]->get_port_type());
|
||||
assert(rc);
|
||||
|
||||
} else switch ((*decl)[idx]->port_type) {
|
||||
|
||||
case NetNet::PIMPLICIT:
|
||||
case NetNet::POUTPUT:
|
||||
assert(defs[(*decl)[idx]->name]->port_type != NetNet::PINPUT);
|
||||
// OK, merge the output definitions.
|
||||
defs[(*decl)[idx]->name]->port_type = NetNet::POUTPUT;
|
||||
if ((*decl)[idx]->type == NetNet::REG)
|
||||
defs[(*decl)[idx]->name]->type = NetNet::REG;
|
||||
break;
|
||||
|
||||
case NetNet::PINPUT:
|
||||
// Allow duplicate input declarations.
|
||||
assert(defs[(*decl)[idx]->name]->port_type == NetNet::PINPUT);
|
||||
delete (*decl)[idx];
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
} else {
|
||||
defs[pname] = (*decl)[idx];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -138,11 +126,11 @@ void pform_make_udp(string*name, list<string>*parms,
|
|||
declared a register, if anything. */
|
||||
assert(pins.count() > 0);
|
||||
assert(pins[0]);
|
||||
assert(pins[0]->port_type == NetNet::POUTPUT);
|
||||
assert(pins[0]->get_port_type() == NetNet::POUTPUT);
|
||||
for (unsigned idx = 1 ; idx < pins.count() ; idx += 1) {
|
||||
assert(pins[idx]);
|
||||
assert(pins[idx]->port_type == NetNet::PINPUT);
|
||||
assert(pins[idx]->type != NetNet::REG);
|
||||
assert(pins[idx]->get_port_type() == NetNet::PINPUT);
|
||||
assert(pins[idx]->get_wire_type() != NetNet::REG);
|
||||
}
|
||||
|
||||
/* Interpret and check the table entry strings, to make sure
|
||||
|
|
@ -162,7 +150,7 @@ void pform_make_udp(string*name, list<string>*parms,
|
|||
input[idx] = tmp.substr(0, pins.count()-1);
|
||||
tmp = tmp.substr(pins.count()-1);
|
||||
|
||||
if (pins[0]->type == NetNet::REG) {
|
||||
if (pins[0]->get_wire_type() == NetNet::REG) {
|
||||
assert(tmp[0] == ':');
|
||||
assert(tmp.size() == 4);
|
||||
current[idx] = tmp[1];
|
||||
|
|
@ -181,7 +169,7 @@ void pform_make_udp(string*name, list<string>*parms,
|
|||
verinum::V init = verinum::Vx;
|
||||
if (init_expr) {
|
||||
// XXXX
|
||||
assert(pins[0]->type == NetNet::REG);
|
||||
assert(pins[0]->get_wire_type() == NetNet::REG);
|
||||
|
||||
PAssign*pa = dynamic_cast<PAssign*>(init_expr);
|
||||
assert(pa);
|
||||
|
|
@ -190,7 +178,7 @@ void pform_make_udp(string*name, list<string>*parms,
|
|||
assert(id);
|
||||
|
||||
// XXXX
|
||||
assert(id->name() == pins[0]->name);
|
||||
assert(id->name() == pins[0]->name());
|
||||
|
||||
const PENumber*np = dynamic_cast<const PENumber*>(pa->rval());
|
||||
assert(np);
|
||||
|
|
@ -206,12 +194,12 @@ void pform_make_udp(string*name, list<string>*parms,
|
|||
PUdp*udp = new PUdp(*name, parms->size());
|
||||
|
||||
// Detect sequential udp.
|
||||
if (pins[0]->type == NetNet::REG)
|
||||
if (pins[0]->get_wire_type() == NetNet::REG)
|
||||
udp->sequential = true;
|
||||
|
||||
// Make the port list for the UDP
|
||||
for (unsigned idx = 0 ; idx < pins.count() ; idx += 1)
|
||||
udp->ports[idx] = pins[idx]->name;
|
||||
udp->ports[idx] = pins[idx]->name();
|
||||
|
||||
udp->tinput = input;
|
||||
udp->tcurrent = current;
|
||||
|
|
@ -353,17 +341,19 @@ void pform_makewire(const vlltype&li, const string&name,
|
|||
{
|
||||
PWire*cur = cur_module->get_wire(name);
|
||||
if (cur) {
|
||||
if (cur->type != NetNet::IMPLICIT) {
|
||||
if (cur->get_wire_type() != NetNet::IMPLICIT) {
|
||||
strstream msg;
|
||||
msg << name << " previously defined at " <<
|
||||
cur->get_line() << ".";
|
||||
VLerror(msg.str());
|
||||
} else {
|
||||
bool rc = cur->set_wire_type(type);
|
||||
assert(rc);
|
||||
}
|
||||
cur->type = type;
|
||||
return;
|
||||
}
|
||||
|
||||
cur = new PWire(name, type);
|
||||
cur = new PWire(name, type, NetNet::NOT_A_PORT);
|
||||
cur->set_file(li.text);
|
||||
cur->set_lineno(li.first_line);
|
||||
cur_module->add_wire(cur);
|
||||
|
|
@ -387,12 +377,8 @@ void pform_set_port_type(const string&name, NetNet::PortType pt)
|
|||
return;
|
||||
}
|
||||
|
||||
if (cur->port_type != NetNet::PIMPLICIT) {
|
||||
if (! cur->set_port_type(pt))
|
||||
VLerror("error setting port direction.");
|
||||
return;
|
||||
}
|
||||
|
||||
cur->port_type = pt;
|
||||
}
|
||||
|
||||
void pform_set_attrib(const string&name, const string&key, const string&value)
|
||||
|
|
@ -418,6 +404,10 @@ void pform_set_type_attrib(const string&name, const string&key,
|
|||
(*udp).second ->attributes[key] = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function attaches a memory index range to an existing
|
||||
* register. (The named wire must be a register.
|
||||
*/
|
||||
void pform_set_reg_idx(const string&name, PExpr*l, PExpr*r)
|
||||
{
|
||||
PWire*cur = cur_module->get_wire(name);
|
||||
|
|
@ -426,10 +416,7 @@ void pform_set_reg_idx(const string&name, PExpr*l, PExpr*r)
|
|||
return;
|
||||
}
|
||||
|
||||
assert(cur->lidx == 0);
|
||||
assert(cur->ridx == 0);
|
||||
cur->lidx = l;
|
||||
cur->ridx = r;
|
||||
cur->set_memory_idx(l, r);
|
||||
}
|
||||
|
||||
static void pform_set_net_range(const string&name, const svector<PExpr*>*range)
|
||||
|
|
@ -443,35 +430,9 @@ static void pform_set_net_range(const string&name, const svector<PExpr*>*range)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((cur->msb == 0) && (cur->lsb == 0)){
|
||||
cur->msb = (*range)[0];
|
||||
cur->lsb = (*range)[1];
|
||||
} else {
|
||||
if (cur->msb == 0) {
|
||||
VLerror(yylloc, "missing msb of range.");
|
||||
return;
|
||||
}
|
||||
if (cur->lsb == 0) {
|
||||
VLerror(yylloc, "missing lsb of range.");
|
||||
return;
|
||||
}
|
||||
PExpr*msb = (*range)[0];
|
||||
PExpr*lsb = (*range)[1];
|
||||
assert(msb);
|
||||
assert(lsb);
|
||||
if (msb == 0) {
|
||||
VLerror(yylloc, "failed to parse msb of range.");
|
||||
} else if (lsb == 0) {
|
||||
VLerror(yylloc, "failed to parse lsb of range.");
|
||||
} else if (! (cur->msb->is_the_same(msb) &&
|
||||
cur->lsb->is_the_same(lsb))) {
|
||||
cerr << msb->get_line() << ": bit range mismatch"
|
||||
" for " << name << ": [" << *msb << ":" <<
|
||||
*lsb << "] != [" << *cur->msb << ":" <<
|
||||
*cur->lsb << "]" << endl;
|
||||
error_count += 1;
|
||||
}
|
||||
}
|
||||
assert((*range)[0]);
|
||||
assert((*range)[1]);
|
||||
cur->set_range((*range)[0], (*range)[1]);
|
||||
}
|
||||
|
||||
void pform_set_net_range(list<string>*names, const svector<PExpr*>*range)
|
||||
|
|
@ -503,11 +464,11 @@ static void pform_set_reg_integer(const string&name)
|
|||
{
|
||||
PWire*cur = cur_module->get_wire(name);
|
||||
assert(cur);
|
||||
assert(cur->type == NetNet::REG);
|
||||
cur->type = NetNet::INTEGER;
|
||||
bool rc = cur->set_wire_type(NetNet::INTEGER);
|
||||
assert(rc);
|
||||
|
||||
cur->msb = new PENumber(new verinum(INTEGER_WIDTH-1, INTEGER_WIDTH));
|
||||
cur->lsb = new PENumber(new verinum(0UL, INTEGER_WIDTH));
|
||||
cur->set_range(new PENumber(new verinum(INTEGER_WIDTH-1, INTEGER_WIDTH)),
|
||||
new PENumber(new verinum(0UL, INTEGER_WIDTH)));
|
||||
}
|
||||
|
||||
void pform_set_reg_integer(list<string>*names)
|
||||
|
|
@ -527,8 +488,7 @@ svector<PWire*>* pform_make_udp_input_ports(list<string>*names)
|
|||
for (list<string>::const_iterator cur = names->begin()
|
||||
; cur != names->end()
|
||||
; cur ++ ) {
|
||||
PWire*pp = new PWire(*cur);
|
||||
pp->port_type = NetNet::PINPUT;
|
||||
PWire*pp = new PWire(*cur, NetNet::IMPLICIT, NetNet::PINPUT);
|
||||
(*out)[idx] = pp;
|
||||
}
|
||||
|
||||
|
|
@ -590,6 +550,10 @@ int pform_parse(const char*path, map<string,Module*>&modules,
|
|||
|
||||
/*
|
||||
* $Log: pform.cc,v $
|
||||
* Revision 1.28 1999/06/17 05:34:42 steve
|
||||
* Clean up interface of the PWire class,
|
||||
* Properly match wire ranges.
|
||||
*
|
||||
* Revision 1.27 1999/06/15 03:44:53 steve
|
||||
* Get rid of the STL vector template.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: pform_dump.cc,v 1.22 1999/06/15 05:38:39 steve Exp $"
|
||||
#ident "$Id: pform_dump.cc,v 1.23 1999/06/17 05:34:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -138,9 +138,9 @@ void PEBinary::dump(ostream&out) const
|
|||
|
||||
void PWire::dump(ostream&out) const
|
||||
{
|
||||
out << " " << type;
|
||||
out << " " << type_;
|
||||
|
||||
switch (port_type) {
|
||||
switch (port_type_) {
|
||||
case NetNet::PIMPLICIT:
|
||||
out << " (implicit input)";
|
||||
break;
|
||||
|
|
@ -157,18 +157,18 @@ void PWire::dump(ostream&out) const
|
|||
break;
|
||||
}
|
||||
|
||||
if (lsb || msb) {
|
||||
assert(lsb && msb);
|
||||
out << " [" << *msb << ":" << *lsb << "]";
|
||||
for (unsigned idx = 0 ; idx < msb_.count() ; idx += 1) {
|
||||
assert(lsb_[idx] && msb_[idx]);
|
||||
out << " [" << *msb_[idx] << ":" << *lsb_[idx] << "]";
|
||||
}
|
||||
|
||||
out << " " << name;
|
||||
out << " " << name_;
|
||||
|
||||
// If the wire has indices, dump them.
|
||||
if (lidx || ridx) {
|
||||
if (lidx_ || ridx_) {
|
||||
out << "[";
|
||||
if (lidx) out << *lidx;
|
||||
if (ridx) out << ":" << *ridx;
|
||||
if (lidx_) out << *lidx_;
|
||||
if (ridx_) out << ":" << *ridx_;
|
||||
out << "]";
|
||||
}
|
||||
|
||||
|
|
@ -489,6 +489,10 @@ void PUdp::dump(ostream&out) const
|
|||
|
||||
/*
|
||||
* $Log: pform_dump.cc,v $
|
||||
* Revision 1.23 1999/06/17 05:34:42 steve
|
||||
* Clean up interface of the PWire class,
|
||||
* Properly match wire ranges.
|
||||
*
|
||||
* Revision 1.22 1999/06/15 05:38:39 steve
|
||||
* Support case expression lists.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue