Generate references into a table of nexus objects instead of

generating lots of isolated nexus objects. Easier on linkers
 and compilers,

 Add missing nexus support for l-value bit selects,

 Detemplatize the vvm_mux type.

 Fix up the vvm_nexus destructor to disconnect from drivers.
This commit is contained in:
steve 2000-03-18 01:26:59 +00:00
parent 48de739506
commit 567de6ba39
6 changed files with 392 additions and 222 deletions

296
t-vvm.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: t-vvm.cc,v 1.115 2000/03/17 20:21:14 steve Exp $"
#ident "$Id: t-vvm.cc,v 1.116 2000/03/18 01:26:59 steve Exp $"
#endif
# include <iostream>
@ -135,7 +135,9 @@ class target_vvm : public target_t {
// of things that may be scanned multiple times.
map<string,bool>esignal_printed_flag;
map<string,bool>pevent_printed_flag;
map<string,bool>nexus_printed_flag;
map<string,unsigned>nexus_wire_map;
unsigned nexus_wire_counter;
// String constants that are made into vpiHandles have th
// handle name mapped by this.
@ -670,6 +672,7 @@ void target_vvm::start_design(ostream&os, const Design*mod)
process_counter = 0;
string_counter = 1;
number_counter = 1;
nexus_wire_counter = 1;
init_code << "static void design_init()" << endl;
init_code << "{" << endl;
@ -714,8 +717,10 @@ void target_vvm::end_design(ostream&os, const Design*mod)
string_counter+1 << "];" << endl;
os << "static struct __vpiNumberConst number_table[" <<
number_counter+1 << "];" << endl;
os << "static vvm_nexus_wire nexus_wire_table[" <<
nexus_wire_counter << "];" << endl;
defn.close();
os << "// **** Definition code" << endl;
{ ifstream rdefn (defn_name);
os << rdefn.rdbuf();
@ -803,15 +808,15 @@ void target_vvm::signal(ostream&os, const NetNet*sig)
string net_name = mangle(sig->name());
for (unsigned idx = 0 ; idx < sig->pin_count() ; idx += 1) {
string nexus = mangle(nexus_from_link(&sig->pin(idx)));
if (! nexus_printed_flag[nexus]) {
nexus_printed_flag[nexus] = true;
os << "vvm_nexus_wire " << nexus << "_nex;" << endl;
string nexus = nexus_from_link(&sig->pin(idx));
unsigned ncode = nexus_wire_map[nexus];
if (ncode == 0) {
nexus_wire_map[nexus] = ncode = nexus_wire_counter;
nexus_wire_counter += 1;
}
init_code << " " << nexus << "_nex.connect(&" <<
net_name << ", " << idx << ");" << endl;
init_code << " nexus_wire_table[" << ncode <<
"].connect(&" << net_name << ", " << idx << ");" << endl;
}
os << "static vvm_bitset_t<" << sig->pin_count() << "> " <<
@ -1020,9 +1025,9 @@ void target_vvm::lpm_add_sub(ostream&os, const NetAddSub*gate)
/* Connect the DataA inputs. */
for (unsigned idx = 0 ; idx < gate->width() ; idx += 1) {
unsigned pin = gate->pin_DataA(idx).get_pin();
string nexus = mangle(nexus_from_link(&gate->pin(pin)));
init_code << " " << nexus << "_nex.connect(&" <<
string nexus = nexus_from_link(&gate->pin_DataA(idx));
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect(&" <<
mangle(gate->name()) << ", " <<
mangle(gate->name()) << ".key_DataA(" << idx <<
"));" << endl;
@ -1031,9 +1036,10 @@ void target_vvm::lpm_add_sub(ostream&os, const NetAddSub*gate)
/* Connect the DataB inputs. */
for (unsigned idx = 0 ; idx < gate->width() ; idx += 1) {
unsigned pin = gate->pin_DataB(idx).get_pin();
string nexus = mangle(nexus_from_link(&gate->pin(pin)));
init_code << " " << nexus << "_nex.connect(&" <<
string nexus = nexus_from_link(&gate->pin_DataB(idx));
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect(&" <<
mangle(gate->name()) << ", " <<
mangle(gate->name()) << ".key_DataB(" << idx <<
"));" << endl;
@ -1042,18 +1048,20 @@ void target_vvm::lpm_add_sub(ostream&os, const NetAddSub*gate)
/* Connect the outputs of the adder. */
for (unsigned idx = 0 ; idx < gate->width() ; idx += 1) {
unsigned pin = gate->pin_Result(idx).get_pin();
string nexus = mangle(nexus_from_link(&gate->pin(pin)));
init_code << " " << nexus << "_nex.connect(" <<
string nexus = nexus_from_link(&gate->pin_Result(idx));
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect(" <<
mangle(gate->name()) << ".config_rout(" << idx <<
"));" << endl;
}
// Connect the carry output if necessary.
if (gate->pin_Cout().is_linked()) {
unsigned pin = gate->pin_Cout().get_pin();
string nexus = mangle(nexus_from_link(&gate->pin(pin)));
init_code << " " << nexus << "_nex.connect(" <<
string nexus = nexus_from_link(&gate->pin_Cout());
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect(" <<
mangle(gate->name()) << ".config_cout());" << endl;
}
@ -1072,32 +1080,39 @@ void target_vvm::lpm_add_sub(ostream&os, const NetAddSub*gate)
void target_vvm::lpm_clshift(ostream&os, const NetCLShift*gate)
{
os << "static vvm_clshift " << mangle(gate->name()) << "(" <<
string mname = mangle(gate->name());
os << "static vvm_clshift " << mname << "(" <<
gate->width() << "," << gate->width_dist() << ");" <<
endl;
/* Connect the Data input pins... */
for (unsigned idx = 0 ; idx < gate->width() ; idx += 1) {
string nexus = mangle(nexus_from_link(&gate->pin_Data(idx)));
init_code << " " << nexus << "_nex.connect(&" <<
mangle(gate->name()) << ", " << mangle(gate->name())
string nexus = nexus_from_link(&gate->pin_Data(idx));
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect(&"
<< mname << ", " << mname
<< ".key_Data(" << idx << "));" << endl;
}
/* Connect the Distance input pins... */
for (unsigned idx = 0 ; idx < gate->width_dist() ; idx += 1) {
string nexus = mangle(nexus_from_link(&gate->pin_Distance(idx)));
init_code << " " << nexus << "_nex.connect(&" <<
mangle(gate->name()) << ", " << mangle(gate->name())
string nexus = nexus_from_link(&gate->pin_Distance(idx));
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect(&"
<< mname << ", " << mname
<< ".key_Distance(" << idx << "));" << endl;
}
/* Connect the output drivers to the nexus nodes. */
for (unsigned idx = 0 ; idx < gate->width() ; idx += 1) {
string nexus = mangle(nexus_from_link(&gate->pin_Result(idx)));
init_code << " " << nexus << "_nex.connect(" <<
mangle(gate->name()) << ".config_rout(" << idx <<
"));" << endl;
string nexus = nexus_from_link(&gate->pin_Result(idx));
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect("
<< mname << ".config_rout(" << idx << "));" << endl;
}
}
@ -1110,43 +1125,55 @@ void target_vvm::lpm_compare(ostream&os, const NetCompare*gate)
/* Connect DataA inputs... */
for (unsigned idx = 0 ; idx < gate->width() ; idx += 1) {
string nexus = mangle(nexus_from_link(&gate->pin_DataA(idx)));
init_code << " " << nexus << "_nex.connect(&" << mname
<< ", " << mname << ".key_DataA(" << idx
string nexus = nexus_from_link(&gate->pin_DataA(idx));
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect(&"
<< mname << ", " << mname << ".key_DataA(" << idx
<< "));" << endl;
}
/* Connect DataB inputs... */
for (unsigned idx = 0 ; idx < gate->width() ; idx += 1) {
string nexus = mangle(nexus_from_link(&gate->pin_DataB(idx)));
init_code << " " << nexus << "_nex.connect(&" << mname
<< ", " << mname << ".key_DataB(" << idx
string nexus = nexus_from_link(&gate->pin_DataB(idx));
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect(&"
<< mname << ", " << mname << ".key_DataB(" << idx
<< "));" << endl;
}
if (gate->pin_ALB().is_linked()) {
string nexus = mangle(nexus_from_link(&gate->pin_ALB()));
init_code << " " << nexus << "_nex.connect(" << mname
<< ".config_ALB_out());" << endl;
string nexus = nexus_from_link(&gate->pin_ALB());
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect("
<< mname << ".config_ALB_out());" << endl;
}
if (gate->pin_AGB().is_linked()) {
string nexus = mangle(nexus_from_link(&gate->pin_AGB()));
init_code << " " << nexus << "_nex.connect(" << mname
<< ".config_AGB_out());" << endl;
string nexus = nexus_from_link(&gate->pin_AGB());
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect("
<< mname << ".config_AGB_out());" << endl;
}
if (gate->pin_ALEB().is_linked()) {
string nexus = mangle(nexus_from_link(&gate->pin_ALEB()));
init_code << " " << nexus << "_nex.connect(" << mname
<< ".config_ALEB_out());" << endl;
string nexus = nexus_from_link(&gate->pin_ALEB());
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect("
<< mname << ".config_ALEB_out());" << endl;
}
if (gate->pin_AGEB().is_linked()) {
string nexus = mangle(nexus_from_link(&gate->pin_AGEB()));
init_code << " " << nexus << "_nex.connect(" << mname
<< ".config_AGEB_out());" << endl;
string nexus = nexus_from_link(&gate->pin_AGEB());
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect("
<< mname << ".config_AGEB_out());" << endl;
}
}
@ -1168,6 +1195,7 @@ void target_vvm::lpm_ff(ostream&os, const NetFF*gate)
void target_vvm::lpm_mult(ostream&os, const NetMult*mul)
{
string mname = mangle(mul->name());
os << "static vvm_mult " << mname << "(" << mul->width_r() <<
"," << mul->width_a() << "," << mul->width_b() << "," <<
mul->width_s() << ");" << endl;
@ -1176,7 +1204,9 @@ void target_vvm::lpm_mult(ostream&os, const NetMult*mul)
/* Connect the DataA inputs... */
for (unsigned idx = 0 ; idx < mul->width_a() ; idx += 1) {
string nexus = nexus_from_link(&mul->pin_DataA(idx));
init_code << " " << mangle(nexus) << "_nex.connect(&"
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect(&"
<< mname << ", " << mname << ".key_DataA("
<< idx << "));" << endl;
}
@ -1184,7 +1214,9 @@ void target_vvm::lpm_mult(ostream&os, const NetMult*mul)
/* Connect the Datab inputs... */
for (unsigned idx = 0 ; idx < mul->width_b() ; idx += 1) {
string nexus = nexus_from_link(&mul->pin_DataB(idx));
init_code << " " << mangle(nexus) << "_nex.connect(&"
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect(&"
<< mname << ", " << mname << ".key_DataB("
<< idx << "));" << endl;
}
@ -1192,7 +1224,9 @@ void target_vvm::lpm_mult(ostream&os, const NetMult*mul)
/* Connect the output pins... */
for (unsigned idx = 0 ; idx < mul->width_r() ; idx += 1) {
string nexus = nexus_from_link(&mul->pin_Result(idx));
init_code << " " << mangle(nexus) << "_nex.connect("
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect("
<< mname << ".config_rout(" << idx << "));" << endl;
}
}
@ -1200,34 +1234,40 @@ void target_vvm::lpm_mult(ostream&os, const NetMult*mul)
void target_vvm::lpm_mux(ostream&os, const NetMux*mux)
{
string mname = mangle(mux->name());
os << "static vvm_mux<" << mux->width() << "," << mux->size() <<
"," << mux->sel_width() << "> " << mname << ";" << endl;
os << "static vvm_mux " << mname << "(" << mux->width() << ","
<< mux->size() << "," << mux->sel_width() << ");" << endl;
/* Connect the select inputs... */
for (unsigned idx = 0 ; idx < mux->sel_width() ; idx += 1) {
string nexus = mangle(nexus_from_link(&mux->pin_Sel(idx)));
init_code << " " << nexus << "_nex.connect(&"
<< mangle(mux->name()) << ", " << mangle(mux->name())
string nexus = nexus_from_link(&mux->pin_Sel(idx));
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect(&"
<< mname << ", " << mname
<< ".key_Sel(" << idx << "));" << endl;
}
/* Connect the data inputs... */
for (unsigned idx = 0 ; idx < mux->size() ; idx += 1) {
for (unsigned wid = 0 ; wid < mux->width() ; wid += 1) {
string nexus = mangle(nexus_from_link(&mux->pin_Data(wid, idx)));
init_code << " " << nexus << "_nex.connect(&"
<< mangle(mux->name()) << ", "
<< mangle(mux->name()) << ".key_Data("
string nexus = nexus_from_link(&mux->pin_Data(wid, idx));
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"]"
<< ".connect(&" << mname << ", "
<< mname << ".key_Data("
<< wid << "," << idx << "));" << endl;
}
}
/* Connect the outputs... */
for (unsigned idx = 0 ; idx < mux->width() ; idx += 1) {
string nexus = mangle(nexus_from_link(&mux->pin_Result(idx)));
init_code << " " << nexus << "_nex.connect(" <<
mangle(mux->name()) << ".config_rout(" << idx <<
"));" << endl;
string nexus = nexus_from_link(&mux->pin_Result(idx));
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect("
<< mname << ".config_rout(" << idx << "));" << endl;
}
}
@ -1309,15 +1349,18 @@ void target_vvm::logic(ostream&os, const NetLogic*gate)
init_code << " // Connect inputs to gate " << gate->name()
<< "." << endl;
{ string nexus = mangle(nexus_from_link(&gate->pin(0)));
init_code << " " << nexus << "_nex.connect(&" <<
mangle(gate->name()) << ");" << endl;
{ string nexus = nexus_from_link(&gate->pin(0));
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table[" << ncode <<
"].connect(&" << mangle(gate->name()) << ");" << endl;
}
for (unsigned idx = 1 ; idx < gate->pin_count() ; idx += 1) {
string nexus = mangle(nexus_from_link(&gate->pin(idx)));
init_code << " " << nexus << "_nex.connect(&" <<
mangle(gate->name()) << ", " << (idx-1) << ");" << endl;
string nexus = nexus_from_link(&gate->pin(idx));
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table[" << ncode
<< "].connect(&" << mangle(gate->name()) << ", "
<< (idx-1) << ");" << endl;
}
}
@ -1408,29 +1451,34 @@ void target_vvm::net_assign_nb(ostream&os, const NetAssignNB*net)
void target_vvm::net_case_cmp(ostream&os, const NetCaseCmp*gate)
{
string mname = mangle(gate->name());
string nexus;
unsigned ncode;
assert(gate->pin_count() == 3);
os << "static vvm_eeq " << mangle(gate->name()) << "(" <<
os << "static vvm_eeq " << mname << "(" <<
gate->rise_time() << ");" << endl;
/* Connect the output pin */
nexus = mangle(nexus_from_link(&gate->pin(0)));
init_code << " " << nexus << "_nex.connect(&" <<
mangle(gate->name()) << ");" << endl;
nexus = nexus_from_link(&gate->pin(0));
ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect(&"
<< mname << ");" << endl;
/* Connect the first input */
nexus = mangle(nexus_from_link(&gate->pin(1)));
init_code << " " << nexus << "_nex.connect(&" <<
mangle(gate->name()) << ", 0);" << endl;
nexus = nexus_from_link(&gate->pin(1));
ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect(&"
<< mname << ", 0);" << endl;
/* Connect the second input */
nexus = mangle(nexus_from_link(&gate->pin(2)));
init_code << " " << nexus << "_nex.connect(&" <<
mangle(gate->name()) << ", 1);" << endl;
nexus = nexus_from_link(&gate->pin(2));
ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect(&"
<< mname << ", 1);" << endl;
start_code << " " << mangle(gate->name()) << ".start();" << endl;
start_code << " " << mname << ".start();" << endl;
}
/*
@ -1487,8 +1535,10 @@ void target_vvm::net_event(ostream&os, const NetNEvent*gate)
source. Write the connect calls into the init code. */
for (unsigned idx = 0 ; idx < gate->pin_count() ; idx += 1) {
string nexus = mangle(nexus_from_link(&gate->pin(idx)));
init_code << " " << nexus << "_nex.connect(&" <<
string nexus = nexus_from_link(&gate->pin(idx));
unsigned ncode = nexus_wire_map[nexus];
init_code << " nexus_wire_table["<<ncode<<"].connect(&" <<
mangle(gate->name()) << ", " << idx << ");" << endl;
}
}
@ -1538,8 +1588,9 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net)
const verinum value = rc->value();
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
string nexus = mangle(nexus_from_link(&net->pin(idx)));
defn << " " << nexus << "_nex.reg_assign(";
string nexus = nexus_from_link(&net->pin(idx));
unsigned ncode = nexus_wire_map[nexus];
defn << " nexus_wire_table[" <<ncode<< "].reg_assign(";
switch (value.get(idx)) {
case verinum::V0:
defn << "V0";
@ -1565,8 +1616,6 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net)
if (net->bmux()) {
//XXXX Not updated to nexus style??
// This is a bit select. Assign the low bit of the rval
// to the selected bit of the lval.
string bval = emit_proc_rval(defn, 8, net->bmux());
@ -1574,43 +1623,26 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net)
defn << " switch (" << bval << ".as_unsigned()) {" << endl;
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
const NetObj*cur;
unsigned pin;
map<string,bool> written;
string nexus = nexus_from_link(&net->pin(idx));
unsigned ncode = nexus_wire_map[nexus];
defn << " case " << idx << ":" << endl;
for (net->pin(idx).next_link(cur, pin)
; net->pin(idx) != cur->pin(pin)
; cur->pin(pin).next_link(cur, pin)) {
// Skip output only pins.
if (cur->pin(pin).get_dir() == NetObj::Link::OUTPUT)
continue;
// It is possible for a named device to show up
// several times in a link. This is the classic
// case with NetESignal objects, which are
// repeated for each expression that uses it.
if (written[cur->name()])
continue;
written[cur->name()] = true;
defn << " " << mangle(cur->name()) <<
".set_" << cur->pin(pin).get_name() <<
"(" << cur->pin(pin).get_inst() <<
", " << rval << "[0]);" << endl;
}
defn << " nexus_wire_table["<<ncode<<"]"
<< ".reg_assign(" << rval << "[0]);" << endl;
defn << " break;" << endl;
}
defn << " }" << endl;
} else {
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
string nexus = mangle(nexus_from_link(&net->pin(idx)));
defn << " " << nexus << "_nex.reg_assign(" <<
rval << "[" << idx << "]);" << endl;
string nexus = nexus_from_link(&net->pin(idx));
unsigned ncode = nexus_wire_map[nexus];
defn << " nexus_wire_table["<<ncode<<"].reg_assign("
<< rval << "[" << idx << "]);" << endl;
}
}
}
@ -1664,11 +1696,13 @@ void target_vvm::proc_assign_nb(ostream&os, const NetAssignNB*net)
defn << " switch (" << bval << ".as_unsigned()) {" << endl;
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
string nexus = mangle(nexus_from_link(&net->pin(idx)));
string nexus = nexus_from_link(&net->pin(idx));
unsigned ncode = nexus_wire_map[nexus];
defn << " case " << idx << ":" << endl;
defn << " vvm_delyed_assign(" << nexus <<
"_nex, " << rval << ", " << delay << ");" << endl;
defn << " vvm_delayed_assign(nexus_wire_table["
<< ncode << "], " << rval << ", " << delay << ");"
<< endl;
defn << " break;" << endl;
}
@ -1676,10 +1710,11 @@ void target_vvm::proc_assign_nb(ostream&os, const NetAssignNB*net)
} else {
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
string nexus = mangle(nexus_from_link(&net->pin(idx)));
defn << " vvm_delayed_assign(" << nexus <<
"_nex, " << rval << "[" << idx << "], " <<
delay << ");" << endl;
string nexus = nexus_from_link(&net->pin(idx));
unsigned ncode = nexus_wire_map[nexus];
defn << " vvm_delayed_assign(nexus_wire_table["
<< ncode << "], " << rval << "[" << idx << "], "
<< delay << ");" << endl;
}
}
}
@ -2245,6 +2280,17 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
* Revision 1.116 2000/03/18 01:26:59 steve
* Generate references into a table of nexus objects instead of
* generating lots of isolated nexus objects. Easier on linkers
* and compilers,
*
* Add missing nexus support for l-value bit selects,
*
* Detemplatize the vvm_mux type.
*
* Fix up the vvm_nexus destructor to disconnect from drivers.
*
* Revision 1.115 2000/03/17 20:21:14 steve
* Detemplatize the vvm_signal_t class.
*

View File

@ -18,7 +18,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.23 2000/03/17 17:25:53 steve Exp $"
#ident "$Id: Makefile.in,v 1.24 2000/03/18 01:26:59 steve Exp $"
#
#
SHELL = /bin/sh
@ -60,7 +60,7 @@ all: libvvm.a
O = vvm_add_sub.o vvm_bit.o vvm_calltf.o vvm_clshift.o vvm_compare.o \
vvm_event.o \
vvm_func.o vvm_gates.o vvm_mult.o \
vvm_func.o vvm_gates.o vvm_mult.o vvm_mux.o \
vvm_nexus.o vvm_pevent.o vvm_signal.o vvm_thread.o vpip.o
P = vpi_callback.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: vvm_gates.cc,v 1.9 2000/03/17 19:24:00 steve Exp $"
#ident "$Id: vvm_gates.cc,v 1.10 2000/03/18 01:27:00 steve Exp $"
#endif
# include "vvm_gates.h"
@ -94,46 +94,6 @@ vpip_bit_t compute_xnor(const vpip_bit_t*inp, unsigned count)
return v_not(compute_xor(inp,count));
}
void compute_mux(vpip_bit_t*out, unsigned wid,
const vpip_bit_t*sel, unsigned swid,
const vpip_bit_t*dat, unsigned size)
{
unsigned tmp = 0;
for (unsigned idx = 0 ; idx < swid ; idx += 1)
switch (sel[idx]) {
case V0:
break;
case V1:
tmp |= (1<<idx);
break;
default:
tmp = size;
break;
}
if (tmp >= size) {
if (swid > 1) {
for (unsigned idx = 0; idx < wid ; idx += 1)
out[idx] = Vx;
} else {
const unsigned b0 = 0;
const unsigned b1 = wid;
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
if (dat[idx+b0] == dat[idx+b1])
out[idx] = dat[idx+b0];
else
out[idx] = Vx;
}
}
} else {
unsigned b = tmp * wid;
for (unsigned idx = 0; idx < wid ; idx += 1)
out[idx] = dat[idx+b];
}
}
vvm_and2::vvm_and2(unsigned long d)
: vvm_1bit_out(d)
{
@ -298,6 +258,17 @@ void vvm_not::take_value(unsigned, vpip_bit_t val)
/*
* $Log: vvm_gates.cc,v $
* Revision 1.10 2000/03/18 01:27:00 steve
* Generate references into a table of nexus objects instead of
* generating lots of isolated nexus objects. Easier on linkers
* and compilers,
*
* Add missing nexus support for l-value bit selects,
*
* Detemplatize the vvm_mux type.
*
* Fix up the vvm_nexus destructor to disconnect from drivers.
*
* Revision 1.9 2000/03/17 19:24:00 steve
* nor2 and and2 optimized gates.
*

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.45 2000/03/17 19:24:00 steve Exp $"
#ident "$Id: vvm_gates.h,v 1.46 2000/03/18 01:27:00 steve Exp $"
#endif
# include "vvm.h"
@ -328,70 +328,36 @@ class vvm_mult : public vvm_nexus::recvr_t {
/*
* This class supports mux devices. The width is the width of the data
* (or bus) path, SIZE is the number of alternative inputs and SELWID
* is the size (in bits) of the selector input.
* is the size (in bits) of the selector input. The device passes to
* the output the bits of the input selected by the selector.
*/
template <unsigned WIDTH, unsigned SIZE, unsigned SELWID>
class vvm_mux : public vvm_nexus::recvr_t {
public:
explicit vvm_mux()
{ unsigned idx;
for (idx = 0 ; idx < WIDTH ; idx += 1) output_[idx] = Vx;
for (idx = 0 ; idx < SELWID; idx += 1) sel_[idx] = Vx;
for (idx = 0 ; idx < WIDTH*SIZE; idx += 1) input_[idx] = Vx;
}
explicit vvm_mux(unsigned width, unsigned size, unsigned selwid);
~vvm_mux();
void init_Sel(unsigned idx, vpip_bit_t val)
{ sel_[idx] = val; }
void init_Sel(unsigned idx, vpip_bit_t val);
void init_Data(unsigned idx, vpip_bit_t val);
void init_Data(unsigned idx, vpip_bit_t val)
{ input_[idx] = val; }
vvm_nexus::drive_t* config_rout(unsigned idx);
vvm_nexus::drive_t* config_rout(unsigned idx)
{ return out_+idx; }
unsigned key_Sel(unsigned idx) const { return idx; }
unsigned key_Data(unsigned wi, unsigned si) const
{ return 0x10000 + si*WIDTH + wi; }
unsigned key_Sel(unsigned idx) const;
unsigned key_Data(unsigned wi, unsigned si) const;
private:
void take_value(unsigned key, vpip_bit_t val)
{ unsigned code = key >> 16;
unsigned idx = key & 0xffff;
if (code == 1)
set_Data(idx, val);
else
set_Sel(idx, val);
}
void take_value(unsigned key, vpip_bit_t val);
void set_Sel(unsigned idx, vpip_bit_t val)
{ if (sel_[idx] == val) return;
sel_[idx] = val;
evaluate_();
}
unsigned width_, size_, selwid_;
vpip_bit_t*bits_;
void set_Data(unsigned idx, vpip_bit_t val)
{ if (input_[idx] == val) return;
input_[idx] = val;
evaluate_();
}
vvm_nexus::drive_t*out_;
private:
vpip_bit_t sel_[SELWID];
vpip_bit_t input_[WIDTH * SIZE];
vpip_bit_t output_[WIDTH];
void evaluate_();
vvm_nexus::drive_t out_[WIDTH];
void evaluate_()
{ vpip_bit_t tmp[WIDTH];
compute_mux(tmp, WIDTH, sel_, SELWID, input_, SIZE);
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1)
if (tmp[idx] != output_[idx]) {
output_[idx] = tmp[idx];
out_[idx].set_value(output_[idx]);
}
}
private: // not implemented
vvm_mux(const vvm_mux&);
vvm_mux& operator= (vvm_mux&);
};
template <unsigned WIDTH>
@ -848,6 +814,17 @@ template <unsigned WIDTH> class vvm_pevent : public vvm_nexus::recvr_t {
/*
* $Log: vvm_gates.h,v $
* Revision 1.46 2000/03/18 01:27:00 steve
* Generate references into a table of nexus objects instead of
* generating lots of isolated nexus objects. Easier on linkers
* and compilers,
*
* Add missing nexus support for l-value bit selects,
*
* Detemplatize the vvm_mux type.
*
* Fix up the vvm_nexus destructor to disconnect from drivers.
*
* Revision 1.45 2000/03/17 19:24:00 steve
* nor2 and and2 optimized gates.
*

159
vvm/vvm_mux.cc Normal file
View File

@ -0,0 +1,159 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.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: vvm_mux.cc,v 1.1 2000/03/18 01:27:00 steve Exp $"
#endif
# include "vvm_gates.h"
# include <assert.h>
/*
* The array of bits is arranged as:
*
* oooo ss 0000 1111 2222 3333 ...
*
*/
vvm_mux::vvm_mux(unsigned w, unsigned s, unsigned sw)
: width_(w), size_(s), selwid_(sw)
{
bits_ = new vpip_bit_t[width_*size_+selwid_+width_];
out_ = new vvm_nexus::drive_t[width_];
for (unsigned idx = 0 ; idx < width_*size_+selwid_+width_ ; idx += 1)
bits_[idx] = Vx;
}
vvm_mux::~vvm_mux()
{
delete[]out_;
delete[]bits_;
}
vvm_nexus::drive_t* vvm_mux::config_rout(unsigned idx)
{
assert(idx < width_);
return out_+idx;
}
unsigned vvm_mux::key_Sel(unsigned idx) const
{
assert(idx < selwid_);
return idx + width_;
}
unsigned vvm_mux::key_Data(unsigned wi, unsigned si) const
{
assert(si < size_);
assert(wi < width_);
return width_ + selwid_ + si*width_ + wi;
}
void vvm_mux::init_Sel(unsigned idx, vpip_bit_t val)
{
assert(idx < selwid_);
bits_[width_+idx] = val;
}
void vvm_mux::init_Data(unsigned idx, vpip_bit_t val)
{
assert(idx < width_*size_);
bits_[width_+selwid_+idx] = val;
}
void vvm_mux::take_value(unsigned key, vpip_bit_t val)
{
if (bits_[key] == val)
return;
bits_[key] = val;
evaluate_();
}
void vvm_mux::evaluate_()
{
vpip_bit_t*tmp = new vpip_bit_t[width_];
vpip_bit_t*sel = bits_+width_;
vpip_bit_t*inp = bits_+width_+selwid_;
compute_mux(tmp, width_, sel, selwid_, inp, size_);
for (unsigned idx = 0 ; idx < width_ ; idx += 1)
if (tmp[idx] != bits_[idx]) {
bits_[idx] = tmp[idx];
out_[idx].set_value(bits_[idx]);
}
delete[]tmp;
}
void compute_mux(vpip_bit_t*out, unsigned wid,
const vpip_bit_t*sel, unsigned swid,
const vpip_bit_t*dat, unsigned size)
{
unsigned tmp = 0;
for (unsigned idx = 0 ; idx < swid ; idx += 1)
switch (sel[idx]) {
case V0:
break;
case V1:
tmp |= (1<<idx);
break;
default:
tmp = size;
break;
}
if (tmp >= size) {
if (swid > 1) {
for (unsigned idx = 0; idx < wid ; idx += 1)
out[idx] = Vx;
} else {
const unsigned b0 = 0;
const unsigned b1 = wid;
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
if (dat[idx+b0] == dat[idx+b1])
out[idx] = dat[idx+b0];
else
out[idx] = Vx;
}
}
} else {
unsigned b = tmp * wid;
for (unsigned idx = 0; idx < wid ; idx += 1)
out[idx] = dat[idx+b];
}
}
/*
* $Log: vvm_mux.cc,v $
* Revision 1.1 2000/03/18 01:27:00 steve
* Generate references into a table of nexus objects instead of
* generating lots of isolated nexus objects. Easier on linkers
* and compilers,
*
* Add missing nexus support for l-value bit selects,
*
* Detemplatize the vvm_mux type.
*
* Fix up the vvm_nexus destructor to disconnect from drivers.
*
*/

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.2 2000/03/16 21:45:07 steve Exp $"
#ident "$Id: vvm_nexus.cc,v 1.3 2000/03/18 01:27:00 steve Exp $"
#endif
# include "vvm_nexus.h"
@ -34,7 +34,13 @@ vvm_nexus::vvm_nexus()
vvm_nexus::~vvm_nexus()
{
assert(drivers_ == 0);
while (drivers_) {
drive_t*cur = drivers_;
drivers_ = cur->next_;
assert(cur->nexus_ == this);
cur->nexus_ = 0;
cur->next_ = 0;
}
/* assert(recvrs_ == 0); XXXX I really should make a point to
guarantee that all the receivers that I refer to are gone,
@ -227,6 +233,17 @@ void vvm_delayed_assign(vvm_nexus&l_val, vpip_bit_t r_val,
/*
* $Log: vvm_nexus.cc,v $
* Revision 1.3 2000/03/18 01:27:00 steve
* Generate references into a table of nexus objects instead of
* generating lots of isolated nexus objects. Easier on linkers
* and compilers,
*
* Add missing nexus support for l-value bit selects,
*
* Detemplatize the vvm_mux type.
*
* Fix up the vvm_nexus destructor to disconnect from drivers.
*
* Revision 1.2 2000/03/16 21:45:07 steve
* Properly initialize driver and nexus values.
*