Пример #1
0
/*
the flipflop I get:
LPM_FF: _s12 scope=main aset_value='d0
    0 pin0 I (strong0 strong1): 0x86abca0 main.clk
    1 pin1 I (strong0 strong1):.
    2 pin2 I (strong0 strong1):.
    3 pin3 I (strong0 strong1):.
    4 pin4 I (strong0 strong1):.
    5 pin5 I (strong0 strong1):.
    6 pin6 I (strong0 strong1): 0x86cf6c0 main.D
    7 pin7 O (strong0 strong1): 0x86acb80 main.Q
    
I assume the unlabeled pins are the set/reset pins etc...
have to figure out which is which...
       netlist.cc:
 *    0  -- Clock
 *    1  -- Enable
 *    2  -- Aset
 *    3  -- Aclr
 *    4  -- Sset
 *    5  -- Sclr
 *    6  -- Data
 *    7  -- Q
 
 
 have to make sure that:
 pin 0 is always clk (rising edge...)
 1 is the enable... either fit in 1 product term or loop throu a output cell
 
 either 
 ASET/SCLR
 or
 ACLR/SSET
 are used
 (but not two sync or two async pins)
 
 have to make sure it uses the right signals, too (ar for async, sp for sync)
 
 the aset_value etc...
 and clock enable are also missing...
 
 supposedly the blif tgt does 
 Q <= Q if ce off..
 and
 Q <= D if ce on..
 
 not sure what aset_value is good for...
 Looks like it never gets set.. default constructor?
 but sset_value is..(synth2.cc) but commented out..
 
 The code path for Sset/Sclr in synth2.cc is commented out...
 
 async reset is not necessarily driven for evey bit.. there's a mask...
 how to get at it?

the sset_value is supposed to be used for wide FFs
seems the set/clr inputs are only 1 bit...
uses clr if aset_value is all zeroes.
Otherwise set is supposed to set the value...
(in synth2.cc, but commented out..)

22V10 can only trigger on posedge 
 */
