コード例 #1
0
ファイル: stub.c プロジェクト: nickg/iverilog
static void show_lpm_shift(ivl_lpm_t net, const char*shift_dir)
{
      ivl_nexus_t nex;
      unsigned width = ivl_lpm_width(net);

      fprintf(out, "  LPM_SHIFT%s %s: <width=%u, %ssigned>\n", shift_dir,
	      ivl_lpm_basename(net), width,
	      ivl_lpm_signed(net)? "" : "un");

      nex = ivl_lpm_q(net);
      fprintf(out, "    Q: %p\n", nex);

      if (width != width_of_nexus(nex)) {
	    fprintf(out, "    ERROR: Q output nexus width=%u "
		    "does not match part width\n", width_of_nexus(nex));
	    stub_errors += 1;
      }

      nex = ivl_lpm_data(net, 0);
      fprintf(out, "    D: %p\n", nex);

      if (width != width_of_nexus(nex)) {
	    fprintf(out, "    ERROR: Q output nexus width=%u "
		    "does not match part width\n", width_of_nexus(nex));
	    stub_errors += 1;
      }

      nex = ivl_lpm_data(net, 1);
      fprintf(out, "    S: %p <width=%u>\n", nex, width_of_nexus(nex));
}
コード例 #2
0
ファイル: stub.c プロジェクト: nickg/iverilog
/* IVL_LPM_CMP_GT
 * This LPM node supports two-input compare.
 */
