Ejemplo n.º 1
0
void draw_ufunc_real(ivl_expr_t expr)
{
      ivl_scope_t def = ivl_expr_def(expr);
      ivl_signal_t retval = ivl_scope_port(def, 0);
      unsigned idx;

        /* If this is an automatic function, allocate the local storage. */
      if (ivl_scope_is_auto(def)) {
            fprintf(vvp_out, "    %%alloc S_%p;\n", def);
      }

      assert(ivl_expr_parms(expr) == (ivl_scope_ports(def)-1));
      for (idx = 0 ;  idx < ivl_expr_parms(expr) ;  idx += 1) {
	    ivl_signal_t port = ivl_scope_port(def, idx+1);
	    draw_function_argument(port, ivl_expr_parm(expr, idx));
      }


	/* Call the function */
      fprintf(vvp_out, "    %%fork TD_%s", vvp_mangle_id(ivl_scope_name(def)));
      fprintf(vvp_out, ", S_%p;\n", def);
      fprintf(vvp_out, "    %%join;\n");

	/* Return value signal cannot be an array. */
      assert(ivl_signal_dimensions(retval) == 0);

	/* Load the result into a word. */
      fprintf(vvp_out, "  %%load/real v%p_0;\n", retval);

        /* If this is an automatic function, free the local storage. */
      if (ivl_scope_is_auto(def)) {
            fprintf(vvp_out, "    %%free S_%p;\n", def);
      }

}
Ejemplo n.º 2
0
static void draw_ufunc_preamble(ivl_expr_t expr)
{
      ivl_scope_t def = ivl_expr_def(expr);
      unsigned idx;

        /* If this is an automatic function, allocate the local storage. */
      if (ivl_scope_is_auto(def)) {
            fprintf(vvp_out, "    %%alloc S_%p;\n", def);
      }

	/* evaluate the expressions and send the results to the
	   function ports. */

      assert(ivl_expr_parms(expr) == (ivl_scope_ports(def)-1));
      for (idx = 0 ;  idx < ivl_expr_parms(expr) ;  idx += 1) {
	    ivl_signal_t port = ivl_scope_port(def, idx+1);
	    draw_function_argument(port, ivl_expr_parm(expr, idx));
      }

	/* Call the function */
      fprintf(vvp_out, "    %%fork TD_%s", vvp_mangle_id(ivl_scope_name(def)));
      fprintf(vvp_out, ", S_%p;\n", def);
      fprintf(vvp_out, "    %%join;\n");

}
Ejemplo n.º 3
0
static void draw_ufunc_preamble(ivl_expr_t expr)
{
      ivl_scope_t def = ivl_expr_def(expr);
      unsigned idx;

        /* If this is an automatic function, allocate the local storage. */
      if (ivl_scope_is_auto(def)) {
            fprintf(vvp_out, "    %%alloc S_%p;\n", def);
      }

	/* Evaluate the expressions and send the results to the
	   function ports. Do this in two passes - evaluate,
	   then send - this avoids the function input variables
	   being overwritten if the same (non-automatic) function
	   is called in one of the exressions. */

      assert(ivl_expr_parms(expr) == (ivl_scope_ports(def)-1));
      for (idx = 0 ;  idx < ivl_expr_parms(expr) ;  idx += 1) {
	    ivl_signal_t port = ivl_scope_port(def, idx+1);
	    draw_eval_function_argument(port, ivl_expr_parm(expr, idx));
      }
      for (idx = ivl_expr_parms(expr) ;  idx > 0 ;  idx -= 1) {
	    ivl_signal_t port = ivl_scope_port(def, idx);
	    draw_send_function_argument(port);
      }

	/* Call the function */
      fprintf(vvp_out, "    %%fork TD_%s", vvp_mangle_id(ivl_scope_name(def)));
      fprintf(vvp_out, ", S_%p;\n", def);
      fprintf(vvp_out, "    %%join;\n");

}
Ejemplo n.º 4
0
static void draw_ufunc_preamble(ivl_expr_t expr)
{
    ivl_scope_t def = ivl_expr_def(expr);
    unsigned idx;

    /* If this is an automatic function, allocate the local storage. */
    if (ivl_scope_is_auto(def)) {
        fprintf(vvp_out, "    %%alloc S_%p;\n", def);
    }

    /* Evaluate the expressions and send the results to the
       function ports. Do this in two passes - evaluate,
       then send - this avoids the function input variables
       being overwritten if the same (non-automatic) function
       is called in one of the expressions. */

    assert(ivl_expr_parms(expr) == (ivl_scope_ports(def)-1));
    for (idx = 0 ;  idx < ivl_expr_parms(expr) ;  idx += 1) {
        ivl_signal_t port = ivl_scope_port(def, idx+1);
        draw_eval_function_argument(port, ivl_expr_parm(expr, idx));
    }
    for (idx = ivl_expr_parms(expr) ;  idx > 0 ;  idx -= 1) {
        ivl_signal_t port = ivl_scope_port(def, idx);
        draw_send_function_argument(port);
    }

    /* Call the function */
    switch (ivl_expr_value(expr)) {
    case IVL_VT_VOID:
        fprintf(vvp_out, "    %%callf/void TD_%s", vvp_mangle_id(ivl_scope_name(def)));
        fprintf(vvp_out, ", S_%p;\n", def);
        break;
    case IVL_VT_REAL:
        fprintf(vvp_out, "    %%callf/real TD_%s", vvp_mangle_id(ivl_scope_name(def)));
        fprintf(vvp_out, ", S_%p;\n", def);
        break;
    case IVL_VT_BOOL:
    case IVL_VT_LOGIC:
        fprintf(vvp_out, "    %%callf/vec4 TD_%s", vvp_mangle_id(ivl_scope_name(def)));
        fprintf(vvp_out, ", S_%p;\n", def);
        break;
    case IVL_VT_STRING:
        fprintf(vvp_out, "    %%callf/str TD_%s", vvp_mangle_id(ivl_scope_name(def)));
        fprintf(vvp_out, ", S_%p;\n", def);
        break;
    case IVL_VT_CLASS:
    case IVL_VT_DARRAY:
    case IVL_VT_QUEUE:
        fprintf(vvp_out, "    %%callf/obj TD_%s", vvp_mangle_id(ivl_scope_name(def)));
        fprintf(vvp_out, ", S_%p;\n", def);
        break;
    default:
        fprintf(vvp_out, "    %%fork TD_%s", vvp_mangle_id(ivl_scope_name(def)));
        fprintf(vvp_out, ", S_%p;\n", def);
        fprintf(vvp_out, "    %%join;\n");
        break;
    }
}
Ejemplo n.º 5
0
static void draw_ufunc_epilogue(ivl_expr_t expr)
{
      ivl_scope_t def = ivl_expr_def(expr);

        /* If this is an automatic function, free the local storage. */
      if (ivl_scope_is_auto(def)) {
            fprintf(vvp_out, "    %%free S_%p;\n", def);
      }
}
Ejemplo n.º 6
0
struct vector_info draw_ufunc_expr(ivl_expr_t expr, unsigned wid)
{
      unsigned idx;
      unsigned swid = ivl_expr_width(expr);
      ivl_scope_t def = ivl_expr_def(expr);
      ivl_signal_t retval = ivl_scope_port(def, 0);
      struct vector_info res;
      unsigned load_wid;

