Add procedural while loops,

Parse procedural for loops,
 Add procedural wait statements,
 Add constant nodes,
 Add XNOR logic gate,
 Make vvm output look a bit prettier.
This commit is contained in:
steve 1998-11-09 18:55:33 +00:00
parent 9a93912ce7
commit ebad845fc3
15 changed files with 510 additions and 91 deletions

11
PExpr.h
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: PExpr.h,v 1.2 1998/11/07 17:05:05 steve Exp $" #ident "$Id: PExpr.h,v 1.3 1998/11/09 18:55:33 steve Exp $"
#endif #endif
# include <string> # include <string>
@ -84,6 +84,7 @@ class PENumber : public PExpr {
const verinum& value() const { return *value_; } const verinum& value() const { return *value_; }
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, const string&path) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const; virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
virtual verinum* eval_const() const; virtual verinum* eval_const() const;
@ -138,6 +139,14 @@ class PEBinary : public PExpr {
/* /*
* $Log: PExpr.h,v $ * $Log: PExpr.h,v $
* Revision 1.3 1998/11/09 18:55:33 steve
* Add procedural while loops,
* Parse procedural for loops,
* Add procedural wait statements,
* Add constant nodes,
* Add XNOR logic gate,
* Make vvm output look a bit prettier.
*
* Revision 1.2 1998/11/07 17:05:05 steve * Revision 1.2 1998/11/07 17:05:05 steve
* Handle procedural conditional, and some * Handle procedural conditional, and some
* of the conditional expressions. * of the conditional expressions.

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: Statement.h,v 1.2 1998/11/07 17:05:05 steve Exp $" #ident "$Id: Statement.h,v 1.3 1998/11/09 18:55:33 steve Exp $"
#endif #endif
# include <string> # include <string>
@ -198,6 +198,30 @@ class PEventStatement : public Statement {
Statement*statement_; Statement*statement_;
}; };
class PForStatement : public Statement {
public:
PForStatement(const string&n1, PExpr*e1, PExpr*cond,
const string&n2, PExpr*e2, Statement*st)
: name1_(n1), expr1_(e1), cond_(cond), name2_(n2), expr2_(e2),
statement_(st)
{ }
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
string name1_;
PExpr* expr1_;
PExpr*cond_;
string name2_;
PExpr* expr2_;
Statement*statement_;
};
class PNoop : public Statement { class PNoop : public Statement {
public: public:
@ -206,6 +230,14 @@ class PNoop : public Statement {
/* /*
* $Log: Statement.h,v $ * $Log: Statement.h,v $
* Revision 1.3 1998/11/09 18:55:33 steve
* Add procedural while loops,
* Parse procedural for loops,
* Add procedural wait statements,
* Add constant nodes,
* Add XNOR logic gate,
* Make vvm output look a bit prettier.
*
* Revision 1.2 1998/11/07 17:05:05 steve * Revision 1.2 1998/11/07 17:05:05 steve
* Handle procedural conditional, and some * Handle procedural conditional, and some
* of the conditional expressions. * of the conditional expressions.

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: design_dump.cc,v 1.2 1998/11/07 17:05:05 steve Exp $" #ident "$Id: design_dump.cc,v 1.3 1998/11/09 18:55:34 steve Exp $"
#endif #endif
/* /*
@ -115,6 +115,12 @@ void NetBUFZ::dump_node(ostream&o, unsigned ind) const
dump_node_pins(o, ind+4); dump_node_pins(o, ind+4);
} }
void NetConst::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "constant " << value_ << ": " << name() << endl;
dump_node_pins(o, ind+4);
}
void NetLogic::dump_node(ostream&o, unsigned ind) const void NetLogic::dump_node(ostream&o, unsigned ind) const
{ {
o << setw(ind) << "" << "logic: "; o << setw(ind) << "" << "logic: ";
@ -134,6 +140,9 @@ void NetLogic::dump_node(ostream&o, unsigned ind) const
case OR: case OR:
o << "or"; o << "or";
break; break;
case XNOR:
o << "xnor";
break;
case XOR: case XOR:
o << "xor"; o << "xor";
break; break;
@ -157,6 +166,9 @@ void NetPEvent::dump_node(ostream&o, unsigned ind) const
case NEGEDGE: case NEGEDGE:
o << "negedge "; o << "negedge ";
break; break;
case POSITIVE:
o << "positive ";
break;
} }
o << name() << endl; o << name() << endl;
@ -222,16 +234,19 @@ void NetPDelay::dump(ostream&o, unsigned ind) const
void NetPEvent::dump(ostream&o, unsigned ind) const void NetPEvent::dump(ostream&o, unsigned ind) const
{ {
o << setw(ind) << "" << "@"; o << setw(ind) << "" ;
switch (edge_) { switch (edge_) {
case NEGEDGE: case NEGEDGE:
o << "(negedge " << name() << ")"; o << "@" << "(negedge " << name() << ")";
break; break;
case POSEDGE: case POSEDGE:
o << "(posedge " << name() << ")"; o << "@" << "(posedge " << name() << ")";
break; break;
case ANYEDGE: case ANYEDGE:
o << name(); o << "@" << name();
break;
case POSITIVE:
o << "wait (" << name() << ")";
break; break;
} }
o << endl; o << endl;
@ -261,6 +276,12 @@ void NetTask::dump(ostream&o, unsigned ind) const
o << ";" << endl; o << ";" << endl;
} }
void NetWhile::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "while (" << *cond_ << ")" << endl;
proc_->dump(o, ind+3);
}
/* Dump a statement type that someone didn't write a dump for. */ /* Dump a statement type that someone didn't write a dump for. */
void NetProc::dump(ostream&o, unsigned ind) const void NetProc::dump(ostream&o, unsigned ind) const
{ {
@ -285,6 +306,9 @@ void NetEBinary::dump(ostream&o) const
case 'e': case 'e':
o << "=="; o << "==";
break; break;
case 'n':
o << "!=";
break;
} }
o << "("; o << "(";
right_->dump(o); right_->dump(o);
@ -351,6 +375,14 @@ void Design::dump(ostream&o) const
/* /*
* $Log: design_dump.cc,v $ * $Log: design_dump.cc,v $
* Revision 1.3 1998/11/09 18:55:34 steve
* Add procedural while loops,
* Parse procedural for loops,
* Add procedural wait statements,
* Add constant nodes,
* Add XNOR logic gate,
* Make vvm output look a bit prettier.
*
* Revision 1.2 1998/11/07 17:05:05 steve * Revision 1.2 1998/11/07 17:05:05 steve
* Handle procedural conditional, and some * Handle procedural conditional, and some
* of the conditional expressions. * of the conditional expressions.

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.2 1998/11/07 17:05:05 steve Exp $" #ident "$Id: elaborate.cc,v 1.3 1998/11/09 18:55:34 steve Exp $"
#endif #endif
/* /*
@ -149,25 +149,31 @@ void PGAssign::elaborate(Design*des, const string&path) const
void PGBuiltin::elaborate(Design*des, const string&path) const void PGBuiltin::elaborate(Design*des, const string&path) const
{ {
NetLogic*cur = 0; NetLogic*cur = 0;
string name = get_name();
if (name == "")
name = local_symbol(path);
switch (type()) { switch (type()) {
case AND: case AND:
cur = new NetLogic(get_name(), pin_count(), NetLogic::AND); cur = new NetLogic(name, pin_count(), NetLogic::AND);
break; break;
case NAND: case NAND:
cur = new NetLogic(get_name(), pin_count(), NetLogic::NAND); cur = new NetLogic(name, pin_count(), NetLogic::NAND);
break; break;
case NOR: case NOR:
cur = new NetLogic(get_name(), pin_count(), NetLogic::NOR); cur = new NetLogic(name, pin_count(), NetLogic::NOR);
break; break;
case NOT: case NOT:
cur = new NetLogic(get_name(), pin_count(), NetLogic::NOT); cur = new NetLogic(name, pin_count(), NetLogic::NOT);
break; break;
case OR: case OR:
cur = new NetLogic(get_name(), pin_count(), NetLogic::OR); cur = new NetLogic(name, pin_count(), NetLogic::OR);
break;
case XNOR:
cur = new NetLogic(name, pin_count(), NetLogic::XNOR);
break; break;
case XOR: case XOR:
cur = new NetLogic(get_name(), pin_count(), NetLogic::XOR); cur = new NetLogic(name, pin_count(), NetLogic::XOR);
break; break;
} }
@ -225,6 +231,9 @@ void PGModule::elaborate(Design*des, const string&path) const
assert(pin_count() == rmod->ports.size()); assert(pin_count() == rmod->ports.size());
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) { for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
// Skip unconnected module ports.
if (pin(idx) == 0)
continue;
NetNet*sig = pin(idx)->elaborate_net(des, path); NetNet*sig = pin(idx)->elaborate_net(des, path);
if (sig == 0) { if (sig == 0) {
cerr << "Expression too complicated for elaboration." << endl; cerr << "Expression too complicated for elaboration." << endl;
@ -311,6 +320,19 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path) const
des->add_node(gate); des->add_node(gate);
break; break;
case 'e': // ==
assert(lsig->pin_count() == 1);
assert(rsig->pin_count() == 1);
gate = new NetLogic(local_symbol(path), 3, NetLogic::XNOR);
connect(gate->pin(1), lsig->pin(0));
connect(gate->pin(2), rsig->pin(0));
osig = new NetNet(local_symbol(path), NetNet::WIRE);
osig->local_flag(true);
connect(gate->pin(0), osig->pin(0));
des->add_signal(osig);
des->add_node(gate);
break;
default: default:
cerr << "Unhandled BINARY '" << op_ << "'" << endl; cerr << "Unhandled BINARY '" << op_ << "'" << endl;
osig = 0; osig = 0;
@ -363,6 +385,21 @@ NetNet* PEIdent::elaborate_net(Design*des, const string&path) const
return sig; return sig;
} }
/*
* XXXX For now, only generate a single bit. I am going to have to add
* code to properly calculate expression bit widths, eventually.
*/
NetNet* PENumber::elaborate_net(Design*des, const string&path) const
{
NetNet*net = new NetNet(local_symbol(path), NetNet::IMPLICIT);
net->local_flag(true);
NetConst*tmp = new NetConst(local_symbol(path), value_->get(0));
des->add_node(tmp);
des->add_signal(net);
connect(net->pin(0), tmp->pin(0));
return net;
}
NetNet* PEUnary::elaborate_net(Design*des, const string&path) const NetNet* PEUnary::elaborate_net(Design*des, const string&path) const
{ {
NetNet* sub_sig = expr_->elaborate_net(des, path); NetNet* sub_sig = expr_->elaborate_net(des, path);
@ -449,7 +486,8 @@ NetExpr* PEUnary::elaborate_expr(Design*des, const string&path) const
NetProc* Statement::elaborate(Design*des, const string&path) const NetProc* Statement::elaborate(Design*des, const string&path) const
{ {
cerr << "What kind of statement? " << typeid(*this).name() << endl; cerr << "elaborate: What kind of statement? " <<
typeid(*this).name() << endl;
NetProc*cur = new NetProc; NetProc*cur = new NetProc;
return cur; return cur;
} }
@ -540,6 +578,40 @@ NetProc* PEventStatement::elaborate(Design*des, const string&path) const
return ev; return ev;
} }
/*
* elaborate the for loop as the equivilent while loop. This eases the
* task for the target code generator. The structure is:
*
* begin
* name1_ = expr1_;
* while (cond_) begin
* statement_;
* name2_ = expr2_;
* end
* end
*/
NetProc* PForStatement::elaborate(Design*des, const string&path) const
{
NetBlock*top = new NetBlock(NetBlock::SEQU);
NetNet*sig = des->find_signal(path+"."+name1_);
assert(sig);
NetAssign*init = new NetAssign(sig, expr1_->elaborate_expr(des, path));
top->append(init);
NetBlock*body = new NetBlock(NetBlock::SEQU);
body->append(statement_->elaborate(des, path));
sig = des->find_signal(path+"."+name2_);
assert(sig);
NetAssign*step = new NetAssign(sig, expr2_->elaborate_expr(des, path));
body->append(step);
NetWhile*loop = new NetWhile(cond_->elaborate_expr(des, path), body);
top->append(loop);
return top;
}
void Module::elaborate(Design*des, const string&path) const void Module::elaborate(Design*des, const string&path) const
{ {
// Get all the explicitly declared wires of the module and // Get all the explicitly declared wires of the module and
@ -618,6 +690,14 @@ Design* elaborate(const list<Module*>&modules, const string&root)
/* /*
* $Log: elaborate.cc,v $ * $Log: elaborate.cc,v $
* Revision 1.3 1998/11/09 18:55:34 steve
* Add procedural while loops,
* Parse procedural for loops,
* Add procedural wait statements,
* Add constant nodes,
* Add XNOR logic gate,
* Make vvm output look a bit prettier.
*
* Revision 1.2 1998/11/07 17:05:05 steve * Revision 1.2 1998/11/07 17:05:05 steve
* Handle procedural conditional, and some * Handle procedural conditional, and some
* of the conditional expressions. * of the conditional expressions.

25
emit.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: emit.cc,v 1.2 1998/11/07 17:05:05 steve Exp $" #ident "$Id: emit.cc,v 1.3 1998/11/09 18:55:34 steve Exp $"
#endif #endif
/* /*
@ -45,6 +45,11 @@ void NetAssign::emit_node(ostream&o, struct target_t*tgt) const
tgt->net_assign(o, this); tgt->net_assign(o, this);
} }
void NetConst::emit_node(ostream&o, struct target_t*tgt) const
{
tgt->net_const(o, this);
}
void NetPEvent::emit_node(ostream&o, struct target_t*tgt) const void NetPEvent::emit_node(ostream&o, struct target_t*tgt) const
{ {
tgt->net_pevent(o, this); tgt->net_pevent(o, this);
@ -109,6 +114,11 @@ void NetTask::emit_proc(ostream&o, struct target_t*tgt) const
tgt->proc_task(o, this); tgt->proc_task(o, this);
} }
void NetWhile::emit_proc(ostream&o, struct target_t*tgt) const
{
tgt->proc_while(o, this);
}
void NetBlock::emit_recurse(ostream&o, struct target_t*tgt) const void NetBlock::emit_recurse(ostream&o, struct target_t*tgt) const
{ {
if (last_ == 0) if (last_ == 0)
@ -133,6 +143,11 @@ void NetCondit::emit_recurse_else(ostream&o, struct target_t*tgt) const
else_->emit_proc(o, tgt); else_->emit_proc(o, tgt);
} }
void NetWhile::emit_proc_recurse(ostream&o, struct target_t*tgt) const
{
proc_->emit_proc(o, tgt);
}
void Design::emit(ostream&o, struct target_t*tgt) const void Design::emit(ostream&o, struct target_t*tgt) const
{ {
tgt->start_design(o, this); tgt->start_design(o, this);
@ -203,6 +218,14 @@ void emit(ostream&o, const Design*des, const char*type)
/* /*
* $Log: emit.cc,v $ * $Log: emit.cc,v $
* Revision 1.3 1998/11/09 18:55:34 steve
* Add procedural while loops,
* Parse procedural for loops,
* Add procedural wait statements,
* Add constant nodes,
* Add XNOR logic gate,
* Make vvm output look a bit prettier.
*
* Revision 1.2 1998/11/07 17:05:05 steve * Revision 1.2 1998/11/07 17:05:05 steve
* Handle procedural conditional, and some * Handle procedural conditional, and some
* of the conditional expressions. * of the conditional expressions.

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: lexor.lex,v 1.2 1998/11/07 17:05:05 steve Exp $" #ident "$Id: lexor.lex,v 1.3 1998/11/09 18:55:34 steve Exp $"
#endif #endif
//# define YYSTYPE lexval //# define YYSTYPE lexval
@ -68,7 +68,7 @@ static verinum*make_sized_hex(const char*txt);
"===" { return K_CEQ; } "===" { return K_CEQ; }
"!==" { return K_CNE; } "!==" { return K_CNE; }
[;:\[\],()#=.@&!<|^~+-] { return yytext[0]; } [;:\[\],()#=.@&!<|^~+*/-] { return yytext[0]; }
\" { BEGIN(CSTRING); } \" { BEGIN(CSTRING); }
<CSTRING>\\\" { yymore(); } <CSTRING>\\\" { yymore(); }

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: netlist.cc,v 1.3 1998/11/07 19:17:10 steve Exp $" #ident "$Id: netlist.cc,v 1.4 1998/11/09 18:55:34 steve Exp $"
#endif #endif
# include <cassert> # include <cassert>
@ -149,7 +149,9 @@ NetEBinary::NetEBinary(char op, NetExpr*l, NetExpr*r)
: op_(op), left_(l), right_(r) : op_(op), left_(l), right_(r)
{ {
switch (op_) { switch (op_) {
// comparison operators return a 1-bin wide result.
case 'e': case 'e':
case 'n':
expr_width(1); expr_width(1);
break; break;
default: default:
@ -178,6 +180,7 @@ void NetEBinary::set_width(unsigned w)
op_ << "." << endl; op_ << "." << endl;
case '+': case '+':
case '-':
left_->set_width(w); left_->set_width(w);
right_->set_width(w); right_->set_width(w);
expr_width(w); expr_width(w);
@ -317,6 +320,14 @@ void Design::add_process(NetProcTop*pro)
/* /*
* $Log: netlist.cc,v $ * $Log: netlist.cc,v $
* Revision 1.4 1998/11/09 18:55:34 steve
* Add procedural while loops,
* Parse procedural for loops,
* Add procedural wait statements,
* Add constant nodes,
* Add XNOR logic gate,
* Make vvm output look a bit prettier.
*
* Revision 1.3 1998/11/07 19:17:10 steve * Revision 1.3 1998/11/07 19:17:10 steve
* Calculate expression widths at elaboration time. * Calculate expression widths at elaboration time.
* *

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: netlist.h,v 1.3 1998/11/07 19:17:10 steve Exp $" #ident "$Id: netlist.h,v 1.4 1998/11/09 18:55:34 steve Exp $"
#endif #endif
/* /*
@ -252,13 +252,28 @@ class NetBUFZ : public NetNode {
virtual void emit_node(ostream&, struct target_t*) const; virtual void emit_node(ostream&, struct target_t*) const;
}; };
class NetConst : public NetNode {
public:
explicit NetConst(const string&n, verinum::V v)
: NetNode(n, 1), value_(v) { }
verinum::V value() const { return value_; }
virtual void emit_node(ostream&, struct target_t*) const;
virtual void dump_node(ostream&, unsigned ind) const;
private:
verinum::V value_;
};
/* /*
* This class represents all manner of logic gates. * This class represents all manner of logic gates.
*/ */
class NetLogic : public NetNode { class NetLogic : public NetNode {
public: public:
enum TYPE { AND, NAND, NOR, NOT, OR, XOR }; enum TYPE { AND, NAND, NOR, NOT, OR, XNOR, XOR };
explicit NetLogic(const string&n, unsigned pins, TYPE t) explicit NetLogic(const string&n, unsigned pins, TYPE t)
: NetNode(n, pins), type_(t) { } : NetNode(n, pins), type_(t) { }
@ -390,7 +405,7 @@ class NetPDelay : public NetProc {
class NetPEvent : public NetProc, public NetNode { class NetPEvent : public NetProc, public NetNode {
public: public:
enum Type { ANYEDGE, POSEDGE, NEGEDGE }; enum Type { ANYEDGE, POSEDGE, NEGEDGE, POSITIVE };
public: public:
NetPEvent(const string&ev, Type ed, NetProc*st) NetPEvent(const string&ev, Type ed, NetProc*st)
@ -448,6 +463,30 @@ class NetTask : public NetProc {
NetExpr**parms_; NetExpr**parms_;
}; };
/*
* The while statement is a condition that is tested in the front of
* each iteration, and a statement (a NetProc) that is executed as
* long as the condition is true.
*/
class NetWhile : public NetProc {
public:
NetWhile(NetExpr*c, NetProc*p)
: cond_(c), proc_(p) { }
NetExpr*expr() const { return cond_; }
void emit_proc_recurse(ostream&, struct target_t*) const;
virtual void emit_proc(ostream&, struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const;
private:
NetExpr*cond_;
NetProc*proc_;
};
/* The is the top of any process. It carries the type (initial or /* The is the top of any process. It carries the type (initial or
always) and a pointer to the statement, probably a block, that always) and a pointer to the statement, probably a block, that
makes up the process. */ makes up the process. */
@ -670,6 +709,14 @@ inline ostream& operator << (ostream&o, const NetExpr&exp)
/* /*
* $Log: netlist.h,v $ * $Log: netlist.h,v $
* Revision 1.4 1998/11/09 18:55:34 steve
* Add procedural while loops,
* Parse procedural for loops,
* Add procedural wait statements,
* Add constant nodes,
* Add XNOR logic gate,
* Make vvm output look a bit prettier.
*
* Revision 1.3 1998/11/07 19:17:10 steve * Revision 1.3 1998/11/07 19:17:10 steve
* Calculate expression widths at elaboration time. * Calculate expression widths at elaboration time.
* *

39
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.2 1998/11/07 17:05:05 steve Exp $" #ident "$Id: parse.y,v 1.3 1998/11/09 18:55:34 steve Exp $"
#endif #endif
# include "parse_misc.h" # include "parse_misc.h"
@ -177,6 +177,9 @@ expression
| expression '+' expression | expression '+' expression
{ $$ = new PEBinary('+', $1, $3); { $$ = new PEBinary('+', $1, $3);
} }
| expression '-' expression
{ $$ = new PEBinary('-', $1, $3);
}
| expression '&' expression | expression '&' expression
{ $$ = new PEBinary('&', $1, $3); { $$ = new PEBinary('&', $1, $3);
} }
@ -530,6 +533,34 @@ statement
{ yyerror(@1, "Malformed conditional expression."); { yyerror(@1, "Malformed conditional expression.");
$$ = $5; $$ = $5;
} }
| K_for '(' lvalue '=' expression ';' expression ';'
lvalue '=' expression ')' statement
{ $$ = new PForStatement(*$3, $5, $7, *$9, $11, $13);
delete $3;
delete $9;
}
| K_for '(' lvalue '=' expression ';' expression ';'
error ')' statement
{ $$ = 0;
yyerror(@9, "Error in for loop step assigment.");
}
| K_for '(' lvalue '=' expression ';' error ';'
lvalue '=' expression ')' statement
{ $$ = 0;
yyerror(@7, "Error in for loop condition expression.");
}
| K_for '(' error ')' statement
{ $$ = 0;
yyerror(@3, "Incomprehensible for loop.");
}
| K_while '(' expression ')' statement
{ $$ = 0;
yyerror(@1, "Sorry, while loops not implemented.");
}
| K_while '(' error ')' statement
{ $$ = 0;
yyerror(@3, "Error in while loop condition.");
}
| delay statement_opt | delay statement_opt
{ PDelayStatement*tmp = new PDelayStatement($1, $2); { PDelayStatement*tmp = new PDelayStatement($1, $2);
$$ = tmp; $$ = tmp;
@ -546,6 +577,12 @@ statement
{ $$ = pform_make_assignment($1, $3); { $$ = pform_make_assignment($1, $3);
yyerror(@1, "Sorry, non-blocking assignment not implemented."); yyerror(@1, "Sorry, non-blocking assignment not implemented.");
} }
| K_wait '(' expression ')' statement_opt
{ PEventStatement*tmp;
tmp = new PEventStatement(NetPEvent::POSITIVE, $3);
tmp->set_statement($5);
$$ = tmp;
}
| SYSTEM_IDENTIFIER '(' expression_list ')' ';' | SYSTEM_IDENTIFIER '(' expression_list ')' ';'
{ $$ = pform_make_calltask($1, $3); { $$ = pform_make_calltask($1, $3);
} }

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.2 1998/11/07 17:05:06 steve Exp $" #ident "$Id: pform_dump.cc,v 1.3 1998/11/09 18:55:34 steve Exp $"
#endif #endif
/* /*
@ -105,9 +105,6 @@ void PWire::dump(ostream&out) const
case NetNet::REG: case NetNet::REG:
out << " reg "; out << " reg ";
break; break;
default:
out << " (" << type << ") ";
break;
} }
switch (port_type) { switch (port_type) {
@ -141,7 +138,8 @@ void PGate::dump_pins(ostream&out) const
out << *pin(0); out << *pin(0);
for (unsigned idx = 1 ; idx < pin_count() ; idx += 1) { for (unsigned idx = 1 ; idx < pin_count() ; idx += 1) {
out << ", " << *pin(idx); out << ", ";
if (pin(idx)) out << *pin(idx);
} }
} }
} }
@ -256,12 +254,23 @@ void PEventStatement::dump(ostream&out, unsigned ind) const
case NetPEvent::NEGEDGE: case NetPEvent::NEGEDGE:
out << "negedge "; out << "negedge ";
break; break;
case NetPEvent::POSITIVE:
out << "positive ";
break;
} }
out << *expr_ << ")" << endl; out << *expr_ << ")" << endl;
statement_->dump(out, ind+2); statement_->dump(out, ind+2);
} }
void PForStatement::dump(ostream&out, unsigned ind) const
{
out << setw(ind) << "" << "for (" << name1_ << " = " << *expr1_
<< "; " << *cond_ << "; " << name2_ << " = " << *expr2_ <<
")" << endl;
statement_->dump(out, ind+3);
}
void PProcess::dump(ostream&out, unsigned ind) const void PProcess::dump(ostream&out, unsigned ind) const
{ {
switch (type_) { switch (type_) {
@ -314,6 +323,14 @@ void pform_dump(ostream&out, Module*mod)
/* /*
* $Log: pform_dump.cc,v $ * $Log: pform_dump.cc,v $
* Revision 1.3 1998/11/09 18:55:34 steve
* Add procedural while loops,
* Parse procedural for loops,
* Add procedural wait statements,
* Add constant nodes,
* Add XNOR logic gate,
* Make vvm output look a bit prettier.
*
* Revision 1.2 1998/11/07 17:05:06 steve * Revision 1.2 1998/11/07 17:05:06 steve
* Handle procedural conditional, and some * Handle procedural conditional, and some
* of the conditional expressions. * of the conditional expressions.

153
t-vvm.cc
View File

@ -17,11 +17,12 @@
* 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: t-vvm.cc,v 1.3 1998/11/07 19:17:10 steve Exp $" #ident "$Id: t-vvm.cc,v 1.4 1998/11/09 18:55:34 steve Exp $"
#endif #endif
# include <iostream> # include <iostream>
# include <strstream> # include <strstream>
# include <iomanip>
# include <string> # include <string>
# include <typeinfo> # include <typeinfo>
# include "netlist.h" # include "netlist.h"
@ -42,12 +43,14 @@ class target_vvm : public target_t {
virtual void signal(ostream&os, const NetNet*); virtual void signal(ostream&os, const NetNet*);
virtual void logic(ostream&os, const NetLogic*); virtual void logic(ostream&os, const NetLogic*);
virtual void bufz(ostream&os, const NetBUFZ*); virtual void bufz(ostream&os, const NetBUFZ*);
virtual void net_const(ostream&os, const NetConst*);
virtual void net_pevent(ostream&os, const NetPEvent*); virtual void net_pevent(ostream&os, const NetPEvent*);
virtual void start_process(ostream&os, const NetProcTop*); virtual void start_process(ostream&os, const NetProcTop*);
virtual void proc_assign(ostream&os, const NetAssign*); virtual void proc_assign(ostream&os, const NetAssign*);
virtual void proc_block(ostream&os, const NetBlock*); virtual void proc_block(ostream&os, const NetBlock*);
virtual void proc_condit(ostream&os, const NetCondit*); virtual void proc_condit(ostream&os, const NetCondit*);
virtual void proc_task(ostream&os, const NetTask*); virtual void proc_task(ostream&os, const NetTask*);
virtual void proc_while(ostream&os, const NetWhile*);
virtual void proc_event(ostream&os, const NetPEvent*); virtual void proc_event(ostream&os, const NetPEvent*);
virtual void proc_delay(ostream&os, const NetPDelay*); virtual void proc_delay(ostream&os, const NetPDelay*);
virtual void end_process(ostream&os, const NetProcTop*); virtual void end_process(ostream&os, const NetProcTop*);
@ -57,8 +60,11 @@ class target_vvm : public target_t {
void emit_gate_outputfun_(const NetNode*); void emit_gate_outputfun_(const NetNode*);
ostrstream delayed; ostrstream delayed;
ostrstream init_code;
unsigned process_counter; unsigned process_counter;
unsigned thread_step_; unsigned thread_step_;
unsigned indent_;
}; };
/* /*
@ -69,13 +75,14 @@ class target_vvm : public target_t {
class vvm_proc_rval : public expr_scan_t { class vvm_proc_rval : public expr_scan_t {
public: public:
explicit vvm_proc_rval(ostream&os) explicit vvm_proc_rval(ostream&os, unsigned i)
: result(""), os_(os) { } : result(""), os_(os), indent_(i) { }
string result; string result;
private: private:
ostream&os_; ostream&os_;
unsigned indent_;
private: private:
virtual void expr_const(const NetEConst*); virtual void expr_const(const NetEConst*);
@ -88,10 +95,10 @@ class vvm_proc_rval : public expr_scan_t {
void vvm_proc_rval::expr_const(const NetEConst*expr) void vvm_proc_rval::expr_const(const NetEConst*expr)
{ {
string tname = make_temp(); string tname = make_temp();
os_ << " vvm_bitset_t<" << expr->expr_width() << "> " os_ << setw(indent_) << "" << "vvm_bitset_t<" <<
<< tname << ";" << endl; expr->expr_width() << "> " << tname << ";" << endl;
for (unsigned idx = 0 ; idx < expr->expr_width() ; idx += 1) { for (unsigned idx = 0 ; idx < expr->expr_width() ; idx += 1) {
os_ << " " << tname << "[" << idx << "] = "; os_ << setw(indent_) << "" << tname << "[" << idx << "] = ";
switch (expr->value().get(idx)) { switch (expr->value().get(idx)) {
case verinum::V0: case verinum::V0:
os_ << "V0"; os_ << "V0";
@ -153,16 +160,24 @@ void vvm_proc_rval::expr_binary(const NetEBinary*expr)
string rres = result; string rres = result;
result = make_temp(); result = make_temp();
os_ << " vvm_bitset_t<" << expr->expr_width() << ">" << os_ << setw(indent_) << "" << "vvm_bitset_t<" <<
result << ";" << endl; expr->expr_width() << ">" << result << ";" << endl;
switch (expr->op()) { switch (expr->op()) {
case 'e': case 'e':
os_ << " " << result << " = vvm_binop_eq(" << lres os_ << setw(indent_) << "" << result << " = vvm_binop_eq("
<< "," << rres << ");" << endl; << lres << "," << rres << ");" << endl;
break;
case 'n':
os_ << setw(indent_) << "" << result << " = vvm_binop_ne("
<< lres << "," << rres << ");" << endl;
break; break;
case '+': case '+':
os_ << " " << result << " = vvm_binop_plus(" << lres os_ << setw(indent_) << "" << result << " = vvm_binop_plus("
<< "," << rres << ");" << endl; << lres << "," << rres << ");" << endl;
break;
case '-':
os_ << setw(indent_) << "" << result << " = vvm_binop_minus("
<< lres << "," << rres << ");" << endl;
break; break;
default: default:
cerr << "vvm: Unhandled binary op `" << expr->op() << "': " cerr << "vvm: Unhandled binary op `" << expr->op() << "': "
@ -173,9 +188,9 @@ void vvm_proc_rval::expr_binary(const NetEBinary*expr)
} }
} }
static string emit_proc_rval(ostream&os, const NetExpr*expr) static string emit_proc_rval(ostream&os, unsigned indent, const NetExpr*expr)
{ {
vvm_proc_rval scan (os); vvm_proc_rval scan (os, indent);
expr->expr_scan(&scan); expr->expr_scan(&scan);
return scan.result; return scan.result;
} }
@ -254,6 +269,9 @@ void target_vvm::end_design(ostream&os, const Design*mod)
os << "main()" << endl << "{" << endl; os << "main()" << endl << "{" << endl;
os << " vvm_simulation sim;" << endl; os << " vvm_simulation sim;" << endl;
init_code << ends;
os << init_code.str();
for (unsigned idx = 0 ; idx < process_counter ; idx += 1) for (unsigned idx = 0 ; idx < process_counter ; idx += 1)
os << " thread" << (idx+1) << "_t thread_" << os << " thread" << (idx+1) << "_t thread_" <<
(idx+1) << "(&sim);" << endl; (idx+1) << "(&sim);" << endl;
@ -333,6 +351,10 @@ void target_vvm::logic(ostream&os, const NetLogic*gate)
os << "static vvm_or" << "<" << gate->pin_count()-1 << os << "static vvm_or" << "<" << gate->pin_count()-1 <<
"," << gate->delay1() << "> "; "," << gate->delay1() << "> ";
break; break;
case NetLogic::XNOR:
os << "static vvm_xnor" << "<" << gate->pin_count()-1 <<
"," << gate->delay1() << "> ";
break;
case NetLogic::XOR: case NetLogic::XOR:
os << "static vvm_xor" << "<" << gate->pin_count()-1 << os << "static vvm_xor" << "<" << gate->pin_count()-1 <<
"," << gate->delay1() << "> "; "," << gate->delay1() << "> ";
@ -356,6 +378,41 @@ void target_vvm::bufz(ostream&os, const NetBUFZ*gate)
emit_gate_outputfun_(gate); emit_gate_outputfun_(gate);
} }
/*
* The NetConst is a synthetic device created to represent constant
* values. I represent them in the output as a vvm_bufz object that
* has its input connected to nothing but is initialized to the
* desired constant value.
*/
void target_vvm::net_const(ostream&os, const NetConst*gate)
{
os << "static void " << mangle(gate->name()) <<
"_output_fun(vvm_simulation*, vvm_bit_t);" << endl;
os << "static vvm_bufz " << mangle(gate->name()) << "(&" <<
mangle(gate->name()) << "_output_fun);" << endl;
init_code << " " << mangle(gate->name()) << ".set(&sim, 1, ";
switch (gate->value()) {
case verinum::V0:
init_code << "V0";
break;
case verinum::V1:
init_code << "V1";
break;
case verinum::Vx:
init_code << "Vx";
break;
case verinum::Vz:
init_code << "Vz";
break;
}
init_code << ");" << endl;
emit_gate_outputfun_(gate);
}
/* /*
* The net_pevent device is a synthetic device type--a fabrication of * The net_pevent device is a synthetic device type--a fabrication of
* the elaboration phase. An event device receives value changes from * the elaboration phase. An event device receives value changes from
@ -375,6 +432,7 @@ void target_vvm::net_pevent(ostream&os, const NetPEvent*gate)
void target_vvm::start_process(ostream&os, const NetProcTop*proc) void target_vvm::start_process(ostream&os, const NetProcTop*proc)
{ {
process_counter += 1; process_counter += 1;
indent_ = 8;
thread_step_ = 0; thread_step_ = 0;
os << "class thread" << process_counter << os << "class thread" << process_counter <<
@ -402,16 +460,16 @@ void target_vvm::start_process(ostream&os, const NetProcTop*proc)
*/ */
void target_vvm::proc_assign(ostream&os, const NetAssign*net) void target_vvm::proc_assign(ostream&os, const NetAssign*net)
{ {
string rval = emit_proc_rval(os, net->rval()); string rval = emit_proc_rval(os, indent_, net->rval());
os << " // " << net->lval()->name() << " = "; os << setw(indent_) << "" << "// " << net->lval()->name() << " = ";
net->rval()->dump(os); net->rval()->dump(os);
os << endl; os << endl;
os << " " << mangle(net->lval()->name()) << " = " << rval << os << setw(indent_) << "" << mangle(net->lval()->name()) << " = "
";" << endl; << rval << ";" << endl;
os << " " << mangle(net->lval()->name()) << os << setw(indent_) << "" << mangle(net->lval()->name()) <<
"_mon.trigger(sim_);" << endl; "_mon.trigger(sim_);" << endl;
@ -430,14 +488,14 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net)
continue; continue;
if (const NetNet*sig = dynamic_cast<const NetNet*>(cur)) { if (const NetNet*sig = dynamic_cast<const NetNet*>(cur)) {
os << " " << mangle(sig->name()) << "[" << os << setw(indent_) << "" << mangle(sig->name())
pin << "] = " << rval << "[" << idx << << "[" << pin << "] = " << rval << "[" << idx
"];" << endl; << "];" << endl;
os << " " << mangle(sig->name()) << os <<setw(indent_) << "" << mangle(sig->name())
"_mon.trigger(sim_);" << endl; << "_mon.trigger(sim_);" << endl;
} else { } else {
os << " " << mangle(cur->name()) << os << setw(indent_) << "" << mangle(cur->name()) <<
".set(sim_, " << pin << ", " << ".set(sim_, " << pin << ", " <<
rval << "[" << idx << "]);" << endl; rval << "[" << idx << "]);" << endl;
} }
@ -452,12 +510,17 @@ void target_vvm::proc_block(ostream&os, const NetBlock*net)
void target_vvm::proc_condit(ostream&os, const NetCondit*net) void target_vvm::proc_condit(ostream&os, const NetCondit*net)
{ {
string expr = emit_proc_rval(os, net->expr()); unsigned ind = indent_;
os << " if (" << expr << "[0] == V1) {" << endl; indent_ += 4;
string expr = emit_proc_rval(os, indent_, net->expr());
os << setw(ind) << "" << "if (" << expr << "[0] == V1) {" << endl;
net->emit_recurse_if(os, this); net->emit_recurse_if(os, this);
os << " } else {" << endl; os << setw(ind) << "" << "} else {" << endl;
net->emit_recurse_else(os, this); net->emit_recurse_else(os, this);
os << " }" << endl; os << setw(ind) << "" << "}" << endl;
indent_ = ind;
} }
void target_vvm::proc_task(ostream&os, const NetTask*net) void target_vvm::proc_task(ostream&os, const NetTask*net)
@ -479,6 +542,21 @@ void target_vvm::proc_task(ostream&os, const NetTask*net)
} }
} }
void target_vvm::proc_while(ostream&os, const NetWhile*net)
{
unsigned ind = indent_;
indent_ += 4;
os << setw(ind) << "" << "for (;;) {" << endl;
string expr = emit_proc_rval(os, indent_, net->expr());
os << setw(indent_) << "" << "if (" << expr << "[0] != V1)"
" break;" << endl;
net->emit_proc_recurse(os, this);
os << setw(ind) << "" << "}" << endl;
indent_ = ind;
}
/* /*
* Within a process, the proc_event is a statement that is blocked * Within a process, the proc_event is a statement that is blocked
* until the event is signalled. * until the event is signalled.
@ -486,8 +564,10 @@ void target_vvm::proc_task(ostream&os, const NetTask*net)
void target_vvm::proc_event(ostream&os, const NetPEvent*proc) void target_vvm::proc_event(ostream&os, const NetPEvent*proc)
{ {
thread_step_ += 1; thread_step_ += 1;
os << " step_ = &step_" << thread_step_ << "_;" << endl; os << setw(indent_) << "" << "step_ = &step_" << thread_step_ <<
os << " " << mangle(proc->name()) << ".wait(vvm_pevent::"; "_;" << endl;
os << setw(indent_) << "" << mangle(proc->name()) <<
".wait(vvm_pevent::";
switch (proc->edge()) { switch (proc->edge()) {
case NetPEvent::ANYEDGE: case NetPEvent::ANYEDGE:
os << "ANYEDGE"; os << "ANYEDGE";
@ -498,6 +578,9 @@ void target_vvm::proc_event(ostream&os, const NetPEvent*proc)
case NetPEvent::NEGEDGE: case NetPEvent::NEGEDGE:
os << "NEGEDGE"; os << "NEGEDGE";
break; break;
case NetPEvent::POSITIVE:
os << "POSITIVE";
break;
} }
os << ", this);" << endl; os << ", this);" << endl;
os << " }" << endl; os << " }" << endl;
@ -545,6 +628,14 @@ extern const struct target tgt_vvm = {
}; };
/* /*
* $Log: t-vvm.cc,v $ * $Log: t-vvm.cc,v $
* Revision 1.4 1998/11/09 18:55:34 steve
* Add procedural while loops,
* Parse procedural for loops,
* Add procedural wait statements,
* Add constant nodes,
* Add XNOR logic gate,
* Make vvm output look a bit prettier.
*
* Revision 1.3 1998/11/07 19:17:10 steve * Revision 1.3 1998/11/07 19:17:10 steve
* Calculate expression widths at elaboration time. * Calculate expression widths at elaboration time.
* *

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: target.cc,v 1.2 1998/11/07 17:05:06 steve Exp $" #ident "$Id: target.cc,v 1.3 1998/11/09 18:55:34 steve Exp $"
#endif #endif
# include "target.h" # include "target.h"
@ -49,6 +49,12 @@ void target_t::net_assign(ostream&os, const NetAssign*)
{ {
} }
void target_t::net_const(ostream&os, const NetConst*)
{
cerr << "target (" << typeid(*this).name() << "): "
"Unhandled CONSTANT node." << endl;
}
void target_t::net_pevent(ostream&os, const NetPEvent*) void target_t::net_pevent(ostream&os, const NetPEvent*)
{ {
cerr << "target (" << typeid(*this).name() << "): " cerr << "target (" << typeid(*this).name() << "): "
@ -90,6 +96,13 @@ void target_t::proc_task(ostream&os, const NetTask*)
{ {
} }
void target_t::proc_while(ostream&os, const NetWhile*net)
{
cerr << "target (" << typeid(*this).name() << "): "
"Unhandled while:" << endl;
net->dump(cerr, 6);
}
void target_t::end_process(ostream&os, const NetProcTop*) void target_t::end_process(ostream&os, const NetProcTop*)
{ {
} }
@ -134,6 +147,14 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/* /*
* $Log: target.cc,v $ * $Log: target.cc,v $
* Revision 1.3 1998/11/09 18:55:34 steve
* Add procedural while loops,
* Parse procedural for loops,
* Add procedural wait statements,
* Add constant nodes,
* Add XNOR logic gate,
* Make vvm output look a bit prettier.
*
* Revision 1.2 1998/11/07 17:05:06 steve * Revision 1.2 1998/11/07 17:05:06 steve
* Handle procedural conditional, and some * Handle procedural conditional, and some
* of the conditional expressions. * of the conditional expressions.

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: target.h,v 1.2 1998/11/07 17:05:06 steve Exp $" #ident "$Id: target.h,v 1.3 1998/11/09 18:55:35 steve Exp $"
#endif #endif
# include "netlist.h" # include "netlist.h"
@ -62,6 +62,7 @@ struct target_t {
virtual void logic(ostream&os, const NetLogic*); virtual void logic(ostream&os, const NetLogic*);
virtual void bufz(ostream&os, const NetBUFZ*); virtual void bufz(ostream&os, const NetBUFZ*);
virtual void net_assign(ostream&os, const NetAssign*); virtual void net_assign(ostream&os, const NetAssign*);
virtual void net_const(ostream&os, const NetConst*);
virtual void net_pevent(ostream&os, const NetPEvent*); virtual void net_pevent(ostream&os, const NetPEvent*);
/* Output a process (called for each process) */ /* Output a process (called for each process) */
@ -72,6 +73,7 @@ struct target_t {
virtual void proc_block(ostream&os, const NetBlock*); virtual void proc_block(ostream&os, const NetBlock*);
virtual void proc_condit(ostream&os, const NetCondit*); virtual void proc_condit(ostream&os, const NetCondit*);
virtual void proc_task(ostream&os, const NetTask*); virtual void proc_task(ostream&os, const NetTask*);
virtual void proc_while(ostream&os, const NetWhile*);
virtual void proc_event(ostream&os, const NetPEvent*); virtual void proc_event(ostream&os, const NetPEvent*);
virtual void proc_delay(ostream&os, const NetPDelay*); virtual void proc_delay(ostream&os, const NetPDelay*);
@ -111,6 +113,14 @@ extern const struct target *target_table[];
/* /*
* $Log: target.h,v $ * $Log: target.h,v $
* Revision 1.3 1998/11/09 18:55:35 steve
* Add procedural while loops,
* Parse procedural for loops,
* Add procedural wait statements,
* Add constant nodes,
* Add XNOR logic gate,
* Make vvm output look a bit prettier.
*
* Revision 1.2 1998/11/07 17:05:06 steve * Revision 1.2 1998/11/07 17:05:06 steve
* Handle procedural conditional, and some * Handle procedural conditional, and some
* of the conditional expressions. * of the conditional expressions.

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: verinum.cc,v 1.2 1998/11/07 17:04:48 steve Exp $" #ident "$Id: verinum.cc,v 1.3 1998/11/09 18:55:35 steve Exp $"
#endif #endif
# include "verinum.h" # include "verinum.h"
@ -162,6 +162,24 @@ string verinum::as_string() const
return result; return result;
} }
ostream& operator<< (ostream&o, verinum::V v)
{
switch (v) {
case verinum::V0:
o << "0";
break;
case verinum::V1:
o << "1";
break;
case verinum::Vx:
o << "x";
break;
case verinum::Vz:
o << "z";
break;
}
}
ostream& operator<< (ostream&o, const verinum&v) ostream& operator<< (ostream&o, const verinum&v)
{ {
o << v.len() << "'b"; o << v.len() << "'b";
@ -178,36 +196,10 @@ ostream& operator<< (ostream&o, const verinum&v)
if (trim_left != v.get(idx-1)) if (trim_left != v.get(idx-1))
break; break;
switch (trim_left) { o << trim_left;
case verinum::V0:
o << "0";
break;
case verinum::V1:
o << "1";
break;
case verinum::Vx:
o << "x";
break;
case verinum::Vz:
o << "z";
break;
}
while (idx > 0) { while (idx > 0) {
switch (v.get(idx-1)) { o << v.get(idx-1);
case verinum::V0:
o << "0";
break;
case verinum::V1:
o << "1";
break;
case verinum::Vx:
o << "x";
break;
case verinum::Vz:
o << "z";
break;
}
idx -= 1; idx -= 1;
} }
@ -216,6 +208,14 @@ ostream& operator<< (ostream&o, const verinum&v)
/* /*
* $Log: verinum.cc,v $ * $Log: verinum.cc,v $
* Revision 1.3 1998/11/09 18:55:35 steve
* Add procedural while loops,
* Parse procedural for loops,
* Add procedural wait statements,
* Add constant nodes,
* Add XNOR logic gate,
* Make vvm output look a bit prettier.
*
* Revision 1.2 1998/11/07 17:04:48 steve * Revision 1.2 1998/11/07 17:04:48 steve
* Properly dump 0 length numbers. * Properly dump 0 length numbers.
* *

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: verinum.h,v 1.1 1998/11/03 23:29:08 steve Exp $" #ident "$Id: verinum.h,v 1.2 1998/11/09 18:55:35 steve Exp $"
#endif #endif
# include <string> # include <string>
@ -74,9 +74,18 @@ class verinum {
class ostream; class ostream;
ostream& operator<< (ostream&, const verinum&); ostream& operator<< (ostream&, const verinum&);
ostream& operator<< (ostream&, verinum::V);
/* /*
* $Log: verinum.h,v $ * $Log: verinum.h,v $
* Revision 1.2 1998/11/09 18:55:35 steve
* Add procedural while loops,
* Parse procedural for loops,
* Add procedural wait statements,
* Add constant nodes,
* Add XNOR logic gate,
* Make vvm output look a bit prettier.
*
* Revision 1.1 1998/11/03 23:29:08 steve * Revision 1.1 1998/11/03 23:29:08 steve
* Introduce verilog to CVS. * Introduce verilog to CVS.
* *