]> Nick Gasson's Git Repositories - nvc.git/commitdiff
FST dumping for nested arrays. Fixes #1071 master github/master sr.ht/master
authorNick Gasson <nick@nickg.me.uk>
Sun, 17 Nov 2024 10:54:22 +0000 (10:54 +0000)
committerNick Gasson <nick@nickg.me.uk>
Sun, 17 Nov 2024 12:20:43 +0000 (12:20 +0000)
NEWS.md
src/rt/wave.c
test/regress/gold/issue1071.dump [new file with mode: 0644]
test/regress/issue1071.vhd [new file with mode: 0644]
test/regress/testlist.txt

diff --git a/NEWS.md b/NEWS.md
index cf45d044d5ce2f52a87eac407b5eb891830dc177..4f400c029307a274f3ec1266ab0a14840279c224 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
   on Apple silicon macOS (#1069).
 - Partial association of ports with interface views now works correctly
   (#1074).
   on Apple silicon macOS (#1069).
 - Partial association of ports with interface views now works correctly
   (#1074).
-- Added support for PSL suffix implication, SERE repetition, and SERE 
+- Added support for PSL suffix implication, SERE repetition, and SERE
   fusion.
   fusion.
+- Nested arrays more than two levels deep can now be dumped in FST
+  format (#1071).
 - Several other minor bugs were resolved (#1038, #1055, #1057, #1067).
 
 ## Version 1.14.1 - 2024-10-26
 - Several other minor bugs were resolved (#1038, #1055, #1057, #1067).
 
 ## Version 1.14.1 - 2024-10-26
index 98348d489b34edfc8fdeb39ce0cd7598724580e0..c24fc046890abb22dae60e94710df2d4463dd820 100644 (file)
@@ -89,6 +89,13 @@ typedef struct _fst_data {
 
 typedef A(fst_data_t *) data_array_t;
 
 
 typedef A(fst_data_t *) data_array_t;
 
+typedef struct {
+   int64_t      length;
+   int64_t      msb;
+   int64_t      lsb;
+   range_kind_t dir;
+} fst_dim_t;
+
 typedef struct {
    FILE       *file;
    int         colour;
 typedef struct {
    FILE       *file;
    int         colour;
@@ -550,6 +557,31 @@ static fstHandle fst_create_handle(wave_dumper_t *wd, fst_data_t *data,
       data->type->sdt);
 }
 
       data->type->sdt);
 }
 
+static void fst_create_memory(wave_dumper_t *wd, fst_data_t *data, int *pos,
+                              const fst_dim_t *dims, int ndims, int curdim,
+                              enum fstVarDir vd, type_t type, text_buf_t *tb)
+{
+   if (curdim == ndims - 1) {
+      tb_printf(tb, "[%"PRIi64":%"PRIi64"]",
+                dims[curdim].msb, dims[curdim].lsb);
+
+      data->handle[(*pos)++] = fst_create_handle(wd, data, tb_get(tb),
+                                                 vd, type, 0);
+   }
+   else {
+      const size_t pfxlen = tb_len(tb);
+      type_t elem = type_elem(type);
+
+      for (int i = 0; i < dims[curdim].length; i++) {
+         tb_trim(tb, pfxlen);
+         tb_printf(tb, "[%"PRIi64"]",
+                   dims[curdim].msb + (dims[curdim].dir == RANGE_TO ? i : -i));
+         fst_create_memory(wd, data, pos, dims, ndims, curdim + 1,
+                           vd, elem, tb);
+      }
+   }
+}
+
 static void fst_create_array_var(wave_dumper_t *wd, tree_t d, rt_signal_t *s,
                                  type_t type, text_buf_t *tb)
 {
 static void fst_create_array_var(wave_dumper_t *wd, tree_t d, rt_signal_t *s,
                                  type_t type, text_buf_t *tb)
 {
@@ -595,19 +627,28 @@ static void fst_create_array_var(wave_dumper_t *wd, tree_t d, rt_signal_t *s,
       return;   // Dumping memories and nested arrays can be slow
    else if (type_is_record(elem))
       return;   // Not yet supported
       return;   // Dumping memories and nested arrays can be slow
    else if (type_is_record(elem))
       return;   // Not yet supported
-   else {
+   else if (type_is_array(elem)) {
       fst_type_t *ft = fst_type_for(wd, elem, tree_loc(d));
       if (ft == NULL)
          return;
 
       fst_type_t *ft = fst_type_for(wd, elem, tree_loc(d));
       if (ft == NULL)
          return;
 
-      const bool is_memory = type_is_array(elem);
+      SCOPED_A(fst_dim_t) dims = AINIT;
+
+      fst_dim_t dim0 = { length, left, right, dir };
+      APUSH(dims, dim0);
 
 
-      int64_t e_length = 1, e_msb = 0, e_lsb = 0;
-      if (is_memory) {
-         range_kind_t dir;
-         assert(dimension_of(type) == 1);
-         fst_get_array_range(wd, elem, s->parent, s->where, 1, &e_msb, &e_lsb,
-                             &dir, &e_length);
+      int64_t e_length = 1;
+      for (type_t e = elem; type_is_array(e); e = type_elem(e)) {
+         if (dims.count > 1)
+            length *= dims.items[dims.count - 1].length;
+
+         fst_dim_t dim;
+         assert(dimension_of(e) == 1);
+         fst_get_array_range(wd, e, s->parent, s->where, dims.count,
+                             &dim.msb, &dim.lsb, &dim.dir, &dim.length);
+
+         APUSH(dims, dim);
+         e_length = dim.length;
       }
 
       data = xcalloc_flex(sizeof(fst_data_t), length, sizeof(fstHandle));
       }
 
       data = xcalloc_flex(sizeof(fst_data_t), length, sizeof(fstHandle));
@@ -615,13 +656,37 @@ static void fst_create_array_var(wave_dumper_t *wd, tree_t d, rt_signal_t *s,
       data->size  = e_length * ft->size;
       data->type  = ft;
 
       data->size  = e_length * ft->size;
       data->type  = ft;
 
+      tb_rewind(tb);
+      tb_istr(tb, tree_ident(d));
+      tb_downcase(tb);
+
+      int pos = 0;
+      fst_create_memory(wd, data, &pos, dims.items, dims.count, 0,
+                        vd, type, tb);
+      fflush(stdout);
+      assert(pos == length);
+
+      fstWriterSetAttrEnd(wd->fst_ctx);
+   }
+   else {
+      fst_type_t *ft = fst_type_for(wd, elem, tree_loc(d));
+      if (ft == NULL)
+         return;
+
+      data = xcalloc_flex(sizeof(fst_data_t), length, sizeof(fstHandle));
+      data->count = length;
+      data->size  = ft->size;
+      data->type  = ft;
+
+      tb_rewind(tb);
+      tb_istr(tb, tree_ident(d));
+      tb_downcase(tb);
+
+      const size_t pfxlen = tb_len(tb);
+
       for (int i = 0; i < length; i++) {
       for (int i = 0; i < length; i++) {
-         tb_rewind(tb);
-         tb_istr(tb, tree_ident(d));
+         tb_trim(tb, pfxlen);
          tb_printf(tb, "[%"PRIi64"]", dir == RANGE_TO ? left + i : left - i);
          tb_printf(tb, "[%"PRIi64"]", dir == RANGE_TO ? left + i : left - i);
-         if (is_memory)
-            tb_printf(tb, "[%"PRIi64":%"PRIi64"]", e_msb, e_lsb);
-         tb_downcase(tb);
 
          data->handle[i] =
             fst_create_handle(wd, data, tb_get(tb), vd, elem, 0);
 
          data->handle[i] =
             fst_create_handle(wd, data, tb_get(tb), vd, elem, 0);
diff --git a/test/regress/gold/issue1071.dump b/test/regress/gold/issue1071.dump
new file mode 100644 (file)
index 0000000..83e1727
--- /dev/null
@@ -0,0 +1,8 @@
+#0 issue1071.e[0][1][7:0] 00000000
+#0 issue1071.e[0][0][7:0] 00000000
+#0 issue1071.c[1][7:0] 00000000
+#0 issue1071.c[0][7:0] 00000000
+#10000000 issue1071.c[0][7:0] 00000010
+#10000000 issue1071.c[1][7:0] 00000001
+#10000000 issue1071.e[0][0][7:0] 00000010
+#10000000 issue1071.e[0][1][7:0] 00000001
diff --git a/test/regress/issue1071.vhd b/test/regress/issue1071.vhd
new file mode 100644 (file)
index 0000000..41f4291
--- /dev/null
@@ -0,0 +1,36 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use std.env.finish;
+
+entity issue1071 is
+end issue1071;
+
+architecture sim of issue1071 is
+
+  subtype A is unsigned(7 downto 0);
+  type B is array (natural range <>) of A;
+  signal C : B(0 to 1) := (others => (others => '0'));
+
+  type D is array (0 to 0) of B(0 to 1);
+  signal E : D := (others => (others => (others => '0')));
+
+begin
+
+  E(0) <= C;
+
+  process
+  begin
+    wait for 10 ns;
+
+    for i in C'range loop
+      C(i) <= to_unsigned(C'length - i, A'length);
+    end loop;
+
+    wait for 10 ns;
+
+    finish;
+  end process;
+
+end architecture;
index 90bfa5ea46b05a4998d973d61d286a1fab531615..fd12a44b60c07735d1d1cbe75c67655d5d6fb93b 100644 (file)
@@ -1074,3 +1074,4 @@ psl14           gold,psl
 issue1074       normal,2019
 psl15           gold,psl
 psl16           gold,psl
 issue1074       normal,2019
 psl15           gold,psl
 psl16           gold,psl
+issue1071       wave,2008,dump-arrays