Do not generate code for signals,

instead use the NetESignal node to
 generate gate-like signal devices.
This commit is contained in:
steve 1999-02-08 03:55:55 +00:00
parent 30a3953c85
commit fef81958bc
2 changed files with 85 additions and 84 deletions

138
t-vvm.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: t-vvm.cc,v 1.10 1999/02/08 02:49:56 steve Exp $"
#ident "$Id: t-vvm.cc,v 1.11 1999/02/08 03:55:55 steve Exp $"
#endif
# include <iostream>
@ -67,8 +67,6 @@ class target_vvm : public target_t {
ostrstream start_code;
unsigned process_counter;
unsigned thread_step_;
unsigned indent_;
};
@ -131,7 +129,7 @@ void vvm_proc_rval::expr_ident(const NetEIdent*expr)
void vvm_proc_rval::expr_signal(const NetESignal*expr)
{
result = mangle(expr->name());
result = mangle(expr->name()) + "_bits";
}
void vvm_proc_rval::expr_unary(const NetEUnary*expr)
@ -243,9 +241,9 @@ void vvm_parm_rval::expr_signal(const NetESignal*expr)
string res = make_temp();
os_ << " vvm_calltf_parm::SIG " << res << ";" << endl;
os_ << " " << res << ".bits = &" <<
mangle(expr->name()) << ";" << endl;
mangle(expr->name()) << "_bits;" << endl;
os_ << " " << res << ".mon = &" <<
mangle(expr->name()) << "_mon;" << endl;
mangle(expr->name()) << ";" << endl;
result = res;
}
@ -298,10 +296,6 @@ void target_vvm::end_design(ostream&os, const Design*mod)
void target_vvm::signal(ostream&os, const NetNet*sig)
{
os << "static vvm_bitset_t<" << sig->pin_count() << "> " <<
mangle(sig->name()) << "; /* " << sig->name() << " */" << endl;
os << "static vvm_monitor_t " << mangle(sig->name()) << "_mon(\""
<< sig->name() << "\");" << endl;
/* Scan the signals of the vector, passing the initial value
to the inputs of all the connected devices. */
@ -341,15 +335,11 @@ void target_vvm::emit_gate_outputfun_(const NetNode*gate)
unsigned pin;
gate->pin(0).next_link(cur, pin);
while (cur != gate) {
// Skip signals
if (const NetNet*sig = dynamic_cast<const NetNet*>(cur)) {
delayed << " " << mangle(sig->name()) << "[" <<
pin << "] = val;" << endl;
delayed << " " << mangle(sig->name()) <<
"_mon.trigger(sim);" << endl;
if (dynamic_cast<const NetNet*>(cur)) {
// Skip signals
} else {
delayed << " " << mangle(cur->name()) << ".set(sim, "
<< pin << ", val);" << endl;
}
@ -522,8 +512,14 @@ void target_vvm::net_const(ostream&os, const NetConst*gate)
emit_gate_outputfun_(gate);
}
void target_vvm::net_esignal(ostream&, const NetESignal*)
void target_vvm::net_esignal(ostream&os, const NetESignal*net)
{
os << "static vvm_bitset_t<" << net->pin_count() << "> " <<
mangle(net->name()) << "_bits; /* " << net->name() <<
" */" << endl;
os << "static vvm_signal_t<" << net->pin_count() << "> " <<
mangle(net->name()) << "(\"" << net->name() << "\", &" <<
mangle(net->name()) << "_bits);" << endl;
}
/*
@ -545,7 +541,6 @@ 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 <<
@ -573,7 +568,7 @@ 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, indent_, net->rval());
string rval = emit_proc_rval(os, 8, net->rval());
const NetNet*lval;
unsigned msb, lsb;
@ -583,17 +578,10 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net)
os << " // " << lval->name() << " = ";
net->rval()->dump(os);
os << endl;
os << " " << mangle(lval->name())
<< " = " << rval << ";" << endl;
} else {
assert(0);
}
os << " " << mangle(lval->name()) <<
"_mon.trigger(sim_);" << endl;
/* Not only is the lvalue signal assigned to, send the bits to
all the other pins that are connected to this signal. */
@ -608,23 +596,14 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net)
if (dynamic_cast<const NetAssign*>(cur))
continue;
// Skip NetESignal nodes. They are handled as
// expressions.
if (dynamic_cast<const NetESignal*>(cur))
// Skip signals, I'll hit them when I handle the
// NetESignal nodes.
if (dynamic_cast<const NetNet*>(cur))
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;
} else {
os << " " << mangle(cur->name()) <<
".set(sim_, " << pin << ", " <<
rval << "[" << idx << "]);" << endl;
}
os << " " << mangle(cur->name()) <<
".set(sim_, " << pin << ", " <<
rval << "[" << idx << "]);" << endl;
}
}
}
@ -651,7 +630,7 @@ void target_vvm::proc_block(ostream&os, const NetBlock*net)
*/
void target_vvm::proc_case(ostream&os, const NetCase*net)
{
string expr = emit_proc_rval(os, indent_, net->expr());
string expr = emit_proc_rval(os, 8, net->expr());
ostrstream sc;
unsigned default_step_ = thread_step_ + 1;
@ -662,7 +641,7 @@ void target_vvm::proc_case(ostream&os, const NetCase*net)
to. Once that is done, return true so that statement is
executed. */
for (unsigned idx = 0 ; idx < net->nitems() ; idx += 1) {
string guard = emit_proc_rval(os, indent_, net->expr(idx));
string guard = emit_proc_rval(os, 8, net->expr(idx));
thread_step_ += 1;
@ -671,16 +650,12 @@ void target_vvm::proc_case(ostream&os, const NetCase*net)
os << " step_ = &step_" <<
thread_step_ << "_;" << endl;
{ unsigned save_indent = indent_;
indent_ = 8;
sc << " bool step_" << thread_step_ << "_()" << endl;
sc << " {" << endl;
net->stat(idx)->emit_proc(sc, this);
sc << " step_ = &step_" << default_step_ << "_;" << endl;
sc << " return true;" << endl;
sc << " }" << endl;
indent_ = save_indent;
}
sc << " bool step_" << thread_step_ << "_()" << endl;
sc << " {" << endl;
net->stat(idx)->emit_proc(sc, this);
sc << " step_ = &step_" << default_step_ << "_;" << endl;
sc << " return true;" << endl;
sc << " }" << endl;
}
os << " else" << endl;
@ -694,11 +669,11 @@ void target_vvm::proc_case(ostream&os, const NetCase*net)
void target_vvm::proc_condit(ostream&os, const NetCondit*net)
{
string expr = emit_proc_rval(os, indent_, net->expr());
string expr = emit_proc_rval(os, 8, net->expr());
unsigned if_step = ++thread_step_;
unsigned if_step = ++thread_step_;
unsigned else_step = ++thread_step_;
unsigned out_step = ++thread_step_;
unsigned out_step = ++thread_step_;
os << " if (" << expr << "[0] == V1)" << endl;
os << " step_ = &step_" << if_step << "_;" << endl;
@ -746,17 +721,11 @@ 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;
os << " for (;;) {" << endl;
string expr = emit_proc_rval(os, 12, net->expr());
os << " if (" << expr << "[0] != V1) break;" << endl;
net->emit_proc_recurse(os, this);
os << setw(ind) << "" << "}" << endl;
indent_ = ind;
os << " }" << endl;
}
/*
@ -766,8 +735,7 @@ void target_vvm::proc_while(ostream&os, const NetWhile*net)
void target_vvm::proc_event(ostream&os, const NetPEvent*proc)
{
thread_step_ += 1;
os << setw(indent_) << "" << "step_ = &step_" << thread_step_ <<
"_;" << endl;
os << " step_ = &step_" << thread_step_ << "_;" << endl;
/* POSITIVE is for the wait construct, and needs to be handled
specially. The structure of the generated code is:
@ -790,18 +758,17 @@ void target_vvm::proc_event(ostream&os, const NetPEvent*proc)
edge. */
if (proc->edge() == NetPEvent::POSITIVE) {
os << setw(indent_) << "" << "if (" <<
mangle(proc->name()) << ".get()==V1) {" << endl;
os << setw(indent_+3) << "" << "return true;" << endl;
os << setw(indent_) << "" << "} else {" << endl;
os << setw(indent_+3) << "" << mangle(proc->name()) <<
os << " if (" << mangle(proc->name()) <<
".get()==V1) {" << endl;
os << " return true;" << endl;
os << " } else {" << endl;
os << " " << mangle(proc->name()) <<
".wait(vvm_pevent::POSEDGE, this);" << endl;
os << setw(indent_+3) << "" << "return false;" << endl;
os << setw(indent_) << "" << "}" << endl;
os << " return false;" << endl;
os << " }" << endl;
} else {
os << setw(indent_) << "" << mangle(proc->name()) <<
".wait(vvm_pevent::";
os << " " << mangle(proc->name()) << ".wait(vvm_pevent::";
switch (proc->edge()) {
case NetPEvent::ANYEDGE:
os << "ANYEDGE";
@ -815,7 +782,7 @@ void target_vvm::proc_event(ostream&os, const NetPEvent*proc)
break;
}
os << ", this);" << endl;
os << setw(indent_+3) << "" << "return false;" << endl;
os << " return false;" << endl;
}
os << " }" << endl;
os << " bool step_" << thread_step_ << "_()" << endl;
@ -844,11 +811,11 @@ void target_vvm::proc_delay(ostream&os, const NetPDelay*proc)
void target_vvm::end_process(ostream&os, const NetProcTop*proc)
{
if (proc->type() == NetProcTop::KALWAYS) {
os << setw(indent_) << "" << "step_ = &step_0_;" << endl;
os << setw(indent_) << "" << "return true;" << endl;
os << " step_ = &step_0_;" << endl;
os << " return true;" << endl;
} else {
os << setw(indent_) << "" << "step_ = 0;" << endl;
os << setw(indent_) << "" << "return false;" << endl;
os << " step_ = 0;" << endl;
os << " return false;" << endl;
}
os << " }" << endl;
@ -864,6 +831,11 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
* Revision 1.11 1999/02/08 03:55:55 steve
* Do not generate code for signals,
* instead use the NetESignal node to
* generate gate-like signal devices.
*
* Revision 1.10 1999/02/08 02:49:56 steve
* Turn the NetESignal into a NetNode so
* that it can connect to the netlist.

View File

@ -19,11 +19,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vvm.h,v 1.3 1998/12/17 23:54:58 steve Exp $"
#ident "$Id: vvm.h,v 1.4 1999/02/08 03:55:55 steve Exp $"
#endif
# include <vector>
# include <string>
# include <cassert>
/*
* The Verilog Virtual Machine are definitions for the virtual machine
@ -101,6 +102,13 @@ template <unsigned WIDTH> class vvm_bitset_t : public vvm_bits_t {
unsigned get_width() const { return WIDTH; }
vvm_bit_t get_bit(unsigned idx) const { return bits_[idx]; }
bool eequal(const vvm_bitset_t<WIDTH>&that) const
{ for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
if (bits_[idx] != that.bits_[idx])
return false;
return true;
}
private:
vvm_bit_t bits_[WIDTH];
};
@ -215,8 +223,29 @@ class vvm_monitor_t {
};
template <unsigned WIDTH> class vvm_signal_t : public vvm_monitor_t {
public:
vvm_signal_t(const string&n, vvm_bitset_t<WIDTH>*b)
: vvm_monitor_t(n), bits_(b)
{ }
void set(vvm_simulation*sim, unsigned idx, vvm_bit_t val)
{ (*bits_)[idx] = val;
trigger(sim);
}
private:
vvm_bitset_t<WIDTH>*bits_;
};
/*
* $Log: vvm.h,v $
* Revision 1.4 1999/02/08 03:55:55 steve
* Do not generate code for signals,
* instead use the NetESignal node to
* generate gate-like signal devices.
*
* Revision 1.3 1998/12/17 23:54:58 steve
* VVM support for small sequential UDP objects.
*