mirror of
https://github.com/steveicarus/iverilog.git
synced 2026-08-27 08:16:13 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c66d319d9c | ||
|
|
ae27165ffe | ||
|
|
32f1ca6f8b | ||
|
|
9ce2806710 | ||
|
|
3d4593d4d5 | ||
|
|
df5ae54ec7 | ||
|
|
fbee1b424d |
+7
-2
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user