예제 #1
0
static tree_t elab_port_to_signal(tree_t arch, tree_t port, tree_t actual)
{
   assert(tree_kind(port) == T_PORT_DECL);

   ident_t name = tree_ident(port);

   const int ndecls = tree_decls(arch);
   for (int i = 0; i < ndecls; i++) {
      tree_t d = tree_decl(arch, i);
      if (tree_ident(d) == name)
         return d;
   }

   type_t port_type   = tree_type(port);
   type_t actual_type = tree_type(actual);

   type_t type = (type_is_unconstrained(port_type)) ? actual_type : port_type;

   port_mode_t mode = tree_subkind(port);

   tree_t s = tree_new(T_SIGNAL_DECL);
   tree_set_ident(s, tree_ident(port));
   tree_set_type(s, type);
   tree_add_attr_int(s, fst_dir_i, mode);
   tree_set_loc(s, tree_loc(port));
   tree_set_flag(s, tree_flags(port) & TREE_F_LAST_VALUE);

   if ((mode == PORT_OUT) || (mode == PORT_INOUT) || (mode == PORT_BUFFER)) {
      if (tree_has_value(port))
         tree_add_attr_tree(s, driver_init_i, tree_value(port));
   }

   tree_add_decl(arch, s);
   return s;
}
예제 #2
0
파일: eval.c 프로젝트: manasdas17/nvc
static tree_t get_bool_lit(tree_t t, bool v)
{
   tree_t fdecl = tree_ref(t);
   assert(tree_kind(fdecl) == T_FUNC_DECL);

   static type_t bool_type = NULL;
   if (bool_type == NULL) {
      lib_t std = lib_find("std", true, true);
      assert(std != NULL);

      tree_t standard = lib_get(std, ident_new("STD.STANDARD"));
      assert(standard != NULL);

      const int ndecls = tree_decls(standard);
      for (int i = 0; (i < ndecls) && (bool_type == NULL); i++) {
         tree_t d = tree_decl(standard, i);
         if (tree_ident(d) == std_bool_i)
            bool_type = tree_type(d);
      }
      assert(bool_type != NULL);
   }

   tree_t lit = type_enum_literal(bool_type, v ? 1 : 0);

   tree_t b = tree_new(T_REF);
   tree_set_loc(b, tree_loc(t));
   tree_set_ref(b, lit);
   tree_set_type(b, bool_type);
   tree_set_ident(b, tree_ident(lit));

   return b;
}
예제 #3
0
파일: test_elab.c 프로젝트: manasdas17/nvc
END_TEST

