示例#1
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;
}
示例#2
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;
}
示例#3
0
static void elab_add_context(tree_t t, const elab_ctx_t *ctx)
{
   ident_t cname = tree_ident(t);
   ident_t lname = ident_until(cname, '.');

   lib_t lib = elab_find_lib(lname, ctx);

   tree_t unit = lib_get(lib, cname);
   if (unit == NULL)
      fatal_at(tree_loc(t), "cannot find unit %s", istr(cname));
   else if (tree_kind(unit) == T_PACKAGE) {
      elab_copy_context(unit, ctx);

      ident_t name = tree_ident(unit);

      ident_t body_i = ident_prefix(name, ident_new("body"), '-');
      tree_t body = lib_get(lib, body_i);
      if (body != NULL)
         elab_copy_context(unit, ctx);
   }

   // Always use real library name rather than WORK alias
   tree_set_ident(t, tree_ident(unit));

   tree_add_context(ctx->out, t);
}
示例#4
0
static void find_arch(ident_t name, int kind, void *context)
{
   lib_search_params_t *params = context;

   ident_t prefix = ident_until(name, '-');

   if ((kind == T_ARCH) && (prefix == params->name)) {
      tree_t t = lib_get_check_stale(params->lib, name);
      assert(t != NULL);

      if (*(params->tree) == NULL)
         *(params->tree) = t;
      else {
         lib_mtime_t old_mtime = lib_mtime(params->lib,
                                           tree_ident(*(params->tree)));
         lib_mtime_t new_mtime = lib_mtime(params->lib, tree_ident(t));

         if (new_mtime == old_mtime) {
            // Analysed at the same time: compare line number
            // Note this assumes both architectures are from the same
            // file but this shouldn't be a problem with high-resolution
            // timestamps
            uint16_t new_line = tree_loc(t)->first_line;
            uint16_t old_line = tree_loc(*(params->tree))->first_line;

            if (new_line > old_line)
               *(params->tree) = t;
         }
         else if (new_mtime > old_mtime)
            *(params->tree) = t;
      }
   }
}
示例#5
0
文件: common.c 项目: gr8linux/nvc
tree_t find_record_field(tree_t rref)
{
   ident_t fname = tree_ident(rref);
   type_t value_type = tree_type(tree_value(rref));

   const int nfields = type_fields(value_type);
   for (int i = 0; i < nfields; i++) {
      tree_t field = type_field(value_type, i);
      if (tree_ident(field) == fname)
         return field;
   }

   return NULL;
}
示例#6
0
文件: link.c 项目: ifreemyli/nvc
static bool link_find_native_library(lib_t lib, tree_t unit, FILE *deps)
{
#ifdef ENABLE_NATIVE
   ident_t name = tree_ident(unit);

   char *so_name = xasprintf("_%s.so", istr(name));

   lib_mtime_t so_mt;
   if (!lib_stat(lib, so_name, &so_mt)) {
      free(so_name);
      return false;
   }

   lib_mtime_t unit_mt = lib_mtime(lib, name);

   if (unit_mt > so_mt) {
      warnf("unit %s has stale native shared library", istr(name));
      free(so_name);
      return false;
   }

   if (deps != NULL) {
      char path[PATH_MAX];
      lib_realpath(lib, so_name, path, sizeof(path));

      fprintf(deps, "%s\n", path);
   }

   free(so_name);
   return true;
#else   // ENABLE_NATIVE
   return false;
#endif  // ENABLE_NATIVE
}
示例#7
0
文件: link.c 项目: ifreemyli/nvc
static void link_context_bc_fn(lib_t lib, tree_t unit, FILE *deps)
{
   if (!link_find_native_library(lib, unit, deps)) {
      link_arg_bc(lib, tree_ident(unit));
      n_linked_bc++;
   }
}
示例#8
0
文件: link.c 项目: ifreemyli/nvc
static void link_context_package(tree_t unit, lib_t lib,
                                 FILE *deps, context_fn_t fn)
{
   assert(n_linked < MAX_ARGS - 1);

   if (pack_needs_cgen(unit) && !link_already_have(unit)) {
      (*fn)(lib, unit, deps);
      linked[n_linked++] = unit;
   }

   link_all_context(unit, deps, fn);

   ident_t name = tree_ident(unit);

   ident_t body_i = ident_prefix(name, ident_new("body"), '-');
   tree_t body = lib_get(lib, body_i);
   if (body == NULL) {
      if (link_needs_body(unit))
         fatal("missing body for package %s", istr(name));
      else
         return;
   }

   link_all_context(body, deps, fn);

   if (!link_already_have(body)) {
      (*fn)(lib, body, deps);
      linked[n_linked++] = body;
   }
}
示例#9
0
文件: lxt.c 项目: SnookEE/nvc
static void lxt_fmt_enum(tree_t decl, watch_t *w, lxt_data_t *data)
{
   uint64_t val;
   rt_watch_value(w, &val, 1, false);

   tree_t lit = type_enum_literal(tree_type(decl), val);
   lt_emit_value_string(trace, data->sym, 0, (char *)istr(tree_ident(lit)));
}
示例#10
0
文件: shell.c 项目: a4a881d4/nvc
static void event_watch(event_watch_msg_t *event, tree_rd_ctx_t ctx)
{
   tree_t decl = tree_read_recall(ctx, event->index);

   printf("%s: update %s ", event->now_text, istr(tree_ident(decl)));
   printf("%s -> ", pprint(decl, &(event->last), 1));
   printf("%s\n", pprint(decl, &(event->value), 1));
}
示例#11
0
文件: common.c 项目: gr8linux/nvc
tree_t make_ref(tree_t to)
{
   tree_t t = tree_new(T_REF);
   tree_set_ident(t, tree_ident(to));
   tree_set_ref(t, to);
   tree_set_type(t, tree_type(to));
   return t;
}
示例#12
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);
}
示例#13
0
文件: lxt.c 项目: SnookEE/nvc
static char *lxt_fmt_name(tree_t decl)
{
   char *s = strdup(istr(tree_ident(decl)) + 1);
   for (char *p = s; *p != '\0'; p++) {
      if (*p == ':')
         *p = '.';
   }
   return s;
}
示例#14
0
文件: fst.c 项目: SnookEE/nvc
static void fst_fmt_enum(tree_t decl, watch_t *w, fst_data_t *data)
{
   uint64_t val;
   rt_watch_value(w, &val, 1, false);

   tree_t lit = type_enum_literal(tree_type(decl), val);
   const char *str = istr(tree_ident(lit));

   fstWriterEmitVariableLengthValueChange(
      fst_ctx, data->handle, str, strlen(str));
}
示例#15
0
static void elab_pseudo_context(tree_t out, tree_t src)
{
   // Add a pseudo use clause for an entity or architecture so the
   // makefile generator can find the dependencies

   ident_t name = tree_ident(src);

   const int nctx = tree_contexts(out);
   for (int i = 0; i < nctx; i++) {
      tree_t c = tree_context(out, i);
      if (tree_kind(c) != T_USE)
         continue;
      else if (tree_ident(c) == name)
         return;
   }

   tree_t c = tree_new(T_USE);
   tree_set_ident(c, name);

   tree_add_context(out, c);
}
示例#16
0
文件: shell.c 项目: SnookEE/nvc
static void event_watch(uint64_t now, tree_t decl, watch_t *w, void *user)
{
   uint64_t value[1];
   rt_watch_value(w, value, 1, false);

   uint64_t last[1];
   rt_watch_value(w, last, 1, true);

   LOCAL_TEXT_BUF last_tb = pprint(decl, last, 1);
   LOCAL_TEXT_BUF now_tb  = pprint(decl, value, 1);
   printf("%s: update %s %s -> %s\n", fmt_time(rt_now(NULL)),
          istr(tree_ident(decl)), tb_get(last_tb), tb_get(now_tb));
}
示例#17
0
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);
}
示例#18
0
文件: common.c 项目: gr8linux/nvc
tree_t get_bool_lit(tree_t t, bool v)
{
   type_t bool_type = tree_type(t);
   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;
}
示例#19
0
static bool elab_have_context(tree_t unit, ident_t name)
{
   const int ndest = tree_contexts(unit);
   for (int i = 0; i < ndest; i++) {
      tree_t c2 = tree_context(unit, i);
      if (tree_kind(c2) != T_USE)
         continue;

      if (tree_ident(c2) == name)
         return true;
   }

   return false;
}
示例#20
0
文件: fst.c 项目: SnookEE/nvc
static fst_unit_t *fst_make_unit_map(type_t type)
{
   type_t base = type_base_recur(type);

   const int nunits = type_units(base);

   fst_unit_t *map = xmalloc(nunits * sizeof(fst_unit_t));
   for (int i = 0; i < nunits; i++) {
      tree_t unit = type_unit(base, nunits - 1 - i);
      map[i].mult = assume_int(tree_value(unit));
      map[i].name = strdup(istr(tree_ident(unit)));
   }

   return map;
}
示例#21
0
文件: common.c 项目: gr8linux/nvc
int record_field_to_net(type_t type, ident_t name)
{
   int offset = 0;

   const int nfields = type_fields(type);
   for (int i = 0; i < nfields; i++) {
      tree_t field = type_field(type, i);
      if (tree_ident(field) == name)
         return offset;
      else
         offset += type_width(tree_type(field));
   }

   assert(false);
}
示例#22
0
static void elab_use_clause(tree_t use, const elab_ctx_t *ctx)
{
   tree_set_ident2(use, all_i);

   ident_t name = tree_ident(use);
   ident_t lname = ident_until(name, '.');

   elab_ctx_t new_ctx = *ctx;
   new_ctx.library = elab_find_lib(lname, ctx);

   if (name == lname)
      lib_walk_index(new_ctx.library, elab_context_walk_fn, &new_ctx);
   else if (!elab_have_context(ctx->out, name))
      elab_add_context(use, &new_ctx);
}
示例#23
0
文件: link.c 项目: ifreemyli/nvc
static void link_context(tree_t ctx, FILE *deps, context_fn_t fn)
{
   ident_t cname = tree_ident(ctx);
   ident_t lname = ident_until(cname, '.');

   lib_t lib = lib_find(istr(lname), true, true);
   if (lib == NULL)
      fatal("cannot link library %s", istr(lname));

   if (lname == cname) {
         lib_walk_params_t params = {
            .lib  = lib,
            .deps = deps,
            .fn   = fn
         };
         lib_walk_index(lib, link_walk_lib, &params);
   }
示例#24
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");
}
示例#25
0
文件: opt.c 项目: chiggs/nvc
static void opt_tag_last_value_attr_ref(tree_t t)
{
   static ident_t last_value_attr_i = NULL;

   if (last_value_attr_i == NULL)
      last_value_attr_i = ident_new("LAST_VALUE");

   if (tree_ident(t) == last_value_attr_i) {
      tree_t signal = tree_ref(tree_name(t));
      if (tree_kind(signal) != T_SIGNAL_DECL)
         return;

      // A signal in a package will not have nets assigned yet so we cannot
      // optimise out 'LAST_VALUE
      if (tree_nets(signal) > 0)
         tree_add_attr_int(signal, last_value_i, 1);
   }
}
示例#26
0
static ident_t elab_formal_name(tree_t t)
{
   tree_kind_t kind;
   while ((kind = tree_kind(t)) != T_REF) {
      switch (kind) {
      case T_ARRAY_REF:
      case T_ARRAY_SLICE:
         t = tree_value(t);
         break;

      default:
         fatal_at(tree_loc(t), "sorry, this kind of formal is not supported %s",
                  tree_kind_str(kind));
      }
   }

   return tree_ident(t);
}
示例#27
0
文件: group.c 项目: nickg/nvc
static void group_write_netdb(tree_t top, group_nets_ctx_t *ctx)
{
   char *name = xasprintf("_%s.netdb", istr(tree_ident(top)));

   fbuf_t *f = lib_fbuf_open(lib_work(), name, FBUF_OUT);
   if (f == NULL)
      fatal("failed to create net database file %s", name);

   free(name);

   for (group_t *it = ctx->groups; it != NULL; it = it->next) {
      write_u32(it->gid, f);
      write_u32(it->first, f);
      write_u32(it->length, f);
   }
   write_u32(GROUPID_INVALID, f);

   fbuf_close(f);
}
示例#28
0
文件: common.c 项目: gr8linux/nvc
tree_t str_to_literal(const char *start, const char *end, type_t type)
{
   tree_t t = tree_new(T_LITERAL);
   tree_set_subkind(t, L_STRING);

   type_t elem = NULL;
   if (type != NULL) {
      tree_set_type(t, type);
      elem = type_elem(type);
   }

   char last = '\0';
   for (const char *p = start; *p != '\0' && p != end; p++) {
      if (*p == -127)
         continue;
      else if (*p == '"' && last == '"') {
         last = '\0';
         continue;
      }
      else
         last = *p;

      const char ch[] = { '\'', *p, '\'', '\0' };
      ident_t id = ident_new(ch);
      tree_t ref = tree_new(T_REF);
      tree_set_ident(ref, id);
      tree_add_char(t, ref);

      if (elem != NULL) {
         const int nlit = type_enum_literals(elem);
         for (int i = 0; i < nlit; i++) {
            tree_t lit = type_enum_literal(elem, i);
            if (tree_ident(lit) == id) {
               tree_set_ref(ref, lit);
               break;
            }
         }
      }
   }

   return t;
}
示例#29
0
文件: elab.c 项目: sylphase/nvc
static void elab_copy_context(tree_t src, const elab_ctx_t *ctx)
{
   const int nsrc = tree_contexts(src);
   for (int i = 0; i < nsrc; i++) {
      tree_t c = tree_context(src, i);
      if (tree_kind(c) != T_USE)
         continue;

      tree_set_ident2(c, all_i);

      ident_t name = tree_ident(c);
      ident_t lname = ident_until(name, '.');

      elab_ctx_t new_ctx = *ctx;
      new_ctx.library = elab_find_lib(lname, ctx);

      if (name == lname)
         lib_walk_index(new_ctx.library, elab_context_walk_fn, &new_ctx);
      else if (!elab_have_context(ctx->out, name))
         elab_add_context(c, &new_ctx);
   }
}
示例#30
0
文件: fst.c 项目: SnookEE/nvc
static void fst_process_hier(tree_t h)
{
   const tree_kind_t scope_kind = tree_subkind(h);

   enum fstScopeType st;
   switch (scope_kind) {
   case T_ARCH: st = FST_ST_VHDL_ARCHITECTURE; break;
   case T_BLOCK: st = FST_ST_VHDL_BLOCK; break;
   case T_FOR_GENERATE: st = FST_ST_VHDL_FOR_GENERATE; break;
   case T_PACKAGE: st = FST_ST_VHDL_PACKAGE; break;
   default:
      st = FST_ST_VHDL_ARCHITECTURE;
      warn_at(tree_loc(h), "no FST scope type for %s",
              tree_kind_str(scope_kind));
      break;
   }

   const loc_t *loc = tree_loc(h);
   fstWriterSetSourceStem(fst_ctx, loc->file, loc->first_line, 1);

   fstWriterSetScope(fst_ctx, st, istr(tree_ident(h)),
                     tree_has_ident2(h) ? istr(tree_ident2(h)) : "");
}