/* aset is zero if there's no aset input at all or (there's a set input and values !=NULL and this bit of aset_value sets to 0). */ static int aset_zero (ivl_lpm_t ff, int idx) { return (NULL == ivl_lpm_async_set (ff)) || (ivl_lpm_async_set (ff) && (ivl_lpm_aset_value (ff) != NULL) && (ivl_expr_bits (ivl_lpm_aset_value (ff))[idx] == '0')); }
/* * primitive FD (q, clk, ce, d); * output q; * reg q; * input clk, ce, d; * table * // clk ce d r s q q+ * r 1 0 0 0 : ? : 0; * r 1 1 0 0 : ? : 1; * f 1 ? 0 0 : ? : -; * ? 1 ? 0 0 : ? : -; * * 0 ? 0 0 : ? : -; * ? ? ? 1 ? : ? : 0; * ? ? ? 0 1 : ? : 1; * endtable * endprimitive */ static void draw_lpm_ff(ivl_lpm_t net) { ivl_expr_t aset_expr = 0; const char*aset_bits = 0; ivl_nexus_t nex; unsigned width; width = ivl_lpm_width(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); } fprintf(vvp_out, "L_%p .dff ", net); nex = ivl_lpm_data(net,0); assert(nex); fprintf(vvp_out, "%s", draw_net_input(nex)); nex = ivl_lpm_clk(net); assert(nex); fprintf(vvp_out, ", %s", draw_net_input(nex)); nex = ivl_lpm_enable(net); if (nex) { fprintf(vvp_out, ", %s", draw_net_input(nex)); } else { fprintf(vvp_out, ", C4<1>"); } /* Stub asynchronous input for now. */ fprintf(vvp_out, ", C4<z>"); fprintf(vvp_out, ";\n"); }
/* aclr is zero if there's no aclr input or (there's a set input and (aset_value ==NULL or aset_value bit of 1)) */ static int aclr_zero (ivl_lpm_t ff, int idx) { return (NULL == ivl_lpm_async_clr (ff)) || (ivl_lpm_async_set (ff) && ((ivl_lpm_aset_value (ff) == NULL) || /*does this work? */ (ivl_expr_bits (ivl_lpm_aset_value (ff))[idx] == '1'))); }
void virtex_generic_dff(ivl_lpm_t net) { unsigned idx; ivl_nexus_t aclr = ivl_lpm_async_clr(net); ivl_nexus_t aset = ivl_lpm_async_set(net); ivl_nexus_t sclr = ivl_lpm_sync_clr(net); ivl_nexus_t sset = ivl_lpm_sync_set(net); const char*abits = 0; if (aset) { ivl_expr_t avalue = ivl_lpm_aset_value(net); assert(avalue); abits = ivl_expr_bits(avalue); assert(abits); } /* XXXX Can't handle both synchronous and asynchronous clear. */ assert( ! (aclr && sclr) ); /* XXXX Can't handle synchronous set at all. */ assert( ! sset ); for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { edif_cellref_t obj; ivl_nexus_t nex; edif_joint_t jnt; /* If there is a preset, then select an FDCPE instead of an FDCE device. */ if (aset && (abits[idx] == '1')) { obj = edif_cellref_create(edf, xilinx_cell_fdcpe(xlib)); } else if (aclr) { obj = edif_cellref_create(edf, xilinx_cell_fdce(xlib)); } else if (sclr) { obj = edif_cellref_create(edf, xilinx_cell_fdre(xlib)); } else { obj = edif_cellref_create(edf, xilinx_cell_fdce(xlib)); } jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, idx)); edif_add_to_joint(jnt, obj, FDCE_Q); jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, idx)); edif_add_to_joint(jnt, obj, FDCE_D); jnt = edif_joint_of_nexus(edf, ivl_lpm_clk(net)); edif_add_to_joint(jnt, obj, FDCE_C); if ( (nex = ivl_lpm_enable(net)) ) { jnt = edif_joint_of_nexus(edf, nex); edif_add_to_joint(jnt, obj, FDCE_CE); } if (aclr) { jnt = edif_joint_of_nexus(edf, aclr); edif_add_to_joint(jnt, obj, FDCE_CLR); } else if (sclr) { jnt = edif_joint_of_nexus(edf, sclr); edif_add_to_joint(jnt, obj, FDCE_CLR); } if (aset) { if (abits[idx] == '1') { jnt = edif_joint_of_nexus(edf, aset); edif_add_to_joint(jnt, obj, FDCE_PRE); } else { assert(aclr == 0); jnt = edif_joint_of_nexus(edf, aset); edif_add_to_joint(jnt, obj, FDCE_CLR); } } } }
static void edif_show_generic_dff(ivl_lpm_t net) { ivl_nexus_t nex; char jbuf[1024]; unsigned idx; ivl_nexus_t aclr = ivl_lpm_async_clr(net); ivl_nexus_t aset = ivl_lpm_async_set(net); ivl_expr_t avalue = 0; const char*abits = 0; const char*fdcell = "FDCE"; if (aset != 0) { fdcell = "FDCPE"; avalue = ivl_lpm_aset_value(net); assert(avalue); abits = ivl_expr_bits(avalue); assert(abits); } for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { edif_uref += 1; fprintf(xnf, "(instance (rename U%u \"%s.%s[%u]\")", edif_uref, ivl_scope_name(ivl_lpm_scope(net)), ivl_lpm_basename(net), idx); fprintf(xnf, " (viewRef net" " (cellRef %s (libraryRef VIRTEX))))\n", fdcell); nex = ivl_lpm_q(net, idx); sprintf(jbuf, "(portRef Q (instanceRef U%u))", edif_uref); edif_set_nexus_joint(nex, jbuf); nex = ivl_lpm_data(net, idx); sprintf(jbuf, "(portRef D (instanceRef U%u))", edif_uref); edif_set_nexus_joint(nex, jbuf); nex = ivl_lpm_clk(net); sprintf(jbuf, "(portRef C (instanceRef U%u))", edif_uref); edif_set_nexus_joint(nex, jbuf); if ((nex = ivl_lpm_enable(net))) { sprintf(jbuf, "(portRef CE (instanceRef U%u))", edif_uref); edif_set_nexus_joint(nex, jbuf); } if (aclr) { sprintf(jbuf, "(portRef CLR (instanceRef U%u))", edif_uref); edif_set_nexus_joint(aclr, jbuf); } if (aset) { if (abits[idx] == '1') { sprintf(jbuf, "(portRef PRE (instanceRef U%u))", edif_uref); edif_set_nexus_joint(aset, jbuf); } else { assert(aclr == 0); sprintf(jbuf, "(portRef CLR (instanceRef U%u))", edif_uref); edif_set_nexus_joint(aset, jbuf); } } } }