START_TEST(test_copy1)
{
   input_from_file(TESTDIR "/elab/copy1.vhd");

   const error_t expect[] = {
      { -1, NULL }
   };
   expect_errors(expect);

   tree_t e = run_elab();

   int nfuncs = 0, nshared = 0;

   const int ndecls = tree_decls(e);
   for (int i = 0; i < ndecls; i++) {
      tree_t t = tree_decl(e, i);
      if (tree_kind(t) == T_FUNC_BODY)
         nfuncs++;
      else if (tree_kind(t) == T_VAR_DECL)
         nshared++;
   }

   fail_unless(nfuncs == 1);
   fail_unless(nshared == 2);
}
예제 #4
0
파일: vcd.c 프로젝트: SnookEE/nvc
void vcd_restart(void)
{
   if (vcd_file == NULL)
      return;

   vcd_emit_header();

   int next_key = 0;
   const int ndecls = tree_decls(vcd_top);
   for (int i = 0; i < ndecls; i++) {
      tree_t d = tree_decl(vcd_top, i);
      switch (tree_kind(d)) {
      case T_HIER:
         fprintf(vcd_file, "$scope module %s $end\n", istr(tree_ident(d)));
         break;
      case T_SIGNAL_DECL:
         if (wave_should_dump(d))
            vcd_process_signal(d, &next_key);
         break;
      default:
         break;
      }

      int npop = tree_attr_int(d, ident_new("scope_pop"), 0);
      while (npop-- > 0)
         fprintf(vcd_file, "$upscope $end\n");
   }

   fprintf(vcd_file, "$enddefinitions $end\n");

   fprintf(vcd_file, "$dumpvars\n");

   last_time = UINT64_MAX;

   for (int i = 0; i < ndecls; i++) {
      tree_t d = tree_decl(vcd_top, i);
      if (tree_kind(d) == T_SIGNAL_DECL) {
         vcd_data_t *data = tree_attr_ptr(d, vcd_data_i);
         if (likely(data != NULL))
            vcd_event_cb(0, d, data->watch, data);
      }
   }

   fprintf(vcd_file, "$end\n");
}
예제 #5
0
파일: shell.c 프로젝트: a4a881d4/nvc
void shell_run(tree_t e, struct tree_rd_ctx *ctx)
{
   const int ndecls = tree_decls(e);
   hash_t *decl_hash = hash_new(ndecls * 2, true);
   for (int i = 0; i < ndecls; i++) {
      tree_t d = tree_decl(e, i);
      hash_put(decl_hash, tree_ident(d), d);
   }

   Tcl_Interp *interp = Tcl_CreateInterp();

   bool have_quit = false;

   Tcl_CreateExitHandler(shell_exit_handler, &have_quit);

   shell_cmd_t shell_cmds[] = {
      CMD(quit,      &have_quit, "Exit simulation"),
      CMD(run,       ctx,        "Start or resume simulation"),
      CMD(restart,   NULL,       "Restart simulation"),
      CMD(show,      decl_hash,  "Display simulation objects"),
      CMD(help,      shell_cmds, "Display this message"),
      CMD(copyright, NULL,       "Display copyright information"),
      CMD(signals,   e,          "Find signal objects in the design"),
      CMD(now,       NULL,       "Display current simulation time"),
      CMD(watch,     decl_hash,  "Trace changes to a signal"),
      CMD(unwatch,   decl_hash,  "Stop tracing signals"),

      { NULL, NULL, NULL, NULL}
   };

   qsort(shell_cmds, ARRAY_LEN(shell_cmds) - 1, sizeof(shell_cmd_t),
         compare_shell_cmd);

   for (shell_cmd_t *c = shell_cmds; c->name != NULL; c++)
      Tcl_CreateObjCommand(interp, c->name, c->fn, c->cd, NULL);

   show_banner();

   slave_post_msg(SLAVE_RESTART, NULL, 0);

   char *line;
   while (!have_quit && (line = shell_get_line())) {
      switch (Tcl_Eval(interp, line)) {
      case TCL_OK:
         break;
      case TCL_ERROR:
         errorf("%s", Tcl_GetStringResult(interp));
         break;
      default:
         assert(false);
      }

      free(line);
   }

   Tcl_Exit(EXIT_SUCCESS);
}
예제 #6
0
파일: test_elab.c 프로젝트: manasdas17/nvc
END_TEST

