Clean up interface of the PWire class,

Properly match wire ranges.
This commit is contained in:
steve 1999-06-17 05:34:42 +00:00
parent 332a2d7ff7
commit 37b60a4c52
8 changed files with 266 additions and 165 deletions

View File

@ -18,7 +18,7 @@
# 59 Temple Place - Suite 330 # 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA # 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 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 \ 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 \ 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 Makefile: Makefile.in config.status
./config.status ./config.status

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "Module.h" # include "Module.h"
@ -44,7 +44,7 @@ PWire* Module::get_wire(const string&name)
; cur != wires_.end() ; cur != wires_.end()
; cur ++ ) { ; cur ++ ) {
if ((*cur)->name == name) if ((*cur)->name() == name)
return *cur; return *cur;
} }
@ -54,6 +54,10 @@ PWire* Module::get_wire(const string&name)
/* /*
* $Log: Module.cc,v $ * $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 * Revision 1.1 1998/11/03 23:28:51 steve
* Introduce verilog to CVS. * Introduce verilog to CVS.
* *

104
PWire.cc Normal file
View File

@ -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
View File

@ -19,12 +19,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "netlist.h" # include "netlist.h"
# include "LineInfo.h" # include "LineInfo.h"
# include <map> # include <map>
# include "svector.h"
class ostream; class ostream;
class PExpr; class PExpr;
class Design; class Design;
@ -37,22 +38,20 @@ class Design;
class PWire : public LineInfo { class PWire : public LineInfo {
public: public:
PWire(const string&n, NetNet::Type t =NetNet::IMPLICIT) PWire(const string&n, NetNet::Type t, NetNet::PortType pt);
: name(n), type(t), port_type(NetNet::NOT_A_PORT), msb(0),
lsb(0), lidx(0), ridx(0)
{ }
string name;
NetNet::Type type;
NetNet::PortType port_type;
PExpr*msb; const string&name() const { return name_; }
PExpr*lsb;
// If this wire is actually a memory, these indices will give NetNet::Type get_wire_type() const;
// me the size and address range of the memory. bool set_wire_type(NetNet::Type);
PExpr*lidx;
PExpr*ridx; 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; map<string,string> attributes;
@ -61,6 +60,21 @@ class PWire : public LineInfo {
void elaborate(Design*, const string&path) const; 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 private: // not implemented
PWire(const PWire&); PWire(const PWire&);
PWire& operator= (const PWire&); PWire& operator= (const PWire&);
@ -68,6 +82,10 @@ class PWire : public LineInfo {
/* /*
* $Log: PWire.h,v $ * $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 * Revision 1.4 1999/06/02 15:38:46 steve
* Line information with nets. * Line information with nets.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
/* /*
@ -100,70 +100,82 @@ static const map<string,PUdp*>* udplist = 0;
*/ */
void PWire::elaborate(Design*des, const string&path) const void PWire::elaborate(Design*des, const string&path) const
{ {
NetNet::Type wtype = type; NetNet::Type wtype = type_;
if (wtype == NetNet::IMPLICIT) if (wtype == NetNet::IMPLICIT)
wtype = NetNet::WIRE; wtype = NetNet::WIRE;
unsigned wid = 1; unsigned wid = 1;
/* Wires, registers and memories can have a width, expressed if (msb_.count()) {
as the msb index and lsb index. */ svector<long>mnum (msb_.count());
if (msb && lsb) { svector<long>lnum (msb_.count());
verinum*mval = msb->eval_const(des, path);
if (mval == 0) { for (unsigned idx = 0 ; idx < msb_.count() ; idx += 1) {
cerr << msb->get_line() << ": Unable to evaluate " verinum*mval = msb_[idx]->eval_const(des,path);
"constant expression ``" << *msb << "''." << if (mval == 0) {
endl; cerr << msb_[idx]->get_line() << ": Unable to "
des->errors += 1; "evaluate constant expression ``" <<
return; *msb_[idx] << "''." << endl;
} des->errors += 1;
verinum*lval = lsb->eval_const(des, path); return;
if (mval == 0) { }
cerr << lsb->get_line() << ": Unable to evaluate " verinum*lval = lsb_[idx]->eval_const(des, path);
"constant expression ``" << *lsb << "''." << if (mval == 0) {
endl; cerr << lsb_[idx]->get_line() << ": Unable to "
des->errors += 1; "evaluate constant expression ``" <<
return; *lsb_[idx] << "''." << endl;
des->errors += 1;
return;
}
mnum[idx] = mval->as_long();
lnum[idx] = lval->as_long();
delete mval;
delete lval;
} }
long mnum = mval->as_long(); for (unsigned idx = 1 ; idx < msb_.count() ; idx += 1) {
long lnum = lval->as_long(); if ((mnum[idx] != mnum[0]) || (lnum[idx] != lnum[0])) {
delete mval; cerr << get_line() << ": Inconsistent width, "
delete lval; "[" << mnum[idx] << ":" << lnum[idx] << "]"
" vs. [" << mnum[0] << ":" << lnum[0] << "]"
" for signal ``" << name_ << "''" << endl;
des->errors += 1;
return;
}
}
if (mnum > lnum) if (mnum[0] > lnum[0])
wid = mnum - lnum + 1; wid = mnum[0] - lnum[0] + 1;
else else
wid = lnum - mnum + 1; wid = lnum[0] - mnum[0] + 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) { if (lidx_ || ridx_) {
assert(lidx_ && ridx_);
// If the register has indices, then this is a // If the register has indices, then this is a
// memory. Create the memory object. // memory. Create the memory object.
verinum*lval = lidx->eval_const(des, path); verinum*lval = lidx_->eval_const(des, path);
assert(lval); assert(lval);
verinum*rval = ridx->eval_const(des, path); verinum*rval = ridx_->eval_const(des, path);
assert(rval); assert(rval);
long lnum = lval->as_long(); long lnum = lval->as_long();
long rnum = rval->as_long(); long rnum = rval->as_long();
delete lval; delete lval;
delete rval; delete rval;
NetMemory*sig = new NetMemory(path+"."+name, wid, lnum, rnum); NetMemory*sig = new NetMemory(path+"."+name_, wid, lnum, rnum);
sig->set_attributes(attributes); sig->set_attributes(attributes);
des->add_memory(sig); des->add_memory(sig);
} else { } else {
NetNet*sig = new NetNet(path + "." + name, wtype, wid); NetNet*sig = new NetNet(path + "." + name_, wtype, wid);
sig->set_line(*this); sig->set_line(*this);
sig->port_type(port_type); sig->port_type(port_type_);
sig->set_attributes(attributes); sig->set_attributes(attributes);
des->add_signal(sig); 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. // for the position that matches the binding name.
unsigned pidx = 0; unsigned pidx = 0;
while (pidx < nexp) { while (pidx < nexp) {
if (pins_[idx].name == rmod->ports[pidx]->name) if (pins_[idx].name == rmod->ports[pidx]->name())
break; break;
pidx += 1; pidx += 1;
@ -439,14 +451,14 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, const string&path) const
assert(sig); assert(sig);
NetNet*prt = des->find_signal(my_name + "." + NetNet*prt = des->find_signal(my_name + "." +
rmod->ports[idx]->name); rmod->ports[idx]->name());
assert(prt); assert(prt);
// Check that the parts have matching pin counts. If // Check that the parts have matching pin counts. If
// not, they are different widths. // not, they are different widths.
if (prt->pin_count() != sig->pin_count()) { if (prt->pin_count() != sig->pin_count()) {
cerr << get_line() << ": Port " << cerr << get_line() << ": Port " <<
rmod->ports[idx]->name << " of " << type_ << rmod->ports[idx]->name() << " of " << type_ <<
" expects " << prt->pin_count() << " pins, got " << " expects " << prt->pin_count() << " pins, got " <<
sig->pin_count() << " from " << sig->name() << endl; sig->pin_count() << " from " << sig->name() << endl;
des->errors += 1; des->errors += 1;
@ -1563,6 +1575,10 @@ Design* elaborate(const map<string,Module*>&modules,
/* /*
* $Log: elaborate.cc,v $ * $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 * Revision 1.45 1999/06/15 05:38:39 steve
* Support case expression lists. * Support case expression lists.
* *

25
parse.y
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "parse_misc.h" # include "parse_misc.h"
@ -1057,38 +1057,31 @@ parameter_assign_list
port port
: IDENTIFIER : IDENTIFIER
{ $$ = new PWire(*$1, NetNet::IMPLICIT); { $$ = new PWire(*$1, NetNet::IMPLICIT, NetNet::PIMPLICIT);
$$->port_type = NetNet::PIMPLICIT;
$$->set_file(@1.text); $$->set_file(@1.text);
$$->set_lineno(@1.first_line); $$->set_lineno(@1.first_line);
delete $1; delete $1;
} }
| IDENTIFIER '[' expression ':' expression ']' | IDENTIFIER '[' expression ':' expression ']'
{ PWire*tmp = new PWire(*$1, NetNet::IMPLICIT); { PWire*tmp = new PWire(*$1, NetNet::IMPLICIT,
tmp->port_type = NetNet::PIMPLICIT; NetNet::PIMPLICIT);
tmp->set_file(@1.text); tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line); tmp->set_lineno(@1.first_line);
if (!pform_expression_is_constant($3)) { if (!pform_expression_is_constant($3)) {
yyerror(@3, "msb expression of port bit select " yyerror(@3, "msb expression of port bit select "
"must be constant."); "must be constant.");
delete $3;
} else {
tmp->msb = $3;
} }
if (!pform_expression_is_constant($5)) { if (!pform_expression_is_constant($5)) {
yyerror(@3, "lsb expression of port bit select " yyerror(@3, "lsb expression of port bit select "
"must be constant."); "must be constant.");
delete $5;
} else {
tmp->lsb = $5;
} }
tmp->set_range($3, $5);
delete $1; delete $1;
$$ = tmp; $$ = tmp;
} }
| IDENTIFIER '[' error ']' | IDENTIFIER '[' error ']'
{ yyerror(@1, "invalid port bit select"); { yyerror(@1, "invalid port bit select");
$$ = new PWire(*$1, NetNet::IMPLICIT); $$ = new PWire(*$1, NetNet::IMPLICIT, NetNet::PIMPLICIT);
$$->port_type = NetNet::PIMPLICIT;
$$->set_file(@1.text); $$->set_file(@1.text);
$$->set_lineno(@1.first_line); $$->set_lineno(@1.first_line);
delete $1; delete $1;
@ -1583,16 +1576,14 @@ udp_port_decl
: K_input list_of_variables ';' : K_input list_of_variables ';'
{ $$ = pform_make_udp_input_ports($2); } { $$ = pform_make_udp_input_ports($2); }
| K_output IDENTIFIER ';' | K_output IDENTIFIER ';'
{ PWire*pp = new PWire(*$2); { PWire*pp = new PWire(*$2, NetNet::IMPLICIT, NetNet::POUTPUT);
pp->port_type = NetNet::POUTPUT;
svector<PWire*>*tmp = new svector<PWire*>(1); svector<PWire*>*tmp = new svector<PWire*>(1);
(*tmp)[0] = pp; (*tmp)[0] = pp;
delete $2; delete $2;
$$ = tmp; $$ = tmp;
} }
| K_reg IDENTIFIER ';' | K_reg IDENTIFIER ';'
{ PWire*pp = new PWire(*$2, NetNet::REG); { PWire*pp = new PWire(*$2, NetNet::REG, NetNet::PIMPLICIT);
pp->port_type = NetNet::PIMPLICIT;
svector<PWire*>*tmp = new svector<PWire*>(1); svector<PWire*>*tmp = new svector<PWire*>(1);
(*tmp)[0] = pp; (*tmp)[0] = pp;
delete $2; delete $2;

122
pform.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "compiler.h" # include "compiler.h"
@ -91,34 +91,22 @@ void pform_make_udp(string*name, list<string>*parms,
assert(parms->size() > 0); assert(parms->size() > 0);
/* Put the declarations into a map, so that I can check them /* 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. */ of parameters for the PUdp object. */
map<string,PWire*> defs; 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) { string pname = (*decl)[idx]->name();
defs[(*decl)[idx]->name] = (*decl)[idx]; 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) { } else {
defs[pname] = (*decl)[idx];
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);
} }
}
/* Put the parameters into a vector of wire descriptions. Look /* Put the parameters into a vector of wire descriptions. Look
@ -138,11 +126,11 @@ void pform_make_udp(string*name, list<string>*parms,
declared a register, if anything. */ declared a register, if anything. */
assert(pins.count() > 0); assert(pins.count() > 0);
assert(pins[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) { for (unsigned idx = 1 ; idx < pins.count() ; idx += 1) {
assert(pins[idx]); assert(pins[idx]);
assert(pins[idx]->port_type == NetNet::PINPUT); assert(pins[idx]->get_port_type() == NetNet::PINPUT);
assert(pins[idx]->type != NetNet::REG); assert(pins[idx]->get_wire_type() != NetNet::REG);
} }
/* Interpret and check the table entry strings, to make sure /* 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); input[idx] = tmp.substr(0, pins.count()-1);
tmp = tmp.substr(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[0] == ':');
assert(tmp.size() == 4); assert(tmp.size() == 4);
current[idx] = tmp[1]; current[idx] = tmp[1];
@ -181,7 +169,7 @@ void pform_make_udp(string*name, list<string>*parms,
verinum::V init = verinum::Vx; verinum::V init = verinum::Vx;
if (init_expr) { if (init_expr) {
// XXXX // XXXX
assert(pins[0]->type == NetNet::REG); assert(pins[0]->get_wire_type() == NetNet::REG);
PAssign*pa = dynamic_cast<PAssign*>(init_expr); PAssign*pa = dynamic_cast<PAssign*>(init_expr);
assert(pa); assert(pa);
@ -190,7 +178,7 @@ void pform_make_udp(string*name, list<string>*parms,
assert(id); assert(id);
// XXXX // XXXX
assert(id->name() == pins[0]->name); assert(id->name() == pins[0]->name());
const PENumber*np = dynamic_cast<const PENumber*>(pa->rval()); const PENumber*np = dynamic_cast<const PENumber*>(pa->rval());
assert(np); assert(np);
@ -206,12 +194,12 @@ void pform_make_udp(string*name, list<string>*parms,
PUdp*udp = new PUdp(*name, parms->size()); PUdp*udp = new PUdp(*name, parms->size());
// Detect sequential udp. // Detect sequential udp.
if (pins[0]->type == NetNet::REG) if (pins[0]->get_wire_type() == NetNet::REG)
udp->sequential = true; udp->sequential = true;
// Make the port list for the UDP // Make the port list for the UDP
for (unsigned idx = 0 ; idx < pins.count() ; idx += 1) 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->tinput = input;
udp->tcurrent = current; udp->tcurrent = current;
@ -353,17 +341,19 @@ void pform_makewire(const vlltype&li, const string&name,
{ {
PWire*cur = cur_module->get_wire(name); PWire*cur = cur_module->get_wire(name);
if (cur) { if (cur) {
if (cur->type != NetNet::IMPLICIT) { if (cur->get_wire_type() != NetNet::IMPLICIT) {
strstream msg; strstream msg;
msg << name << " previously defined at " << msg << name << " previously defined at " <<
cur->get_line() << "."; cur->get_line() << ".";
VLerror(msg.str()); VLerror(msg.str());
} else {
bool rc = cur->set_wire_type(type);
assert(rc);
} }
cur->type = type;
return; return;
} }
cur = new PWire(name, type); cur = new PWire(name, type, NetNet::NOT_A_PORT);
cur->set_file(li.text); cur->set_file(li.text);
cur->set_lineno(li.first_line); cur->set_lineno(li.first_line);
cur_module->add_wire(cur); cur_module->add_wire(cur);
@ -387,12 +377,8 @@ void pform_set_port_type(const string&name, NetNet::PortType pt)
return; return;
} }
if (cur->port_type != NetNet::PIMPLICIT) { if (! cur->set_port_type(pt))
VLerror("error setting port direction."); VLerror("error setting port direction.");
return;
}
cur->port_type = pt;
} }
void pform_set_attrib(const string&name, const string&key, const string&value) 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; (*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) void pform_set_reg_idx(const string&name, PExpr*l, PExpr*r)
{ {
PWire*cur = cur_module->get_wire(name); PWire*cur = cur_module->get_wire(name);
@ -426,10 +416,7 @@ void pform_set_reg_idx(const string&name, PExpr*l, PExpr*r)
return; return;
} }
assert(cur->lidx == 0); cur->set_memory_idx(l, r);
assert(cur->ridx == 0);
cur->lidx = l;
cur->ridx = r;
} }
static void pform_set_net_range(const string&name, const svector<PExpr*>*range) 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; return;
} }
if ((cur->msb == 0) && (cur->lsb == 0)){ assert((*range)[0]);
cur->msb = (*range)[0]; assert((*range)[1]);
cur->lsb = (*range)[1]; cur->set_range((*range)[0], (*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;
}
}
} }
void pform_set_net_range(list<string>*names, const svector<PExpr*>*range) 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); PWire*cur = cur_module->get_wire(name);
assert(cur); assert(cur);
assert(cur->type == NetNet::REG); bool rc = cur->set_wire_type(NetNet::INTEGER);
cur->type = NetNet::INTEGER; assert(rc);
cur->msb = new PENumber(new verinum(INTEGER_WIDTH-1, INTEGER_WIDTH)); cur->set_range(new PENumber(new verinum(INTEGER_WIDTH-1, INTEGER_WIDTH)),
cur->lsb = new PENumber(new verinum(0UL, INTEGER_WIDTH)); new PENumber(new verinum(0UL, INTEGER_WIDTH)));
} }
void pform_set_reg_integer(list<string>*names) 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() for (list<string>::const_iterator cur = names->begin()
; cur != names->end() ; cur != names->end()
; cur ++ ) { ; cur ++ ) {
PWire*pp = new PWire(*cur); PWire*pp = new PWire(*cur, NetNet::IMPLICIT, NetNet::PINPUT);
pp->port_type = NetNet::PINPUT;
(*out)[idx] = pp; (*out)[idx] = pp;
} }
@ -590,6 +550,10 @@ int pform_parse(const char*path, map<string,Module*>&modules,
/* /*
* $Log: pform.cc,v $ * $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 * Revision 1.27 1999/06/15 03:44:53 steve
* Get rid of the STL vector template. * Get rid of the STL vector template.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
/* /*
@ -138,9 +138,9 @@ void PEBinary::dump(ostream&out) const
void PWire::dump(ostream&out) const void PWire::dump(ostream&out) const
{ {
out << " " << type; out << " " << type_;
switch (port_type) { switch (port_type_) {
case NetNet::PIMPLICIT: case NetNet::PIMPLICIT:
out << " (implicit input)"; out << " (implicit input)";
break; break;
@ -157,18 +157,18 @@ void PWire::dump(ostream&out) const
break; break;
} }
if (lsb || msb) { for (unsigned idx = 0 ; idx < msb_.count() ; idx += 1) {
assert(lsb && msb); assert(lsb_[idx] && msb_[idx]);
out << " [" << *msb << ":" << *lsb << "]"; out << " [" << *msb_[idx] << ":" << *lsb_[idx] << "]";
} }
out << " " << name; out << " " << name_;
// If the wire has indices, dump them. // If the wire has indices, dump them.
if (lidx || ridx) { if (lidx_ || ridx_) {
out << "["; out << "[";
if (lidx) out << *lidx; if (lidx_) out << *lidx_;
if (ridx) out << ":" << *ridx; if (ridx_) out << ":" << *ridx_;
out << "]"; out << "]";
} }
@ -489,6 +489,10 @@ void PUdp::dump(ostream&out) const
/* /*
* $Log: pform_dump.cc,v $ * $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 * Revision 1.22 1999/06/15 05:38:39 steve
* Support case expression lists. * Support case expression lists.
* *