Add support for procedural continuous assignment.

This commit is contained in:
steve 2000-05-11 23:37:26 +00:00
parent 4f0b0cb8ce
commit 367db72c99
18 changed files with 586 additions and 91 deletions

View File

@ -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 \

View File

@ -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.
*

View File

@ -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 <string>
@ -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.
*

View File

@ -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.

View File

@ -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<string,Module*>&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.
*

20
emit.cc
View File

@ -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.

106
net_force.cc Normal file
View File

@ -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 <assert.h>
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.
*
*/

View File

@ -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 <cassert>
@ -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<NetNet*>&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.

View File

@ -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 <expr>;" 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.

109
parse.y
View File

@ -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);

View File

@ -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.
*

View File

@ -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 <iostream>
@ -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["<<ncode<<"].connect(&"
<< mname << ", " << idx << ");" << endl;
}
return true;
}
/*
* The NetConst is a synthetic device created to represent constant
* values. I represent them in the output as a vvm_bufz object that
@ -2457,6 +2483,21 @@ void target_vvm::proc_case_fun(ostream&os, const NetCase*net)
defn << " } while(0);" << endl;
}
bool target_vvm::proc_cassign(ostream&os, const NetCAssign*dev)
{
const string mname = mangle(dev->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("<<idx<<", "
<< "nexus_wire_table+"<<ncode << ");" << endl;
}
return true;
}
void target_vvm::proc_condit(ostream&os, const NetCondit*net)
{
if (function_def_flag_) {
@ -2523,6 +2564,20 @@ void target_vvm::proc_condit_fun(ostream&os, const NetCondit*net)
defn << " }" << endl;
}
bool target_vvm::proc_deassign(ostream&os, const NetDeassign*dev)
{
const NetNet*lval = dev->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["<<ncode<<"].deassign();"
<< endl;
}
return true;
}
bool target_vvm::proc_force(ostream&os, const NetForce*dev)
{
const string mname = mangle(dev->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.
*

View File

@ -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.

View File

@ -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.

View File

@ -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.
*

View File

@ -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
*

View File

@ -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.
*

View File

@ -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.
*