Add support for negedge FFs by using attributes.

This commit is contained in:
steve 2006-02-25 05:03:28 +00:00
parent 27e633410c
commit 79cb8c883a
8 changed files with 159 additions and 38 deletions

View File

@ -62,6 +62,8 @@ ivl_logic_udp
ivl_lpm_aset_value
ivl_lpm_async_clr
ivl_lpm_async_set
ivl_lpm_attr_cnt
ivl_lpm_attr_val
ivl_lpm_basename
ivl_lpm_clk
ivl_lpm_data

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.126.2.1 2006/02/19 00:11:31 steve Exp $"
#ident "$Id: ivl_target.h,v 1.126.2.2 2006/02/25 05:03:28 steve Exp $"
#endif
#ifdef __cplusplus
@ -630,6 +630,11 @@ extern const char* ivl_udp_name(ivl_udp_t net);
* the LPM type, but it generally has to do with the width of the
* output data path.
*
* ivl_lpm_attr_cnt
* ivl_lpm_attr_val
* These functions access attributes attached to LPM devices. These
* attributes may be explicit attributes collected from the Verilog
* source, or implicit attributes generated by the compiler.
*
* These functions apply to a subset of the LPM devices, or may have
* varying meaning depending on the device:
@ -667,11 +672,19 @@ extern const char* ivl_udp_name(ivl_udp_t net);
*
* SEMANTIC NOTES:
*
* - IVL_LPM_FF
* The IVL_LPM_FF and IVL_LPM_DECODE devices are closely related. If
* the ivl_lpm_decode function returns a non-nil value, then the
* decoder represents an extra ENABLE-like input, where exactly one(1)
* bit of the width of the FF is enabled. The decoder inputs are and
* address that selects the FF to be enabled.
*
* The core compiler generates these attributes in certain cases:
*
* - ivl:clock_polarity
* If present, the string value can be "INVERT". That indicates
* that the clock is negedge sensitive instead of the default
* posedge sensitive.
*/
extern const char* ivl_lpm_name(ivl_lpm_t net); /* (Obsolete) */
@ -681,6 +694,9 @@ extern int ivl_lpm_signed(ivl_lpm_t net);
extern ivl_lpm_type_t ivl_lpm_type(ivl_lpm_t net);
extern unsigned ivl_lpm_width(ivl_lpm_t net);
extern unsigned ivl_lpm_attr_cnt(ivl_lpm_t net);
extern ivl_attribute_t ivl_lpm_attr_val(ivl_lpm_t net, unsigned idx);
/* 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);
@ -1252,6 +1268,9 @@ _END_DECL
/*
* $Log: ivl_target.h,v $
* Revision 1.126.2.2 2006/02/25 05:03:28 steve
* Add support for negedge FFs by using attributes.
*
* Revision 1.126.2.1 2006/02/19 00:11:31 steve
* Handle synthesis of FF vectors with l-value decoder.
*

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.39.2.21 2006/02/19 00:11:33 steve Exp $"
#ident "$Id: synth2.cc,v 1.39.2.22 2006/02/25 05:03:29 steve Exp $"
#endif
# include "config.h"
@ -1458,7 +1458,7 @@ bool NetEvWait::synth_sync(Design*des, NetScope*scope,
NetFF*ff = nex_ff[0].ff;
connect(ff->pin_Clock(), pclk->pin(0));
if (pclk->edge() == NetEvProbe::NEGEDGE)
ff->attribute(perm_string::literal("Clock:LPM_Polarity"), verinum("INVERT"));
ff->attribute(perm_string::literal("ivl:clock_polarity"), verinum("INVERT"));
/* Synthesize the input to the DFF. */
bool flag = statement_->synth_sync(des, scope, nex_ff,
@ -1639,6 +1639,9 @@ void synth2(Design*des)
/*
* $Log: synth2.cc,v $
* Revision 1.39.2.22 2006/02/25 05:03:29 steve
* Add support for negedge FFs by using attributes.
*
* Revision 1.39.2.21 2006/02/19 00:11:33 steve
* Handle synthesis of FF vectors with l-value decoder.
*

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.108.2.1 2006/02/19 00:11:33 steve Exp $"
#ident "$Id: t-dll-api.cc,v 1.108.2.2 2006/02/25 05:03:29 steve Exp $"
#endif
# include "config.h"
@ -620,6 +620,19 @@ extern "C" const char* ivl_udp_name(ivl_udp_t net)
return net->name;
}
extern "C" unsigned ivl_lpm_attr_cnt(ivl_lpm_t net)
{
return net->nattr;
}
extern "C" ivl_attribute_t ivl_lpm_attr_val(ivl_lpm_t net, unsigned idx)
{
if (idx >= net->nattr)
return 0;
else
return net->attr + idx;
}
extern "C" const char* ivl_lpm_basename(ivl_lpm_t net)
{
return net->name;
@ -1951,6 +1964,9 @@ extern "C" ivl_variable_type_t ivl_variable_type(ivl_variable_t net)
/*
* $Log: t-dll-api.cc,v $
* Revision 1.108.2.2 2006/02/25 05:03:29 steve
* Add support for negedge FFs by using attributes.
*
* Revision 1.108.2.1 2006/02/19 00:11:33 steve
* Handle synthesis of FF vectors with l-value decoder.
*

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.131.2.3 2006/02/19 00:11:34 steve Exp $"
#ident "$Id: t-dll.cc,v 1.131.2.4 2006/02/25 05:03:29 steve Exp $"
#endif
# include "config.h"
@ -967,6 +967,8 @@ bool dll_target::net_function(const NetUserFunc*net)
obj->type = IVL_LPM_UFUNC;
obj->name = net->name();
obj->scope = find_scope(des_, net->scope());
obj->attr = 0;
obj->nattr = 0;
assert(obj->scope);
/* Get the definition of the function and save it. */
@ -1109,6 +1111,8 @@ void dll_target::lpm_add_sub(const NetAddSub*net)
obj->name = net->name(); // NetAddSub names are permallocated
assert(net->scope());
obj->scope = find_scope(des_, net->scope());
obj->attr = 0;
obj->nattr = 0;
assert(obj->scope);
obj->u_.arith.signed_flag = 0;
@ -1178,6 +1182,8 @@ void dll_target::lpm_clshift(const NetCLShift*net)
ivl_lpm_t obj = new struct ivl_lpm_s;
obj->type = IVL_LPM_SHIFTL;
obj->name = net->name();
obj->attr = 0;
obj->nattr = 0;
assert(net->scope());
obj->scope = find_scope(des_, net->scope());
assert(obj->scope);
@ -1245,6 +1251,8 @@ void dll_target::lpm_clshift(const NetCLShift*net)
void dll_target::lpm_compare(const NetCompare*net)
{
ivl_lpm_t obj = new struct ivl_lpm_s;
obj->attr = 0;
obj->nattr = 0;
obj->name = net->name(); // NetCompare names are permallocated
assert(net->scope());
obj->scope = find_scope(des_, net->scope());
@ -1359,6 +1367,8 @@ void dll_target::lpm_divide(const NetDivide*net)
ivl_lpm_t obj = new struct ivl_lpm_s;
obj->type = IVL_LPM_DIVIDE;
obj->name = net->name();
obj->attr = 0;
obj->nattr = 0;
assert(net->scope());
obj->scope = find_scope(des_, net->scope());
assert(obj->scope);
@ -1429,6 +1439,8 @@ void dll_target::lpm_modulo(const NetModulo*net)
ivl_lpm_t obj = new struct ivl_lpm_s;
obj->type = IVL_LPM_MOD;
obj->name = net->name();
obj->attr = 0;
obj->nattr = 0;
assert(net->scope());
obj->scope = find_scope(des_, net->scope());
assert(obj->scope);
@ -1504,6 +1516,8 @@ ivl_lpm_t dll_target::lpm_decode_ff_(const NetDecode*net)
ivl_lpm_t obj = new struct ivl_lpm_s;
obj->type = IVL_LPM_DECODE;
obj->name = net->name();
obj->attr = 0;
obj->nattr = 0;
obj->scope = find_scope(des_, net->scope());
obj->u_.mux.swid = net->awidth();
@ -1538,12 +1552,17 @@ void dll_target::lpm_ff(const NetFF*net)
ivl_lpm_t obj = new struct ivl_lpm_s;
obj->type = IVL_LPM_FF;
obj->name = net->name();
obj->attr = 0;
obj->nattr = 0;
obj->scope = find_scope(des_, net->scope());
obj->u_.ff.a.decode = lpm_decode_ff_(net->get_demux());
assert(obj->scope);
obj->u_.ff.width = net->width();
obj->nattr = net->attr_cnt();
obj->attr = fill_in_attributes(net);
scope_add_lpm(obj->scope, obj);
const Nexus*nex;
@ -1655,6 +1674,8 @@ void dll_target::lpm_ram_dq(const NetRamDq*net)
ivl_lpm_t obj = new struct ivl_lpm_s;
obj->type = IVL_LPM_RAM;
obj->name = net->name();
obj->attr = 0;
obj->nattr = 0;
obj->u_.ff.a.mem = find_memory(des_, net->mem());
assert(obj->u_.ff.a.mem);
obj->scope = find_scope(des_, net->mem()->scope());
@ -1769,6 +1790,8 @@ void dll_target::lpm_mult(const NetMult*net)
ivl_lpm_t obj = new struct ivl_lpm_s;
obj->type = IVL_LPM_MULT;
obj->name = net->name();
obj->attr = 0;
obj->nattr = 0;
assert(net->scope());
obj->scope = find_scope(des_, net->scope());
assert(obj->scope);
@ -1849,6 +1872,8 @@ void dll_target::lpm_mux(const NetMux*net)
ivl_lpm_t obj = new struct ivl_lpm_s;
obj->type = IVL_LPM_MUX;
obj->name = net->name(); // NetMux names are permallocated
obj->attr = 0;
obj->nattr = 0;
obj->scope = find_scope(des_, net->scope());
assert(obj->scope);
@ -2225,6 +2250,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
/*
* $Log: t-dll.cc,v $
* Revision 1.131.2.4 2006/02/25 05:03:29 steve
* Add support for negedge FFs by using attributes.
*
* Revision 1.131.2.3 2006/02/19 00:11:34 steve
* Handle synthesis of FF vectors with l-value decoder.
*

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.115.2.1 2006/02/19 00:11:34 steve Exp $"
#ident "$Id: t-dll.h,v 1.115.2.2 2006/02/25 05:03:30 steve Exp $"
#endif
# include "target.h"
@ -293,6 +293,9 @@ struct ivl_lpm_s {
ivl_scope_t scope;
perm_string name;
struct ivl_attribute_s*attr;
unsigned nattr;
union {
struct ivl_lpm_ff_s {
unsigned width;
@ -690,6 +693,9 @@ struct ivl_variable_s {
/*
* $Log: t-dll.h,v $
* Revision 1.115.2.2 2006/02/25 05:03:30 steve
* Add support for negedge FFs by using attributes.
*
* Revision 1.115.2.1 2006/02/19 00:11:34 steve
* Handle synthesis of FF vectors with l-value decoder.
*

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.90.2.5 2006/02/19 00:11:34 steve Exp $"
#ident "$Id: stub.c,v 1.90.2.6 2006/02/25 05:03:30 steve Exp $"
#endif
# include "config.h"
@ -35,6 +35,23 @@
static FILE*out;
static void show_attribute(ivl_attribute_t attr, unsigned ind)
{
switch (attr->type) {
case IVL_ATT_VOID:
fprintf(out, "%*s(* %s *)\n", ind,"", attr->key);
break;
case IVL_ATT_STR:
fprintf(out, "%*s(* %s = \"%s\" *)\n", ind,"", attr->key,
attr->val.str);
break;
case IVL_ATT_NUM:
fprintf(out, "%*s(* %s = %ld *)\n", ind,"", attr->key,
attr->val.num);
break;
}
}
static void show_expression(ivl_expr_t net, unsigned ind)
{
unsigned idx;
@ -433,6 +450,11 @@ static void show_lpm(ivl_lpm_t net)
ivl_lpm_width(net),
ivl_lpm_signed(net));
}
for (idx = 0 ; idx < ivl_lpm_attr_cnt(net) ; idx += 1) {
ivl_attribute_t atr = ivl_lpm_attr_val(net,idx);
show_attribute(atr, 4);
}
}
static void show_assign_lval(ivl_lval_t lval, unsigned ind)
@ -643,19 +665,7 @@ static int show_process(ivl_process_t net, void*x)
for (idx = 0 ; idx < ivl_process_attr_cnt(net) ; idx += 1) {
ivl_attribute_t attr = ivl_process_attr_val(net, idx);
switch (attr->type) {
case IVL_ATT_VOID:
fprintf(out, " (* %s *)\n", attr->key);
break;
case IVL_ATT_STR:
fprintf(out, " (* %s = \"%s\" *)\n", attr->key,
attr->val.str);
break;
case IVL_ATT_NUM:
fprintf(out, " (* %s = %ld *)\n", attr->key,
attr->val.num);
break;
}
show_attribute(attr,4);
}
show_statement(ivl_process_stmt(net), 4);
@ -1023,6 +1033,9 @@ int target_design(ivl_design_t des)
/*
* $Log: stub.c,v $
* Revision 1.90.2.6 2006/02/25 05:03:30 steve
* Add support for negedge FFs by using attributes.
*
* Revision 1.90.2.5 2006/02/19 00:11:34 steve
* Handle synthesis of FF vectors with l-value decoder.
*

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.103.2.2 2006/02/19 00:11:35 steve Exp $"
#ident "$Id: vvp_scope.c,v 1.103.2.3 2006/02/25 05:03:30 steve Exp $"
#endif
# include "vvp_priv.h"
@ -38,6 +38,18 @@ inline static char hex_digit(unsigned i)
return i>=10 ? i-10+'A' : i+'0';
}
ivl_attribute_t find_lpm_attr(ivl_lpm_t net, const char*key)
{
unsigned idx;
for (idx = 0 ; idx < ivl_lpm_attr_cnt(net) ; idx += 1) {
ivl_attribute_t atr = ivl_lpm_attr_val(net, idx);
if (strcmp(key,atr->key) == 0)
return atr;
}
return 0;
}
const char *vvp_mangle_id(const char *id)
{
static char *out = 0x0;
@ -1304,26 +1316,45 @@ static void draw_lpm_ff(ivl_lpm_t net)
const char*aset_bits = 0;
unsigned width, idx;
ivl_attribute_t clock_pol = find_lpm_attr(net, "ivl:clock_polarity");
width = ivl_lpm_width(net);
/* Q C CE D RS --> Q+ */
fprintf(vvp_out, "L_%s.%s/def .udp/sequ \"DFF\", 5, 2,"
" \"?" "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_scope_name(ivl_lpm_scope(net))),
vvp_mangle_id(ivl_lpm_basename(net)));
if (clock_pol) {
/* Q C CE D RS --> Q+ */
fprintf(vvp_out, "L_%s.%s/def .udp/sequ \"DFF\", 5, 2,"
" \"?" "f" "1" "0" "00" "0\","
" \"?" "f" "1" "1" "00" "1\","
" \"?" "f" "1" "x" "00" "x\","
" \"0" "f" "x" "0" "00" "0\","
" \"1" "f" "x" "1" "00" "1\","
" \"?" "*" "0" "?" "00" "-\","
" \"?" "_" "?" "?" "00" "-\","
" \"?" "?" "?" "?" "01" "1\","
" \"?" "?" "?" "?" "1?" "0\","
" \"?" "?" "1" "?" "00" "-\","
" \"?" "?" "?" "?" "00" "-\""
";\n",
vvp_mangle_id(ivl_scope_name(ivl_lpm_scope(net))),
vvp_mangle_id(ivl_lpm_basename(net)));
} else {
/* Q C CE D RS --> Q+ */
fprintf(vvp_out, "L_%s.%s/def .udp/sequ \"DFF\", 5, 2,"
" \"?" "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_scope_name(ivl_lpm_scope(net))),
vvp_mangle_id(ivl_lpm_basename(net)));
}
aset_expr = ivl_lpm_aset_value(net);
if (aset_expr) {
assert(ivl_expr_width(aset_expr) == width);
@ -1745,6 +1776,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
/*
* $Log: vvp_scope.c,v $
* Revision 1.103.2.3 2006/02/25 05:03:30 steve
* Add support for negedge FFs by using attributes.
*
* Revision 1.103.2.2 2006/02/19 00:11:35 steve
* Handle synthesis of FF vectors with l-value decoder.
*