Elaborate gate ranges.

This commit is contained in:
steve 1999-02-15 02:06:15 +00:00
parent fef81958bc
commit e5f5f41515
12 changed files with 282 additions and 75 deletions

View File

@ -19,10 +19,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: LineInfo.h,v 1.2 1999/02/01 00:26:48 steve Exp $"
#ident "$Id: LineInfo.h,v 1.3 1999/02/15 02:06:15 steve Exp $"
#endif
# include <cstdio>
# include <string>
class LineInfo {
public:
@ -49,6 +50,9 @@ class LineInfo {
/*
* $Log: LineInfo.h,v $
* Revision 1.3 1999/02/15 02:06:15 steve
* Elaborate gate ranges.
*
* Revision 1.2 1999/02/01 00:26:48 steve
* Carry some line info to the netlist,
* Dump line numbers for processes.

View File

@ -11,7 +11,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 target.o \
targets.o Module.o PExpr.o Statement.o $(FF) $(TT)
targets.o Module.o PExpr.o PGate.o Statement.o $(FF) $(TT)
ivl: $O
$(CXX) $(CXXFLAGS) -o ivl $O

40
PGate.cc Normal file
View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 1999 Stephen Williams (steve@picturel.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: PGate.cc,v 1.1 1999/02/15 02:06:15 steve Exp $"
#endif
# include "PGate.h"
void PGBuiltin::set_range(PExpr*msb, PExpr*lsb)
{
assert(msb_ == 0);
assert(lsb_ == 0);
msb_ = msb;
lsb_ = lsb;
}
/*
* $Log: PGate.cc,v $
* Revision 1.1 1999/02/15 02:06:15 steve
* Elaborate gate ranges.
*
*/

27
PGate.h
View File

@ -1,7 +1,7 @@
#ifndef __PGate_H
#define __PGate_H
/*
* Copyright (c) 1998 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-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
@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: PGate.h,v 1.3 1999/01/25 05:45:56 steve Exp $"
#ident "$Id: PGate.h,v 1.4 1999/02/15 02:06:15 steve Exp $"
#endif
# include <vector>
@ -27,6 +27,7 @@
class PExpr;
class PUdp;
class Design;
class Module;
/*
* A PGate represents a Verilog gate. The gate has a name and other
@ -85,9 +86,16 @@ class PGAssign : public PGate {
};
/* The Builtin class is specifically a gate with one of the builtin
types. The parser recognizes these types during parse. These types
have special properties that allow them to be treated specially. */
/*
* The Builtin class is specifically a gate with one of the builtin
* types. The parser recognizes these types during parse. These types
* have special properties that allow them to be treated specially.
*
* A PGBuiltin can be grouped into an array of devices. If this is
* done, the msb_ and lsb_ are set to the indices of the array
* range. Elaboration causes a gate to be created for each element of
* the array, and a name will be generated for each gate.
*/
class PGBuiltin : public PGate {
public:
@ -99,16 +107,20 @@ class PGBuiltin : public PGate {
public:
explicit PGBuiltin(Type t, const string&name,
const vector<PExpr*>&pins, long del = 0)
: PGate(name, pins, del), type_(t)
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
{ }
Type type() const { return type_; }
void set_range(PExpr*msb, PExpr*lsb);
virtual void dump(ostream&out) const;
virtual void elaborate(Design*, const string&path) const;
private:
Type type_;
PExpr*msb_;
PExpr*lsb_;
};
/*
@ -136,6 +148,9 @@ class PGModule : public PGate {
/*
* $Log: PGate.h,v $
* Revision 1.4 1999/02/15 02:06:15 steve
* Elaborate gate ranges.
*
* Revision 1.3 1999/01/25 05:45:56 steve
* Add the LineInfo class to carry the source file
* location of things. PGate, Statement and PProcess.

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: design_dump.cc,v 1.12 1999/02/08 02:49:56 steve Exp $"
#ident "$Id: design_dump.cc,v 1.13 1999/02/15 02:06:15 steve Exp $"
#endif
/*
@ -143,6 +143,12 @@ void NetLogic::dump_node(ostream&o, unsigned ind) const
case BUF:
o << "buf";
break;
case BUFIF0:
o << "bufif0";
break;
case BUFIF1:
o << "bufif1";
break;
case NAND:
o << "nand";
break;
@ -330,7 +336,10 @@ void NetCondit::dump(ostream&o, unsigned ind) const
o << setw(ind) << "" << "if (";
expr_->dump(o);
o << ")" << endl;
if_->dump(o, ind+4);
if (if_) if_->dump(o, ind+4);
else o << setw(ind+4) << "" << "/* empty */ ;" << endl;
if (else_) {
o << setw(ind) << "" << "else" << endl;
else_->dump(o, ind+4);
@ -497,6 +506,9 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.13 1999/02/15 02:06:15 steve
* Elaborate gate ranges.
*
* Revision 1.12 1999/02/08 02:49:56 steve
* Turn the NetESignal into a NetNode so
* that it can connect to the netlist.

View File

@ -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.14 1999/02/08 02:49:56 steve Exp $"
#ident "$Id: elaborate.cc,v 1.15 1999/02/15 02:06:15 steve Exp $"
#endif
/*
@ -145,53 +145,127 @@ void PGAssign::elaborate(Design*des, const string&path) const
do_assign(des, path, lval, rval);
}
/* Elaborate a Builtin gate. These normally get translated into
NetLogic nodes that reflect the particular logic function. */
/*
* Elaborate a Builtin gate. These normally get translated into
* NetLogic nodes that reflect the particular logic function.
*/
void PGBuiltin::elaborate(Design*des, const string&path) const
{
NetLogic*cur = 0;
unsigned count = 1;
unsigned low, high;
string name = get_name();
if (name == "")
name = des->local_symbol(path);
switch (type()) {
case AND:
cur = new NetLogic(name, pin_count(), NetLogic::AND);
break;
case BUF:
cur = new NetLogic(name, pin_count(), NetLogic::BUF);
break;
case NAND:
cur = new NetLogic(name, pin_count(), NetLogic::NAND);
break;
case NOR:
cur = new NetLogic(name, pin_count(), NetLogic::NOR);
break;
case NOT:
cur = new NetLogic(name, pin_count(), NetLogic::NOT);
break;
case OR:
cur = new NetLogic(name, pin_count(), NetLogic::OR);
break;
case XNOR:
cur = new NetLogic(name, pin_count(), NetLogic::XNOR);
break;
case XOR:
cur = new NetLogic(name, pin_count(), NetLogic::XOR);
break;
/* If the verilog source has a range specification for the
gates, then I am expected to make more then one
gate. Figure out how many are desired. */
if (msb_) {
verinum*msb = msb_->eval_const();
verinum*lsb = lsb_->eval_const();
if (msb == 0) {
cerr << get_line() << ": Unable to evaluate expression "
<< *msb_ << endl;
des->errors += 1;
return;
}
if (lsb == 0) {
cerr << get_line() << ": Unable to evaluate expression "
<< *lsb_ << endl;
des->errors += 1;
return;
}
if (msb->as_long() > lsb->as_long())
count = msb->as_long() - lsb->as_long() + 1;
else
count = lsb->as_long() - msb->as_long() + 1;
low = lsb->as_long();
high = msb->as_long();
}
/* Allocate all the getlist nodes for the gates. */
NetLogic**cur = new NetLogic*[count];
assert(cur);
cur->delay1(get_delay());
cur->delay2(get_delay());
cur->delay3(get_delay());
des->add_node(cur);
for (unsigned idx = 0 ; idx < count ; idx += 1) {
strstream tmp;
unsigned index;
if (low < high)
index = low + idx;
else
index = low - idx;
tmp << name << "<" << index << ">";
const string inm = tmp.str();
switch (type()) {
case AND:
cur[idx] = new NetLogic(inm, pin_count(), NetLogic::AND);
break;
case BUF:
cur[idx] = new NetLogic(inm, pin_count(), NetLogic::BUF);
break;
case BUFIF0:
cur[idx] = new NetLogic(inm, pin_count(), NetLogic::BUFIF0);
break;
case BUFIF1:
cur[idx] = new NetLogic(inm, pin_count(), NetLogic::BUFIF1);
break;
case NAND:
cur[idx] = new NetLogic(inm, pin_count(), NetLogic::NAND);
break;
case NOR:
cur[idx] = new NetLogic(inm, pin_count(), NetLogic::NOR);
break;
case NOT:
cur[idx] = new NetLogic(inm, pin_count(), NetLogic::NOT);
break;
case OR:
cur[idx] = new NetLogic(inm, pin_count(), NetLogic::OR);
break;
case XNOR:
cur[idx] = new NetLogic(inm, pin_count(), NetLogic::XNOR);
break;
case XOR:
cur[idx] = new NetLogic(inm, pin_count(), NetLogic::XOR);
break;
}
cur[idx]->delay1(get_delay());
cur[idx]->delay2(get_delay());
cur[idx]->delay3(get_delay());
des->add_node(cur[idx]);
}
/* The gates have all been allocated, this loop runs through
the parameters and attaches the ports of the objects. */
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
const PExpr*ex = pin(idx);
NetNet*sig = ex->elaborate_net(des, path);
assert(sig);
connect(cur->pin(idx), sig->pin(0));
if (sig->pin_count() == 1)
for (unsigned gdx = 0 ; gdx < count ; gdx += 1)
connect(cur[gdx]->pin(idx), sig->pin(0));
else if (sig->pin_count() == count)
for (unsigned gdx = 0 ; gdx < count ; gdx += 1)
connect(cur[gdx]->pin(idx), sig->pin(gdx));
else {
cerr << get_line() << ": Gate count of " << count <<
" does not match net width of " <<
sig->pin_count() << " at pin " << idx << "."
<< endl;
des->errors += 1;
}
if (NetTmp*tmp = dynamic_cast<NetTmp*>(sig))
delete tmp;
}
@ -873,6 +947,9 @@ Design* elaborate(const map<string,Module*>&modules,
/*
* $Log: elaborate.cc,v $
* Revision 1.15 1999/02/15 02:06:15 steve
* Elaborate gate ranges.
*
* Revision 1.14 1999/02/08 02:49:56 steve
* Turn the NetESignal into a NetNode so
* that it can connect to the netlist.

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: netlist.h,v 1.18 1999/02/08 02:49:56 steve Exp $"
#ident "$Id: netlist.h,v 1.19 1999/02/15 02:06:15 steve Exp $"
#endif
/*
@ -337,7 +337,8 @@ class NetConst : public NetNode {
class NetLogic : public NetNode {
public:
enum TYPE { AND, BUF, NAND, NOR, NOT, OR, XNOR, XOR };
enum TYPE { AND, BUF, BUFIF0, BUFIF1, NAND, NOR, NOT, OR, XNOR,
XOR };
explicit NetLogic(const string&n, unsigned pins, TYPE t);
@ -959,6 +960,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.19 1999/02/15 02:06:15 steve
* Elaborate gate ranges.
*
* Revision 1.18 1999/02/08 02:49:56 steve
* Turn the NetESignal into a NetNode so
* that it can connect to the netlist.

17
parse.y
View File

@ -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.12 1999/02/03 04:20:11 steve Exp $"
#ident "$Id: parse.y,v 1.13 1999/02/15 02:06:15 steve Exp $"
#endif
# include "parse_misc.h"
@ -316,6 +316,21 @@ gate_instance
delete $1;
$$ = tmp;
}
| IDENTIFIER range '(' expression_list ')'
{ lgate*tmp = new lgate;
list<PExpr*>*rng = $2;
tmp->name = *$1;
tmp->parms = $4;
tmp->range[0] = rng->front();
rng->pop_front();
tmp->range[1] = rng->front();
rng->pop_front();
tmp->file = @1.text;
tmp->lineno = @1.first_line;
delete $1;
delete rng;
$$ = tmp;
}
| '(' expression_list ')'
{ lgate*tmp = new lgate;
tmp->name = "";

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-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
@ -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.8 1999/01/25 05:45:56 steve Exp $"
#ident "$Id: pform.cc,v 1.9 1999/02/15 02:06:15 steve Exp $"
#endif
# include "pform.h"
@ -226,35 +226,44 @@ void pform_make_udp(string*name, list<string>*parms,
delete init_expr;
}
/*
* pform_makegates is called when a list of gates (with the same type)
* are ready to be instantiated. The function runs through the list of
* gates and makes an array of wires for the ports of the gate. It
* then calls the pform_makegate function to make the individual gate.
*/
void pform_makegate(PGBuiltin::Type type,
const string&name,
const vector<PExpr*>&wires,
unsigned long delay_val)
unsigned long delay_val,
const lgate&info)
{
PGate*cur = new PGBuiltin(type, name, wires, delay_val);
vector<PExpr*>wires (info.parms->size());
for (unsigned idx = 0 ; idx < wires.size() ; idx += 1) {
PExpr*ep = info.parms->front();
info.parms->pop_front();
wires[idx] = ep;
}
PGBuiltin*cur = new PGBuiltin(type, info.name, wires, delay_val);
if (info.range[0])
cur->set_range(info.range[0], info.range[1]);
cur->set_file(info.file);
cur->set_lineno(info.lineno);
cur_module->add_gate(cur);
}
void pform_makegates(PGBuiltin::Type type,
PExpr*delay, list<lgate>*gates)
{
unsigned long delay_val = evaluate_delay(delay);
unsigned long delay_val = delay? evaluate_delay(delay) : 0;
delete delay;
while (! gates->empty()) {
lgate cur = gates->front();
gates->pop_front();
vector<PExpr*>wires (cur.parms->size());
for (unsigned idx = 0 ; idx < wires.size() ; idx += 1) {
PExpr*ep = cur.parms->front();
cur.parms->pop_front();
wires[idx] = ep;
}
pform_makegate(type, cur.name, wires, delay_val);
pform_makegate(type, delay_val, cur);
}
delete gates;
@ -500,6 +509,9 @@ int pform_parse(const char*path, map<string,Module*>&modules,
/*
* $Log: pform.cc,v $
* Revision 1.9 1999/02/15 02:06:15 steve
* Elaborate gate ranges.
*
* Revision 1.8 1999/01/25 05:45:56 steve
* Add the LineInfo class to carry the source file
* location of things. PGate, Statement and PProcess.

20
pform.h
View File

@ -1,7 +1,7 @@
#ifndef __pform_H
#define __pform_H
/*
* Copyright (c) 1998 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-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
@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: pform.h,v 1.6 1999/01/25 05:45:56 steve Exp $"
#ident "$Id: pform.h,v 1.7 1999/02/15 02:06:15 steve Exp $"
#endif
# include "netlist.h"
@ -63,11 +63,17 @@ class PExpr;
*/
struct lgate {
lgate() : parms(0), lineno(0) { }
lgate()
: parms(0), lineno(0)
{ range[0] = 0;
range[1] = 0;
}
string name;
list<PExpr*>*parms;
PExpr*range[2];
string file;
unsigned lineno;
};
@ -110,11 +116,6 @@ extern list<PWire*>* pform_make_udp_input_ports(list<string>*);
* The makegate function creates a new gate (which need not have a
* name) and connects it to the specified wires.
*/
extern void pform_makegate(PGBuiltin::Type type,
const string&name,
const vector<string>&wires,
unsigned long delay_value);
extern void pform_makegates(PGBuiltin::Type type,
PExpr*delay,
list<lgate>*gates);
@ -137,6 +138,9 @@ extern void pform_dump(ostream&out, Module*mod);
/*
* $Log: pform.h,v $
* Revision 1.7 1999/02/15 02:06:15 steve
* Elaborate gate ranges.
*
* Revision 1.6 1999/01/25 05:45:56 steve
* Add the LineInfo class to carry the source file
* location of things. PGate, Statement and PProcess.

View File

@ -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.9 1999/02/03 04:20:11 steve Exp $"
#ident "$Id: pform_dump.cc,v 1.10 1999/02/15 02:06:15 steve Exp $"
#endif
/*
@ -157,6 +157,12 @@ void PGAssign::dump(ostream&out) const
void PGBuiltin::dump(ostream&out) const
{
switch (type()) {
case PGBuiltin::BUFIF0:
out << " bufif0 #";
break;
case PGBuiltin::BUFIF1:
out << " bufif1 #";
break;
case PGBuiltin::NAND:
out << " nand #";
break;
@ -164,7 +170,13 @@ void PGBuiltin::dump(ostream&out) const
out << " builtin gate #";
}
out << get_delay() << " " << get_name() << "(";
out << get_delay() << " " << get_name();
if (msb_) {
out << " [" << *msb_ << ":" << *lsb_ << "]";
}
out << "(";
dump_pins(out);
out << ");" << endl;
}
@ -395,6 +407,9 @@ void PUdp::dump(ostream&out) const
/*
* $Log: pform_dump.cc,v $
* Revision 1.10 1999/02/15 02:06:15 steve
* Elaborate gate ranges.
*
* Revision 1.9 1999/02/03 04:20:11 steve
* Parse and elaborate the Verilog CASE statement.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: t-vvm.cc,v 1.11 1999/02/08 03:55:55 steve Exp $"
#ident "$Id: t-vvm.cc,v 1.12 1999/02/15 02:06:15 steve Exp $"
#endif
# include <iostream>
@ -360,6 +360,12 @@ void target_vvm::logic(ostream&os, const NetLogic*gate)
os << "static vvm_and" << "<" << gate->pin_count()-1 <<
"," << gate->delay1() << "> ";
break;
case NetLogic::BUFIF0:
os << "static vvm_bufif0<" << gate->delay1() << "> ";
break;
case NetLogic::BUFIF1:
os << "static vvm_bufif1<" << gate->delay1() << "> ";
break;
case NetLogic::NAND:
os << "static vvm_nand" << "<" << gate->pin_count()-1 <<
"," << gate->delay1() << "> ";
@ -831,6 +837,9 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
* Revision 1.12 1999/02/15 02:06:15 steve
* Elaborate gate ranges.
*
* Revision 1.11 1999/02/08 03:55:55 steve
* Do not generate code for signals,
* instead use the NetESignal node to