Beispiel #1
0
Datei: fst.c Projekt: SnookEE/nvc
static bool fst_can_fmt_chars(type_t type, fst_data_t *data,
                              enum fstVarType *vt,
                              enum fstSupplementalDataType *sdt)
{
   type_t base = type_base_recur(type);
   ident_t name = type_ident(base);
   if (name == std_ulogic_i) {
      if (type_ident(type) == std_logic_i)
         *sdt = (data->size > 1) ?
            FST_SDT_VHDL_STD_LOGIC_VECTOR : FST_SDT_VHDL_STD_LOGIC;
      else
         *sdt = (data->size > 1) ?
            FST_SDT_VHDL_STD_ULOGIC_VECTOR : FST_SDT_VHDL_STD_ULOGIC;
      *vt = FST_VT_SV_LOGIC;
      data->fmt = fst_fmt_chars;
      data->type.map = "UX01ZWLH-";
      return true;
   }
   else if (name == std_bit_i) {
      *sdt = FST_SDT_VHDL_BIT;
      *vt  = FST_VT_SV_LOGIC;
      data->fmt = fst_fmt_chars;
      data->type.map = "01";
      return true;
   }
   else if ((name == std_char_i) && (data->size > 0)) {
      *sdt = FST_SDT_VHDL_STRING;
      *vt  = FST_VT_GEN_STRING;
      data->fmt = fst_fmt_chars;
      data->type.map = NULL;
      return true;
   }
   else
      return false;
}
Beispiel #2
0
const char *type_pp_minify(type_t t, minify_fn_t fn)
{
   assert(t != NULL);

   switch (type_kind(t)) {
   case T_FUNC:
   case T_PROC:
      {
         char *buf = get_fmt_buf(256);
         static_printf_begin(buf, 256);

         const char *fname = (*fn)(istr(type_ident(t)));

         static_printf(buf, "%s(", fname);
         const int nparams = type_params(t);
         for (int i = 0; i < nparams; i++)
            static_printf(buf, "%s%s",
                          (i == 0 ? "" : ", "),
                          (*fn)(istr(type_ident(type_param(t, i)))));
         static_printf(buf, ")");
         if (type_kind(t) == T_FUNC)
            static_printf(buf, " return %s",
                          (*fn)(istr(type_ident(type_result(t)))));

         return buf;
      }

   default:
      return (*fn)(istr(type_ident(t)));
   }
}
Beispiel #3
0
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;
   }
}
Beispiel #4
0
ident_t type_ident(type_t t)
{
   assert(t != NULL);

   if (t->ident == NULL) {
      char *buf;
      switch (t->kind) {
      case T_SUBTYPE:
         return type_ident(type_base(t));

      case T_ACCESS:
         buf = xasprintf("access to %s",
                  istr(type_ident(type_access(t))));
         break;

      case T_NONE:
         buf = xasprintf("none");
         break;

      default:
         assert(false);
      }

      ident_t ident = ident_new(buf);
      free(buf);
      return ident;
   }
   else
      return t->ident;
}
Beispiel #5
0
void type_write(type_t t, type_wr_ctx_t ctx)
{
   fbuf_t *f = tree_write_file(ctx->tree_ctx);

   if (t == NULL) {
      write_u16(UINT16_C(0xffff), f);   // Null marker
      return;
   }

   if (t->generation == ctx->generation) {
      // Already visited this type
      write_u16(UINT16_C(0xfffe), f);   // Back reference marker
      write_u32(t->index, f);
      return;
   }

   t->generation = ctx->generation;
   t->index      = (ctx->n_types)++;

   write_u16(t->kind, f);

   // Call type_ident here to generate an arbitrary name if needed
   ident_write(type_ident(t), ctx->ident_ctx);

   const uint32_t has = has_map[t->kind];
   const int nitems = __builtin_popcount(has);
   uint32_t mask = 1;
   for (int n = 0; n < nitems; mask <<= 1) {
      if (has & mask) {
         if (ITEM_TYPE_ARRAY & mask) {
            type_array_t *a = &(t->items[n].type_array);
            write_u16(a->count, f);
            for (unsigned i = 0; i < a->count; i++)
               type_write(a->items[i], ctx);
         }
         else if (ITEM_TYPE & mask)
            type_write(t->items[n].type, ctx);
         else if (ITEM_TREE & mask)
            tree_write(t->items[n].tree, ctx->tree_ctx);
         else if (ITEM_TREE_ARRAY & mask) {
            tree_array_t *a = &(t->items[n].tree_array);
            write_u16(a->count, f);
            for (unsigned i = 0; i < a->count; i++)
               tree_write(a->items[i], ctx->tree_ctx);
         }
         else if (ITEM_RANGE_ARRAY & mask) {
            range_array_t *a = &(t->items[n].range_array);
            write_u16(a->count, f);
            for (unsigned i = 0; i < a->count; i++) {
               write_u8(a->items[i].kind, f);
               tree_write(a->items[i].left, ctx->tree_ctx);
               tree_write(a->items[i].right, ctx->tree_ctx);
            }
         }
         else
            item_without_type(mask);
         n++;
      }
   }
}
Beispiel #6
0
bool folded_bool(tree_t t, bool *b)
{
   if (tree_kind(t) == T_REF) {
      tree_t decl = tree_ref(t);
      if (tree_kind(decl) == T_ENUM_LIT
          && type_ident(tree_type(decl)) == std_bool_i) {
         *b = (tree_pos(decl) == 1);
         return true;
      }
   }

   return false;
}
Beispiel #7
0
bool folded_bool(tree_t t, bool *b)
{
   ident_t std_bool_i = ident_new("STD.STANDARD.BOOLEAN");
   if (tree_kind(t) == T_REF) {
      tree_t decl = tree_ref(t);
      if (tree_kind(decl) == T_ENUM_LIT
          && type_ident(tree_type(decl)) == std_bool_i) {
         *b = (tree_pos(decl) == 1);
         return true;
      }
   }

   return false;
}
Beispiel #8
0
Datei: vcd.c Projekt: SnookEE/nvc
static bool vcd_can_fmt_chars(type_t type, vcd_data_t *data)
{
   type_t base = type_base_recur(type);
   ident_t name = type_ident(base);
   if (name == std_ulogic_i) {
      data->fmt = vcd_fmt_chars;
      data->map = "xx01zx01x";
      return true;
   }
   else if (name == std_bit_i) {
      data->fmt = vcd_fmt_chars;
      data->map = "01";
      return true;
   }
   else
      return false;
}
Beispiel #9
0
Datei: lxt.c Projekt: SnookEE/nvc
static bool lxt_can_fmt_enum_chars(type_t type, lxt_data_t *data, int *flags)
{
   ident_t name = type_ident(type);
   if (icmp(name, "IEEE.STD_LOGIC_1164.STD_ULOGIC")) {
      data->fmt = lxt_fmt_chars;
      data->map = std_logic_map;
      *flags = LT_SYM_F_BITS;
      return true;
   }
   else if (icmp(name, "STD.STANDARD.BIT")) {
      data->fmt = lxt_fmt_chars;
      data->map = bit_map;
      *flags = LT_SYM_F_BITS;
      return true;
   }
   else if (icmp(name, "STD.STANDARD.CHARACTER")) {
      data->fmt = lxt_fmt_chars;
      data->map = NULL;
      *flags = LT_SYM_F_STRING;
      return true;
   }
   else
      return false;
}
Beispiel #10
0
Datei: fst.c Projekt: SnookEE/nvc
static void fst_process_signal(tree_t d)
{
   type_t type = tree_type(d);
   type_t base = type_base_recur(type);

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

   int msb = 0, lsb = 0;

   enum fstVarType vt;
   enum fstSupplementalDataType sdt;
   if (type_is_array(type)) {
      if (type_dims(type) > 1) {
         warn_at(tree_loc(d), "cannot represent multidimensional arrays "
                 "in FST format");
         free(data);
         return;
      }

      range_t r = type_dim(type, 0);

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

      data->dir  = r.kind;
      data->size = high - low + 1;

      msb = assume_int(r.left);
      lsb = assume_int(r.right);

      type_t elem = type_elem(type);
      if (!fst_can_fmt_chars(elem, data, &vt, &sdt)) {
         warn_at(tree_loc(d), "cannot represent arrays of type %s "
                 "in FST format", type_pp(elem));
         free(data);
         return;
      }
      else {
         ident_t ident = type_ident(base);
         if (ident == unsigned_i)
            sdt = FST_SDT_VHDL_UNSIGNED;
         else if (ident == signed_i)
            sdt = FST_SDT_VHDL_SIGNED;
      }
   }
   else {
      switch (type_kind(base)) {
      case T_INTEGER:
         {
            ident_t ident = type_ident(type);
            if (ident == natural_i)
               sdt = FST_SDT_VHDL_NATURAL;
            else if (ident == positive_i)
               sdt = FST_SDT_VHDL_POSITIVE;
            else
               sdt = FST_SDT_VHDL_INTEGER;

            int64_t low, high;
            range_bounds(type_dim(type, 0), &low, &high);

            vt = FST_VT_VCD_INTEGER;
            data->size = ilog2(high - low + 1);
            data->fmt  = fst_fmt_int;
         }
         break;

      case T_ENUM:
         if (!fst_can_fmt_chars(type, data, &vt, &sdt)) {
            ident_t ident = type_ident(base);
            if (ident == std_bool_i)
               sdt = FST_SDT_VHDL_BOOLEAN;
            else if (ident == std_char_i)
               sdt = FST_SDT_VHDL_CHARACTER;
            else
               sdt = FST_SDT_NONE;

            vt = FST_VT_GEN_STRING;
            data->size = 0;
            data->fmt  = fst_fmt_enum;
         }
         else
            data->size = 1;
         break;

      case T_PHYSICAL:
         {
            sdt = FST_SDT_NONE;
            vt  = FST_VT_GEN_STRING;
            data->size = 0;
            data->type.units = fst_make_unit_map(type);
            data->fmt = fst_fmt_physical;
         }
         break;

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

   enum fstVarDir dir = FST_VD_IMPLICIT;

   switch (tree_attr_int(d, fst_dir_i, -1)) {
   case PORT_IN: dir = FST_VD_INPUT; break;
   case PORT_OUT: dir = FST_VD_OUTPUT; break;
   case PORT_INOUT: dir = FST_VD_INOUT; break;
   case PORT_BUFFER: dir = FST_VD_BUFFER; break;
   }

   const char *name_base = strrchr(istr(tree_ident(d)), ':') + 1;
   const size_t base_len = strlen(name_base);
   char name[base_len + 64];
   strncpy(name, name_base, base_len + 64);
   if (type_is_array(type))
      snprintf(name + base_len, 64, "[%d:%d]\n", msb, lsb);

   data->handle = fstWriterCreateVar2(
      fst_ctx,
      vt,
      dir,
      data->size,
      name,
      0,
      type_pp(type),
      FST_SVT_VHDL_SIGNAL,
      sdt);

   tree_add_attr_ptr(d, fst_data_i, data);

   data->watch = rt_set_event_cb(d, fst_event_cb, data, true);
}
Beispiel #11
0
bool type_eq(type_t a, type_t b)
{
   assert(a != NULL);
   assert(b != NULL);

   type_kind_t kind_a = type_kind(a);
   type_kind_t kind_b = type_kind(b);

   if ((kind_a == T_UNRESOLVED) || (kind_b == T_UNRESOLVED))
      return false;

   if (a == b)
      return true;

   // Subtypes are convertible to the base type
   while ((kind_a = type_kind(a)) == T_SUBTYPE)
      a = type_base(a);
   while ((kind_b = type_kind(b)) == T_SUBTYPE)
      b = type_base(b);

   const bool compare_c_u_arrays =
      (kind_a == T_CARRAY && kind_b == T_UARRAY)
      || (kind_a == T_UARRAY && kind_b == T_CARRAY);

   if ((kind_a != kind_b) && !compare_c_u_arrays)
      return false;

   // Universal integer type is equal to any other integer type
   type_t universal_int = type_universal_int();
   ident_t uint_i = type_ident(universal_int);
   if (kind_a == T_INTEGER
       && (type_ident(a) == uint_i || type_ident(b) == uint_i))
      return true;

   // Universal real type is equal to any other real type
   type_t universal_real = type_universal_real();
   ident_t ureal_i = type_ident(universal_real);
   if (kind_a == T_REAL
       && (type_ident(a) == ureal_i || type_ident(b) == ureal_i))
      return true;

   // XXX: this is not quite right as structurally equivalent types
   // may be declared in different scopes with the same name but
   // shouldn't compare equal

   if (type_ident(a) != type_ident(b))
      return false;

   // Access types are equal if the pointed to type is the same
   if (kind_a == T_ACCESS)
      return type_eq(type_access(a), type_access(b));

   if (compare_c_u_arrays)
      return type_eq(type_elem(a), type_elem(b));

   const imask_t has = has_map[a->kind];

   if ((has & I_DIMS) && (type_dims(a) != type_dims(b)))
      return false;

   if (type_kind(a) == T_FUNC) {
      if (!type_eq(type_result(a), type_result(b)))
         return false;
   }

   if (has & I_PARAMS) {
      if (type_params(a) != type_params(b))
         return false;

      const int nparams = type_params(a);
      for (int i = 0; i < nparams; i++) {
         if (!type_eq(type_param(a, i), type_param(b, i)))
             return false;
      }
   }

   return true;
}