Compare commits

...
7 Commits
Author SHA1 Message Date
steve c66d319d9c UPdate to 20021027 snapshot. 2002-10-28 02:26:41 +00:00
steve ae27165ffe Add Virtex code generators for left shift,
subtraction, and GE comparators.
2002-10-28 02:05:56 +00:00
steve 32f1ca6f8b draw lpm ff with aset_expr taken into account. 2002-10-23 04:39:35 +00:00
steve 9ce2806710 Fix synth2 handling of aset/aclr signals where
flip-flops are split by begin-end blocks.
2002-10-23 01:45:24 +00:00
steve 3d4593d4d5 Synthesizer support for synchronous begin-end blocks. 2002-10-21 01:42:08 +00:00
steve df5ae54ec7 Handle conditional error cases better. 2002-10-20 19:19:37 +00:00
steve fbee1b424d Properly set or clear expression lookaside for binary expressions. 2002-10-20 02:55:37 +00:00
20 changed files with 761 additions and 87 deletions
+7 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: design_dump.cc,v 1.134 2002/10/19 22:59:49 steve Exp $"
#ident "$Id: design_dump.cc,v 1.135 2002/10/23 01:47:17 steve Exp $"
#endif
# include "config.h"
@@ -271,7 +271,8 @@ void NetConst::dump_node(ostream&o, unsigned ind) const
void NetFF::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "LPM_FF: " << name()
<< " scope=" << (scope()? scope()->name() : "") << endl;
<< " scope=" << (scope()? scope()->name() : "")
<< " aset_value=" << aset_value_ << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
@@ -1003,6 +1004,10 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.135 2002/10/23 01:47:17 steve
* Fix synth2 handling of aset/aclr signals where
* flip-flops are split by begin-end blocks.
*
* Revision 1.134 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
+1
View File
@@ -54,6 +54,7 @@ ivl_logic_pin
ivl_logic_pins
ivl_logic_udp
ivl_lpm_aset_value
ivl_lpm_async_clr
ivl_lpm_async_set
ivl_lpm_basename
+6 -1
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: ivl_target.h,v 1.107 2002/09/26 03:18:04 steve Exp $"
#ident "$Id: ivl_target.h,v 1.108 2002/10/23 01:47:17 steve Exp $"
#endif
#ifdef __cplusplus
@@ -615,6 +615,7 @@ extern unsigned ivl_lpm_width(ivl_lpm_t net);
/* IVL_LPM_FF */
extern ivl_nexus_t ivl_lpm_async_clr(ivl_lpm_t net);
extern ivl_nexus_t ivl_lpm_async_set(ivl_lpm_t net);
extern ivl_expr_t ivl_lpm_aset_value(ivl_lpm_t net);
/* IVL_LPM_FF IVL_LPM_RAM */
extern ivl_nexus_t ivl_lpm_clk(ivl_lpm_t net);
/* IVL_LPM_UFUNC */
@@ -1090,6 +1091,10 @@ _END_DECL
/*
* $Log: ivl_target.h,v $
* Revision 1.108 2002/10/23 01:47:17 steve
* Fix synth2 handling of aset/aclr signals where
* flip-flops are split by begin-end blocks.
*
* Revision 1.107 2002/09/26 03:18:04 steve
* Generate vvp code for asynch set/reset of NetFF.
*
+17 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_link.cc,v 1.11 2002/08/18 22:07:16 steve Exp $"
#ident "$Id: net_link.cc,v 1.12 2002/10/21 01:42:08 steve Exp $"
#endif
# include "config.h"
@@ -484,8 +484,24 @@ bool NexusSet::contains(const NexusSet&that) const
return true;
}
bool NexusSet::intersect(const NexusSet&that) const
{
for (unsigned idx = 0 ; idx < that.nitems_ ; idx += 1) {
unsigned where = bsearch_(that[idx]);
if (where == nitems_)
continue;
if (items_[where] == that[idx])
return true;
}
return false;
}
/*
* $Log: net_link.cc,v $
* Revision 1.12 2002/10/21 01:42:08 steve
* Synthesizer support for synchronous begin-end blocks.
*
* Revision 1.11 2002/08/18 22:07:16 steve
* Detect temporaries in sequential block synthesis.
*
+15 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: netlist.cc,v 1.200 2002/09/26 03:18:04 steve Exp $"
#ident "$Id: netlist.cc,v 1.201 2002/10/23 01:47:17 steve Exp $"
#endif
# include "config.h"
@@ -650,6 +650,16 @@ const Link& NetFF::pin_Q(unsigned w) const
return pin(pn);
}
void NetFF::aset_value(const verinum&val)
{
aset_value_ = val;
}
const verinum& NetFF::aset_value() const
{
return aset_value_;
}
/*
* The NetAddSub class represents an LPM_ADD_SUB device. The pinout is
@@ -2310,6 +2320,10 @@ const NetProc*NetTaskDef::proc() const
/*
* $Log: netlist.cc,v $
* Revision 1.201 2002/10/23 01:47:17 steve
* Fix synth2 handling of aset/aclr signals where
* flip-flops are split by begin-end blocks.
*
* Revision 1.200 2002/09/26 03:18:04 steve
* Generate vvp code for asynch set/reset of NetFF.
*
+21 -1
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: netlist.h,v 1.265 2002/10/19 22:59:49 steve Exp $"
#ident "$Id: netlist.h,v 1.267 2002/10/23 01:47:17 steve Exp $"
#endif
/*
@@ -297,6 +297,9 @@ class NexusSet {
// Return true if this set contains every nexus in that set.
bool contains(const NexusSet&that) const;
// Return true if this set contains any nexus in that set.
bool intersect(const NexusSet&that) const;
private:
Nexus**items_;
unsigned nitems_;
@@ -668,9 +671,15 @@ class NetFF : public NetNode {
const Link& pin_Data(unsigned) const;
const Link& pin_Q(unsigned) const;
void aset_value(const verinum&val);
const verinum& aset_value() const;
virtual void dump_node(ostream&, unsigned ind) const;
virtual bool emit_node(struct target_t*) const;
virtual void functor_node(Design*des, functor_t*fun);
private:
verinum aset_value_;
};
@@ -1411,6 +1420,10 @@ class NetBlock : public NetProc {
bool synth_async(Design*des, NetScope*scope,
const NetNet*nex_map, NetNet*nex_out);
bool synth_sync(Design*des, NetScope*scope, NetFF*ff,
const NetNet*nex_map, NetNet*nex_out,
const svector<NetEvProbe*>&events);
// This version of emit_recurse scans all the statements of
// the begin-end block sequentially. It is typically of use
// for sequential blocks.
@@ -3070,6 +3083,13 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.267 2002/10/23 01:47:17 steve
* Fix synth2 handling of aset/aclr signals where
* flip-flops are split by begin-end blocks.
*
* Revision 1.266 2002/10/21 01:42:08 steve
* Synthesizer support for synchronous begin-end blocks.
*
* Revision 1.265 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
+160 -9
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: synth2.cc,v 1.14 2002/09/26 03:42:10 steve Exp $"
#ident "$Id: synth2.cc,v 1.17 2002/10/23 01:47:17 steve Exp $"
#endif
# include "config.h"
@@ -228,6 +228,14 @@ bool NetCondit::synth_async(Design*des, NetScope*scope,
NetNet*ssig = expr_->synthesize(des);
assert(ssig);
if (if_ == 0)
return false;
if (else_ == 0) {
cerr << get_line() << ": error: Asynchronous if statement"
<< " is missing the else clause." << endl;
return false;
}
assert(if_ != 0);
assert(else_ != 0);
@@ -284,6 +292,128 @@ bool NetProcTop::synth_async(Design*des)
return flag;
}
/*
* This method is called when a block is encountered near the surface
* of a synchronous always statement. For example, this code will be
* invoked for input like this:
*
* always @(posedge clk...) begin
* <statement1>
* <statement2>
* ...
* end
*
* This needs to be split into a DFF bank for each statement, because
* the statements may each infer different reset and enable signals.
*/
bool NetBlock::synth_sync(Design*des, NetScope*scope, NetFF*ff,
const NetNet*nex_map, NetNet*nex_out,
const svector<NetEvProbe*>&events_in)
{
if (last_ == 0)
return true;
bool flag = true;
NetProc*cur = last_;
unsigned offset = 0;
do {
cur = cur->next_;
/* Create a temporary nex_map for the substatement. */
NexusSet tmp_set;
cur->nex_output(tmp_set);
NetNet*tmp_map = new NetNet(scope, "tmp1", NetNet::WIRE,
tmp_set.count());
for (unsigned idx = 0 ; idx < tmp_map->pin_count() ; idx += 1)
connect(tmp_set[idx], tmp_map->pin(idx));
/* Create also a temporary net_out to collect the
output. */
NetNet*tmp_out = new NetNet(scope, "tmp2", NetNet::WIRE,
tmp_set.count());
verinum tmp_aset = ff->aset_value();
/* Create a new DFF to handle this part of the begin-end
block. Connect this NetFF to the associated pins of
the existing wide NetFF device. While I'm at it, also
copy the aset_value bits for the new ff device. */
NetFF*ff2 = new NetFF(scope, scope->local_hsymbol().c_str(),
tmp_out->pin_count());
des->add_node(ff2);
verinum aset_value2 (verinum::V1, ff2->width());
for (unsigned idx = 0 ; idx < ff2->width() ; idx += 1) {
unsigned ptr = find_nexus_in_set(nex_map, tmp_set[idx]);
connect(ff->pin_Data(ptr), ff2->pin_Data(idx));
connect(ff->pin_Q(ptr), ff2->pin_Q(idx));
if (ptr < tmp_aset.len())
aset_value2.set(idx, tmp_aset[ptr]);
}
if (ff->pin_Aclr().is_linked())
connect(ff->pin_Aclr(), ff2->pin_Aclr());
if (ff->pin_Aset().is_linked())
connect(ff->pin_Aset(), ff2->pin_Aset());
if (ff->pin_Clock().is_linked())
connect(ff->pin_Clock(), ff2->pin_Clock());
if (ff->pin_Enable().is_linked())
connect(ff->pin_Enable(),ff2->pin_Enable());
/* Remember to store the aset value into the new FF. If
this leads to an Aset value of 0 (and Aclr is not
otherwise used) then move the Aset input to Aclr. */
if (tmp_aset.len() == ff->width()) {
if ((aset_value2.as_ulong() == 0)
&& ff2->pin_Aset().is_linked()
&& !ff2->pin_Aclr().is_linked()) {
connect(ff2->pin_Aclr(), ff2->pin_Aset());
ff2->pin_Aset().unlink();
} else {
ff2->aset_value(aset_value2);
}
}
/* Now go on with the synchronous synthesis for this
subset of the statement. */
bool ok_flag = cur->synth_sync(des, scope, ff2, tmp_map,
tmp_out, events_in);
flag = flag && ok_flag;
if (ok_flag == false)
continue;
/* Use the nex_map to link up the output from the
substatement to the output of the block as a whole. */
for (unsigned idx = 0 ; idx < tmp_out->pin_count() ; idx += 1) {
unsigned ptr = find_nexus_in_set(nex_map, tmp_set[idx]);
connect(nex_out->pin(ptr), tmp_out->pin(idx));
}
delete tmp_map;
delete tmp_out;
offset += ff2->width();
} while (cur != last_);
/* Done. The large NetFF is no longer needed, as it has been
taken up by the smaller NetFF devices. */
assert(offset == ff->width());
delete ff;
return flag;
}
/*
* This method handles the case where I find a conditional near the
* surface of a synchronous thread. This conditional can be a CE or an
* asynchronous set/reset, depending on whether the pin of the
* expression is connected to an event, or not.
*/
bool NetCondit::synth_sync(Design*des, NetScope*scope, NetFF*ff,
const NetNet*nex_map, NetNet*nex_out,
const svector<NetEvProbe*>&events_in)
@@ -310,16 +440,25 @@ bool NetCondit::synth_sync(Design*des, NetScope*scope, NetFF*ff,
if_->synth_async(des, scope, nex_map, asig);
assert(asig->pin_count() == ff->width());
assert(asig->pin(0).nexus()->drivers_constant());
switch (asig->pin(0).nexus()->driven_value()) {
case verinum::V0:
/* Collect the set/reset value into a verinum. If
this turns out to be entirely 0 values, then
use the Aclr input. Otherwise, use the Aset
input and save the set value. */
verinum tmp (verinum::V0, ff->width());
for (unsigned bit = 0 ; bit < ff->width() ; bit += 1) {
assert(asig->pin(bit).nexus()->drivers_constant());
tmp.set(bit, asig->pin(bit).nexus()->driven_value());
}
assert(tmp.is_defined());
if (tmp.as_ulong() == 0) {
connect(ff->pin_Aclr(), ce->pin(0));
break;
case verinum::V1:
} else {
connect(ff->pin_Aset(), ce->pin(0));
break;
default:
assert(0);
ff->aset_value(tmp);
}
delete asig;
@@ -498,6 +637,8 @@ void synth2_f::process(class Design*des, class NetProcTop*top)
if (top->is_synchronous()) do {
bool flag = top->synth_sync(des);
if (! flag) {
cerr << top->get_line() << ": error: "
<< "Unable to synthesize synchronous process." << endl;
des->errors += 1;
return;
}
@@ -548,6 +689,16 @@ void synth2(Design*des)
/*
* $Log: synth2.cc,v $
* Revision 1.17 2002/10/23 01:47:17 steve
* Fix synth2 handling of aset/aclr signals where
* flip-flops are split by begin-end blocks.
*
* Revision 1.16 2002/10/21 01:42:09 steve
* Synthesizer support for synchronous begin-end blocks.
*
* Revision 1.15 2002/10/20 19:19:37 steve
* Handle conditional error cases better.
*
* Revision 1.14 2002/09/26 03:42:10 steve
* Remove excess debug messages.
*
+17 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll-api.cc,v 1.87 2002/09/26 03:18:04 steve Exp $"
#ident "$Id: t-dll-api.cc,v 1.88 2002/10/23 01:47:17 steve Exp $"
#endif
# include "config.h"
@@ -577,6 +577,18 @@ extern "C" ivl_nexus_t ivl_lpm_clk(ivl_lpm_t net)
}
}
extern "C" ivl_expr_t ivl_lpm_aset_value(ivl_lpm_t net)
{
assert(net);
switch (net->type) {
case IVL_LPM_FF:
case IVL_LPM_RAM:
return net->u_.ff.aset_value;
default:
assert(0);
return 0;
}
}
extern "C" ivl_scope_t ivl_lpm_define(ivl_lpm_t net)
{
assert(net);
@@ -1573,6 +1585,10 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net)
/*
* $Log: t-dll-api.cc,v $
* Revision 1.88 2002/10/23 01:47:17 steve
* Fix synth2 handling of aset/aclr signals where
* flip-flops are split by begin-end blocks.
*
* Revision 1.87 2002/09/26 03:18:04 steve
* Generate vvp code for asynch set/reset of NetFF.
*
+37 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll-expr.cc,v 1.28 2002/08/12 01:35:00 steve Exp $"
#ident "$Id: t-dll-expr.cc,v 1.29 2002/10/23 01:47:17 steve Exp $"
#endif
# include "config.h"
@@ -103,6 +103,38 @@ void dll_target::mul_expr_by_const_(long val)
expr_ = tmps;
}
ivl_expr_t dll_target::expr_from_value_(const verinum&val)
{
ivl_expr_t expr = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
assert(expr);
unsigned idx;
char*bits;
expr->type_ = IVL_EX_NUMBER;
expr->width_= val.len();
expr->signed_ = val.has_sign()? 1 : 0;
expr->u_.number_.bits_ = bits = (char*)malloc(expr->width_);
for (idx = 0 ; idx < expr->width_ ; idx += 1)
switch (val.get(idx)) {
case verinum::V0:
bits[idx] = '0';
break;
case verinum::V1:
bits[idx] = '1';
break;
case verinum::Vx:
bits[idx] = 'x';
break;
case verinum::Vz:
bits[idx] = 'z';
break;
default:
assert(0);
}
return expr;
}
void dll_target::expr_binary(const NetEBinary*net)
{
assert(expr_ == 0);
@@ -458,6 +490,10 @@ void dll_target::expr_unary(const NetEUnary*net)
/*
* $Log: t-dll-expr.cc,v $
* Revision 1.29 2002/10/23 01:47:17 steve
* Fix synth2 handling of aset/aclr signals where
* flip-flops are split by begin-end blocks.
*
* Revision 1.28 2002/08/12 01:35:00 steve
* conditional ident string using autoconfig.
*
+11 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll.cc,v 1.96 2002/09/26 03:18:04 steve Exp $"
#ident "$Id: t-dll.cc,v 1.97 2002/10/23 01:47:18 steve Exp $"
#endif
# include "config.h"
@@ -1376,9 +1376,14 @@ void dll_target::lpm_ff(const NetFF*net)
assert(nex->t_cookie());
obj->u_.ff.aset = (ivl_nexus_t) nex->t_cookie();
assert(obj->u_.ff.aset);
nexus_lpm_add(obj->u_.ff.aclr, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
nexus_lpm_add(obj->u_.ff.aset, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
verinum tmp = net->aset_value();
obj->u_.ff.aset_value = expr_from_value_(tmp);
} else {
obj->u_.ff.aset = 0;
obj->u_.ff.aset_value = 0;
}
if (obj->u_.ff.width == 1) {
@@ -1974,6 +1979,10 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
/*
* $Log: t-dll.cc,v $
* Revision 1.97 2002/10/23 01:47:18 steve
* Fix synth2 handling of aset/aclr signals where
* flip-flops are split by begin-end blocks.
*
* Revision 1.96 2002/09/26 03:18:04 steve
* Generate vvp code for asynch set/reset of NetFF.
*
+8 -1
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll.h,v 1.94 2002/09/26 03:18:04 steve Exp $"
#ident "$Id: t-dll.h,v 1.95 2002/10/23 01:47:17 steve Exp $"
#endif
# include "target.h"
@@ -154,6 +154,8 @@ struct dll_target : public target_t, public expr_scan_t {
void sub_off_from_expr_(long);
void mul_expr_by_const_(long);
static ivl_expr_t expr_from_value_(const verinum&that);
};
/*
@@ -282,6 +284,7 @@ struct ivl_lpm_s {
ivl_nexus_t pin;
} s;
ivl_memory_t mem; // ram only
ivl_expr_t aset_value;
} ff;
struct ivl_lpm_mux_s {
@@ -619,6 +622,10 @@ struct ivl_statement_s {
/*
* $Log: t-dll.h,v $
* Revision 1.95 2002/10/23 01:47:17 steve
* Fix synth2 handling of aset/aclr signals where
* flip-flops are split by begin-end blocks.
*
* Revision 1.94 2002/09/26 03:18:04 steve
* Generate vvp code for asynch set/reset of NetFF.
*
+10 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: d-generic-edif.c,v 1.9 2002/08/12 01:35:02 steve Exp $"
#ident "$Id: d-generic-edif.c,v 1.10 2002/10/28 02:05:56 steve Exp $"
#endif
# include "device.h"
@@ -394,12 +394,20 @@ const struct device_s d_generic_edif = {
0,
0,
0,
0
0,
0, /* show_add */
0, /* show_sub */
0, /* show_shiftl */
0 /* show_shiftr */
};
/*
* $Log: d-generic-edif.c,v $
* Revision 1.10 2002/10/28 02:05:56 steve
* Add Virtex code generators for left shift,
* subtraction, and GE comparators.
*
* Revision 1.9 2002/08/12 01:35:02 steve
* conditional ident string using autoconfig.
*
+10 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: d-generic.c,v 1.11 2002/08/12 01:35:02 steve Exp $"
#ident "$Id: d-generic.c,v 1.12 2002/10/28 02:05:56 steve Exp $"
#endif
# include "device.h"
@@ -503,13 +503,21 @@ const struct device_s d_generic = {
generic_show_dff,
generic_show_cmp_eq,
generic_show_cmp_eq,
0, /* ge not implemented */
generic_show_mux,
generic_show_add
generic_show_add,
0, /* subtract not implemented */
0,
0
};
/*
* $Log: d-generic.c,v $
* Revision 1.12 2002/10/28 02:05:56 steve
* Add Virtex code generators for left shift,
* subtraction, and GE comparators.
*
* Revision 1.11 2002/08/12 01:35:02 steve
* conditional ident string using autoconfig.
*
+318 -41
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: d-virtex.c,v 1.15 2002/09/15 21:52:19 steve Exp $"
#ident "$Id: d-virtex.c,v 1.16 2002/10/28 02:05:56 steve Exp $"
#endif
# include "device.h"
@@ -1159,6 +1159,18 @@ static void edif_show_virtex_add(ivl_lpm_t net)
char jbuf [1024];
unsigned idx;
unsigned nref = 0;
unsigned ha_init = 6;
switch (ivl_lpm_type(net)) {
case IVL_LPM_ADD:
ha_init = 6;
break;
case IVL_LPM_SUB:
ha_init = 9;
break;
default:
assert(0);
}
/* Handle the special case that the adder is only one bit
wide. Generate an XOR gate to perform the half-add. */
@@ -1169,7 +1181,7 @@ static void edif_show_virtex_add(ivl_lpm_t net)
ivl_lpm_q(net, 0),
ivl_lpm_data(net, 0),
ivl_lpm_datab(net, 0),
"6");
(ha_init == 6) ? "6" : "9");
return;
}
@@ -1180,8 +1192,8 @@ static void edif_show_virtex_add(ivl_lpm_t net)
includes the LUT2 device to perform the addition, and a
MUXCY_L device to send the carry up to the next bit. */
fprintf(xnf, "(instance (rename U%u_L0 \"%s\"[0])"
" (property INIT (string \"6\"))", edif_uref,
ivl_lpm_name(net));
" (property INIT (string \"%u\"))", edif_uref,
ivl_lpm_name(net), ha_init);
fprintf(xnf, " (viewRef net"
" (cellRef LUT2 (libraryRef VIRTEX))))\n");
@@ -1207,8 +1219,8 @@ static void edif_show_virtex_add(ivl_lpm_t net)
device, the other devices have local names. */
for (idx = 1 ; idx < (ivl_lpm_width(net)-1) ; idx += 1) {
fprintf(xnf, "(instance U%u_L%u) (property INIT (string \"6\"))",
edif_uref, idx);
fprintf(xnf, "(instance U%u_L%u) (property INIT (string \"%u\"))",
edif_uref, idx, ha_init);
fprintf(xnf, " (viewRef net"
" (cellRef LUT2 (libraryRef VIRTEX))))\n");
@@ -1249,8 +1261,8 @@ static void edif_show_virtex_add(ivl_lpm_t net)
}
fprintf(xnf, "(instance U%u_L%u) (property INIT (string \"6\"))",
edif_uref, idx);
fprintf(xnf, "(instance U%u_L%u) (property INIT (string \"%u\"))",
edif_uref, idx, ha_init);
fprintf(xnf, " (viewRef net"
" (cellRef LUT2 (libraryRef VIRTEX))))\n");
@@ -1282,6 +1294,295 @@ static void edif_show_virtex_add(ivl_lpm_t net)
edif_set_nexus_joint(ivl_lpm_q(net, idx), jbuf);
}
static void virtex_show_cmp_ge(ivl_lpm_t net)
{
char jbuf [1024];
unsigned idx;
unsigned nref = 0;
/* Handle the special case that the adder is only one bit
wide. Generate an XOR gate to perform the half-add. */
if (ivl_lpm_width(net) == 1) {
edif_uref += 1;
edif_show_lut2(ivl_lpm_name(net), edif_uref,
ivl_lpm_q(net, 0),
ivl_lpm_data(net, 0),
ivl_lpm_datab(net, 0),
"D");
return;
}
assert(ivl_lpm_width(net) > 1);
edif_uref += 1;
/* First, draw the bottom bit slice of the comparator. This
includes the LUT2 device to perform the addition, and a
MUXCY_L device to send the carry up to the next bit. */
fprintf(xnf, "(instance (rename U%u_L0 \"%s\"[0])"
" (property INIT (string \"9\"))", edif_uref,
ivl_lpm_name(net));
fprintf(xnf, " (viewRef net"
" (cellRef LUT2 (libraryRef VIRTEX))))\n");
fprintf(xnf, "(instance U%u_M0", edif_uref);
fprintf(xnf, " (viewRef net"
" (cellRef MUXCY_L (libraryRef VIRTEX))))\n");
sprintf(jbuf, "(portRef I0 (instanceRef U%u_L0))", edif_uref);
edif_set_nexus_joint(ivl_lpm_data(net, 0), jbuf);
sprintf(jbuf, "(portRef I1 (instanceRef U%u_L0))", edif_uref);
edif_set_nexus_joint(ivl_lpm_datab(net, 0), jbuf);
sprintf(jbuf, "(portRef DI (instanceRef U%u_M0))", edif_uref);
edif_set_nexus_joint(ivl_lpm_data(net, 0), jbuf);
switch (ivl_lpm_type(net)) {
case IVL_LPM_CMP_GT:
fprintf(xnf, "(instance U%u_FILL "
" (viewRef net"
" (cellRef GND (libraryRef VIRTEX))))\n",
edif_uref);
fprintf(xnf, "(net U%u_FILLN (joined"
" (portRef GROUND (instanceRef U%u_FILL))"
" (portRef CI (instanceRef U%u_M0))))\n",
edif_uref, edif_uref, edif_uref);
break;
case IVL_LPM_CMP_GE:
fprintf(xnf, "(instance U%u_FILL "
" (viewRef net"
" (cellRef VCC (libraryRef VIRTEX))))\n",
edif_uref);
fprintf(xnf, "(net U%u_FILLN (joined"
" (portRef VCC (instanceRef U%u_FILL))"
" (portRef CI (instanceRef U%u_M0))))\n",
edif_uref, edif_uref, edif_uref);
break;
default:
assert(0);
}
/* Now draw all the inside bit slices. These include the LUT2
device for the basic add, the MUXCY_L device to propagate
the carry, and an XORCY device to generate the real
output. The XORCY device carries the name of the LPM
device, the other devices have local names. */
for (idx = 1 ; idx < (ivl_lpm_width(net)-1) ; idx += 1) {
fprintf(xnf, "(instance U%u_L%u) (property INIT (string \"9\"))",
edif_uref, idx);
fprintf(xnf, " (viewRef net"
" (cellRef LUT2 (libraryRef VIRTEX))))\n");
fprintf(xnf, "(instance U%u_M%u", edif_uref, idx);
fprintf(xnf, " (viewRef net"
" (cellRef MUXCY_L (libraryRef VIRTEX))))\n");
fprintf(xnf, "(net U%uN%u (joined"
" (portRef O (instanceRef U%u_L%u))"
" (portRef S (instanceRef U%u_M%u))))\n",
edif_uref, nref++, edif_uref, idx, edif_uref, idx);
fprintf(xnf, "(net U%uN%u (joined"
" (portRef CI (instanceRef U%u_M%u))"
" (portRef LO (instanceRef U%u_M%u))))\n",
edif_uref, nref++, edif_uref, idx, edif_uref, idx-1);
sprintf(jbuf, "(portRef I0 (instanceRef U%u_L%u))",
edif_uref, idx);
edif_set_nexus_joint(ivl_lpm_data(net, idx), jbuf);
sprintf(jbuf, "(portRef I1 (instanceRef U%u_L%u))",
edif_uref, idx);
edif_set_nexus_joint(ivl_lpm_datab(net, idx), jbuf);
sprintf(jbuf, "(portRef DI (instanceRef U%u_M%u))",
edif_uref, idx);
edif_set_nexus_joint(ivl_lpm_data(net, idx), jbuf);
}
fprintf(xnf, "(instance U%u_L%u) (property INIT (string \"9\"))",
edif_uref, idx);
fprintf(xnf, " (viewRef net"
" (cellRef LUT2 (libraryRef VIRTEX))))\n");
fprintf(xnf, "(net U%uN%u (joined"
" (portRef O (instanceRef U%u_L%u))"
" (portRef LI (instanceRef U%u_X%u))))\n",
edif_uref, nref++, edif_uref, idx, edif_uref, idx);
fprintf(xnf, "(net U%uN%u (joined"
" (portRef CI (instanceRef U%u_X%u))"
" (portRef LO (instanceRef U%u_M%u))))\n",
edif_uref, nref++, edif_uref, idx, edif_uref, idx-1);
sprintf(jbuf, "(portRef I0 (instanceRef U%u_L%u))",
edif_uref, idx);
edif_set_nexus_joint(ivl_lpm_data(net, idx), jbuf);
sprintf(jbuf, "(portRef I1 (instanceRef U%u_L%u))",
edif_uref, idx);
edif_set_nexus_joint(ivl_lpm_datab(net, idx), jbuf);
sprintf(jbuf, "(portRef DI (instanceRef U%u_M%u))",
edif_uref, idx);
edif_set_nexus_joint(ivl_lpm_data(net, idx), jbuf);
sprintf(jbuf, "(portRef LO (instanceRef U%u_M%u))",
edif_uref, idx);
edif_set_nexus_joint(ivl_lpm_q(net, 0), jbuf);
}
/*
* The left shift is implemented as a matrix of MUX2_1 devices. The
* matrix has as many rows as the device width, and a column for each
* select.
*/
static void virtex_show_shiftl(ivl_lpm_t net)
{
char jbuf[64];
unsigned width = ivl_lpm_width(net);
unsigned nsel = 0, swid = 0;
unsigned sdx, qdx;
edif_uref += 1;
/* First, find out how many select inputs we really need. We
can only use the selects that are enough to shift out the
entire width of the device. The excess can be used as an
enable for the last column. When disabled, the last column
emits zeros. */
while (nsel < ivl_lpm_selects(net)) {
nsel += 1;
swid = 1 << nsel;
if (swid >= width)
break;
}
assert(nsel > 0);
/* Draw the gates of the matrix, and connect the select inputs
up the columns. Column 0 is the first to see the input
data, so it gets select[0], and so on. */
for (sdx = 0 ; sdx < nsel ; sdx += 1) {
unsigned lutn = 3;
if ( (sdx == (nsel-1)) && (nsel < ivl_lpm_selects(net)))
lutn = 4;
for (qdx = 0 ; qdx < width ; qdx += 1) {
fprintf(xnf, "(instance U%uC%uR%u"
" (viewRef net"
" (cellRef LUT%u (libraryRef VIRTEX)))"
" (property INIT (string \"CA\")))\n",
edif_uref, sdx, qdx, lutn);
sprintf(jbuf, "(portRef I2 (instanceRef U%uC%uR%u))",
edif_uref, sdx, qdx);
edif_set_nexus_joint(ivl_lpm_select(net, sdx), jbuf);
/* If this is the last column, and there are
excess selects to account for, then connect the
I3 inputs of the LUT4 devices to the excess
select, to act as an enable. */
if (lutn == 4) {
assert((nsel + 1) == ivl_lpm_selects(net));
sprintf(jbuf, "(portRef I3 (instanceRef U%uC%uR%u))",
edif_uref, sdx, qdx);
edif_set_nexus_joint(ivl_lpm_select(net, nsel), jbuf);
}
}
}
/* Connect the output of the matrix to the outputs of the
shiftl. */
for (qdx = 0 ; qdx < width ; qdx += 1) {
sprintf(jbuf, "(portRef O (instanceRef U%uC%uR%u))",
edif_uref, nsel-1, qdx);
edif_set_nexus_joint(ivl_lpm_q(net, qdx), jbuf);
}
/* Connect the input of the matrix to the inputs of the
shiftl. The B inputs of the input column MUXes also get the
inputs shifted up 1. */
for (qdx = 0 ; qdx < width ; qdx += 1) {
sprintf(jbuf, "(portRef I0 (instanceRef U%uC%uR%u))",
edif_uref, 0, qdx);
edif_set_nexus_joint(ivl_lpm_data(net, qdx), jbuf);
if (qdx < (width-1)) {
sprintf(jbuf, "(portRef I1 (instanceRef U%uC%uR%u))",
edif_uref, 0, qdx+1);
edif_set_nexus_joint(ivl_lpm_data(net, qdx), jbuf);
}
}
/* Connect the B side 0 padding to the input column. */
fprintf(xnf, "(instance U%uC%uP"
" (viewRef net"
" (cellRef GND (libraryRef VIRTEX))))\n",
edif_uref, 0);
fprintf(xnf, "(net U%uC0PN (joined"
" (portRef I1 (instanceRef U%uC0R0))"
" (portRef GROUND (instanceRef U%uC0P))))\n",
edif_uref, edif_uref, edif_uref);
/* Connect the sdx column outputs to the sdx+1 column
inputs. This includes the A side which is straight
through, and the B side which is shifted based on the
selector identity. */
for (sdx = 0 ; sdx < (nsel-1) ; sdx += 1) {
unsigned shift = 1 << sdx;
for (qdx = 0 ; qdx < shift ; qdx += 1) {
fprintf(xnf, "(net U%uC%uR%uN (joined"
" (portRef O (instanceRef U%uC%uR%u))"
" (portRef I0 (instanceRef U%uC%uR%u))))\n",
edif_uref, sdx, qdx,
edif_uref, sdx+1, qdx,
edif_uref, sdx+1, qdx);
fprintf(xnf, "(instance U%uC%uR%uG"
" (viewRef net"
" (cellRef GND (libraryRef VIRTEX))))\n",
edif_uref, sdx+1, qdx);
fprintf(xnf, "(net U%uC%uR%uGN (joined"
" (portRef I1 (instanceRef U%uC%uR%u))"
" (portRef GROUND (instanceRef U%uC%uR%uG))))\n",
edif_uref, sdx+1, qdx,
edif_uref, sdx+1, qdx,
edif_uref, sdx+1, qdx);
}
for (qdx = shift ; qdx < width ; qdx += 1) {
fprintf(xnf, "(net U%uC%uR%uN (joined"
" (portRef O (instanceRef U%uC%uR%u))"
" (portRef I0 (instanceRef U%uC%uR%u))"
" (portRef I1 (instancdRef U%uC%uR%u))))\n",
edif_uref, sdx, qdx,
edif_uref, sdx, qdx,
edif_uref, sdx+1, qdx,
edif_uref, sdx+1, qdx - shift);
}
}
}
const struct device_s d_virtex_edif = {
edif_show_header,
edif_show_footer,
@@ -1290,13 +1591,21 @@ const struct device_s d_virtex_edif = {
edif_show_generic_dff,
edif_show_virtex_eq,
edif_show_virtex_eq,
virtex_show_cmp_ge,
edif_show_virtex_mux,
edif_show_virtex_add
edif_show_virtex_add,
edif_show_virtex_add,
virtex_show_shiftl,
0 /* show_shiftr */
};
/*
* $Log: d-virtex.c,v $
* Revision 1.16 2002/10/28 02:05:56 steve
* Add Virtex code generators for left shift,
* subtraction, and GE comparators.
*
* Revision 1.15 2002/09/15 21:52:19 steve
* Generate code for 8:1 muxes msing F5 and F6 muxes.
*
@@ -1317,37 +1626,5 @@ const struct device_s d_virtex_edif = {
*
* Revision 1.9 2001/09/16 01:48:16 steve
* Suppor the PAD attribute on signals.
*
* Revision 1.8 2001/09/15 18:27:04 steve
* Make configure detect malloc.h
*
* Revision 1.7 2001/09/15 05:06:04 steve
* Support != in virtex code generator.
*
* Revision 1.6 2001/09/14 04:17:20 steve
* Add XOR and XNOR gates.
*
* Revision 1.5 2001/09/12 04:35:25 steve
* Xilinx uses GROUND and VCC as pin names for the
* GND and VCC devices.
*
* Connect the top end of the EQ chain to the MUXCY
* instead of to the LUT. The MUXCY has the real output.
*
* Revision 1.4 2001/09/11 05:52:31 steve
* Use carry mux to implement wide identity compare,
* Place property item in correct place in LUT cell list.
*
* Revision 1.3 2001/09/10 03:48:34 steve
* Add 4 wide identity compare.
*
* Revision 1.2 2001/09/09 22:23:28 steve
* Virtex support for mux devices and adders
* with carry chains. Also, make Virtex specific
* implementations of primitive logic.
*
* Revision 1.1 2001/09/06 04:28:40 steve
* Separate the virtex and generic-edif code generators.
*
*/
+10 -1
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: device.h,v 1.9 2002/08/12 01:35:02 steve Exp $"
#ident "$Id: device.h,v 1.10 2002/10/28 02:05:56 steve Exp $"
#endif
# include <ivl_target.h>
@@ -50,10 +50,15 @@ struct device_s {
/* These methods show various comparators */
void (*show_cmp_eq)(ivl_lpm_t net);
void (*show_cmp_ne)(ivl_lpm_t net);
void (*show_cmp_ge)(ivl_lpm_t net);
/* This method draws MUX devices */
void (*show_mux)(ivl_lpm_t net);
/* This method draws ADD devices */
void (*show_add)(ivl_lpm_t net);
void (*show_sub)(ivl_lpm_t net);
/* These methods draw SHIFT devices */
void (*show_shiftl)(ivl_lpm_t net);
void (*show_shiftr)(ivl_lpm_t net);
};
/*
@@ -68,6 +73,10 @@ extern device_t device_from_arch(const char*arch);
/*
* $Log: device.h,v $
* Revision 1.10 2002/10/28 02:05:56 steve
* Add Virtex code generators for left shift,
* subtraction, and GE comparators.
*
* Revision 1.9 2002/08/12 01:35:02 steve
* conditional ident string using autoconfig.
*
+41 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: gates.c,v 1.9 2002/08/12 01:35:03 steve Exp $"
#ident "$Id: gates.c,v 1.10 2002/10/28 02:05:56 steve Exp $"
#endif
# include <ivl_target.h>
@@ -42,6 +42,15 @@ static void show_gate_lpm(ivl_lpm_t net)
device->show_add(net);
break;
case IVL_LPM_SUB:
if (device->show_sub == 0) {
fprintf(stderr, "fpga.tgt: IVL_LPM_SUB not supported"
" by this target.\n");
return;
}
device->show_sub(net);
break;
case IVL_LPM_CMP_EQ:
if (device->show_cmp_eq == 0) {
fprintf(stderr, "fpga.tgt: IVL_LPM_CMP_EQ not supported"
@@ -60,6 +69,15 @@ static void show_gate_lpm(ivl_lpm_t net)
device->show_cmp_ne(net);
break;
case IVL_LPM_CMP_GE:
if (device->show_cmp_ge == 0) {
fprintf(stderr, "fpga.tgt: IVL_LPM_CMP_GE not supported"
" by this target.\n");
return;
}
device->show_cmp_ge(net);
break;
case IVL_LPM_FF:
if (device->show_dff == 0) {
fprintf(stderr, "fpga.tgt: IVL_LPM_FF not supported"
@@ -78,6 +96,24 @@ static void show_gate_lpm(ivl_lpm_t net)
device->show_mux(net);
break;
case IVL_LPM_SHIFTL:
if (device->show_shiftl == 0) {
fprintf(stderr, "fpga.tgt: IVL_LPM_SHIFTL not supported"
" by this target.\n");
return;
}
device->show_shiftl(net);
break;
case IVL_LPM_SHIFTR:
if (device->show_shiftr == 0) {
fprintf(stderr, "fpga.tgt: IVL_LPM_SHIFTR not supported"
" by this target.\n");
return;
}
device->show_shiftr(net);
break;
default:
fprintf(stderr, "fpga.tgt: unknown LPM type %u\n",
ivl_lpm_type(net));
@@ -100,6 +136,10 @@ int show_scope_gates(ivl_scope_t net, void*x)
/*
* $Log: gates.c,v $
* Revision 1.10 2002/10/28 02:05:56 steve
* Add Virtex code generators for left shift,
* subtraction, and GE comparators.
*
* Revision 1.9 2002/08/12 01:35:03 steve
* conditional ident string using autoconfig.
*
+9 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: stub.c,v 1.69 2002/09/26 03:18:04 steve Exp $"
#ident "$Id: stub.c,v 1.70 2002/10/23 01:45:24 steve Exp $"
#endif
# include "config.h"
@@ -195,9 +195,12 @@ static void show_lpm(ivl_lpm_t net)
fprintf(out, " Aclr: %s\n",
ivl_nexus_name(ivl_lpm_async_clr(net)));
if (ivl_lpm_async_set(net))
if (ivl_lpm_async_set(net)) {
fprintf(out, " Aset: %s\n",
ivl_nexus_name(ivl_lpm_async_set(net)));
if (ivl_lpm_aset_value(net))
show_expression(ivl_lpm_aset_value(net), 10);
}
for (idx = 0 ; idx < width ; idx += 1)
fprintf(out, " Data %u: %s\n", idx,
@@ -725,6 +728,10 @@ int target_design(ivl_design_t des)
/*
* $Log: stub.c,v $
* Revision 1.70 2002/10/23 01:45:24 steve
* Fix synth2 handling of aset/aclr signals where
* flip-flops are split by begin-end blocks.
*
* Revision 1.69 2002/09/26 03:18:04 steve
* Generate vvp code for asynch set/reset of NetFF.
*
+22 -3
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: eval_expr.c,v 1.81 2002/09/27 20:24:42 steve Exp $"
#ident "$Id: eval_expr.c,v 1.82 2002/10/20 02:55:37 steve Exp $"
#endif
# include "vvp_priv.h"
@@ -842,6 +842,7 @@ static struct vector_info draw_binary_expr(ivl_expr_t exp,
int stuff_ok_flag)
{
struct vector_info rv;
int stuff_ok_used_flag = 0;
switch (ivl_expr_opcode(exp)) {
case 'a': /* && (logical and) */
@@ -853,6 +854,7 @@ static struct vector_info draw_binary_expr(ivl_expr_t exp,
case 'N': /* !== */
case 'n': /* != */
rv = draw_binary_expr_eq(exp, wid, stuff_ok_flag);
stuff_ok_used_flag = 1;
break;
case '<':
@@ -860,6 +862,7 @@ static struct vector_info draw_binary_expr(ivl_expr_t exp,
case 'L': /* <= */
case 'G': /* >= */
rv = draw_binary_expr_le(exp, wid, stuff_ok_flag);
stuff_ok_used_flag = 1;
break;
case '+':
@@ -894,8 +897,21 @@ static struct vector_info draw_binary_expr(ivl_expr_t exp,
assert(0);
}
if ((rv.base >= 8) && (! stuff_ok_flag))
save_expression_lookaside(rv.base, exp, wid);
/* Mark in the lookaside that this value is done. If any OK
flags besides the STUFF_OK_47 flag are set, then the result
may not be a pure one, so clear the lookaside for the range
instead of setting in to the new expression result.
The stuff_ok_used_flag tells me if the stuff_ok_flag was
even used by anything. If not, then I can ignore it in the
following logic. */
if (rv.base >= 8) {
if (stuff_ok_used_flag && (stuff_ok_flag & ~STUFF_OK_47))
save_expression_lookaside(rv.base, 0, wid);
else
save_expression_lookaside(rv.base, exp, wid);
}
return rv;
}
@@ -1852,6 +1868,9 @@ struct vector_info draw_eval_expr(ivl_expr_t exp, int stuff_ok_flag)
/*
* $Log: eval_expr.c,v $
* Revision 1.82 2002/10/20 02:55:37 steve
* Properly set or clear expression lookaside for binary expressions.
*
* Revision 1.81 2002/09/27 20:24:42 steve
* Allow expression lookaside map to spam statements.
*
+38 -12
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvp_scope.c,v 1.79 2002/09/26 03:18:04 steve Exp $"
#ident "$Id: vvp_scope.c,v 1.80 2002/10/23 04:39:35 steve Exp $"
#endif
# include "vvp_priv.h"
@@ -1284,20 +1284,34 @@ static void draw_lpm_eq(ivl_lpm_t net)
*/
static void draw_lpm_ff(ivl_lpm_t net)
{
ivl_expr_t aset_expr = 0;
const char*aset_bits = 0;
unsigned width, idx;
width = ivl_lpm_width(net);
/* Q C CE D RS --> Q+ */
fprintf(vvp_out, "L_%s/def .udp/sequ \"DFF\", 5, 2,"
" \"?r10000\","
" \"?r11001\","
" \"?f1?00-\","
" \"?\?1?00-\","
" \"?*0\?00-\","
" \"????1?0\","
" \"????011\""
" \"?" "r" "1" "0" "00" "0\","
" \"?" "r" "1" "1" "00" "1\","
" \"?" "r" "1" "x" "00" "x\","
" \"0" "r" "x" "0" "00" "0\","
" \"1" "r" "x" "1" "00" "1\","
" \"?" "*" "0" "?" "00" "-\","
" \"?" "_" "?" "?" "00" "-\","
" \"?" "?" "?" "?" "01" "1\","
" \"?" "?" "?" "?" "1?" "0\","
" \"?" "?" "1" "?" "00" "-\","
" \"?" "?" "?" "?" "00" "-\""
";\n", vvp_mangle_id(ivl_lpm_name(net)));
aset_expr = ivl_lpm_aset_value(net);
if (aset_expr) {
assert(ivl_expr_width(aset_expr) == width);
aset_bits = ivl_expr_bits(aset_expr);
}
for (idx = 0 ; idx < width ; idx += 1) {
ivl_nexus_t tmp;
@@ -1321,17 +1335,26 @@ static void draw_lpm_ff(ivl_lpm_t net)
fprintf(vvp_out, ", ");
draw_input_from_net(tmp);
/* Connect reset input */
/* Connect reset input. This may be the Aclr input, or
an Aset to zero. */
fprintf(vvp_out, ", ");
tmp = ivl_lpm_async_clr(net);
if (tmp)
if (tmp) {
draw_input_from_net(tmp);
else
fprintf(vvp_out, "C<0>");
} else {
tmp = ivl_lpm_async_set(net);
if (aset_bits && (aset_bits[idx] == '0'))
draw_input_from_net(tmp);
else
fprintf(vvp_out, "C<0>");
}
/* Connect set input */
fprintf(vvp_out, ", ");
tmp = ivl_lpm_async_set(net);
if (aset_bits && (aset_bits[idx] != '1'))
tmp = 0;
if (tmp)
draw_input_from_net(tmp);
else
@@ -1569,6 +1592,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
/*
* $Log: vvp_scope.c,v $
* Revision 1.80 2002/10/23 04:39:35 steve
* draw lpm ff with aset_expr taken into account.
*
* Revision 1.79 2002/09/26 03:18:04 steve
* Generate vvp code for asynch set/reset of NetFF.
*
+3 -3
View File
@@ -1,10 +1,10 @@
Summary: Icarus Verilog
Name: verilog
Version: 0.6.20021019
Version: 0.6.20021027
Release: 0
Copyright: GPL
Group: Applications/Engineering
Source: ftp://icarus.com/pub/eda/verilog/snapshots/verilog-20021019.tar.gz
Source: ftp://icarus.com/pub/eda/verilog/snapshots/verilog-20021027.tar.gz
URL: http://www.icarus.com/eda/verilog/index.html
Packager: Stephen Williams <[email protected]>
@@ -20,7 +20,7 @@ engineering formats, including simulation. It strives to be true
to the IEEE-1364 standard.
%prep
%setup -n verilog-20021019
%setup -n verilog-20021027
%build
./configure --prefix=/usr