コード例 #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
ファイル: common.c プロジェクト: gr8linux/nvc
type_t array_aggregate_type(type_t array, int from_dim)
{
   if (type_is_unconstrained(array)) {
      const int nindex = type_index_constrs(array);
      assert(from_dim < nindex);

      type_t type = type_new(T_UARRAY);
      type_set_ident(type, type_ident(array));
      type_set_elem(type, type_elem(array));

      for (int i = from_dim; i < nindex; i++)
         type_add_index_constr(type, type_index_constr(array, i));

      return type;
   }
   else {
      const int ndims = type_dims(array);
      assert(from_dim < ndims);

      type_t type = type_new(T_CARRAY);
      type_set_ident(type, type_ident(array));
      type_set_elem(type, type_elem(array));

      for (int i = from_dim; i < ndims; i++)
         type_add_dim(type, type_dim(array, i));

      return type;
   }
}
コード例 #3
0
ファイル: type.c プロジェクト: manasdas17/nvc
bool type_is_unconstrained(type_t t)
{
   assert(t != NULL);
   if (t->kind == T_SUBTYPE) {
      if (type_dims(t) == 0)
         return type_is_unconstrained(type_base(t));
      else
         return false;
   }
   else
      return (t->kind == T_UARRAY);
}
コード例 #4
0
ファイル: common.c プロジェクト: gr8linux/nvc
type_t index_type_of(type_t type, int dim)
{
   if (type_is_unconstrained(type))
      return type_index_constr(type_base_recur(type), dim);
   else if (type_kind(type) == T_ENUM)
      return type;
   else {
      tree_t left = type_dim(type, dim).left;

      // If the left bound has not been assigned a type then there is some
      // error with it so just return a dummy type here
      return tree_has_type(left) ? tree_type(left) : type;
   }
}
コード例 #5
0
ファイル: group.c プロジェクト: nickg/nvc
static bool group_name(tree_t target, group_nets_ctx_t *ctx, int start, int n)
{
   switch (tree_kind(target)) {
   case T_REF:
      group_ref(target, ctx, start, n);
      return true;

   case T_ARRAY_REF:
      {
         tree_t value = tree_value(target);

         type_t type = tree_type(value);
         if (type_is_unconstrained(type))
            return false;

         int offset = 0;
         const int nparams = tree_params(target);
         for (int i = 0; i < nparams; i++) {
            tree_t index = tree_value(tree_param(target, i));
            const int stride = type_width(type_elem(type));

            if (tree_kind(index) != T_LITERAL) {
               if (i > 0)
                  return false;

               const int twidth = type_width(type);
               for (int j = 0; j < twidth; j += stride)
                  group_name(value, ctx, start + j, n);
               return true;
            }
            else {
               if (i > 0) {
                  range_t type_r = range_of(type, i);
                  int64_t low, high;
                  range_bounds(type_r, &low, &high);
                  offset *= high - low + 1;
               }

               offset += stride * rebase_index(type, i, assume_int(index));
            }
         }

         return group_name(value, ctx, start + offset, n);
      }

   case T_ARRAY_SLICE:
      {
         tree_t value = tree_value(target);
         type_t type  = tree_type(value);

         if (type_is_unconstrained(type))
            return false;    // Only in procedure

         range_t slice = tree_range(target, 0 );

         if (tree_kind(slice.left) != T_LITERAL
             || tree_kind(slice.right) != T_LITERAL)
            return false;

         int64_t low, high;
         range_bounds(slice, &low, &high);

         const int64_t low0 = rebase_index(type, 0, assume_int(slice.left));
         const int stride   = type_width(type_elem(type));

         return group_name(value, ctx, start + low0 * stride, n);
      }

   case T_RECORD_REF:
      {
         tree_t value = tree_value(target);
         type_t rec = tree_type(value);
         const int offset = record_field_to_net(rec, tree_ident(target));

         return group_name(value, ctx, start + offset, n);
      }

   case T_AGGREGATE:
   case T_LITERAL:
      // This can appear due to assignments to open ports with a
      // default value
      return true;

   default:
      fatal_at(tree_loc(target), "tree kind %s not yet supported for offset "
               "calculation", tree_kind_str(tree_kind(target)));
   }
}
コード例 #6
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)));
   }
}
コード例 #7
0
ファイル: common.c プロジェクト: gr8linux/nvc
unsigned array_dimension(type_t a)
{
   return (type_is_unconstrained(a)
           ? type_index_constrs(type_base_recur(a))
           : type_dims(a));
}