diff --git a/Makefile.in b/Makefile.in index c8f9d1224..2186417cc 100644 --- a/Makefile.in +++ b/Makefile.in @@ -18,7 +18,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.52 2000/05/08 05:29:43 steve Exp $" +#ident "$Id: Makefile.in,v 1.53 2000/05/11 23:37:26 steve Exp $" # # SHELL = /bin/sh @@ -73,7 +73,7 @@ O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \ elab_net.o elab_pexpr.o elab_scope.o elab_sig.o emit.o eval.o eval_tree.o \ expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \ mangle.o netlist.o \ -net_design.o net_event.o net_scope.o net_udp.o nexus_from_link.o \ +net_design.o net_event.o net_force.o net_scope.o net_udp.o nexus_from_link.o \ pad_to_width.o \ parse.o parse_misc.o pform.o pform_dump.o \ set_width.o \ diff --git a/Statement.cc b/Statement.cc index 3abbad389..12be8f209 100644 --- a/Statement.cc +++ b/Statement.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: Statement.cc,v 1.20 2000/04/22 04:20:19 steve Exp $" +#ident "$Id: Statement.cc,v 1.21 2000/05/11 23:37:26 steve Exp $" #endif # include "Statement.h" @@ -122,6 +122,17 @@ PCase::~PCase() delete[]items_; } +PCAssign::PCAssign(PExpr*l, PExpr*r) +: lval_(l), expr_(r) +{ +} + +PCAssign::~PCAssign() +{ + delete lval_; + delete expr_; +} + PCondit::PCondit(PExpr*ex, Statement*i, Statement*e) : expr_(ex), if_(i), else_(e) { @@ -134,6 +145,16 @@ PCondit::~PCondit() delete else_; } +PDeassign::PDeassign(PExpr*l) +: lval_(l) +{ +} + +PDeassign::~PDeassign() +{ + delete lval_; +} + PDelayStatement::PDelayStatement(PExpr*d, Statement*st) : delay_(d), statement_(st) @@ -231,6 +252,9 @@ PWhile::~PWhile() /* * $Log: Statement.cc,v $ + * Revision 1.21 2000/05/11 23:37:26 steve + * Add support for procedural continuous assignment. + * * Revision 1.20 2000/04/22 04:20:19 steve * Add support for force assignment. * diff --git a/Statement.h b/Statement.h index b2dfe9c04..502acb455 100644 --- a/Statement.h +++ b/Statement.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: Statement.h,v 1.25 2000/04/22 04:20:19 steve Exp $" +#ident "$Id: Statement.h,v 1.26 2000/05/11 23:37:26 steve Exp $" #endif # include @@ -31,6 +31,8 @@ class PExpr; class Statement; class PEventStatement; class Design; +class NetCAssign; +class NetDeassign; class NetScope; /* @@ -222,6 +224,20 @@ class PCase : public Statement { PCase& operator= (const PCase&); }; +class PCAssign : public Statement { + + public: + explicit PCAssign(PExpr*l, PExpr*r); + ~PCAssign(); + + virtual NetCAssign* elaborate(Design*des, const string&path) const; + virtual void dump(ostream&out, unsigned ind) const; + + private: + PExpr*lval_; + PExpr*expr_; +}; + class PCondit : public Statement { public: @@ -242,6 +258,19 @@ class PCondit : public Statement { PCondit& operator= (const PCondit&); }; +class PDeassign : public Statement { + + public: + explicit PDeassign(PExpr*l); + ~PDeassign(); + + virtual NetDeassign* elaborate(Design*des, const string&path) const; + virtual void dump(ostream&out, unsigned ind) const; + + private: + PExpr*lval_; +}; + class PDelayStatement : public Statement { public: @@ -408,6 +437,9 @@ class PWhile : public Statement { /* * $Log: Statement.h,v $ + * Revision 1.26 2000/05/11 23:37:26 steve + * Add support for procedural continuous assignment. + * * Revision 1.25 2000/04/22 04:20:19 steve * Add support for force assignment. * diff --git a/design_dump.cc b/design_dump.cc index 6719f7e08..e0ed53b63 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: design_dump.cc,v 1.84 2000/05/07 18:20:07 steve Exp $" +#ident "$Id: design_dump.cc,v 1.85 2000/05/11 23:37:27 steve Exp $" #endif /* @@ -176,6 +176,13 @@ void NetAddSub::dump_node(ostream&o, unsigned ind) const dump_obj_attr(o, ind+4); } +void NetCAssign::dump_node(ostream&o, unsigned ind) const +{ + o << setw(ind) << "" << "Procedural continuous assign (NetCAssign): " + << name() << endl; + dump_node_pins(o, ind+4); +} + void NetCLShift::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "Combinatorial shift (NetCLShift): " << @@ -539,6 +546,12 @@ void NetCase::dump(ostream&o, unsigned ind) const o << setw(ind) << "" << "endcase" << endl; } +void NetCAssign::dump(ostream&o, unsigned ind) const +{ + o << setw(ind) << "" << "cassign " << lval_->name() << " = " + << name() << ";" << endl; +} + void NetCondit::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "if ("; @@ -554,6 +567,12 @@ void NetCondit::dump(ostream&o, unsigned ind) const } } +void NetDeassign::dump(ostream&o, unsigned ind) const +{ + o << setw(ind) << "" << "deassign " << lval_->name() << "; " + << "/* " << get_line() << " */" << endl; +} + void NetEvProbe::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << ""; @@ -960,6 +979,9 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.85 2000/05/11 23:37:27 steve + * Add support for procedural continuous assignment. + * * Revision 1.84 2000/05/07 18:20:07 steve * Import MCD support from Stephen Tell, and add * system function parameter support to the IVL core. diff --git a/elaborate.cc b/elaborate.cc index 0c105c5cd..8d68a8355 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elaborate.cc,v 1.171 2000/05/08 05:28:29 steve Exp $" +#ident "$Id: elaborate.cc,v 1.172 2000/05/11 23:37:27 steve Exp $" #endif /* @@ -1527,6 +1527,46 @@ NetProc* PCallTask::elaborate_usr(Design*des, const string&path) const return block; } +NetCAssign* PCAssign::elaborate(Design*des, const string&path) const +{ + NetScope*scope = des->find_scope(path); + assert(scope); + + NetNet*lval = lval_->elaborate_net(des, path, 0, 0, 0, 0); + if (lval == 0) + return 0; + + NetNet*rval = expr_->elaborate_net(des, path, lval->pin_count(), + 0, 0, 0); + if (rval == 0) + return 0; + + if (rval->pin_count() < lval->pin_count()) + rval = pad_to_width(des, path, rval, lval->pin_count()); + + NetCAssign* dev = new NetCAssign(des->local_symbol(path), lval); + des->add_node(dev); + + for (unsigned idx = 0 ; idx < dev->pin_count() ; idx += 1) + connect(dev->pin(idx), rval->pin(idx)); + + return dev; +} + +NetDeassign* PDeassign::elaborate(Design*des, const string&path) const +{ + NetScope*scope = des->find_scope(path); + assert(scope); + + NetNet*lval = lval_->elaborate_net(des, path, 0, 0, 0, 0); + if (lval == 0) + return 0; + + NetDeassign*dev = new NetDeassign(lval); + dev->set_line( *this ); + return dev; +} + NetProc* PDelayStatement::elaborate(Design*des, const string&path) const { verinum*num = delay_->eval_const(des, path); @@ -2382,6 +2422,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.172 2000/05/11 23:37:27 steve + * Add support for procedural continuous assignment. + * * Revision 1.171 2000/05/08 05:28:29 steve * Use bufz to make assignments directional. * diff --git a/emit.cc b/emit.cc index 1e5e60886..d21a82d3c 100644 --- a/emit.cc +++ b/emit.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: emit.cc,v 1.44 2000/05/04 03:37:58 steve Exp $" +#ident "$Id: emit.cc,v 1.45 2000/05/11 23:37:27 steve Exp $" #endif /* @@ -70,6 +70,11 @@ void NetCaseCmp::emit_node(ostream&o, struct target_t*tgt) const tgt->net_case_cmp(o, this); } +void NetCAssign::emit_node(ostream&o, struct target_t*tgt) const +{ + tgt->net_cassign(o, this); +} + void NetCLShift::emit_node(ostream&o, struct target_t*tgt) const { tgt->lpm_clshift(o, this); @@ -166,12 +171,22 @@ bool NetCase::emit_proc(ostream&o, struct target_t*tgt) const return true; } +bool NetCAssign::emit_proc(ostream&o, struct target_t*tgt) const +{ + return tgt->proc_cassign(o, this); +} + bool NetCondit::emit_proc(ostream&o, struct target_t*tgt) const { tgt->proc_condit(o, this); return true; } +bool NetDeassign::emit_proc(ostream&o, struct target_t*tgt) const +{ + return tgt->proc_deassign(o, this); +} + bool NetForce::emit_proc(ostream&o, struct target_t*tgt) const { return tgt->proc_force(o, this); @@ -434,6 +449,9 @@ bool emit(ostream&o, const Design*des, const char*type) /* * $Log: emit.cc,v $ + * Revision 1.45 2000/05/11 23:37:27 steve + * Add support for procedural continuous assignment. + * * Revision 1.44 2000/05/04 03:37:58 steve * Add infrastructure for system functions, move * $time to that structure and add $random. diff --git a/net_force.cc b/net_force.cc new file mode 100644 index 000000000..d6a25552a --- /dev/null +++ b/net_force.cc @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2000 Stephen Williams (steve@picturel.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined(WINNT) && !defined(macintosh) +#ident "$Id: net_force.cc,v 1.1 2000/05/11 23:37:27 steve Exp $" +#endif + +/* + * This file contains implementatsion of the NetForce, NetRelease, + * NetCAssign and NetDeassign classes. These are similar or related in + * that they handle the procedural continuous assign and force + * statements. + */ + +# include "netlist.h" +# include + +NetCAssign::NetCAssign(const string&n, NetNet*l) +: NetNode(n, l->pin_count()), lval_(l) +{ + for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) { + pin(idx).set_dir(Link::INPUT); + pin(idx).set_name("I", idx); + } +} + +NetCAssign::~NetCAssign() +{ +} + +const Link& NetCAssign::lval_pin(unsigned idx) const +{ + assert(idx < lval_->pin_count()); + return lval_->pin(idx); +} + +NetDeassign::NetDeassign(NetNet*l) +: lval_(l) +{ +} + +NetDeassign::~NetDeassign() +{ +} + +const NetNet*NetDeassign::lval() const +{ + return lval_; +} + +NetForce::NetForce(const string&n, NetNet*l) +: NetNode(n, l->pin_count()), lval_(l) +{ + for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) { + pin(idx).set_dir(Link::INPUT); + pin(idx).set_name("I", idx); + } +} + +NetForce::~NetForce() +{ +} + +const Link& NetForce::lval_pin(unsigned idx) const +{ + assert(idx < lval_->pin_count()); + return lval_->pin(idx); +} + +NetRelease::NetRelease(NetNet*l) +: lval_(l) +{ +} + +NetRelease::~NetRelease() +{ +} + +const NetNet*NetRelease::lval() const +{ + return lval_; +} + + +/* + * $Log: net_force.cc,v $ + * Revision 1.1 2000/05/11 23:37:27 steve + * Add support for procedural continuous assignment. + * + */ + diff --git a/netlist.cc b/netlist.cc index 7a1696517..2c9e4f320 100644 --- a/netlist.cc +++ b/netlist.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: netlist.cc,v 1.124 2000/05/07 18:20:07 steve Exp $" +#ident "$Id: netlist.cc,v 1.125 2000/05/11 23:37:27 steve Exp $" #endif # include @@ -1780,25 +1780,6 @@ verinum::V NetConst::value(unsigned idx) const return value_[idx]; } -NetForce::NetForce(const string&n, NetNet*l) -: NetNode(n, l->pin_count()), lval_(l) -{ - for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) { - pin(idx).set_dir(Link::INPUT); - pin(idx).set_name("I", idx); - } -} - -NetForce::~NetForce() -{ -} - -const Link& NetForce::lval_pin(unsigned idx) const -{ - assert(idx < lval_->pin_count()); - return lval_->pin(idx); -} - NetFuncDef::NetFuncDef(NetScope*s, const svector&po) : scope_(s), statement_(0), ports_(po) { @@ -2421,20 +2402,6 @@ NetLogic::NetLogic(const string&n, unsigned pins, TYPE t) } } -NetRelease::NetRelease(NetNet*l) -: lval_(l) -{ -} - -NetRelease::~NetRelease() -{ -} - -const NetNet*NetRelease::lval() const -{ - return lval_; -} - NetRepeat::NetRepeat(NetExpr*e, NetProc*p) : expr_(e), statement_(p) { @@ -2637,6 +2604,9 @@ bool NetUDP::sequ_glob_(string input, char output) /* * $Log: netlist.cc,v $ + * Revision 1.125 2000/05/11 23:37:27 steve + * Add support for procedural continuous assignment. + * * Revision 1.124 2000/05/07 18:20:07 steve * Import MCD support from Stephen Tell, and add * system function parameter support to the IVL core. diff --git a/netlist.h b/netlist.h index 5e79cbb9c..636aa2e7b 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: netlist.h,v 1.137 2000/05/07 18:20:07 steve Exp $" +#ident "$Id: netlist.h,v 1.138 2000/05/11 23:37:27 steve Exp $" #endif /* @@ -1046,6 +1046,10 @@ class NetProc : public LineInfo { private: friend class NetBlock; NetProc*next_; + + private: // not implemented + NetProc(const NetProc&); + NetProc& operator= (const NetProc&); }; /* @@ -1256,6 +1260,37 @@ class NetCase : public NetProc { Item*items_; }; +/* + * The cassign statement causes the r-val net to be forced onto the + * l-val reg when it is executed. The code generator is expected to + * know what that means. All the expressions are structural and behave + * like nets. + * + * This class is a NetProc because it it turned on by procedural + * behavior. However, it is also a NetNode because it connects to + * nets, and when activated follows the net values. + */ +class NetCAssign : public NetProc, public NetNode { + + public: + explicit NetCAssign(const string&n, NetNet*l); + ~NetCAssign(); + + const Link& lval_pin(unsigned) const; + + virtual void dump(ostream&, unsigned ind) const; + virtual bool emit_proc(ostream&, struct target_t*) const; + virtual void dump_node(ostream&, unsigned ind) const; + virtual void emit_node(ostream&, struct target_t*) const; + + private: + NetNet*lval_; + + private: // not implemented + NetCAssign(const NetCAssign&); + NetCAssign& operator= (const NetCAssign&); +}; + /* A condit represents a conditional. It has an expression to test, and a pair of statements to select from. */ @@ -1287,6 +1322,31 @@ class NetCondit : public NetProc { NetProc*else_; }; +/* + * The procedural deassign statement (the opposite of assign) releases + * any assign expressions attached to the bits of the reg. The + * lval is the expression of the "deassign ;" statement with the + * expr elaborated to a net. + */ +class NetDeassign : public NetProc { + + public: + explicit NetDeassign(NetNet*l); + ~NetDeassign(); + + const NetNet*lval() const; + + virtual bool emit_proc(ostream&, struct target_t*) const; + virtual void dump(ostream&, unsigned ind) const; + + private: + NetNet*lval_; + + private: // not implemented + NetDeassign(const NetDeassign&); + NetDeassign& operator= (const NetDeassign&); +}; + /* * A NetEvent is an object that represents an event object, that is * objects declared like so in Verilog: @@ -2515,6 +2575,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.138 2000/05/11 23:37:27 steve + * Add support for procedural continuous assignment. + * * Revision 1.137 2000/05/07 18:20:07 steve * Import MCD support from Stephen Tell, and add * system function parameter support to the IVL core. diff --git a/parse.y b/parse.y index 5cbca4b6d..275052dd0 100644 --- a/parse.y +++ b/parse.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: parse.y,v 1.95 2000/05/08 05:30:19 steve Exp $" +#ident "$Id: parse.y,v 1.96 2000/05/11 23:37:27 steve Exp $" #endif # include "parse_misc.h" @@ -1729,11 +1729,51 @@ specparam_list spec_polarity: '+' | '-' | ; + statement + + /* assign and deassign statements are procedural code to do + structural assignments, and to turn that structural assignment + off. This stronger then any other assign, but weaker then the + force assignments. */ + : K_assign lavalue '=' expression ';' - { yyerror(@1, "sorry: procedural continuous assign not supported."); - $$ = 0; + { PCAssign*tmp = new PCAssign($2, $4); + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); + $$ = tmp; } + + | K_deassign lavalue';' + { PDeassign*tmp = new PDeassign($2); + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); + $$ = tmp; + } + + + /* Force and release statements are similar to assignments, + syntactically, but they will be elaborated differently. */ + + | K_force lavalue '=' expression ';' + { PForce*tmp = new PForce($2, $4); + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); + $$ = tmp; + } + | K_release lavalue ';' + { PRelease*tmp = new PRelease($2); + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); + $$ = tmp; + } + + /* begin-end blocks come in a variety of forms, including named and + anonymous. The named blocks can also carry their own reg + variables, which are placed in the scope created by the block + name. These are handled by pushing the scope name then matching + the declarations. The scope is popped at the end of the block. */ + | K_begin statement_list K_end { PBlock*tmp = new PBlock(PBlock::BL_SEQ, *$2); tmp->set_file(@1.text); @@ -1767,40 +1807,12 @@ statement } | K_begin error K_end { yyerrok; } - | K_deassign lavalue';' - { yyerror(@1, "sorry:, deassign not supported."); - $$ = 0; - } - | K_disable IDENTIFIER ';' - { yyerror(@1, "sorry: disable statements not supported."); - delete $2; - $$ = 0; - } - | K_force lavalue '=' expression ';' - { PForce*tmp = new PForce($2, $4); - tmp->set_file(@1.text); - tmp->set_lineno(@1.first_line); - $$ = tmp; - } - | K_TRIGGER IDENTIFIER ';' - { PTrigger*tmp = new PTrigger($2); - tmp->set_file(@2.text); - tmp->set_lineno(@2.first_line); - $$ = tmp; - } - | K_forever statement - { PForever*tmp = new PForever($2); - tmp->set_file(@1.text); - tmp->set_lineno(@1.first_line); - $$ = tmp; - } - | K_fork statement_list K_join - { PBlock*tmp = new PBlock(PBlock::BL_PAR, *$2); - tmp->set_file(@1.text); - tmp->set_lineno(@1.first_line); - delete $2; - $$ = tmp; - } + + /* fork-join blocks are very similar to begin-end blocks. In fact, + from the parser's perspective there is no real difference. All we + need to do is remember that this is a parallel block so that the + code generator can do the right thing. */ + | K_fork ':' IDENTIFIER { pform_push_scope($3); } block_item_decls_opt @@ -1825,12 +1837,31 @@ statement tmp->set_lineno(@1.first_line); $$ = tmp; } - | K_release lavalue ';' - { PRelease*tmp = new PRelease($2); + + | K_disable IDENTIFIER ';' + { yyerror(@1, "sorry: disable statements not supported."); + delete $2; + $$ = 0; + } + | K_TRIGGER IDENTIFIER ';' + { PTrigger*tmp = new PTrigger($2); + tmp->set_file(@2.text); + tmp->set_lineno(@2.first_line); + $$ = tmp; + } + | K_forever statement + { PForever*tmp = new PForever($2); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); $$ = tmp; } + | K_fork statement_list K_join + { PBlock*tmp = new PBlock(PBlock::BL_PAR, *$2); + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); + delete $2; + $$ = tmp; + } | K_repeat '(' expression ')' statement { PRepeat*tmp = new PRepeat($3, $5); tmp->set_file(@1.text); diff --git a/pform_dump.cc b/pform_dump.cc index 0898d16ee..13429ec89 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: pform_dump.cc,v 1.57 2000/05/06 15:41:57 steve Exp $" +#ident "$Id: pform_dump.cc,v 1.58 2000/05/11 23:37:27 steve Exp $" #endif /* @@ -481,6 +481,18 @@ void PCondit::dump(ostream&out, unsigned ind) const } } +void PCAssign::dump(ostream&out, unsigned ind) const +{ + out << setw(ind) << "" << "assign " << *lval_ << " = " << *expr_ + << "; /* " << get_line() << " */" << endl; +} + +void PDeassign::dump(ostream&out, unsigned ind) const +{ + out << setw(ind) << "" << "deassign " << *lval_ << "; /* " + << get_line() << " */" << endl; +} + void PDelayStatement::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "#" << *delay_ << " /* " << @@ -773,6 +785,9 @@ void PUdp::dump(ostream&out) const /* * $Log: pform_dump.cc,v $ + * Revision 1.58 2000/05/11 23:37:27 steve + * Add support for procedural continuous assignment. + * * Revision 1.57 2000/05/06 15:41:57 steve * Carry assignment strength to pform. * diff --git a/t-vvm.cc b/t-vvm.cc index bb174b5a2..eb32b58c8 100644 --- a/t-vvm.cc +++ b/t-vvm.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-vvm.cc,v 1.148 2000/05/09 21:16:35 steve Exp $" +#ident "$Id: t-vvm.cc,v 1.149 2000/05/11 23:37:27 steve Exp $" #endif # include @@ -79,6 +79,7 @@ class target_vvm : public target_t { void udp_sequ_(ostream&os, const NetUDP*); virtual void net_assign_nb(ostream&os, const NetAssignNB*); virtual void net_case_cmp(ostream&os, const NetCaseCmp*); + virtual bool net_cassign(ostream&os, const NetCAssign*); virtual void net_const(ostream&os, const NetConst*); virtual bool net_force(ostream&os, const NetForce*); virtual void net_probe(ostream&os, const NetEvProbe*); @@ -90,8 +91,10 @@ class target_vvm : public target_t { virtual bool proc_block(ostream&os, const NetBlock*); virtual void proc_case(ostream&os, const NetCase*net); void proc_case_fun(ostream&os, const NetCase*net); + virtual bool proc_cassign(ostream&os, const NetCAssign*); virtual void proc_condit(ostream&os, const NetCondit*); void proc_condit_fun(ostream&os, const NetCondit*); + virtual bool proc_deassign(ostream&os, const NetDeassign*); virtual bool proc_force(ostream&os, const NetForce*); virtual void proc_forever(ostream&os, const NetForever*); virtual bool proc_release(ostream&os, const NetRelease*); @@ -1862,6 +1865,29 @@ void target_vvm::net_case_cmp(ostream&os, const NetCaseCmp*gate) start_code << " " << mname << ".start();" << endl; } +/* + * Implement continuous assign with the force object, because they are + * so similar. I'll be using different methods to tickle this device, + * but it receives values the same as force. + */ +bool target_vvm::net_cassign(ostream&os, const NetCAssign*dev) +{ + string mname = mangle(dev->name()); + + os << "static vvm_force " << mname << "(" << dev->pin_count() + << ");" << endl; + + for (unsigned idx = 0 ; idx < dev->pin_count() ; idx += 1) { + string nexus = nexus_from_link(&dev->pin(idx)); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<name()); + + for (unsigned idx = 0 ; idx < dev->pin_count() ; idx += 1) { + string nexus = nexus_from_link(&dev->lval_pin(idx)); + unsigned ncode = nexus_wire_map[nexus]; + + defn << " " << mname << ".assign("<lval(); + for (unsigned idx = 0 ; idx < lval->pin_count() ; idx += 1) { + string nexus = nexus_from_link(&lval->pin(idx)); + unsigned ncode = nexus_wire_map[nexus]; + + defn << " nexus_wire_table["<name()); @@ -2868,6 +2923,9 @@ extern const struct target tgt_vvm = { }; /* * $Log: t-vvm.cc,v $ + * Revision 1.149 2000/05/11 23:37:27 steve + * Add support for procedural continuous assignment. + * * Revision 1.148 2000/05/09 21:16:35 steve * Give strengths to logic and bufz devices. * diff --git a/target.cc b/target.cc index 065a0cac0..d279155b8 100644 --- a/target.cc +++ b/target.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: target.cc,v 1.38 2000/05/04 03:37:59 steve Exp $" +#ident "$Id: target.cc,v 1.39 2000/05/11 23:37:27 steve Exp $" #endif # include "target.h" @@ -149,6 +149,13 @@ void target_t::net_case_cmp(ostream&os, const NetCaseCmp*) "Unhandled case compare node." << endl; } +bool target_t::net_cassign(ostream&os, const NetCAssign*dev) +{ + cerr << "target (" << typeid(*this).name() << "): " + "Unhandled NetCAssign node." << endl; + return false; +} + void target_t::net_const(ostream&os, const NetConst*) { cerr << "target (" << typeid(*this).name() << "): " @@ -212,6 +219,13 @@ void target_t::proc_case(ostream&os, const NetCase*cur) cur->dump(cerr, 6); } +bool target_t::proc_cassign(ostream&os, const NetCAssign*dev) +{ + cerr << "target (" << typeid(*this).name() << "): " + "Unhandled proc_cassign." << endl; + return false; +} + void target_t::proc_condit(ostream&os, const NetCondit*condit) { cerr << "target (" << typeid(*this).name() << "): " @@ -219,6 +233,14 @@ void target_t::proc_condit(ostream&os, const NetCondit*condit) condit->dump(cerr, 6); } +bool target_t::proc_deassign(ostream&os, const NetDeassign*dev) +{ + cerr << dev->get_line() << ": internal error: " + << "target (" << typeid(*this).name() << "): " + << "Unhandled proc_deassign." << endl; + return false; +} + void target_t::proc_delay(ostream&os, const NetPDelay*) { cerr << "target (" << typeid(*this).name() << "): " @@ -242,7 +264,7 @@ bool target_t::proc_release(ostream&os, const NetRelease*dev) { cerr << dev->get_line() << ": internal error: " << "target (" << typeid(*this).name() << "): " - << "Unhandled proc_repeat." << endl; + << "Unhandled proc_release." << endl; return false; } @@ -367,6 +389,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex) /* * $Log: target.cc,v $ + * Revision 1.39 2000/05/11 23:37:27 steve + * Add support for procedural continuous assignment. + * * Revision 1.38 2000/05/04 03:37:59 steve * Add infrastructure for system functions, move * $time to that structure and add $random. diff --git a/target.h b/target.h index 1dc677299..a35beb460 100644 --- a/target.h +++ b/target.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: target.h,v 1.37 2000/05/04 03:37:59 steve Exp $" +#ident "$Id: target.h,v 1.38 2000/05/11 23:37:27 steve Exp $" #endif # include "netlist.h" @@ -90,6 +90,7 @@ struct target_t { virtual void net_assign(ostream&os, const NetAssign*); virtual void net_assign_nb(ostream&os, const NetAssignNB*); virtual void net_case_cmp(ostream&os, const NetCaseCmp*); + virtual bool net_cassign(ostream&os, const NetCAssign*); virtual void net_const(ostream&os, const NetConst*); virtual bool net_force(ostream&os, const NetForce*); virtual void net_probe(ostream&os, const NetEvProbe*); @@ -105,7 +106,9 @@ struct target_t { virtual void proc_assign_mem_nb(ostream&os, const NetAssignMemNB*); virtual bool proc_block(ostream&os, const NetBlock*); virtual void proc_case(ostream&os, const NetCase*); + virtual bool proc_cassign(ostream&os, const NetCAssign*); virtual void proc_condit(ostream&os, const NetCondit*); + virtual bool proc_deassign(ostream&os, const NetDeassign*); virtual bool proc_force(ostream&os, const NetForce*); virtual void proc_forever(ostream&os, const NetForever*); virtual bool proc_release(ostream&os, const NetRelease*); @@ -156,6 +159,9 @@ extern const struct target *target_table[]; /* * $Log: target.h,v $ + * Revision 1.38 2000/05/11 23:37:27 steve + * Add support for procedural continuous assignment. + * * Revision 1.37 2000/05/04 03:37:59 steve * Add infrastructure for system functions, move * $time to that structure and add $random. diff --git a/vvm/vvm_force.cc b/vvm/vvm_force.cc index 4abd9834d..00fdf1301 100644 --- a/vvm/vvm_force.cc +++ b/vvm/vvm_force.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vvm_force.cc,v 1.2 2000/04/23 03:45:25 steve Exp $" +#ident "$Id: vvm_force.cc,v 1.3 2000/05/11 23:37:27 steve Exp $" #endif # include "vvm_gates.h" @@ -26,6 +26,7 @@ vvm_force::vvm_force(unsigned w) : width_(w) { + force_flag_ = true; bits_ = new vpip_bit_t[width_]; target_ = new vvm_nexus*[width_]; for (unsigned idx = 0 ; idx < width_ ; idx += 1) @@ -51,13 +52,29 @@ void vvm_force::take_value(unsigned key, vpip_bit_t val) return; bits_[key] = val; - target_[key]->force_assign(val); + if (! target_[key]) return; + + if (force_flag_) + target_[key]->force_assign(val); + else + target_[key]->cassign(val); +} + +void vvm_force::assign(unsigned key, vvm_nexus*tgt) +{ + assert(key < width_); + assert(target_[key] == 0); + force_flag_ = false; + target_[key] = tgt; + target_[key]->cassign_set(this, key); + target_[key]->cassign(bits_[key]); } void vvm_force::force(unsigned key, vvm_nexus*tgt) { assert(key < width_); assert(target_[key] == 0); + force_flag_ = true; target_[key] = tgt; target_[key]->force_set(this, key); target_[key]->force_assign(bits_[key]); @@ -75,6 +92,9 @@ void vvm_force::release(unsigned key) /* * $Log: vvm_force.cc,v $ + * Revision 1.3 2000/05/11 23:37:27 steve + * Add support for procedural continuous assignment. + * * Revision 1.2 2000/04/23 03:45:25 steve * Add support for the procedural release statement. * diff --git a/vvm/vvm_gates.h b/vvm/vvm_gates.h index c0571107b..1f4082fca 100644 --- a/vvm/vvm_gates.h +++ b/vvm/vvm_gates.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vvm_gates.h,v 1.63 2000/05/11 01:37:33 steve Exp $" +#ident "$Id: vvm_gates.h,v 1.64 2000/05/11 23:37:28 steve Exp $" #endif # include "vvm.h" @@ -302,12 +302,21 @@ class vvm_force : public vvm_nexus::recvr_t { void init_I(unsigned key, vpip_bit_t val); + // These methods turn on a force or continuous assign. They + // cause the vvm_force object to attach itself to the tgt + // object and deliver new values there. void force(unsigned key, vvm_nexus*tgt); + void assign(unsigned key, vvm_nexus*tgt); + + // These methods are called by the attached nexus to detach + // the vvm_force object. void release(unsigned key); + void deassign(unsigned key); private: void take_value(unsigned key, vpip_bit_t val); + bool force_flag_; unsigned width_; vpip_bit_t*bits_; vvm_nexus**target_; @@ -939,6 +948,9 @@ class vvm_posedge : public vvm_nexus::recvr_t { /* * $Log: vvm_gates.h,v $ + * Revision 1.64 2000/05/11 23:37:28 steve + * Add support for procedural continuous assignment. + * * Revision 1.63 2000/05/11 01:37:33 steve * Calculate the X output value from drive0 and drive1 * diff --git a/vvm/vvm_nexus.cc b/vvm/vvm_nexus.cc index 2d3b17266..d28f0d204 100644 --- a/vvm/vvm_nexus.cc +++ b/vvm/vvm_nexus.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vvm_nexus.cc,v 1.7 2000/04/23 03:45:25 steve Exp $" +#ident "$Id: vvm_nexus.cc,v 1.8 2000/05/11 23:37:28 steve Exp $" #endif # include "vvm_nexus.h" @@ -34,6 +34,8 @@ vvm_nexus::vvm_nexus() force_ = 0; forcer_ = 0; forcer_key_ = 0; + assigner_ = 0; + assigner_key_ = 0; } vvm_nexus::~vvm_nexus() @@ -148,6 +150,16 @@ void vvm_nexus::force_set(vvm_force*f, unsigned k) forcer_key_ = k; } +void vvm_nexus::cassign_set(vvm_force*f, unsigned k) +{ + assert(drivers_ == 0); + if (assigner_) + assigner_->release(assigner_key_); + + assigner_ = f; + assigner_key_ = k; +} + void vvm_nexus::force_assign(vpip_bit_t val) { assert(forcer_); @@ -156,6 +168,17 @@ void vvm_nexus::force_assign(vpip_bit_t val) cur->dev->take_value(cur->key, force_); } +void vvm_nexus::cassign(vpip_bit_t val) +{ + assert(assigner_); + value_ = val; + + if (forcer_) return; + + for (recvr_cell*cur = recvrs_; cur ; cur = cur->next) + cur->dev->take_value(cur->key, value_); +} + void vvm_nexus::release() { if (forcer_) { @@ -169,6 +192,15 @@ void vvm_nexus::release() cur->dev->take_value(cur->key, value_); } +void vvm_nexus::deassign() +{ + assert(drivers_ == 0); + if (assigner_) { + assigner_->release(assigner_key_); + assigner_ = 0; + } +} + /* * This method is invoked when something interesting happens at one of * the drivers. It collects all the driver values, resolves them into @@ -265,6 +297,9 @@ void vvm_delayed_assign(vvm_nexus&l_val, vpip_bit_t r_val, /* * $Log: vvm_nexus.cc,v $ + * Revision 1.8 2000/05/11 23:37:28 steve + * Add support for procedural continuous assignment. + * * Revision 1.7 2000/04/23 03:45:25 steve * Add support for the procedural release statement. * diff --git a/vvm/vvm_nexus.h b/vvm/vvm_nexus.h index ad53d644e..945951a0c 100644 --- a/vvm/vvm_nexus.h +++ b/vvm/vvm_nexus.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vvm_nexus.h,v 1.3 2000/04/23 03:45:25 steve Exp $" +#ident "$Id: vvm_nexus.h,v 1.4 2000/05/11 23:37:28 steve Exp $" #endif # include "vvm.h" @@ -103,6 +103,15 @@ class vvm_nexus { // to procedural assignments to the node, as if it where a reg. void reg_assign(vpip_bit_t val); + // These methods support the procedural continuous assign. The + // vvm_force oject will set itself as an assigner, then will + // periodically call the cassign method to do the assign. The + // procedural deassign will call the deassign method to detach + // the vvm_force object. + void cassign_set(class vvm_force*frc, unsigned key); + void cassign(vpip_bit_t val); + void deassign(); + // This method causes the specified value to be forced onto // the nexus. This overrides all drivers that are attached. void force_set(class vvm_force*frc, unsigned key); @@ -128,6 +137,9 @@ class vvm_nexus { vpip_bit_t*ival_; unsigned nival_; + vvm_force *assigner_; + unsigned assigner_key_; + vpip_bit_t force_; vvm_force *forcer_; unsigned forcer_key_; @@ -148,6 +160,9 @@ extern void vvm_delayed_assign(vvm_nexus&l_val, vpip_bit_t r_val, /* * $Log: vvm_nexus.h,v $ + * Revision 1.4 2000/05/11 23:37:28 steve + * Add support for procedural continuous assignment. + * * Revision 1.3 2000/04/23 03:45:25 steve * Add support for the procedural release statement. *