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:
parent
9a93912ce7
commit
ebad845fc3
11
PExpr.h
11
PExpr.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include <string>
|
||||
|
|
@ -84,6 +84,7 @@ class PENumber : public PExpr {
|
|||
const verinum& value() const { return *value_; }
|
||||
|
||||
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 verinum* eval_const() const;
|
||||
|
||||
|
|
@ -138,6 +139,14 @@ class PEBinary : public PExpr {
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Handle procedural conditional, and some
|
||||
* of the conditional expressions.
|
||||
|
|
|
|||
34
Statement.h
34
Statement.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include <string>
|
||||
|
|
@ -198,6 +198,30 @@ class PEventStatement : public 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 {
|
||||
|
||||
public:
|
||||
|
|
@ -206,6 +230,14 @@ class PNoop : public Statement {
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Handle procedural conditional, and some
|
||||
* of the conditional expressions.
|
||||
|
|
|
|||
|
|
@ -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.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
|
||||
|
||||
/*
|
||||
|
|
@ -115,6 +115,12 @@ void NetBUFZ::dump_node(ostream&o, unsigned ind) const
|
|||
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
|
||||
{
|
||||
o << setw(ind) << "" << "logic: ";
|
||||
|
|
@ -134,6 +140,9 @@ void NetLogic::dump_node(ostream&o, unsigned ind) const
|
|||
case OR:
|
||||
o << "or";
|
||||
break;
|
||||
case XNOR:
|
||||
o << "xnor";
|
||||
break;
|
||||
case XOR:
|
||||
o << "xor";
|
||||
break;
|
||||
|
|
@ -157,6 +166,9 @@ void NetPEvent::dump_node(ostream&o, unsigned ind) const
|
|||
case NEGEDGE:
|
||||
o << "negedge ";
|
||||
break;
|
||||
case POSITIVE:
|
||||
o << "positive ";
|
||||
break;
|
||||
}
|
||||
|
||||
o << name() << endl;
|
||||
|
|
@ -222,16 +234,19 @@ void NetPDelay::dump(ostream&o, unsigned ind) const
|
|||
|
||||
void NetPEvent::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "@";
|
||||
o << setw(ind) << "" ;
|
||||
switch (edge_) {
|
||||
case NEGEDGE:
|
||||
o << "(negedge " << name() << ")";
|
||||
o << "@" << "(negedge " << name() << ")";
|
||||
break;
|
||||
case POSEDGE:
|
||||
o << "(posedge " << name() << ")";
|
||||
o << "@" << "(posedge " << name() << ")";
|
||||
break;
|
||||
case ANYEDGE:
|
||||
o << name();
|
||||
o << "@" << name();
|
||||
break;
|
||||
case POSITIVE:
|
||||
o << "wait (" << name() << ")";
|
||||
break;
|
||||
}
|
||||
o << endl;
|
||||
|
|
@ -261,6 +276,12 @@ void NetTask::dump(ostream&o, unsigned ind) const
|
|||
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. */
|
||||
void NetProc::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
|
|
@ -285,6 +306,9 @@ void NetEBinary::dump(ostream&o) const
|
|||
case 'e':
|
||||
o << "==";
|
||||
break;
|
||||
case 'n':
|
||||
o << "!=";
|
||||
break;
|
||||
}
|
||||
o << "(";
|
||||
right_->dump(o);
|
||||
|
|
@ -351,6 +375,14 @@ void Design::dump(ostream&o) const
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Handle procedural conditional, and some
|
||||
* of the conditional expressions.
|
||||
|
|
|
|||
96
elaborate.cc
96
elaborate.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: elaborate.cc,v 1.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
|
||||
|
||||
/*
|
||||
|
|
@ -149,25 +149,31 @@ void PGAssign::elaborate(Design*des, const string&path) const
|
|||
void PGBuiltin::elaborate(Design*des, const string&path) const
|
||||
{
|
||||
NetLogic*cur = 0;
|
||||
string name = get_name();
|
||||
if (name == "")
|
||||
name = local_symbol(path);
|
||||
|
||||
switch (type()) {
|
||||
case AND:
|
||||
cur = new NetLogic(get_name(), pin_count(), NetLogic::AND);
|
||||
cur = new NetLogic(name, pin_count(), NetLogic::AND);
|
||||
break;
|
||||
case NAND:
|
||||
cur = new NetLogic(get_name(), pin_count(), NetLogic::NAND);
|
||||
cur = new NetLogic(name, pin_count(), NetLogic::NAND);
|
||||
break;
|
||||
case NOR:
|
||||
cur = new NetLogic(get_name(), pin_count(), NetLogic::NOR);
|
||||
cur = new NetLogic(name, pin_count(), NetLogic::NOR);
|
||||
break;
|
||||
case NOT:
|
||||
cur = new NetLogic(get_name(), pin_count(), NetLogic::NOT);
|
||||
cur = new NetLogic(name, pin_count(), NetLogic::NOT);
|
||||
break;
|
||||
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;
|
||||
case XOR:
|
||||
cur = new NetLogic(get_name(), pin_count(), NetLogic::XOR);
|
||||
cur = new NetLogic(name, pin_count(), NetLogic::XOR);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -225,6 +231,9 @@ void PGModule::elaborate(Design*des, const string&path) const
|
|||
assert(pin_count() == rmod->ports.size());
|
||||
|
||||
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);
|
||||
if (sig == 0) {
|
||||
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);
|
||||
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:
|
||||
cerr << "Unhandled BINARY '" << op_ << "'" << endl;
|
||||
osig = 0;
|
||||
|
|
@ -363,6 +385,21 @@ NetNet* PEIdent::elaborate_net(Design*des, const string&path) const
|
|||
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* 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
|
||||
{
|
||||
cerr << "What kind of statement? " << typeid(*this).name() << endl;
|
||||
cerr << "elaborate: What kind of statement? " <<
|
||||
typeid(*this).name() << endl;
|
||||
NetProc*cur = new NetProc;
|
||||
return cur;
|
||||
}
|
||||
|
|
@ -540,6 +578,40 @@ NetProc* PEventStatement::elaborate(Design*des, const string&path) const
|
|||
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
|
||||
{
|
||||
// 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 $
|
||||
* 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
|
||||
* Handle procedural conditional, and some
|
||||
* of the conditional expressions.
|
||||
|
|
|
|||
25
emit.cc
25
emit.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
/*
|
||||
|
|
@ -45,6 +45,11 @@ void NetAssign::emit_node(ostream&o, struct target_t*tgt) const
|
|||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
if (last_ == 0)
|
||||
|
|
@ -133,6 +143,11 @@ void NetCondit::emit_recurse_else(ostream&o, struct target_t*tgt) const
|
|||
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
|
||||
{
|
||||
tgt->start_design(o, this);
|
||||
|
|
@ -203,6 +218,14 @@ void emit(ostream&o, const Design*des, const char*type)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Handle procedural conditional, and some
|
||||
* of the conditional expressions.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
//# define YYSTYPE lexval
|
||||
|
|
@ -68,7 +68,7 @@ static verinum*make_sized_hex(const char*txt);
|
|||
"===" { return K_CEQ; }
|
||||
"!==" { return K_CNE; }
|
||||
|
||||
[;:\[\],()#=.@&!<|^~+-] { return yytext[0]; }
|
||||
[;:\[\],()#=.@&!<|^~+*/-] { return yytext[0]; }
|
||||
|
||||
\" { BEGIN(CSTRING); }
|
||||
<CSTRING>\\\" { yymore(); }
|
||||
|
|
|
|||
13
netlist.cc
13
netlist.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include <cassert>
|
||||
|
|
@ -149,7 +149,9 @@ NetEBinary::NetEBinary(char op, NetExpr*l, NetExpr*r)
|
|||
: op_(op), left_(l), right_(r)
|
||||
{
|
||||
switch (op_) {
|
||||
// comparison operators return a 1-bin wide result.
|
||||
case 'e':
|
||||
case 'n':
|
||||
expr_width(1);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -178,6 +180,7 @@ void NetEBinary::set_width(unsigned w)
|
|||
op_ << "." << endl;
|
||||
|
||||
case '+':
|
||||
case '-':
|
||||
left_->set_width(w);
|
||||
right_->set_width(w);
|
||||
expr_width(w);
|
||||
|
|
@ -317,6 +320,14 @@ void Design::add_process(NetProcTop*pro)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Calculate expression widths at elaboration time.
|
||||
*
|
||||
|
|
|
|||
53
netlist.h
53
netlist.h
|
|
@ -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.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
|
||||
|
||||
/*
|
||||
|
|
@ -252,13 +252,28 @@ class NetBUFZ : public NetNode {
|
|||
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.
|
||||
*/
|
||||
class NetLogic : public NetNode {
|
||||
|
||||
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)
|
||||
: NetNode(n, pins), type_(t) { }
|
||||
|
|
@ -390,7 +405,7 @@ class NetPDelay : public NetProc {
|
|||
class NetPEvent : public NetProc, public NetNode {
|
||||
|
||||
public:
|
||||
enum Type { ANYEDGE, POSEDGE, NEGEDGE };
|
||||
enum Type { ANYEDGE, POSEDGE, NEGEDGE, POSITIVE };
|
||||
|
||||
public:
|
||||
NetPEvent(const string&ev, Type ed, NetProc*st)
|
||||
|
|
@ -448,6 +463,30 @@ class NetTask : public NetProc {
|
|||
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
|
||||
always) and a pointer to the statement, probably a block, that
|
||||
makes up the process. */
|
||||
|
|
@ -670,6 +709,14 @@ inline ostream& operator << (ostream&o, const NetExpr&exp)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Calculate expression widths at elaboration time.
|
||||
*
|
||||
|
|
|
|||
39
parse.y
39
parse.y
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: parse.y,v 1.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
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -177,6 +177,9 @@ expression
|
|||
| expression '+' expression
|
||||
{ $$ = new PEBinary('+', $1, $3);
|
||||
}
|
||||
| expression '-' expression
|
||||
{ $$ = new PEBinary('-', $1, $3);
|
||||
}
|
||||
| expression '&' expression
|
||||
{ $$ = new PEBinary('&', $1, $3);
|
||||
}
|
||||
|
|
@ -530,6 +533,34 @@ statement
|
|||
{ yyerror(@1, "Malformed conditional expression.");
|
||||
$$ = $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
|
||||
{ PDelayStatement*tmp = new PDelayStatement($1, $2);
|
||||
$$ = tmp;
|
||||
|
|
@ -546,6 +577,12 @@ statement
|
|||
{ $$ = pform_make_assignment($1, $3);
|
||||
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 ')' ';'
|
||||
{ $$ = pform_make_calltask($1, $3);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.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
|
||||
|
||||
/*
|
||||
|
|
@ -105,9 +105,6 @@ void PWire::dump(ostream&out) const
|
|||
case NetNet::REG:
|
||||
out << " reg ";
|
||||
break;
|
||||
default:
|
||||
out << " (" << type << ") ";
|
||||
break;
|
||||
}
|
||||
|
||||
switch (port_type) {
|
||||
|
|
@ -141,7 +138,8 @@ void PGate::dump_pins(ostream&out) const
|
|||
out << *pin(0);
|
||||
|
||||
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:
|
||||
out << "negedge ";
|
||||
break;
|
||||
case NetPEvent::POSITIVE:
|
||||
out << "positive ";
|
||||
break;
|
||||
}
|
||||
out << *expr_ << ")" << endl;
|
||||
|
||||
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
|
||||
{
|
||||
switch (type_) {
|
||||
|
|
@ -314,6 +323,14 @@ void pform_dump(ostream&out, Module*mod)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Handle procedural conditional, and some
|
||||
* of the conditional expressions.
|
||||
|
|
|
|||
153
t-vvm.cc
153
t-vvm.cc
|
|
@ -17,11 +17,12 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include <iostream>
|
||||
# include <strstream>
|
||||
# include <iomanip>
|
||||
# include <string>
|
||||
# include <typeinfo>
|
||||
# include "netlist.h"
|
||||
|
|
@ -42,12 +43,14 @@ class target_vvm : public target_t {
|
|||
virtual void signal(ostream&os, const NetNet*);
|
||||
virtual void logic(ostream&os, const NetLogic*);
|
||||
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 start_process(ostream&os, const NetProcTop*);
|
||||
virtual void proc_assign(ostream&os, const NetAssign*);
|
||||
virtual void proc_block(ostream&os, const NetBlock*);
|
||||
virtual void proc_condit(ostream&os, const NetCondit*);
|
||||
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_delay(ostream&os, const NetPDelay*);
|
||||
virtual void end_process(ostream&os, const NetProcTop*);
|
||||
|
|
@ -57,8 +60,11 @@ class target_vvm : public target_t {
|
|||
void emit_gate_outputfun_(const NetNode*);
|
||||
|
||||
ostrstream delayed;
|
||||
ostrstream init_code;
|
||||
unsigned process_counter;
|
||||
unsigned thread_step_;
|
||||
|
||||
unsigned indent_;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -69,13 +75,14 @@ class target_vvm : public target_t {
|
|||
class vvm_proc_rval : public expr_scan_t {
|
||||
|
||||
public:
|
||||
explicit vvm_proc_rval(ostream&os)
|
||||
: result(""), os_(os) { }
|
||||
explicit vvm_proc_rval(ostream&os, unsigned i)
|
||||
: result(""), os_(os), indent_(i) { }
|
||||
|
||||
string result;
|
||||
|
||||
private:
|
||||
ostream&os_;
|
||||
unsigned indent_;
|
||||
|
||||
private:
|
||||
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)
|
||||
{
|
||||
string tname = make_temp();
|
||||
os_ << " vvm_bitset_t<" << expr->expr_width() << "> "
|
||||
<< tname << ";" << endl;
|
||||
os_ << setw(indent_) << "" << "vvm_bitset_t<" <<
|
||||
expr->expr_width() << "> " << tname << ";" << endl;
|
||||
for (unsigned idx = 0 ; idx < expr->expr_width() ; idx += 1) {
|
||||
os_ << " " << tname << "[" << idx << "] = ";
|
||||
os_ << setw(indent_) << "" << tname << "[" << idx << "] = ";
|
||||
switch (expr->value().get(idx)) {
|
||||
case verinum::V0:
|
||||
os_ << "V0";
|
||||
|
|
@ -153,16 +160,24 @@ void vvm_proc_rval::expr_binary(const NetEBinary*expr)
|
|||
string rres = result;
|
||||
|
||||
result = make_temp();
|
||||
os_ << " vvm_bitset_t<" << expr->expr_width() << ">" <<
|
||||
result << ";" << endl;
|
||||
os_ << setw(indent_) << "" << "vvm_bitset_t<" <<
|
||||
expr->expr_width() << ">" << result << ";" << endl;
|
||||
switch (expr->op()) {
|
||||
case 'e':
|
||||
os_ << " " << result << " = vvm_binop_eq(" << lres
|
||||
<< "," << rres << ");" << endl;
|
||||
os_ << setw(indent_) << "" << result << " = vvm_binop_eq("
|
||||
<< lres << "," << rres << ");" << endl;
|
||||
break;
|
||||
case 'n':
|
||||
os_ << setw(indent_) << "" << result << " = vvm_binop_ne("
|
||||
<< lres << "," << rres << ");" << endl;
|
||||
break;
|
||||
case '+':
|
||||
os_ << " " << result << " = vvm_binop_plus(" << lres
|
||||
<< "," << rres << ");" << endl;
|
||||
os_ << setw(indent_) << "" << result << " = vvm_binop_plus("
|
||||
<< lres << "," << rres << ");" << endl;
|
||||
break;
|
||||
case '-':
|
||||
os_ << setw(indent_) << "" << result << " = vvm_binop_minus("
|
||||
<< lres << "," << rres << ");" << endl;
|
||||
break;
|
||||
default:
|
||||
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);
|
||||
return scan.result;
|
||||
}
|
||||
|
|
@ -254,6 +269,9 @@ void target_vvm::end_design(ostream&os, const Design*mod)
|
|||
os << "main()" << endl << "{" << endl;
|
||||
os << " vvm_simulation sim;" << endl;
|
||||
|
||||
init_code << ends;
|
||||
os << init_code.str();
|
||||
|
||||
for (unsigned idx = 0 ; idx < process_counter ; idx += 1)
|
||||
os << " thread" << (idx+1) << "_t thread_" <<
|
||||
(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 <<
|
||||
"," << gate->delay1() << "> ";
|
||||
break;
|
||||
case NetLogic::XNOR:
|
||||
os << "static vvm_xnor" << "<" << gate->pin_count()-1 <<
|
||||
"," << gate->delay1() << "> ";
|
||||
break;
|
||||
case NetLogic::XOR:
|
||||
os << "static vvm_xor" << "<" << gate->pin_count()-1 <<
|
||||
"," << gate->delay1() << "> ";
|
||||
|
|
@ -356,6 +378,41 @@ void target_vvm::bufz(ostream&os, const NetBUFZ*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 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)
|
||||
{
|
||||
process_counter += 1;
|
||||
indent_ = 8;
|
||||
thread_step_ = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
os << endl;
|
||||
|
||||
os << " " << mangle(net->lval()->name()) << " = " << rval <<
|
||||
";" << endl;
|
||||
os << setw(indent_) << "" << mangle(net->lval()->name()) << " = "
|
||||
<< rval << ";" << endl;
|
||||
|
||||
os << " " << mangle(net->lval()->name()) <<
|
||||
os << setw(indent_) << "" << mangle(net->lval()->name()) <<
|
||||
"_mon.trigger(sim_);" << endl;
|
||||
|
||||
|
||||
|
|
@ -430,14 +488,14 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net)
|
|||
continue;
|
||||
|
||||
if (const NetNet*sig = dynamic_cast<const NetNet*>(cur)) {
|
||||
os << " " << mangle(sig->name()) << "[" <<
|
||||
pin << "] = " << rval << "[" << idx <<
|
||||
"];" << endl;
|
||||
os << " " << mangle(sig->name()) <<
|
||||
"_mon.trigger(sim_);" << endl;
|
||||
os << setw(indent_) << "" << mangle(sig->name())
|
||||
<< "[" << pin << "] = " << rval << "[" << idx
|
||||
<< "];" << endl;
|
||||
os <<setw(indent_) << "" << mangle(sig->name())
|
||||
<< "_mon.trigger(sim_);" << endl;
|
||||
|
||||
} else {
|
||||
os << " " << mangle(cur->name()) <<
|
||||
os << setw(indent_) << "" << mangle(cur->name()) <<
|
||||
".set(sim_, " << pin << ", " <<
|
||||
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)
|
||||
{
|
||||
string expr = emit_proc_rval(os, net->expr());
|
||||
os << " if (" << expr << "[0] == V1) {" << endl;
|
||||
unsigned ind = indent_;
|
||||
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);
|
||||
os << " } else {" << endl;
|
||||
os << setw(ind) << "" << "} else {" << endl;
|
||||
net->emit_recurse_else(os, this);
|
||||
os << " }" << endl;
|
||||
os << setw(ind) << "" << "}" << endl;
|
||||
|
||||
indent_ = ind;
|
||||
}
|
||||
|
||||
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
|
||||
* 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)
|
||||
{
|
||||
thread_step_ += 1;
|
||||
os << " step_ = &step_" << thread_step_ << "_;" << endl;
|
||||
os << " " << mangle(proc->name()) << ".wait(vvm_pevent::";
|
||||
os << setw(indent_) << "" << "step_ = &step_" << thread_step_ <<
|
||||
"_;" << endl;
|
||||
os << setw(indent_) << "" << mangle(proc->name()) <<
|
||||
".wait(vvm_pevent::";
|
||||
switch (proc->edge()) {
|
||||
case NetPEvent::ANYEDGE:
|
||||
os << "ANYEDGE";
|
||||
|
|
@ -498,6 +578,9 @@ void target_vvm::proc_event(ostream&os, const NetPEvent*proc)
|
|||
case NetPEvent::NEGEDGE:
|
||||
os << "NEGEDGE";
|
||||
break;
|
||||
case NetPEvent::POSITIVE:
|
||||
os << "POSITIVE";
|
||||
break;
|
||||
}
|
||||
os << ", this);" << endl;
|
||||
os << " }" << endl;
|
||||
|
|
@ -545,6 +628,14 @@ extern const struct target tgt_vvm = {
|
|||
};
|
||||
/*
|
||||
* $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
|
||||
* Calculate expression widths at elaboration time.
|
||||
*
|
||||
|
|
|
|||
23
target.cc
23
target.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# 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*)
|
||||
{
|
||||
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*)
|
||||
{
|
||||
}
|
||||
|
|
@ -134,6 +147,14 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Handle procedural conditional, and some
|
||||
* of the conditional expressions.
|
||||
|
|
|
|||
12
target.h
12
target.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -62,6 +62,7 @@ struct target_t {
|
|||
virtual void logic(ostream&os, const NetLogic*);
|
||||
virtual void bufz(ostream&os, const NetBUFZ*);
|
||||
virtual void net_assign(ostream&os, const NetAssign*);
|
||||
virtual void net_const(ostream&os, const NetConst*);
|
||||
virtual void net_pevent(ostream&os, const NetPEvent*);
|
||||
|
||||
/* 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_condit(ostream&os, const NetCondit*);
|
||||
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_delay(ostream&os, const NetPDelay*);
|
||||
|
|
@ -111,6 +113,14 @@ extern const struct target *target_table[];
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Handle procedural conditional, and some
|
||||
* of the conditional expressions.
|
||||
|
|
|
|||
58
verinum.cc
58
verinum.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "verinum.h"
|
||||
|
|
@ -162,6 +162,24 @@ string verinum::as_string() const
|
|||
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)
|
||||
{
|
||||
o << v.len() << "'b";
|
||||
|
|
@ -178,36 +196,10 @@ ostream& operator<< (ostream&o, const verinum&v)
|
|||
if (trim_left != v.get(idx-1))
|
||||
break;
|
||||
|
||||
switch (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;
|
||||
}
|
||||
o << trim_left;
|
||||
|
||||
while (idx > 0) {
|
||||
switch (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;
|
||||
}
|
||||
o << v.get(idx-1);
|
||||
idx -= 1;
|
||||
}
|
||||
|
||||
|
|
@ -216,6 +208,14 @@ ostream& operator<< (ostream&o, const verinum&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
|
||||
* Properly dump 0 length numbers.
|
||||
*
|
||||
|
|
|
|||
11
verinum.h
11
verinum.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include <string>
|
||||
|
|
@ -74,9 +74,18 @@ class verinum {
|
|||
|
||||
class ostream;
|
||||
ostream& operator<< (ostream&, const verinum&);
|
||||
ostream& operator<< (ostream&, verinum::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
|
||||
* Introduce verilog to CVS.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue