Add the LineInfo class to carry the source file

location of things. PGate, Statement and PProcess.

 elaborate handles module parameter mismatches,
 missing or incorrect lvalues for procedural
 assignment, and errors are propogated to the
 top of the elaboration call tree.

 Attach line numbers to processes, gates and
 assignment statements.
This commit is contained in:
steve 1999-01-25 05:45:56 +00:00
parent 4b92e91a54
commit fb439c78b9
9 changed files with 268 additions and 29 deletions

60
LineInfo.h Normal file
View File

@ -0,0 +1,60 @@
#ifndef __LineInfo_H
#define __LineInfo_H
/*
* 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: LineInfo.h,v 1.1 1999/01/25 05:45:56 steve Exp $"
#endif
# include <cstdio>
class LineInfo {
public:
LineInfo() : lineno_(0) { }
string get_line() const
{ char buf[8];
sprintf(buf, "%u", lineno_);
return file_ + ":" + buf;
}
void set_file(const string&f) { file_ = f; }
void set_lineno(unsigned n) { lineno_ = n; }
private:
string file_;
unsigned lineno_;
};
/*
* $Log: LineInfo.h,v $
* Revision 1.1 1999/01/25 05:45:56 steve
* Add the LineInfo class to carry the source file
* location of things. PGate, Statement and PProcess.
*
* elaborate handles module parameter mismatches,
* missing or incorrect lvalues for procedural
* assignment, and errors are propogated to the
* top of the elaboration call tree.
*
* Attach line numbers to processes, gates and
* assignment statements.
*
*/
#endif

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: Module.h,v 1.1 1998/11/03 23:28:52 steve Exp $"
#ident "$Id: Module.h,v 1.2 1999/01/25 05:45:56 steve Exp $"
#endif
# include <list>
@ -57,7 +57,7 @@ class Module {
const list<PGate*>& get_gates() const { return gates_; }
const list<PProcess*>& get_behaviors() const { return behaviors_; }
void elaborate(Design*, const string&path) const;
bool elaborate(Design*, const string&path) const;
private:
const string name_;
@ -74,6 +74,18 @@ class Module {
/*
* $Log: Module.h,v $
* Revision 1.2 1999/01/25 05:45:56 steve
* Add the LineInfo class to carry the source file
* location of things. PGate, Statement and PProcess.
*
* elaborate handles module parameter mismatches,
* missing or incorrect lvalues for procedural
* assignment, and errors are propogated to the
* top of the elaboration call tree.
*
* Attach line numbers to processes, gates and
* assignment statements.
*
* Revision 1.1 1998/11/03 23:28:52 steve
* Introduce verilog to CVS.
*

17
PGate.h
View File

@ -19,10 +19,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: PGate.h,v 1.2 1998/12/01 00:42:13 steve Exp $"
#ident "$Id: PGate.h,v 1.3 1999/01/25 05:45:56 steve Exp $"
#endif
# include <vector>
# include "LineInfo.h"
class PExpr;
class PUdp;
class Design;
@ -36,7 +37,7 @@ class Design;
* step will need to convert expressions to a network of gates in
* order to elaborate expression inputs, but that can easily be done.
*/
class PGate {
class PGate : public LineInfo {
public:
explicit PGate(const string&name, const vector<PExpr*>&pins, long del)
@ -135,6 +136,18 @@ class PGModule : public PGate {
/*
* $Log: PGate.h,v $
* 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.
*
* elaborate handles module parameter mismatches,
* missing or incorrect lvalues for procedural
* assignment, and errors are propogated to the
* top of the elaboration call tree.
*
* Attach line numbers to processes, gates and
* assignment statements.
*
* Revision 1.2 1998/12/01 00:42:13 steve
* Elaborate UDP devices,
* Support UDP type attributes, and

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: Statement.cc,v 1.3 1998/11/11 03:13:04 steve Exp $"
#ident "$Id: Statement.cc,v 1.4 1999/01/25 05:45:56 steve Exp $"
#endif
# include "Statement.h"
@ -64,6 +64,10 @@ PCondit::~PCondit()
delete else_;
}
PProcess::~PProcess()
{
delete statement_;
}
PWhile::~PWhile()
{
@ -73,6 +77,18 @@ PWhile::~PWhile()
/*
* $Log: Statement.cc,v $
* Revision 1.4 1999/01/25 05:45:56 steve
* Add the LineInfo class to carry the source file
* location of things. PGate, Statement and PProcess.
*
* elaborate handles module parameter mismatches,
* missing or incorrect lvalues for procedural
* assignment, and errors are propogated to the
* top of the elaboration call tree.
*
* Attach line numbers to processes, gates and
* assignment statements.
*
* Revision 1.3 1998/11/11 03:13:04 steve
* Handle while loops.
*

View File

@ -19,12 +19,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: Statement.h,v 1.4 1998/11/11 03:13:04 steve Exp $"
#ident "$Id: Statement.h,v 1.5 1999/01/25 05:45:56 steve Exp $"
#endif
# include <string>
# include <list>
# include "netlist.h"
# include "LineInfo.h"
class PExpr;
class Statement;
@ -34,7 +35,7 @@ class Statement;
* pointer to the single statement that is the process. A module may
* have several concurrent processes.
*/
class PProcess {
class PProcess : public LineInfo {
public:
enum Type { PR_INITIAL, PR_ALWAYS };
@ -42,6 +43,8 @@ class PProcess {
PProcess(Type t, Statement*st)
: type_(t), statement_(st) { }
virtual ~PProcess();
Type type() const { return type_; }
Statement*statement() { return statement_; }
@ -57,7 +60,7 @@ class PProcess {
* fact, the Statement class is abstract and represents all the
* possible kinds of statements that exist in Verilog.
*/
class Statement {
class Statement : public LineInfo {
public:
Statement() { }
@ -245,6 +248,18 @@ class PWhile : public Statement {
/*
* $Log: Statement.h,v $
* Revision 1.5 1999/01/25 05:45:56 steve
* Add the LineInfo class to carry the source file
* location of things. PGate, Statement and PProcess.
*
* elaborate handles module parameter mismatches,
* missing or incorrect lvalues for procedural
* assignment, and errors are propogated to the
* top of the elaboration call tree.
*
* Attach line numbers to processes, gates and
* assignment statements.
*
* Revision 1.4 1998/11/11 03:13:04 steve
* Handle while loops.
*

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.10 1998/12/14 02:01:34 steve Exp $"
#ident "$Id: elaborate.cc,v 1.11 1999/01/25 05:45:56 steve Exp $"
#endif
/*
@ -221,6 +221,14 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, const string&path) const
// Now connect the ports of the newly elaborated designs to
// the expressions that are the instantiation parameters.
if (pin_count() != rmod->ports.size()) {
cerr << get_line() << ": Wrong number "
"of parameters. Expecting " << rmod->ports.size() <<
", got " << pin_count() << "."
<< endl;
return;
}
assert(pin_count() == rmod->ports.size());
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
@ -240,12 +248,22 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, const string&path) const
assert(prt->pin_count() == sig->pin_count());
switch (prt->port_type()) {
// INPUT and OUTPUT ports are directional. Handle
// them like assignments.
case NetNet::PINPUT:
do_assign(des, path, prt, sig);
break;
case NetNet::POUTPUT:
do_assign(des, path, sig, prt);
break;
// INOUT ports are like terminal posts. Just
// connect the inside and the outside nets
// together.
case NetNet::PINOUT:
for (unsigned p = 0 ; p < sig->pin_count() ; p += 1)
connect(prt->pin(p), sig->pin(p));
break;
default:
assert(0);
}
@ -569,10 +587,17 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const
{
NetNet*reg = des->find_signal(path+"."+lval());
if (reg == 0) {
cerr << "Could not match signal: " << lval() << endl;
return new NetProc;
cerr << get_line() << ": Could not match signal: " <<
lval() << endl;
return 0;
}
assert(reg);
if (reg->type() != NetNet::REG) {
cerr << get_line() << ": " << lval() << " is not a register."
<< endl;
return 0;
}
assert(reg->type() == NetNet::REG);
assert(expr_);
@ -585,11 +610,29 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const
return cur;
}
/*
* This is the elaboration method for a begin-end block. Try to
* elaborate the entire block, even if it fails somewhere. This way I
* get all the error messages out of it. Then, if I detected a failure
* then pass the failure up.
*/
NetProc* PBlock::elaborate(Design*des, const string&path) const
{
NetBlock*cur = new NetBlock(NetBlock::SEQU);
bool fail_flag = false;
for (unsigned idx = 0 ; idx < size() ; idx += 1) {
cur->append(stat(idx)->elaborate(des, path));
NetProc*tmp = stat(idx)->elaborate(des, path);
if (tmp == 0) {
fail_flag = true;
continue;
}
cur->append(tmp);
}
if (fail_flag) {
delete cur;
cur = 0;
}
return cur;
@ -635,14 +678,18 @@ NetProc* PDelayStatement::elaborate(Design*des, const string&path) const
NetProc* PEventStatement::elaborate(Design*des, const string&path) const
{
NetProc*enet = statement_->elaborate(des, path);
if (enet == 0)
return 0;
NetPEvent*ev = new NetPEvent(des->local_symbol(path), type_, enet);
NetNet*expr = expr_->elaborate_net(des, path);
if (expr == 0) {
cerr << "Failed to elaborate expression: ";
cerr << get_line() << ": Failed to elaborate expression: ";
expr_->dump(cerr);
cerr << endl;
exit(1);
delete ev;
return 0;
}
assert(expr);
connect(ev->pin(0), expr->pin(0));
@ -695,8 +742,10 @@ NetProc* PWhile::elaborate(Design*des, const string&path) const
return loop;
}
void Module::elaborate(Design*des, const string&path) const
bool Module::elaborate(Design*des, const string&path) const
{
bool result_flag = true;
// Get all the explicitly declared wires of the module and
// start the signals list with them.
const list<PWire*>&wl = get_wires();
@ -728,6 +777,13 @@ void Module::elaborate(Design*des, const string&path) const
; st ++ ) {
NetProc*cur = (*st)->statement()->elaborate(des, path);
if (cur == 0) {
cerr << (*st)->get_line() << ": Elaboration "
"failed for this process." << endl;
result_flag = false;
continue;
}
NetProcTop*top;
switch ((*st)->type()) {
case PProcess::PR_INITIAL:
@ -740,6 +796,8 @@ void Module::elaborate(Design*des, const string&path) const
des->add_process(top);
}
return result_flag;
}
Design* elaborate(const map<string,Module*>&modules,
@ -759,16 +817,32 @@ Design* elaborate(const map<string,Module*>&modules,
modlist = &modules;
udplist = &primitives;
rmod->elaborate(des, root);
bool rc = rmod->elaborate(des, root);
modlist = 0;
udplist = 0;
if (rc == false) {
delete des;
des = 0;
}
return des;
}
/*
* $Log: elaborate.cc,v $
* Revision 1.11 1999/01/25 05:45:56 steve
* Add the LineInfo class to carry the source file
* location of things. PGate, Statement and PProcess.
*
* elaborate handles module parameter mismatches,
* missing or incorrect lvalues for procedural
* assignment, and errors are propogated to the
* top of the elaboration call tree.
*
* Attach line numbers to processes, gates and
* assignment statements.
*
* Revision 1.10 1998/12/14 02:01:34 steve
* Fully elaborate Sequential UDP behavior.
*

21
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.10 1998/12/18 05:16:25 steve Exp $"
#ident "$Id: parse.y,v 1.11 1999/01/25 05:45:56 steve Exp $"
#endif
# include "parse_misc.h"
@ -271,6 +271,8 @@ gate_instance
{ lgate*tmp = new lgate;
tmp->name = *$1;
tmp->parms = $3;
tmp->file = @1.text;
tmp->lineno = @1.first_line;
delete $1;
$$ = tmp;
}
@ -278,6 +280,8 @@ gate_instance
{ lgate*tmp = new lgate;
tmp->name = "";
tmp->parms = $2;
tmp->file = @1.text;
tmp->lineno = @1.first_line;
$$ = tmp;
}
;
@ -446,10 +450,14 @@ module_item
delete $3;
}
| K_always statement
{ pform_make_behavior(PProcess::PR_ALWAYS, $2);
{ PProcess*tmp = pform_make_behavior(PProcess::PR_ALWAYS, $2);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
}
| K_initial statement
{ pform_make_behavior(PProcess::PR_INITIAL, $2);
{ PProcess*tmp = pform_make_behavior(PProcess::PR_INITIAL, $2);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
}
| KK_attribute '(' IDENTIFIER ',' STRING ',' STRING ')' ';'
{ pform_set_attrib(*$3, *$5, *$7);
@ -592,7 +600,10 @@ statement
$$ = tmp;
}
| lvalue '=' expression ';'
{ $$ = pform_make_assignment($1, $3);
{ Statement*tmp = pform_make_assignment($1, $3);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
}
| lvalue K_LE expression ';'
{ $$ = pform_make_assignment($1, $3);
@ -699,6 +710,8 @@ udp_initial
: K_initial IDENTIFIER '=' NUMBER ';'
{ PExpr*etmp = new PENumber($4);
PAssign*atmp = new PAssign(*$2, etmp);
atmp->set_file(@2.text);
atmp->set_lineno(@2.first_line);
delete $2;
$$ = atmp;
}

View File

@ -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.7 1998/12/09 04:02:47 steve Exp $"
#ident "$Id: pform.cc,v 1.8 1999/01/25 05:45:56 steve Exp $"
#endif
# include "pform.h"
@ -27,6 +27,7 @@
# include <map>
# include <assert.h>
# include <typeinfo>
# include <strstream>
/*
* The lexor accesses the vl_* variables.
@ -261,9 +262,12 @@ void pform_makegates(PGBuiltin::Type type,
void pform_make_modgate(const string&type,
const string&name,
const vector<PExpr*>&wires)
const vector<PExpr*>&wires,
const string&fn, unsigned ln)
{
PGate*cur = new PGModule(type, name, wires);
cur->set_file(fn);
cur->set_lineno(ln);
cur_module->add_gate(cur);
}
@ -281,7 +285,7 @@ void pform_make_modgates(const string&type, list<lgate>*gates)
wires[idx] = ep;
}
pform_make_modgate(type, cur.name, wires);
pform_make_modgate(type, cur.name, wires, cur.file, cur.lineno);
}
delete gates;
@ -311,9 +315,11 @@ void pform_makewire(const string&name, NetNet::Type type)
{
PWire*cur = cur_module->get_wire(name);
if (cur) {
if (cur->type != NetNet::IMPLICIT)
VLerror("Extra definition of wire.");
if (cur->type != NetNet::IMPLICIT) {
strstream msg;
msg << "Duplicate definition of " << name << ".";
VLerror(msg.str());
}
cur->type = type;
return;
}
@ -433,10 +439,11 @@ list<PWire*>* pform_make_udp_input_ports(list<string>*names)
return out;
}
void pform_make_behavior(PProcess::Type type, Statement*st)
PProcess* pform_make_behavior(PProcess::Type type, Statement*st)
{
PProcess*pp = new PProcess(type, st);
cur_module->add_behavior(pp);
return pp;
}
Statement* pform_make_block(PBlock::BL_TYPE type, list<Statement*>*sl)
@ -493,6 +500,18 @@ int pform_parse(const char*path, map<string,Module*>&modules,
/*
* $Log: pform.cc,v $
* 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.
*
* elaborate handles module parameter mismatches,
* missing or incorrect lvalues for procedural
* assignment, and errors are propogated to the
* top of the elaboration call tree.
*
* Attach line numbers to processes, gates and
* assignment statements.
*
* Revision 1.7 1998/12/09 04:02:47 steve
* Support the include directive.
*

21
pform.h
View File

@ -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.5 1998/12/09 04:02:47 steve Exp $"
#ident "$Id: pform.h,v 1.6 1999/01/25 05:45:56 steve Exp $"
#endif
# include "netlist.h"
@ -63,8 +63,13 @@ class PExpr;
*/
struct lgate {
lgate() : parms(0), lineno(0) { }
string name;
list<PExpr*>*parms;
string file;
unsigned lineno;
};
@ -94,7 +99,7 @@ extern void pform_set_attrib(const string&name, const string&key,
const string&value);
extern void pform_set_type_attrib(const string&name, const string&key,
const string&value);
extern void pform_make_behavior(PProcess::Type, Statement*);
extern PProcess* pform_make_behavior(PProcess::Type, Statement*);
extern Statement* pform_make_block(PBlock::BL_TYPE, list<Statement*>*);
extern Statement* pform_make_assignment(string*t, PExpr*e);
extern Statement* pform_make_calltask(string*t, list<PExpr*>* =0);
@ -132,6 +137,18 @@ extern void pform_dump(ostream&out, Module*mod);
/*
* $Log: pform.h,v $
* 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.
*
* elaborate handles module parameter mismatches,
* missing or incorrect lvalues for procedural
* assignment, and errors are propogated to the
* top of the elaboration call tree.
*
* Attach line numbers to processes, gates and
* assignment statements.
*
* Revision 1.5 1998/12/09 04:02:47 steve
* Support the include directive.
*