Exemple #1
0
static void group_decl(tree_t decl, group_nets_ctx_t *ctx, int start, int n)
{
   netid_t first = NETID_INVALID;
   unsigned len = 0;
   type_t type = tree_type(decl);
   const int nnets = tree_nets(decl);
   const bool record = group_contains_record(type);
   int ffield = -1;
   assert((n == -1) | (start + n <= nnets));
   for (int i = start; i < (n == -1 ? nnets : start + n); i++) {
      netid_t nid = tree_net(decl, i);
      if (first == NETID_INVALID) {
         first  = nid;
         len    = 1;
         ffield = record ? group_net_to_field(type, i) : -1;
      }
      else if (nid == first + len
               && (!record || group_net_to_field(type, i) == ffield))
         ++len;
      else {
         group_add(ctx, first, len);
         first  = nid;
         len    = 1;
         ffield = record ? group_net_to_field(type, i) : -1;
      }
   }

   if (first != NETID_INVALID)
      group_add(ctx, first, len);
   else {
      // Array signal with null range
      tree_add_attr_int(decl, null_range_i, 1);
   }
}
Exemple #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;
}
Exemple #3
0
Fichier : opt.c Projet : chiggs/nvc
static void opt_elide_array_ref_bounds(tree_t t)
{
   tree_t value = tree_value(t);
   if (tree_kind(value) != T_REF)
      return;

   tree_t decl = tree_ref(value);

   const int nparams = tree_params(t);
   for (int i = 0; i < nparams; i++) {
      tree_t index = tree_value(tree_param(t, i));
      if (tree_kind(index) != T_REF)
         return;

      tree_t index_decl = tree_ref(index);

      tree_t range_var = tree_attr_tree(index_decl, range_var_i);
      if (range_var == NULL)
         return;

      if (range_var != decl)
         return;
   }

   tree_add_attr_int(t, elide_bounds_i, 1);
}
Exemple #4
0
Fichier : opt.c Projet : chiggs/nvc
static void opt_tag_last_value_fcall(tree_t t)
{
   tree_t decl = tree_ref(t);

   if (tree_attr_str(decl, builtin_i) != NULL)
      return;

   // A regular subprogram call may pass parameters as class signal which
   // could access 'LAST_VALUE in the body

   const int nports = tree_ports(decl);
   for (int i = 0; i < nports; i++) {
      tree_t port = tree_port(decl, i);
      if (tree_class(port) != C_SIGNAL)
         continue;

      tree_t value = tree_value(tree_param(t, i));
      tree_kind_t kind;
      while ((kind = tree_kind(value)) != T_REF) {
         assert((kind == T_ARRAY_REF) || (kind == T_ARRAY_SLICE));
         value = tree_value(value);
      }

      tree_add_attr_int(tree_ref(value), last_value_i, 1);
   }
}
Exemple #5
0
void cover_tag(tree_t top)
{
   stmt_tag_i = ident_new("stmt_tag");

   int line_tags = 0;
   tree_visit(top, cover_tag_stmts_fn, &line_tags);

   tree_add_attr_int(top, ident_new("stmt_tags"), line_tags);
}
Exemple #6
0
Fichier : opt.c Projet : 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);
   }
}
Exemple #7
0
static void cover_tag_stmts_fn(tree_t t, void *context)
{
   int *next = context;

   switch (tree_kind(t)) {
   case T_SIGNAL_ASSIGN:
   case T_ASSERT:
   case T_VAR_ASSIGN:
   case T_IF:
   case T_WHILE:
   case T_WAIT:
   case T_RETURN:
   case T_NEXT:
   case T_EXIT:
      tree_add_attr_int(t, stmt_tag_i, (*next)++);
      break;

   default:
      break;
   }
}
Exemple #8
0
static tree_t elab_signal_port(tree_t arch, tree_t formal, tree_t param,
                               map_list_t **maps)
{
   assert(tree_kind(param) == T_PARAM);

   tree_t actual = tree_value(param);

   // NULL name means associate the whole port
   tree_t name = NULL;
   if (tree_subkind(param) == P_NAMED) {
      tree_t n = tree_name(param);
      if (tree_kind(n) != T_REF)
         name = n;
   }

   const bool partial_map = name != NULL;

   switch (tree_kind(actual)) {
   case T_REF:
   case T_ARRAY_REF:
   case T_ARRAY_SLICE:
   case T_RECORD_REF:
      {
         // Replace the formal port with a signal and connect its nets to
         // those of the actual

         tree_t ref = actual;
         tree_kind_t ref_kind;
         while ((ref_kind = tree_kind(ref)) != T_REF) {
            if ((ref_kind == T_AGGREGATE) || (ref_kind == T_LITERAL))
               return actual;
            else
               ref = tree_value(ref);
         }

         tree_t decl = tree_ref(ref);
         tree_kind_t decl_kind = tree_kind(decl);
         if (decl_kind == T_SIGNAL_DECL) {
            tree_t s = elab_port_to_signal(arch, formal, actual);

            if (partial_map)
               tree_add_attr_int(s, partial_map_i, 1);

            map_list_t *m = xmalloc(sizeof(map_list_t));
            m->next   = *maps;
            m->formal = formal;
            m->actual = actual;
            m->signal = s;
            m->name   = name;

            *maps = m;

            return s;
         }
         else if (decl_kind == T_PORT_DECL)
            return NULL;    // Port was OPEN at a higher level
         else
            return actual;
      }

   case T_LITERAL:
   case T_AGGREGATE:
      {
         type_t formal_type = tree_type(formal);
         if (!type_is_unconstrained(formal_type))
            tree_set_type(actual, formal_type);
         return actual;
      }

   case T_OPEN:
      return NULL;

   case T_TYPE_CONV:
      // Only allow simple array type conversions for now
      {
         type_t to_type   = tree_type(actual);
         type_t from_type = tree_type(tree_value(tree_param(actual, 0)));

         if (type_is_array(to_type) && type_is_array(from_type))
            return actual;
         else
            fatal_at(tree_loc(actual), "sorry, this form of type conversion "
                     "is not supported as an actual");
      }

   default:
      fatal_at(tree_loc(actual), "tree %s not supported as actual",
               tree_kind_str(tree_kind(actual)));
   }
}