From 9b699504b1d37c36e7dad2fd928fba98e4af9fbb Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Wed, 13 Mar 2024 20:02:03 +0000 Subject: [PATCH] Dump arrays-of-records when --dump-arrays is passed. Issue 856 --- src/lower.c | 8 ++-- src/rt/wave.c | 68 ++++++++++++++++++++++++--------- test/regress/gold/issue703.gtkw | 1 - test/regress/gold/issue856.dump | 14 +++++++ test/regress/gold/wave11.dump | 7 ++++ test/regress/testlist.txt | 2 +- test/regress/wave11.vhd | 3 +- 7 files changed, 78 insertions(+), 25 deletions(-) create mode 100644 test/regress/gold/issue856.dump diff --git a/src/lower.c b/src/lower.c index c6a33e61..1d75c9d8 100644 --- a/src/lower.c +++ b/src/lower.c @@ -7713,11 +7713,11 @@ static void lower_sub_signals(lower_unit_t *lu, type_t type, type_t var_type, if (sig_ptr == VCODE_INVALID_REG) sig_ptr = emit_index(sig_var, VCODE_INVALID_REG); - if (init_reg != VCODE_INVALID_REG) { - vcode_reg_t locus = lower_debug_locus(where); + vcode_reg_t locus = lower_debug_locus(where); + + if (init_reg != VCODE_INVALID_REG) lower_check_array_sizes(lu, type, init_type, VCODE_INVALID_REG, init_reg, locus); - } vcode_reg_t len_reg = lower_array_total_len(lu, type, bounds_reg); @@ -7742,7 +7742,7 @@ static void lower_sub_signals(lower_unit_t *lu, type_t type, type_t var_type, vcode_var_t i_var = lower_temp_var(lu, "i", voffset, voffset); emit_store(emit_const(voffset, 0), i_var); - emit_push_scope(lower_debug_locus(where), lower_type(type)); + emit_push_scope(locus, lower_type(type)); vcode_block_t cmp_bb = emit_block(); vcode_block_t body_bb = emit_block(); diff --git a/src/rt/wave.c b/src/rt/wave.c index 001e5840..1db5aeb0 100644 --- a/src/rt/wave.c +++ b/src/rt/wave.c @@ -424,14 +424,18 @@ static void *fst_get_ptr(wave_dumper_t *wd, rt_scope_t *scope, tree_t where) assert(scope->kind == SCOPE_SIGNAL); type_t rtype = tree_type(scope->where); - assert(type_is_record(rtype)); - assert(type_field(rtype, tree_pos(where)) == where); - const jit_layout_t *l = signal_layout_of(rtype); - assert(l->nparts == type_fields(rtype)); - const ptrdiff_t offset = l->parts[tree_pos(where)].offset; - return fst_get_ptr(wd, scope->parent, scope->where) + offset; + if (type_is_array(rtype)) + return fst_get_ptr(wd, scope->parent, scope->where); + else { + assert(type_is_record(rtype)); + assert(type_field(rtype, tree_pos(where)) == where); + assert(l->nparts == type_fields(rtype)); + + const ptrdiff_t offset = l->parts[tree_pos(where)].offset; + return fst_get_ptr(wd, scope->parent, scope->where) + offset; + } } else { assert(scope->kind == SCOPE_INSTANCE); @@ -440,7 +444,8 @@ static void *fst_get_ptr(wave_dumper_t *wd, rt_scope_t *scope, tree_t where) } } -static void fst_get_array_range(wave_dumper_t *wd, type_t type, rt_signal_t *s, +static void fst_get_array_range(wave_dumper_t *wd, type_t type, + rt_scope_t *scope, tree_t where, int64_t *msb, int64_t *lsb, int64_t *length) { if (!type_is_unconstrained(type)) { @@ -452,7 +457,7 @@ static void fst_get_array_range(wave_dumper_t *wd, type_t type, rt_signal_t *s, } } - ffi_dim_t *dims = fst_get_ptr(wd, s->parent, s->where) + 2*sizeof(int64_t); + ffi_dim_t *dims = fst_get_ptr(wd, scope, where) + 2*sizeof(int64_t); *lsb = ffi_array_right(dims[0].left, dims[0].length); *msb = dims[0].left; @@ -473,7 +478,7 @@ static void fst_create_array_var(wave_dumper_t *wd, tree_t d, rt_signal_t *s, } int64_t lsb, msb, length; - fst_get_array_range(wd, type, s, &msb, &lsb, &length); + fst_get_array_range(wd, type, s->parent, s->where, &msb, &lsb, &length); tb_rewind(tb); tb_istr(tb, tree_ident(d)); @@ -641,10 +646,11 @@ static void gtkw_print_scope_comment(gtkw_writer_t *gtkw, rt_scope_t *scope, static void fst_create_record_var(wave_dumper_t *wd, tree_t d, rt_scope_t *scope, type_t type, - text_buf_t *tb) + const char *suffix, text_buf_t *tb) { tb_rewind(tb); tb_istr(tb, tree_ident(d)); + tb_cat(tb, suffix); tb_downcase(tb); fstWriterSetScope(wd->fst_ctx, FST_ST_VHDL_RECORD, tb_get(tb), NULL); @@ -671,6 +677,27 @@ static void fst_create_record_var(wave_dumper_t *wd, tree_t d, } } +static void fst_create_record_array_var(wave_dumper_t *wd, tree_t d, + rt_scope_t *scope, type_t type, + text_buf_t *tb) +{ + int64_t lsb, msb, length; + fst_get_array_range(wd, type, scope->parent, d, &msb, &lsb, &length); + + type_t elem = type_elem(type); + assert(type_is_record(elem)); + + assert(list_size(scope->children) == length); + + int index = MIN(msb, lsb); + for (list_iter(rt_scope_t *, sub, scope->children)) { + char suffix[32]; + checked_sprintf(suffix, sizeof(suffix), "[%d]", index++); + + fst_create_record_var(wd, d, sub, elem, suffix, tb); + } +} + static void fst_alias_var(wave_dumper_t *wd, tree_t d, rt_signal_t *s, text_buf_t *tb) { @@ -688,7 +715,7 @@ static void fst_alias_var(wave_dumper_t *wd, tree_t d, rt_signal_t *s, tb_istr(tb, tree_ident(d)); if (type_is_array(type)) { int64_t lsb, msb, length; - fst_get_array_range(wd, type, s, &msb, &lsb, &length); + fst_get_array_range(wd, type, s->parent, s->where, &msb, &lsb, &length); tb_printf(tb, "[%"PRIi64":%"PRIi64"]", msb, lsb); } @@ -706,12 +733,7 @@ static void fst_alias_var(wave_dumper_t *wd, tree_t d, rt_signal_t *s, static void fst_process_signal(wave_dumper_t *wd, rt_scope_t *scope, tree_t d, type_t type, text_buf_t *tb) { - if (type_is_record(type)) { - rt_scope_t *sub = child_scope(scope, d); - if (sub != NULL) // NULL means signal was optimised out - fst_create_record_var(wd, d, sub, type, tb); - } - else { + if (type_is_homogeneous(type)) { if (wd->gtkw != NULL) { if (wd->gtkw->end_of_record) { fputs("-\n", wd->gtkw->file); // Blank line after record @@ -722,7 +744,7 @@ static void fst_process_signal(wave_dumper_t *wd, rt_scope_t *scope, tree_t d, rt_signal_t *s = find_signal(scope, d); if (s == NULL) - assert(type_is_array(type) && type_is_record(type_elem(type))); + return; else if (s->where != d) fst_alias_var(wd, d, s, tb); // Collapsed with another signal else if (type_is_array(type)) @@ -730,6 +752,16 @@ static void fst_process_signal(wave_dumper_t *wd, rt_scope_t *scope, tree_t d, else fst_create_scalar_var(wd, d, s, type, tb); } + else if (type_is_record(type)) { + rt_scope_t *sub = child_scope(scope, d); + if (sub != NULL) // NULL means signal was optimised out + fst_create_record_var(wd, d, sub, type, "", tb); + } + else if (opt_get_int(OPT_DUMP_ARRAYS)) { + rt_scope_t *sub = child_scope(scope, d); + if (sub != NULL) // NULL means signal was optimised out + fst_create_record_array_var(wd, d, sub, type, tb); + } } static void fst_process_hier(wave_dumper_t *wd, tree_t h, tree_t block) diff --git a/test/regress/gold/issue703.gtkw b/test/regress/gold/issue703.gtkw index 719c0c76..bf3137d1 100644 --- a/test/regress/gold/issue703.gtkw +++ b/test/regress/gold/issue703.gtkw @@ -1,7 +1,6 @@ -/ [color] 4 issue703.s -[color] 4 -/u/ -r: -r.p: diff --git a/test/regress/gold/issue856.dump b/test/regress/gold/issue856.dump new file mode 100644 index 00000000..d4e65e90 --- /dev/null +++ b/test/regress/gold/issue856.dump @@ -0,0 +1,14 @@ +#0 issue856.b.p[1].g 0000000000000000000000000001101100000000000000000000000000011011 +#0 issue856.b.p[1].f[3].y 0000000000000000000000000000011100000000000000000000000000000111 +#0 issue856.b.p[1].f[3].x 0000000000000000000000000000011000000000000000000000000000000110 +#0 issue856.b.p[1].f[2].y 0000000000000000000000000000010100000000000000000000000000000101 +#0 issue856.b.p[1].f[2].x 0000000000000000000000000000010000000000000000000000000000000100 +#0 issue856.b.p[1].f[1].y 0000000000000000000000000000001100000000000000000000000000000011 +#0 issue856.b.p[1].f[1].x 0000000000000000000000000000001000000000000000000000000000000010 +#0 issue856.s.g 0000000000000000000000000001101100000000000000000000000000011011 +#0 issue856.s.f[3].y 0000000000000000000000000000011100000000000000000000000000000111 +#0 issue856.s.f[3].x 0000000000000000000000000000011000000000000000000000000000000110 +#0 issue856.s.f[2].y 0000000000000000000000000000010100000000000000000000000000000101 +#0 issue856.s.f[2].x 0000000000000000000000000000010000000000000000000000000000000100 +#0 issue856.s.f[1].y 0000000000000000000000000000001100000000000000000000000000000011 +#0 issue856.s.f[1].x 0000000000000000000000000000001000000000000000000000000000000010 diff --git a/test/regress/gold/wave11.dump b/test/regress/gold/wave11.dump index 04aef258..299cd1db 100644 --- a/test/regress/gold/wave11.dump +++ b/test/regress/gold/wave11.dump @@ -1,3 +1,9 @@ +#0 wave11.b.r.f4[2].f2[3:5] 000 +#0 wave11.b.r.f4[2].f1 false +#0 wave11.b.r.f4[1].f2[3:5] 000 +#0 wave11.b.r.f4[1].f1 false +#0 wave11.b.r.f4[0].f2[3:5] 000 +#0 wave11.b.r.f4[0].f1 false #0 wave11.b.r.f3.f2[1:3] 000 #0 wave11.b.r.f3.f1 false #0 wave11.b.r.f2[1:3] 000 @@ -7,3 +13,4 @@ #1000000 wave11.b.r.f2[1:3] 100 #2000000 wave11.b.r.f2[1:3] 000 #3000000 wave11.b.r.f3.f2[1:3] 010 +#4000000 wave11.b.r.f4[1].f1 true diff --git a/test/regress/testlist.txt b/test/regress/testlist.txt index d3d40c29..3cb13acb 100644 --- a/test/regress/testlist.txt +++ b/test/regress/testlist.txt @@ -953,7 +953,7 @@ vlog9 verilog issue654 normal,2008 issue854 normal,2019 ename8 normal,2008 -issue856 normal,2019 +issue856 normal,2019,wave,dump-arrays driver22 fail,gold,2019 vhpi12 normal,vhpi issue862 normal,gold,2008,relaxed diff --git a/test/regress/wave11.vhd b/test/regress/wave11.vhd index 57dfc9b2..fed673dd 100644 --- a/test/regress/wave11.vhd +++ b/test/regress/wave11.vhd @@ -20,7 +20,7 @@ begin f1 : integer; f2 : p1'subtype; f3 : t_rec1; - f4 : t_rec1_array(0 to 2); -- Not dumped currently + f4 : t_rec1_array(0 to 2); end record; signal r : t_rec2; @@ -28,6 +28,7 @@ begin r.f2(1) <= '1' after 1 ns, '0' after 2 ns; r.f3.f2(2) <= '1' after 3 ns; + r.f4(1).f1 <= true after 4 ns; end block; -- 2.39.2