        /* If this is an automatic function, allocate the local storage. */
      if (ivl_scope_is_auto(def)) {
            fprintf(vvp_out, "    %%alloc S_%p;\n", def);
      }

	/* evaluate the expressions and send the results to the
	   function ports. */

      assert(ivl_expr_parms(expr) == (ivl_scope_ports(def)-1));
      for (idx = 0 ;  idx < ivl_expr_parms(expr) ;  idx += 1) {
	    ivl_signal_t port = ivl_scope_port(def, idx+1);
	    draw_function_argument(port, ivl_expr_parm(expr, idx));
      }


	/* Call the function */
      fprintf(vvp_out, "    %%fork TD_%s", vvp_mangle_id(ivl_scope_name(def)));
      fprintf(vvp_out, ", S_%p;\n", def);
      fprintf(vvp_out, "    %%join;\n");

	/* Fresh basic block starts after the join. */
      clear_expression_lookaside();

	/* The return value is in a signal that has the name of the
	   expression. Load that into the thread and return the
	   vector result. */

      res.base = allocate_vector(wid);
      res.wid  = wid;
      if (res.base == 0) {
	    fprintf(stderr, "%s:%u: vvp.tgt error: "
		    "Unable to allocate %u thread bits for function result.\n",
		    ivl_expr_file(expr), ivl_expr_lineno(expr), wid);
	    vvp_errors += 1;
	    return res;
      }

      assert(res.base != 0);

      load_wid = swid;
      if (load_wid > ivl_signal_width(retval))
	    load_wid = ivl_signal_width(retval);

      assert(ivl_signal_dimensions(retval) == 0);
      fprintf(vvp_out, "    %%load/v  %u, v%p_0, %u;\n",
	      res.base, retval, load_wid);