START_TEST(test_issue19)
{
   input_from_file(TESTDIR "/elab/issue19.vhd");

   const error_t expect[] = {
      { -1, NULL }
   };
   expect_errors(expect);

   tree_t e = run_elab();

   tree_t tmp = NULL;
   const int ndecls = tree_decls(e);
   for (int i = 0; (i < ndecls) && (tmp == NULL); i++) {
      tree_t t = tree_decl(e, i);
      if (icmp(tree_ident(t), ":comp6:c1:tmp"))
         tmp = t;
   }

   fail_if(tmp == NULL);

   tree_t value = tree_value(tmp);
   fail_unless(tree_kind(value) == T_LITERAL);
   fail_unless(tree_ival(value) == 32);

   for (int i = 0; (i < ndecls) && (tmp == NULL); i++) {
      tree_t t = tree_decl(e, i);
      if (icmp(tree_ident(t), ":comp6:c1:tmp3"))
         tmp = t;
   }

   fail_if(tmp == NULL);

   value = tree_value(tmp);
   fail_unless(tree_kind(value) == T_LITERAL);
   fail_unless(tree_ival(value) == 32);
}
예제 #7
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);
      }
   }
}
예제 #8
0
파일: lxt.c 프로젝트: SnookEE/nvc
void lxt_restart(void)
{
   if (trace == NULL)
      return;

   lt_set_timescale(trace, -15);
   lt_symbol_bracket_stripping(trace, 0);
   lt_set_clock_compress(trace);

   const int ndecls = tree_decls(lxt_top);
   for (int i = 0; i < ndecls; i++) {
      tree_t d = tree_decl(lxt_top, i);
      if (tree_kind(d) != T_SIGNAL_DECL)
         continue;
      else if (!wave_should_dump(d))
         continue;

      type_t type = tree_type(d);

      int rows, msb, lsb;
      if (type_is_array(type)) {
         rows = type_dims(type) - 1;
         if ((rows > 0) || type_is_array(type_elem(type))) {
            warn_at(tree_loc(d), "cannot emit arrays of greater than one "
                    "dimension or arrays of arrays in LXT yet");
            continue;
         }

         range_t r = type_dim(type, 0);
         msb = assume_int(r.left);
         lsb = assume_int(r.right);
      }
      else {
         rows = 0;
         msb = lsb = -1;
      }

      lxt_data_t *data = xmalloc(sizeof(lxt_data_t));
      memset(data, '\0', sizeof(lxt_data_t));

      int flags = 0;

      if (type_is_array(type)) {
         // Only arrays of CHARACTER, BIT, STD_ULOGIC are supported
         type_t elem = type_base_recur(type_elem(type));
         if ((type_kind(elem) != T_ENUM)
             || !lxt_can_fmt_enum_chars(elem, data, &flags)) {
            warn_at(tree_loc(d), "cannot represent arrays of type %s "
                    "in LXT format", type_pp(elem));
            free(data);
            continue;
         }

         data->dir = type_dim(type, 0).kind;
      }
      else {
         type_t base = type_base_recur(type);
         switch (type_kind(base)) {
         case T_INTEGER:
            data->fmt = lxt_fmt_int;
            flags = LT_SYM_F_INTEGER;
            break;

         case T_ENUM:
            if (!lxt_can_fmt_enum_chars(base, data, &flags)) {
               data->fmt = lxt_fmt_enum;
               flags = LT_SYM_F_STRING;
            }
            break;

         default:
            warn_at(tree_loc(d), "cannot represent type %s in LXT format",
                    type_pp(type));
            free(data);
            continue;
         }
      }

      char *name = lxt_fmt_name(d);
      data->sym = lt_symbol_add(trace, name, rows, msb, lsb, flags);
      free(name);

      tree_add_attr_ptr(d, lxt_data_i, data);

      watch_t *w = rt_set_event_cb(d, lxt_event_cb, data, true);

      (*data->fmt)(d, w, data);
   }

   last_time = (lxttime_t)-1;
}
예제 #9
0
파일: shell.c 프로젝트: SnookEE/nvc
static int shell_cmd_signals(ClientData cd, Tcl_Interp *interp,
                             int objc, Tcl_Obj *const objv[])
{
   const char *help =
      "signals - Find signal objects in the design\n"
      "\n"
      "Usage: signals [GLOB]\n"
      "\n"
      "Returns a list of signal names. Pass to `show' to see current values\n"
      "and types. GLOB is either the fully qualified name of a signal; a\n"
      "pattern containing a wildcard character '*'; or an unqualified name\n"
      "without the hierarchy separator ':' which matches that name at any\n"
      "level.\n"
      "\n"
      "Examples:\n"
      "  signals            List of all signal objects\n"
      "  signals {*foo*}    Find signals containing `foo'\n"
      "  signals {*:clk}    Find signals named `clk' at any level\n"
      "  signals {clk}      Equivalent to the above\n"
      "  show [signals]     Display current value of all signals\n";

   if (show_help(objc, objv, help))
      return TCL_OK;

   tree_t top = cd;
   const int ndecls = tree_decls(top);

   Tcl_Obj *result = Tcl_NewListObj(0, NULL);

   if (objc == 1) {
      for (int j = 0; j < ndecls; j++) {
         tree_t d = tree_decl(top, j);
         if (tree_kind(d) != T_SIGNAL_DECL)
            continue;

         Tcl_Obj *obj = Tcl_NewStringObj(istr(tree_ident(d)), -1);
         Tcl_ListObjAppendElement(interp, result, obj);
      }
   }
   else {
      for (int i = 1; i < objc; i++) {
         const char *glob = Tcl_GetString(objv[i]);
         char *expand = NULL;
         if ((*glob != ':') && (*glob != '*')) {
            const size_t sz = strlen(glob) + 3;
            expand = xmalloc(sz);
            checked_sprintf(expand, sz, "*:%s", glob);

            glob = expand;
         }

         for (int j = 0; j < ndecls; j++) {
            tree_t d = tree_decl(top, j);
            if (tree_kind(d) != T_SIGNAL_DECL)
               continue;

            ident_t name = tree_ident(d);
            if (ident_glob(name, glob, -1)) {
               Tcl_Obj *obj = Tcl_NewStringObj(istr(name), -1);
               Tcl_ListObjAppendElement(interp, result, obj);
            }
         }

         if (expand != NULL)
            free(expand);
      }
   }

   Tcl_SetObjResult(interp, result);
   return TCL_OK;
}