static void show_lpm_cmp_gt(ivl_lpm_t net)
{
      unsigned width = ivl_lpm_width(net);

      fprintf(out, "  LPM_CMP_GT %s: <width=%u %s>\n",
	      ivl_lpm_basename(net), width,
	      ivl_lpm_signed(net)? "signed" : "unsigned");

      fprintf(out, "    O: %p\n", ivl_lpm_q(net));
      fprintf(out, "    A: %p\n", ivl_lpm_data(net,0));
      fprintf(out, "    B: %p\n", ivl_lpm_data(net,1));
      check_cmp_widths(net);
}
コード例 #3
0
ファイル: vvp_scope.c プロジェクト: gserdyuk/gnucap-icarus
static void draw_lpm_cast_real(ivl_lpm_t net)
{
      const char*src_table[1];
      const char*dly;
      const char*is_signed = "";

      draw_lpm_data_inputs(net, 0, 1, src_table);

      dly = draw_lpm_output_delay(net);

      if (ivl_lpm_signed(net)) is_signed = ".s";

      fprintf(vvp_out, "L_%p%s .cast/real%s %s;\n",
	      net, dly, is_signed, src_table[0]);
}
コード例 #4
0
ファイル: vvp_scope.c プロジェクト: gserdyuk/gnucap-icarus
static void draw_lpm_shiftl(ivl_lpm_t net)
{
      unsigned width = ivl_lpm_width(net);
      const char* signed_flag = ivl_lpm_signed(net)? "s" : "";
      const char*dly = draw_lpm_output_delay(net);

      if (ivl_lpm_type(net) == IVL_LPM_SHIFTR)
	    fprintf(vvp_out, "L_%p%s .shift/r%s %u", net, dly, signed_flag,
	            width);
      else
	    fprintf(vvp_out, "L_%p%s .shift/l %u", net, dly, width);

      fprintf(vvp_out, ", %s", draw_net_input(ivl_lpm_data(net, 0)));

      fprintf(vvp_out, ", %s", draw_net_input(ivl_lpm_data(net, 1)));

      fprintf(vvp_out, ";\n");
}
コード例 #5
0
ファイル: vvp_scope.c プロジェクト: gserdyuk/gnucap-icarus
static void draw_lpm_cmp(ivl_lpm_t net)
{
      const char*src_table[2];
      unsigned width;
      const char*type = "";
      const char*signed_string = ivl_lpm_signed(net)? ".s" : "";
      ivl_variable_type_t dta = data_type_of_nexus(ivl_lpm_data(net,0));
      ivl_variable_type_t dtb = data_type_of_nexus(ivl_lpm_data(net,1));
      ivl_variable_type_t dtc = IVL_VT_LOGIC;
      const char*dly;

      if (dta == IVL_VT_REAL || dtb == IVL_VT_REAL)
	    dtc = IVL_VT_REAL;

      width = ivl_lpm_width(net);

      switch (ivl_lpm_type(net)) {
	  case IVL_LPM_CMP_EEQ:
	    assert(dtc != IVL_VT_REAL); /* Should never get here! */
	    type = "eeq";
	    signed_string = "";
	    break;
	  case IVL_LPM_CMP_EQ:
	    if (dtc == IVL_VT_REAL)
		  type = "eq.r";
	    else
		  type = "eq";
	    signed_string = "";
	    break;
	  case IVL_LPM_CMP_GE:
	    if (dtc == IVL_VT_REAL) {
		  type = "ge.r";
		  signed_string = "";
	    } else
		  type = "ge";
	    break;
	  case IVL_LPM_CMP_GT:
	    if (dtc == IVL_VT_REAL) {
		  type = "gt.r";
		  signed_string = "";
	    } else
		  type = "gt";
	    break;
	  case IVL_LPM_CMP_NE:
	    if (dtc == IVL_VT_REAL)
		  type = "ne.r";
	    else
		  type = "ne";
	    signed_string = "";
	    break;
	  case IVL_LPM_CMP_NEE:
	    assert(dtc != IVL_VT_REAL); /* Should never get here! */
	    type = "nee";
	    signed_string = "";
	    break;
	  default:
	    assert(0);
      }

      draw_lpm_data_inputs(net, 0, 2, src_table);

      dly = draw_lpm_output_delay(net);

      fprintf(vvp_out, "L_%p%s .cmp/%s%s %u, %s, %s;\n",
	      net, dly, type, signed_string, width,
	      src_table[0], src_table[1]);
}
コード例 #6
0
ファイル: vvp_scope.c プロジェクト: gserdyuk/gnucap-icarus
static void draw_lpm_add(ivl_lpm_t net)
{
      const char*src_table[2];
      unsigned width;
      const char*type = "";
      ivl_variable_type_t dta = data_type_of_nexus(ivl_lpm_data(net,0));
      ivl_variable_type_t dtb = data_type_of_nexus(ivl_lpm_data(net,1));
      ivl_variable_type_t dto = IVL_VT_LOGIC;
      const char*dly;

      if (dta == IVL_VT_REAL || dtb == IVL_VT_REAL)
	    dto = IVL_VT_REAL;

      width = ivl_lpm_width(net);

      switch (ivl_lpm_type(net)) {
	  case IVL_LPM_ADD:
	    if (dto == IVL_VT_REAL)
		  type = "sum.r";
	    else
		  type = "sum";
	    break;
	  case IVL_LPM_SUB:
	    if (dto == IVL_VT_REAL)
		  type = "sub.r";
	    else
		  type = "sub";
	    break;
	  case IVL_LPM_MULT:
	    if (dto == IVL_VT_REAL)
		  type = "mult.r";
	    else
		  type = "mult";
	    break;
	  case IVL_LPM_DIVIDE:
	    if (dto == IVL_VT_REAL)
		  type = "div.r";
	    else if (ivl_lpm_signed(net))
		  type = "div.s";
	    else
		  type = "div";
	    break;
	  case IVL_LPM_MOD:
	    if (dto == IVL_VT_REAL)
		  type = "mod.r";
	    else if (ivl_lpm_signed(net))
		  type = "mod.s";
	    else
		  type = "mod";
	    break;
	  case IVL_LPM_POW:
	    if (dto == IVL_VT_REAL)
		  type = "pow.r";
	    else if (ivl_lpm_signed(net))
		  type = "pow.s";
	    else
		  type = "pow";
	    break;
	  default:
	    assert(0);
      }

      draw_lpm_data_inputs(net, 0, 2, src_table);

      dly = draw_lpm_output_delay(net);

      fprintf(vvp_out, "L_%p%s .arith/%s %u, %s, %s;\n",
	      net, dly, type, width, src_table[0], src_table[1]);
}
コード例 #7
0
ファイル: stub.c プロジェクト: nickg/iverilog
static void show_lpm(ivl_lpm_t net)
{

      switch (ivl_lpm_type(net)) {

	  case IVL_LPM_ABS:
	    show_lpm_abs(net);
	    break;

	  case IVL_LPM_ADD:
	    show_lpm_add(net);
	    break;

	  case IVL_LPM_ARRAY:
	    show_lpm_array(net);
	    break;

	  case IVL_LPM_CAST_INT:
	    show_lpm_cast_int(net);
	    break;

	  case IVL_LPM_CAST_REAL:
	    show_lpm_cast_real(net);
	    break;

	  case IVL_LPM_DIVIDE:
	    show_lpm_divide(net);
	    break;

	  case IVL_LPM_CMP_EEQ:
	  case IVL_LPM_CMP_NEE:
	    show_lpm_cmp_eeq(net);
	    break;

	  case IVL_LPM_FF:
	    show_lpm_ff(net);
	    break;

	  case IVL_LPM_CMP_GE:
	    show_lpm_cmp_ge(net);
	    break;

	  case IVL_LPM_CMP_GT:
	    show_lpm_cmp_gt(net);
	    break;

	  case IVL_LPM_CMP_NE:
	    show_lpm_cmp_ne(net);
	    break;

	  case IVL_LPM_CONCAT:
	    show_lpm_concat(net);
	    break;

	  case IVL_LPM_RE_AND:
	  case IVL_LPM_RE_NAND:
	  case IVL_LPM_RE_NOR:
	  case IVL_LPM_RE_OR:
	  case IVL_LPM_RE_XOR:
	  case IVL_LPM_RE_XNOR:
	    show_lpm_re(net);
	    break;

	  case IVL_LPM_SHIFTL:
	    show_lpm_shift(net, "L");
	    break;

	  case IVL_LPM_SIGN_EXT:
	    show_lpm_sign_ext(net);
	    break;

	  case IVL_LPM_SHIFTR:
	    show_lpm_shift(net, "R");
	    break;

	  case IVL_LPM_SUB:
	    show_lpm_sub(net);
	    break;

	  case IVL_LPM_MOD:
	    show_lpm_mod(net);
	    break;

	  case IVL_LPM_MULT:
	    show_lpm_mult(net);
	    break;

	  case IVL_LPM_MUX:
	    show_lpm_mux(net);
	    break;

	  case IVL_LPM_PART_VP:
	  case IVL_LPM_PART_PV:
	    show_lpm_part(net);
	    break;

	  case IVL_LPM_REPEAT:
	    show_lpm_repeat(net);
	    break;

	  case IVL_LPM_SFUNC:
	    show_lpm_sfunc(net);
	    break;

	  case IVL_LPM_UFUNC:
	    show_lpm_ufunc(net);
	    break;

	  default:
	    fprintf(out, "  LPM(%d) %s: <width=%u, signed=%d>\n",
		    ivl_lpm_type(net),
		    ivl_lpm_basename(net),
		    ivl_lpm_width(net),
		    ivl_lpm_signed(net));
      }
}
コード例 #8
0
ファイル: stub.c プロジェクト: nickg/iverilog
static void show_lpm_part(ivl_lpm_t net)
{
      unsigned width = ivl_lpm_width(net);
      unsigned base  = ivl_lpm_base(net);
      ivl_nexus_t sel = ivl_lpm_data(net,1);
      const char*part_type_string = "";

      switch (ivl_lpm_type(net)) {
	  case IVL_LPM_PART_VP:
	    part_type_string = "VP";
	    break;
	  case IVL_LPM_PART_PV:
	    part_type_string = "PV";
	    break;
	  default:
	    break;
      }

      fprintf(out, "  LPM_PART_%s %s: <width=%u, base=%u, signed=%d>\n",
	      part_type_string, ivl_lpm_basename(net),
	      width, base, ivl_lpm_signed(net));
      fprintf(out, "    O: %p\n", ivl_lpm_q(net));
      fprintf(out, "    I: %p\n", ivl_lpm_data(net,0));

      if (sel != 0) {
	    fprintf(out, "    S: %p\n", sel);
	    if (base != 0) {
		  fprintf(out, "   ERROR: Part select has base AND selector\n");
		  stub_errors += 1;
	    }
      }

	/* The compiler must assure that the base plus the part select
	   width fits within the input to the part select. */
      switch (ivl_lpm_type(net)) {

	  case IVL_LPM_PART_VP:
	    if (width_of_nexus(ivl_lpm_data(net,0)) < (width+base)) {
		  fprintf(out, "    ERROR: Part select is out of range."
			  " Data nexus width=%u, width+base=%u\n",
			  width_of_nexus(ivl_lpm_data(net,0)), width+base);
		  stub_errors += 1;
	    }

	    if (width_of_nexus(ivl_lpm_q(net)) != width) {
		  fprintf(out, "    ERROR: Part select input mismatch."
			  " Nexus width=%u, expect width=%u\n",
			  width_of_nexus(ivl_lpm_q(net)), width);
		  stub_errors += 1;
	    }
	    break;

	  case IVL_LPM_PART_PV:
	    if (width_of_nexus(ivl_lpm_q(net)) < (width+base)) {
		  fprintf(out, "    ERROR: Part select is out of range."
			  " Target nexus width=%u, width+base=%u\n",
			  width_of_nexus(ivl_lpm_q(net)), width+base);
		  stub_errors += 1;
	    }

	    if (width_of_nexus(ivl_lpm_data(net,0)) != width) {
		  fprintf(out, "    ERROR: Part select input mismatch."
			  " Nexus width=%u, expect width=%u\n",
			  width_of_nexus(ivl_lpm_data(net,0)), width);
		  stub_errors += 1;
	    }
	    break;

	  default:
	    assert(0);
      }
}