	/* Pad the signal value with zeros. */
      if (load_wid < wid)
	    pad_expr_in_place(expr, res, swid);

        /* If this is an automatic function, free the local storage. */
      if (ivl_scope_is_auto(def)) {
            fprintf(vvp_out, "    %%free S_%p;\n", def);
      }

      return res;
}
Ejemplo n.º 7
0
int draw_scope(ivl_scope_t net, ivl_scope_t parent)
{
      unsigned idx;
      const char *type;

      const char*prefix = ivl_scope_is_auto(net) ? "auto" : "";

      switch (ivl_scope_type(net)) {
      case IVL_SCT_MODULE:   type = "module";   break;
      case IVL_SCT_FUNCTION: type = "function"; break;
      case IVL_SCT_TASK:     type = "task";     break;
      case IVL_SCT_BEGIN:    type = "begin";    break;
      case IVL_SCT_FORK:     type = "fork";     break;
      case IVL_SCT_GENERATE: type = "generate"; break;
      default:               type = "?";        assert(0);
      }

      fprintf(vvp_out, "S_%p .scope %s%s, \"%s\" \"%s\" %d %d",
	      net, prefix, type, vvp_mangle_name(ivl_scope_basename(net)),
              ivl_scope_tname(net), ivl_file_table_index(ivl_scope_file(net)),
              ivl_scope_lineno(net));

      if (parent) {
	    fprintf(vvp_out, ", %d %d, S_%p;\n",
	            ivl_file_table_index(ivl_scope_def_file(net)),
	            ivl_scope_def_lineno(net), parent);
      } else {

	    fprintf(vvp_out, ";\n");
      }

      fprintf(vvp_out, " .timescale %d %d;\n", ivl_scope_time_units(net),
                                               ivl_scope_time_precision(net));

      for (idx = 0 ;  idx < ivl_scope_params(net) ;  idx += 1) {
	    ivl_parameter_t par = ivl_scope_param(net, idx);
	    ivl_expr_t pex = ivl_parameter_expr(par);
	    switch (ivl_expr_type(pex)) {
		case IVL_EX_STRING:
		  fprintf(vvp_out, "P_%p .param/str \"%s\" %d %d, \"%s\";\n",
			  par, ivl_parameter_basename(par),
			  ivl_file_table_index(ivl_parameter_file(par)),
			  ivl_parameter_lineno(par),
			  ivl_expr_string(pex));
		  break;
		case IVL_EX_NUMBER:
		  fprintf(vvp_out, "P_%p .param/l \"%s\" %d %d, %sC4<",
			  par, ivl_parameter_basename(par),
			  ivl_file_table_index(ivl_parameter_file(par)),
			  ivl_parameter_lineno(par),
			  ivl_expr_signed(pex)? "+":"");
		  { const char*bits = ivl_expr_bits(pex);
		    unsigned nbits = ivl_expr_width(pex);
		    unsigned bb;
		    for (bb = 0 ;  bb < nbits;  bb += 1)
			  fprintf(vvp_out, "%c", bits[nbits-bb-1]);
		  }
		  fprintf(vvp_out, ">;\n");
		  break;
		case IVL_EX_REALNUM:
		  fprintf(vvp_out, "P_%p .param/real \"%s\" %d %d, %s; value=%g\n",
			  par, ivl_parameter_basename(par),
			  ivl_file_table_index(ivl_parameter_file(par)),
			  ivl_parameter_lineno(par),
			  draw_Cr_to_string(ivl_expr_dvalue(pex)),
			  ivl_expr_dvalue(pex));
		  break;
		default:
		  fprintf(vvp_out, "; parameter type %d unsupported\n",
			  ivl_expr_type(pex));
		  break;
	    }
      }

	/* Scan the scope for logic devices. For each device, draw out
	   a functor that connects pin 0 to the output, and the
	   remaining pins to inputs. */

      for (idx = 0 ;  idx < ivl_scope_logs(net) ;  idx += 1) {
	    ivl_net_logic_t lptr = ivl_scope_log(net, idx);
	    draw_logic_in_scope(lptr);
      }


	/* Scan the signals (reg and net) and draw the appropriate
	   statements to make the signal function. */

      for (idx = 0 ;  idx < ivl_scope_sigs(net) ;  idx += 1) {
	    ivl_signal_t sig = ivl_scope_sig(net, idx);

	    switch (ivl_signal_type(sig)) {
		case IVL_SIT_REG:
		  draw_reg_in_scope(sig);
		  break;
		default:
		  draw_net_in_scope(sig);
		  break;
	    }
      }

      for (idx = 0 ;  idx < ivl_scope_events(net) ;  idx += 1) {
	    ivl_event_t event = ivl_scope_event(net, idx);
	    draw_event_in_scope(event);
      }

      for (idx = 0 ;  idx < ivl_scope_lpms(net) ;  idx += 1) {
	    ivl_lpm_t lpm = ivl_scope_lpm(net, idx);
	    draw_lpm_in_scope(lpm);
      }

      for (idx = 0 ; idx < ivl_scope_switches(net) ; idx += 1) {
	    ivl_switch_t sw = ivl_scope_switch(net, idx);
	    draw_switch_in_scope(sw);
      }

      if (ivl_scope_type(net) == IVL_SCT_TASK)
	    draw_task_definition(net);

      if (ivl_scope_type(net) == IVL_SCT_FUNCTION)
	    draw_func_definition(net);

      ivl_scope_children(net, (ivl_scope_f*) draw_scope, net);
      return 0;
}
Ejemplo n.º 8
0
static int show_scope(ivl_scope_t net, void*x)
{
      unsigned idx;
      const char *is_auto;

      fprintf(out, "scope: %s (%u parameters, %u signals, %u logic)",
	      ivl_scope_name(net), ivl_scope_params(net),
	      ivl_scope_sigs(net), ivl_scope_logs(net));

      is_auto = ivl_scope_is_auto(net) ? "automatic " : "";
      switch (ivl_scope_type(net)) {
	  case IVL_SCT_MODULE:
	    fprintf(out, " module %s%s", ivl_scope_tname(net),
                    ivl_scope_is_cell(net) ? " (cell)" : "");
	    break;
	  case IVL_SCT_FUNCTION:
	    fprintf(out, " function %s%s", is_auto, ivl_scope_tname(net));
	    break;
	  case IVL_SCT_BEGIN:
	    fprintf(out, " begin : %s", ivl_scope_tname(net));
	    break;
	  case IVL_SCT_FORK:
	    fprintf(out, " fork : %s", ivl_scope_tname(net));
	    break;
	  case IVL_SCT_TASK:
	    fprintf(out, " task %s%s", is_auto, ivl_scope_tname(net));
	    break;
	  default:
	    fprintf(out, " type(%u) %s", ivl_scope_type(net),
		    ivl_scope_tname(net));
	    break;
      }

      fprintf(out, " time units = 1e%d\n", ivl_scope_time_units(net));
      fprintf(out, " time precision = 1e%d\n", ivl_scope_time_precision(net));

      for (idx = 0 ;  idx < ivl_scope_attr_cnt(net) ;  idx += 1) {
	    ivl_attribute_t attr = ivl_scope_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;
	    }
      }

      for (idx = 0 ;  idx < ivl_scope_params(net) ;  idx += 1)
	    show_parameter(ivl_scope_param(net, idx));

      for (idx = 0 ; idx < ivl_scope_enumerates(net) ; idx += 1)
	    show_enumerate(ivl_scope_enumerate(net, idx));

      for (idx = 0 ;  idx < ivl_scope_sigs(net) ;  idx += 1)
	    show_signal(ivl_scope_sig(net, idx));

      for (idx = 0 ;  idx < ivl_scope_events(net) ;  idx += 1)
	    show_event(ivl_scope_event(net, idx));

      for (idx = 0 ;  idx < ivl_scope_logs(net) ;  idx += 1)
	    show_logic(ivl_scope_log(net, idx));

      for (idx = 0 ;  idx < ivl_scope_lpms(net) ;  idx += 1)
	    show_lpm(ivl_scope_lpm(net, idx));

      for (idx = 0 ; idx < ivl_scope_switches(net) ; idx += 1)
	    show_switch(ivl_scope_switch(net, idx));

      switch (ivl_scope_type(net)) {
	  case IVL_SCT_FUNCTION:
	  case IVL_SCT_TASK:
	    fprintf(out, "  scope function/task definition\n");
	    if (ivl_scope_def(net) == 0) {
		  fprintf(out, "  ERROR: scope missing required task definition\n");
		  stub_errors += 1;
	    } else {
		  show_statement(ivl_scope_def(net), 6);
	    }
	    break;

	  default:
	    if (ivl_scope_def(net)) {
		  fprintf(out, "  ERROR: scope has an attached task definition:\n");
		  show_statement(ivl_scope_def(net), 6);
		  stub_errors += 1;
	    }
	    break;
      }

      fprintf(out, "end scope %s\n", ivl_scope_name(net));
      return ivl_scope_children(net, show_scope, 0);
}