diff --git a/ivl.def b/ivl.def index 2467f695a..274a14284 100644 --- a/ivl.def +++ b/ivl.def @@ -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 diff --git a/ivl_target.h b/ivl_target.h index e9a68579c..b7eefdf46 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -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. * diff --git a/synth2.cc b/synth2.cc index d912e152e..299e7e57a 100644 --- a/synth2.cc +++ b/synth2.cc @@ -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. * diff --git a/t-dll-api.cc b/t-dll-api.cc index 1214861d2..bcc48784b 100644 --- a/t-dll-api.cc +++ b/t-dll-api.cc @@ -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. * diff --git a/t-dll.cc b/t-dll.cc index 72dfecd7b..7f0c5578a 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -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. * diff --git a/t-dll.h b/t-dll.h index 5db0bdc94..db2067a6d 100644 --- a/t-dll.h +++ b/t-dll.h @@ -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. * diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index f67f7cbaa..c686216ce 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -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. * diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index b90d24465..7c496d878 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -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. *