static void
verify_ff22 (ivl_lpm_t ff, int idx, syn_ctx * pal,int is_async)
{
      ivl_nexus_t cn;
      if(is_async)
	    return;
      if (!aclr_zero (ff, idx))
	    assert (aset_zero (ff, idx));

      if (!aset_zero (ff, idx))
	    assert (aclr_zero (ff, idx));

      assert (NULL == ivl_lpm_sync_set (ff));
      assert (NULL == ivl_lpm_sync_clr (ff));
      assert (0 == ivl_lpm_negedge (ff));

      cn = ivl_lpm_clk (ff);
      /*make sure this is clk */
      assert (cn);
      assert (is_clk (cn, pal));

}
Пример #2
0
// Build the design hierarchy.
int build_hierarchy(ivl_scope_t scope, void* cd)
{
  int return_code;
  unsigned i, j;

  indent();
  fprintf(output, "(scope ");
  quoted_string(ivl_scope_tname(scope));
  fprintf(output, " ");
  quoted_string(ivl_scope_basename(scope));
  fprintf(output, " (\n");

  // Constants (root scope only)
  if (! level)
    for (i = 0; i < ivl_design_consts(design); i++) {
      ivl_net_const_t constant = ivl_design_const(design, i);
      const char* bits = ivl_const_bits(constant);
      unsigned pins = ivl_const_pins(constant);
      unsigned id = new_id();
      indent();
      fprintf(output, "  (const  %i \"", id);
      for (j = pins - 1; j < pins; j--)
        fprintf(output, "%c", bits[j]);
      fprintf(output, "\")\n");
      for (j = 0; j < pins; j++)
        create_bit_select(id_of_nexus(ivl_const_pin(constant, j), 1), pins, j, id);
    }

  // Parameters
  for (i = 0; i < ivl_scope_params(scope); i++) {
    ivl_parameter_t param = ivl_scope_param(scope, i);
    ivl_expr_t param_value = ivl_parameter_expr(param);
    unsigned width = ivl_expr_width(param_value);
    const char* bits;
    unsigned id = new_id();
    indent();
    fprintf(output, "  (const  %i \"", id);
    switch (ivl_expr_type(param_value)) {
      case IVL_EX_STRING : bits = ivl_expr_string(param_value); break;
      case IVL_EX_NUMBER : bits = ivl_expr_bits(param_value);   break;
      default            : fprintf(output, "** ERROR: Unknown parameter type."); return -1;
    }
    for (j = width - 1; j < width; j--)
      fprintf(output, "%c", bits[j]);
    fprintf(output, "\")\n");
    indent();
    fprintf(output, "  (name   %i ", new_id());
    quoted_string(ivl_parameter_basename(param));
    fprintf(output, " %i %i)\n", width, id);
  }

  // Signals
  for (i = 0; i < ivl_scope_sigs(scope); i++) {
    ivl_signal_t sig = ivl_scope_sig(scope, i);
    unsigned pins = ivl_signal_pins(sig);
    ivl_signal_port_t type = ivl_signal_port(sig);
    const char* name = ivl_signal_basename(sig);
    unsigned id;
    if (! level && type == IVL_SIP_INPUT) {
      id = new_id();
      fprintf(output, "  (input  %i \"%s\" %i)\n", id, name, pins);
      for (j = 0; j < pins; j++)
        create_bit_select(id_of_nexus(ivl_signal_pin(sig, j), 1), pins, j, id);
    }
    else if (! level && type == IVL_SIP_INOUT) {
      printf("** ERROR: Inout ports not supported.\n");
    }
    else if (! level && type == IVL_SIP_OUTPUT) {
      id = id_of_nexus(ivl_signal_pin(sig, 0), 0);
      for (j = 1; j < pins; j++) {
        id = create_bit_concat(id, j, ivl_signal_pin(sig, j));
      }
      fprintf(output, "  (output %i \"%s\" %i %i)\n", new_id(), name, pins, id);
    }
    else {
      id = id_of_nexus(ivl_signal_pin(sig, 0), 0);
      for (j = 1; j < pins; j++) {
        id = create_bit_concat(id, j, ivl_signal_pin(sig, j));
      }
      indent();
      fprintf(output, "  (name   %i ", new_id());  //XXX Why is "_s22" getting named?
      quoted_string(name);
      fprintf(output, " %i %i)\n", pins, id);
    }
  }

  // Logic
  for (i = 0; i < ivl_scope_logs(scope); i++) {
    unsigned id;
    ivl_net_logic_t log = ivl_scope_log(scope, i);
    switch (ivl_logic_type(log)) {
      case IVL_LO_BUF:
        indent();
        fprintf(output, "  (buf    %i 1 %i)\n", id_of_nexus(ivl_logic_pin(log, 0), 1), id_of_nexus(ivl_logic_pin(log, 1), 0));
        break;

      case IVL_LO_NOT:
        indent();
        fprintf(output, "  (not    %i 1 %i)\n", id_of_nexus(ivl_logic_pin(log, 0), 1), id_of_nexus(ivl_logic_pin(log, 1), 0));
        break;

      case IVL_LO_AND:
        indent();
        create_multi_gate("and ", id_of_nexus(ivl_logic_pin(log, 0), 1), log);
        break;
      
      case IVL_LO_NAND:
        id = new_id();
        indent();
        create_multi_gate("and ", id, log);
        indent();
        fprintf(output, "  (not    %i 1 %i)\n", id_of_nexus(ivl_logic_pin(log, 0), 1), id);
        break;
      
      case IVL_LO_XOR:
        indent();
        create_multi_gate("xor ", id_of_nexus(ivl_logic_pin(log, 0), 1), log);
        break;
      
      case IVL_LO_XNOR:
        id = new_id();
        indent();
        create_multi_gate("xor ", id, log);
        indent();
        fprintf(output, "  (not    %i 1 %i)\n", id_of_nexus(ivl_logic_pin(log, 0), 1), id);
        break;
      
      case IVL_LO_OR:
        indent();
        create_multi_gate("or  ", id_of_nexus(ivl_logic_pin(log, 0), 1), log);
        break;
      
      case IVL_LO_NOR:
        id = new_id();
        indent();
        create_multi_gate("or  ", id, log);
        indent();
        fprintf(output, "  (not    %i 1 %i)\n", id_of_nexus(ivl_logic_pin(log, 0), 1), id);
        break;

      default:
        printf("** ERROR: Unsupported logic type: %i.\n", ivl_logic_type(log));
        return -1;
    }
  }
  
  // LPMs
  for (i = 0; i < ivl_scope_lpms(scope); i++) {
    ivl_lpm_t lpm = ivl_scope_lpm(scope, i);
    ivl_lpm_type_t lpm_t = ivl_lpm_type(lpm);
    unsigned width   = ivl_lpm_width(lpm);
    unsigned selects;
    unsigned size;
    unsigned id, id1, id2, id3;
    switch (lpm_t) {
      case IVL_LPM_ADD:
        id  = new_id();
        id1 = create_concat_lpm_data(lpm);
        id2 = create_concat_lpm_datab(lpm);
        indent();
        fprintf(output, "  (add    %i %i %i %i)\n", id, width, id1, id2);
        create_split_lpm_q(lpm, id);
        break;

      case IVL_LPM_SUB:
        id  = new_id();
        id1 = create_concat_lpm_data(lpm);
        id2 = create_concat_lpm_datab(lpm);
        indent();
        fprintf(output, "  (sub    %i %i %i %i)\n", id, width, id1, id2);
        create_split_lpm_q(lpm, id);
        break;

      case IVL_LPM_MULT:
        id  = new_id();
        id1 = create_concat_lpm_data(lpm);
        id2 = create_concat_lpm_datab(lpm);
        indent();
        fprintf(output, "  (mul    %i %i %i %i)\n", id, width, id1, id2);
        create_split_lpm_q(lpm, id);
        break;

      case IVL_LPM_CMP_EQ:
        id1 = create_concat_lpm_data(lpm);
        id2 = create_concat_lpm_datab(lpm);
        indent();
        fprintf(output, "  (eq     %i %i %i %i)\n", id_of_nexus(ivl_lpm_q(lpm, 0), 1), width, id1, id2);
        break;

      case IVL_LPM_CMP_NE:
        id1 = create_concat_lpm_data(lpm);
        id2 = create_concat_lpm_datab(lpm);
        id  = new_id();
        indent();
        fprintf(output, "  (eq     %i %i %i %i)\n", id, width, id1, id2);
        indent();
        fprintf(output, "  (not    %i 1 %i)\n", id_of_nexus(ivl_lpm_q(lpm, 0), 1), id);
        break;

      case IVL_LPM_CMP_GT:
        // XXX Check for signed.
        id1 = create_concat_lpm_data(lpm);
        id2 = create_concat_lpm_datab(lpm);
        indent();
        fprintf(output, "  (lt     %i %i %i %i)\n", id_of_nexus(ivl_lpm_q(lpm, 0), 1), width, id2, id1);
        break;

      case IVL_LPM_CMP_GE:
        // XXX Check for signed.
        id1 = create_concat_lpm_data(lpm);
        id2 = create_concat_lpm_datab(lpm);
        id  = new_id();
        indent();
        fprintf(output, "  (lt     %i %i %i %i)\n", id, width, id1, id2);
        indent();
        fprintf(output, "  (not    %i 1 %i)\n", id_of_nexus(ivl_lpm_q(lpm, 0), 1), id);
        break;

      case IVL_LPM_FF:
        {
          ivl_nexus_t async_clr = ivl_lpm_async_clr(lpm);
          ivl_nexus_t async_set = ivl_lpm_async_set(lpm);
          ivl_nexus_t sync_clr = ivl_lpm_sync_clr(lpm);
          ivl_nexus_t sync_set = ivl_lpm_sync_set(lpm);
          ivl_nexus_t clk = ivl_lpm_clk(lpm);
          ivl_nexus_t enable = ivl_lpm_enable(lpm);
          if (async_set || sync_set) { perror("** ERROR: Does not support registers with async or sync sets.\n"); return -1; }
          id = new_id();
          id1 = create_concat_lpm_data(lpm);
          if (enable) {
            id2 = new_id();
            indent();
            fprintf(output, "  (mux    %i %i %i %i %i)\n", id2, width, id_of_nexus(enable, 0), id, id1);
            id1 = id2;
          }
          if (sync_clr) {
            id2 = new_id();
            id3 = new_id();
            indent();
            fprintf(output, "  (const  %i \"", id3);
            for (j = 0; j < width; j++)
              fprintf(output, "0");
            fprintf(output, "\")\n");
            indent();
            fprintf(output, "  (mux    %i %i %i %i %i)\n", id2, width, id_of_nexus(sync_clr, 0), id1, id3);
            id1 = id2;
          }
          // XXX Default to posedge sensitivity.
          if (async_clr) {
            indent();
            fprintf(output, "  (ffc    %i %i %i %i %i)\n", id, width, id_of_nexus(async_clr, 0), id_of_nexus(clk, 0), id1);
          }
          else {
            indent();
            fprintf(output, "  (ff     %i %i %i %i)\n", id, width, id_of_nexus(clk, 0), id1);
          }
          create_split_lpm_q(lpm, id);
        }
        break;

      case IVL_LPM_MUX:
        {
          unsigned t = 1;
          selects = ivl_lpm_selects(lpm);
          size    = ivl_lpm_size(lpm);
          for (j = 0; j < selects; j++)
            t = t * 2;
          assert(t == size); // General case.
          id = create_mux(lpm, selects, 0);
          create_split_lpm_q(lpm, id);
        }
        break;

      default:
        perror("** ERROR: Unsupported LPM type.\n");
        return -1;
    }
  }
  level = level + 1;
  return_code = ivl_scope_children(scope, build_hierarchy, 0);
  level = level - 1;
  if (! level)
    delete_nexus_table(nexus_table);
  indent();
  fprintf(output, "))\n");
  return return_code;
}
Пример #3
0
static void lpm_show_dff(ivl_lpm_t net)
{
      char name[64];
      edif_cell_t cell;
      edif_cellref_t ref;
      edif_joint_t jnt;

      unsigned idx;
      unsigned pin, wid = ivl_lpm_width(net);

      sprintf(name, "fd%s%s%s%s%s%u",
	      ivl_lpm_enable(net)? "ce" : "",
	      ivl_lpm_async_clr(net)? "cl" : "",
	      ivl_lpm_sync_clr(net)? "sc" : "",
	      ivl_lpm_async_set(net)? "se" : "",
	      ivl_lpm_sync_set(net)? "ss" : "",
	      wid);

      cell = edif_xlibrary_findcell(xlib, name);

      if (cell == 0) {
	    unsigned nports = 2 * wid + 1;
	    pin = 0;
	    if (ivl_lpm_enable(net))
		  nports += 1;
	    if (ivl_lpm_async_clr(net))
		  nports += 1;
	    if (ivl_lpm_sync_clr(net))
		  nports += 1;
	    if (ivl_lpm_async_set(net))
		  nports += 1;
	    if (ivl_lpm_sync_set(net))
		  nports += 1;

	    cell = edif_xcell_create(xlib, strdup(name), nports);
	    edif_cell_pstring(cell,  "LPM_Type", "LPM_FF");
	    edif_cell_pinteger(cell, "LPM_Width", wid);

	    for (idx = 0 ;  idx < wid ;  idx += 1) {

		  sprintf(name, "Q%u", idx);
		  edif_cell_portconfig(cell, idx*2+0, strdup(name),
				       IVL_SIP_OUTPUT);

		  sprintf(name, "Data%u", idx);
		  edif_cell_portconfig(cell, idx*2+1, strdup(name),
				       IVL_SIP_INPUT);
	    }

	    pin = wid*2;

	    if (ivl_lpm_enable(net)) {
		  edif_cell_portconfig(cell, pin, "Enable", IVL_SIP_INPUT);
		  pin += 1;
	    }

	    if (ivl_lpm_async_clr(net)) {
		  edif_cell_portconfig(cell, pin, "Aclr", IVL_SIP_INPUT);
		  pin += 1;
	    }

	    if (ivl_lpm_sync_clr(net)) {
		  edif_cell_portconfig(cell, pin, "Sclr", IVL_SIP_INPUT);
		  pin += 1;
	    }

	    if (ivl_lpm_async_set(net)) {
		  edif_cell_portconfig(cell, pin, "Aset", IVL_SIP_INPUT);
		  pin += 1;
	    }

	    if (ivl_lpm_sync_set(net)) {
		  edif_cell_portconfig(cell, pin, "Sset", IVL_SIP_INPUT);
		  pin += 1;
	    }

	    edif_cell_portconfig(cell, pin, "Clock", IVL_SIP_INPUT);
	    pin += 1;

	    assert(pin == nports);
      }

      ref = edif_cellref_create(edf, cell);

      pin = edif_cell_port_byname(cell, "Clock");

      jnt = edif_joint_of_nexus(edf, ivl_lpm_clk(net));
      edif_add_to_joint(jnt, ref, pin);

      if (ivl_lpm_enable(net)) {
	    pin = edif_cell_port_byname(cell, "Enable");

	    jnt = edif_joint_of_nexus(edf, ivl_lpm_enable(net));
	    edif_add_to_joint(jnt, ref, pin);
      }

      if (ivl_lpm_async_clr(net)) {
	    pin = edif_cell_port_byname(cell, "Aclr");

	    jnt = edif_joint_of_nexus(edf, ivl_lpm_async_clr(net));
	    edif_add_to_joint(jnt, ref, pin);
      }

      if (ivl_lpm_sync_clr(net)) {
	    pin = edif_cell_port_byname(cell, "Sclr");

	    jnt = edif_joint_of_nexus(edf, ivl_lpm_sync_clr(net));
	    edif_add_to_joint(jnt, ref, pin);
      }

      if (ivl_lpm_async_set(net)) {
	    pin = edif_cell_port_byname(cell, "Aset");

	    jnt = edif_joint_of_nexus(edf, ivl_lpm_async_set(net));
	    edif_add_to_joint(jnt, ref, pin);
      }

      if (ivl_lpm_sync_set(net)) {
	    ivl_expr_t svalue = ivl_lpm_sset_value(net);

	    pin = edif_cell_port_byname(cell, "Sset");

	    jnt = edif_joint_of_nexus(edf, ivl_lpm_sync_set(net));
	    edif_add_to_joint(jnt, ref, pin);

	    edif_cellref_pinteger(ref, "LPM_Svalue", ivl_expr_uvalue(svalue));
      }

      for (idx = 0 ;  idx < wid ;  idx += 1) {

	    sprintf(name, "Q%u", idx);
	    pin = edif_cell_port_byname(cell, name);

	    jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, idx));
	    edif_add_to_joint(jnt, ref, pin);

	    sprintf(name, "Data%u", idx);
	    pin = edif_cell_port_byname(cell, name);

	    jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, idx));
	    edif_add_to_joint(jnt, ref, pin);
      }
}
Пример #4
0
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);
		  }
	    }
      }
}