示例#1
0
文件: fst.c 项目: SnookEE/nvc
void fst_restart(void)
{
   if (fst_ctx == NULL)
      return;

   const int ndecls = tree_decls(fst_top);
   for (int i = 0; i < ndecls; i++) {
      tree_t d = tree_decl(fst_top, i);

      switch (tree_kind(d)) {
      case T_SIGNAL_DECL:
         if (wave_should_dump(d))
            fst_process_signal(d);
         break;
      case T_HIER:
         fst_process_hier(d);
         break;
      default:
         break;
      }

      int npop = tree_attr_int(d, ident_new("scope_pop"), 0);
      while (npop-- > 0)
         fstWriterSetUpscope(fst_ctx);
   }

   last_time = UINT64_MAX;

   for (int i = 0; i < ndecls; i++) {
      tree_t d = tree_decl(fst_top, i);
      if (tree_kind(d) == T_SIGNAL_DECL) {
         fst_data_t *data = tree_attr_ptr(d, fst_data_i);
         if (likely(data != NULL))
            fst_event_cb(0, d, data->watch, data);
      }
   }
}
示例#2
0
文件: sys_fst.c 项目: bzero/iverilog
static PLI_INT32 sys_dumpvars_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);
      vpiHandle item;
      s_vpi_value value;
      unsigned depth = 0;

      (void)name; /* Parameter is not used. */

      if (dump_file == 0) {
	    open_dumpfile(callh);
	    if (dump_file == 0) {
		  if (argv) vpi_free_object(argv);
		  return 0;
	    }
      }

      if (install_dumpvars_callback()) {
	    if (argv) vpi_free_object(argv);
	    return 0;
      }

        /* Get the depth if it exists. */
      if (argv) {
	    value.format = vpiIntVal;
	    vpi_get_value(vpi_scan(argv), &value);
	    depth = value.value.integer;
      }
      if (!depth) depth = 10000;

        /* This dumps all the modules in the design if none are given. */
      if (!argv || !(item = vpi_scan(argv))) {
	    argv = vpi_iterate(vpiModule, 0x0);
	    assert(argv);  /* There must be at least one top level module. */
	    item = vpi_scan(argv);
      }

      for ( ; item; item = vpi_scan(argv)) {
	    char *scname;
	    const char *fullname;
	    int add_var = 0;
	    int dep;
	    PLI_INT32 item_type = vpi_get(vpiType, item);

	      /* If this is a signal make sure it has not already
	       * been included. */
	    switch (item_type) {
	        case vpiIntegerVar:
		case vpiBitVar:
		case vpiByteVar:
		case vpiShortIntVar:
		case vpiIntVar:
		case vpiLongIntVar:
	        case vpiMemoryWord:
	        case vpiNamedEvent:
	        case vpiNet:
	        case vpiParameter:
	        case vpiRealVar:
	        case vpiReg:
	        case vpiTimeVar:
		    /* Warn if the variables scope (which includes the
		     * variable) or the variable itself was already
		     * included. A scope does not automatically include
		     * memory words so do not check the scope for them.  */
		  scname = strdup(vpi_get_str(vpiFullName,
		                              vpi_handle(vpiScope, item)));
		  fullname = vpi_get_str(vpiFullName, item);
		  if (((item_type != vpiMemoryWord) &&
		       vcd_names_search(&fst_tab, scname)) ||
		      vcd_names_search(&fst_var, fullname)) {
		        vpi_printf("FST warning: skipping signal %s, "
		                   "it was previously included.\n",
		                   fullname);
		        free(scname);
		        continue;
		  } else {
		        add_var = 1;
		  }
		  free(scname);
	    }

	    dep = draw_scope(item, callh);

	    scan_item(depth, item, 0);
	      /* The scope list must be sorted after we scan an item.  */
	    vcd_names_sort(&fst_tab);

	    while (dep--) fstWriterSetUpscope(dump_file);

	      /* Add this signal to the variable list so we can verify it
	       * is not included twice. This must be done after it has
	       * been added */
	    if (add_var) {
		  vcd_names_add(&fst_var, vpi_get_str(vpiFullName, item));
		  vcd_names_sort(&fst_var);
	    }
      }

      return 0;
}
示例#3
0
文件: sys_fst.c 项目: bzero/iverilog
static void scan_item(unsigned depth, vpiHandle item, int skip)
{
      struct t_cb_data cb;
      struct vcd_info* info;

      enum fstVarType type = FST_VT_MAX;
      enum fstScopeType stype = FST_ST_MAX;
      enum fstVarDir dir;
      const char *name;
      const char *fullname;
      char *escname;
      const char *ident;
      fstHandle new_ident;
      int nexus_id;
      unsigned size;
      PLI_INT32 item_type;

	/* Get the displayed type for the various $var and $scope types. */
	/* Not all of these are supported now, but they should be in a
	 * future development version. */
      item_type = vpi_get(vpiType, item);
      switch (item_type) {
	  case vpiNamedEvent: type = FST_VT_VCD_EVENT; break;
	  case vpiIntVar:
	  case vpiIntegerVar: type = FST_VT_VCD_INTEGER; break;
	  case vpiParameter:  type = FST_VT_VCD_PARAMETER; break;
	    /* Icarus converts realtime to real. */
	  case vpiRealVar:    type = FST_VT_VCD_REAL; break;
	  case vpiMemoryWord:
	  case vpiBitVar:
	  case vpiByteVar:
	  case vpiShortIntVar:
	  case vpiLongIntVar:
	  case vpiReg:        type = FST_VT_VCD_REG; break;
	    /* Icarus converts a time to a plain register. */
	  case vpiTimeVar:    type = FST_VT_VCD_TIME; break;
	  case vpiNet:
	    switch (vpi_get(vpiNetType, item)) {
		case vpiWand:    type = FST_VT_VCD_WAND; break;
		case vpiWor:     type = FST_VT_VCD_WOR; break;
		case vpiTri:     type = FST_VT_VCD_TRI; break;
		case vpiTri0:    type = FST_VT_VCD_TRI0; break;
		case vpiTri1:    type = FST_VT_VCD_TRI1; break;
		case vpiTriReg:  type = FST_VT_VCD_TRIREG; break;
		case vpiTriAnd:  type = FST_VT_VCD_TRIAND; break;
		case vpiTriOr:   type = FST_VT_VCD_TRIOR; break;
		case vpiSupply1: type = FST_VT_VCD_SUPPLY1; break;
		case vpiSupply0: type = FST_VT_VCD_SUPPLY0; break;
		default:         type = FST_VT_VCD_WIRE; break;
	    }
	    break;

	  case vpiNamedBegin: stype = FST_ST_VCD_BEGIN; break;
	  case vpiNamedFork:  stype = FST_ST_VCD_FORK; break;
	  case vpiFunction:   stype = FST_ST_VCD_FUNCTION; break;
	  case vpiGenScope:   stype = FST_ST_VCD_GENERATE; break;
	  case vpiModule:     stype = FST_ST_VCD_MODULE; break;
	  case vpiTask:       stype = FST_ST_VCD_TASK; break;

	  default:
	    vpi_printf("FST warning: $dumpvars: Unsupported argument "
	               "type (%s)\n", vpi_get_str(vpiType, item));
	    return;
      }

	/* Do some special processing/checking on array words. Dumping
	 * array words is an Icarus extension. */
      if (item_type == vpiMemoryWord) {
	      /* Turn a non-constant array word select into a constant
	       * word select. */
	    if (vpi_get(vpiConstantSelect, item) == 0) {
		  vpiHandle array = vpi_handle(vpiParent, item);
		  PLI_INT32 idx = vpi_get(vpiIndex, item);
		  item = vpi_handle_by_index(array, idx);
	    }

	      /* An array word is implicitly escaped so look for an
	       * escaped identifier that this could conflict with. */
	      /* This does not work as expected since we always find at
	       * least the array word. We likely need a custom routine. */
            if (vpi_get(vpiType, item) == vpiMemoryWord &&
                vpi_handle_by_name(vpi_get_str(vpiFullName, item), 0)) {
		  vpi_printf("FST warning: array word %s will conflict "
		             "with an escaped identifier.\n",
		             vpi_get_str(vpiFullName, item));
            }
      }

      fullname = vpi_get_str(vpiFullName, item);

	/* Generate the $var or $scope commands. */
      switch (item_type) {
	  case vpiParameter:
	    vpi_printf("FST sorry: $dumpvars: can not dump parameters.\n");
	    break;

	  case vpiNamedEvent:
	  case vpiIntegerVar:
	  case vpiBitVar:
	  case vpiByteVar:
	  case vpiShortIntVar:
	  case vpiIntVar:
	  case vpiLongIntVar:
	  case vpiRealVar:
	  case vpiMemoryWord:
	  case vpiReg:
	  case vpiTimeVar:
	  case vpiNet:

	      /* If we are skipping all signal or this is in an automatic
	       * scope then just return. */
            if (skip || vpi_get(vpiAutomatic, item)) return;

	      /* Skip this signal if it has already been included.
	       * This can only happen for implicitly given signals. */
	    if (vcd_names_search(&fst_var, fullname)) return;

	      /* Declare the variable in the FST file. */
	    name = vpi_get_str(vpiName, item);
	    if (is_escaped_id(name)) {
		  escname = malloc(strlen(name) + 2);
		  sprintf(escname, "\\%s", name);
	    } else escname = strdup(name);

	      /* Some signals can have an alias so handle that. */
	    nexus_id = vpi_get(_vpiNexusId, item);

	    ident = 0;
	    if (nexus_id) ident = find_nexus_ident(nexus_id);

	      /* Named events do not have a size, but other tools use
	       * a size of 1 and some viewers do not accept a width of
	       * zero so we will also use a width of one for events. */
	    if (item_type == vpiNamedEvent) size = 1;
	    else size = vpi_get(vpiSize, item);
	      /* The FST format supports a port direction so if the net
	       * is a port set the direction to one of the following:
	       *   FST_VD_INPUT, FST_VD_OUTPUT or FST_VD_INOUT */
	    dir = FST_VD_IMPLICIT;

	    if (size > 1 || vpi_get(vpiLeftRange, item) != 0) {
		  char *buf = malloc(strlen(escname) + 65);
		  sprintf(buf, "%s [%i:%i]", escname,
                            (int)vpi_get(vpiLeftRange, item),
                            (int)vpi_get(vpiRightRange, item));

		  new_ident = fstWriterCreateVar(dump_file, type,
		                                 dir, size, buf,
		                                 (fstHandle)(long)ident);
		  free(buf);
	    } else {
		  new_ident = fstWriterCreateVar(dump_file, type,
		                                 dir, size, escname,
		                                 (fstHandle)(long)ident);
	    }
	    free(escname);

	    if (!ident) {
		  if (nexus_id) set_nexus_ident(nexus_id,
		                                (const char *)(long)new_ident);

		    /* Add a callback for the signal. */
		  info = malloc(sizeof(*info));

		  info->time.type = vpiSimTime;
		  info->item  = item;
		  info->handle = new_ident;
		  info->scheduled = 0;

		  cb.time      = &info->time;
		  cb.user_data = (char*)info;
		  cb.value     = NULL;
		  cb.obj       = item;
		  cb.reason    = cbValueChange;
		  cb.cb_rtn    = variable_cb_1;

		  info->dmp_next = 0;
		  info->next  = vcd_list;
		  vcd_list    = info;

		  info->cb    = vpi_register_cb(&cb);
	    }

	    break;

	  case vpiModule:
	  case vpiGenScope:
	  case vpiFunction:
	  case vpiTask:
	  case vpiNamedBegin:
	  case vpiNamedFork:

	    if (depth > 0) {
		  char *instname;
		  char *defname = NULL;
		  /* list of types to iterate upon */
		  static int types[] = {
			/* Value */
			vpiNamedEvent,
			vpiNet,
			/* vpiParameter, */
			vpiReg,
			vpiVariables,
			/* Scope */
			vpiFunction,
			vpiGenScope,
			vpiModule,
			vpiNamedBegin,
			vpiNamedFork,
			vpiTask,
			-1
		  };
		  int i;
		  int nskip = (vcd_names_search(&fst_tab, fullname) != 0);

		    /* We have to always scan the scope because the
		     * depth could be different for this call. */
		  if (nskip) {
			vpi_printf("FST warning: ignoring signals in "
			           "previously scanned scope %s.\n", fullname);
		  } else {
			vcd_names_add(&fst_tab, fullname);
		  }

		    /* Set the file and line information for this scope.
		     * Everything has instance information. Only a module
		     * has separate definition information. */
		  instname = vpi_get_str(vpiFile, item);
		  fstWriterSetSourceInstantiationStem(dump_file, instname,
		      (int)vpi_get(vpiLineNo, item), 0);
		  if (item_type == vpiModule) {
			fstWriterSetSourceStem(dump_file,
			    vpi_get_str(vpiDefFile, item),
			    (int)vpi_get(vpiDefLineNo, item), 0);
		  } else {
			fstWriterSetSourceStem(dump_file, instname,
			    (int)vpi_get(vpiLineNo, item), 0);
		  }

		    /* This must be done before the other name is fetched
		     * and the string must always be freed */
		  if (item_type == vpiModule) {
			defname = strdup(vpi_get_str(vpiDefName, item));
		  }
		  name = vpi_get_str(vpiName, item);
		    /* If the two names match only use the vpiName. */
		  if (defname && (strcmp(defname, name) == 0)) {
			free(defname);
			defname = NULL;
		  }
		  fstWriterSetScope(dump_file, stype, name, defname);
		  free(defname);

		  for (i=0; types[i]>0; i++) {
			vpiHandle hand;
			vpiHandle argv = vpi_iterate(types[i], item);
			while (argv && (hand = vpi_scan(argv))) {
			      scan_item(depth-1, hand, nskip);
			}
		  }

		    /* Sort any signals that we added above. */
		  fstWriterSetUpscope(dump_file);
	    }
	    break;
      }
}