From d99add9dbe530607397d799090d15b29bc7785c6 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Tue, 3 Sep 2024 21:06:46 +0100 Subject: [PATCH 1/4] Fix vvp code generator for array word alias corner case (issue #1155) When multiple words in one array were connected to the same nexus as a single word array, the code generator was sometimes failing to generate all the necessary aliases. This was highly dependent on the elaboration order. This fix should be more robust, but there are currently no tests in the test suite that cause the compiler to generate whole-array aliases, and I can't think of a way to make it do so as we don't yet support unpacked arrays in module ports, so that branch of the code is currently untested. --- tgt-vvp/vvp_scope.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index 978b27d59..712bddd85 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2023 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2024 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -696,14 +696,13 @@ static void draw_net_in_scope(ivl_signal_t sig) so the word count for the signal and the alias *must* match. */ - if (ivl_signal_dimensions(nex_data->net) > 0 && + if (iword == 0 && ivl_signal_dimensions(nex_data->net) > 0 && word_count == ivl_signal_array_count(nex_data->net)) { - if (iword == 0) { fprintf(vvp_out, "v%p .array \"%s\", v%p; Alias to %s \n", sig, vvp_mangle_name(ivl_signal_basename(sig)), nex_data->net, ivl_signal_basename(nex_data->net)); - } + break; /* An alias for an individual word. */ } else { if (iword == 0) { From f8947a6aaba270173166d5db9ce3900ec1e74bf4 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Tue, 3 Sep 2024 21:34:12 +0100 Subject: [PATCH 2/4] Fix indentation and white space. --- tgt-vvp/vvp_scope.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index 712bddd85..d5e543672 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -689,20 +689,22 @@ static void draw_net_in_scope(ivl_signal_t sig) nex_data->net_word = iword; } else if (dimensions > 0) { + /* In this case, we have an alias to an existing signal array. this typically is an instance of port collapsing that the elaborator combined to discover that the entire array can be collapsed, so the word count for the signal and the alias *must* match. */ - if (iword == 0 && ivl_signal_dimensions(nex_data->net) > 0 && word_count == ivl_signal_array_count(nex_data->net)) { - fprintf(vvp_out, "v%p .array \"%s\", v%p; Alias to %s \n", - sig, vvp_mangle_name(ivl_signal_basename(sig)), - nex_data->net, - ivl_signal_basename(nex_data->net)); - break; + + fprintf(vvp_out, "v%p .array \"%s\", v%p; Alias to %s \n", + sig, vvp_mangle_name(ivl_signal_basename(sig)), + nex_data->net, + ivl_signal_basename(nex_data->net)); + break; + /* An alias for an individual word. */ } else { if (iword == 0) { @@ -2538,4 +2540,3 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent) ivl_scope_children(net, (ivl_scope_f*) draw_scope, net); return 0; } - From d6abe599832a55b96d30ba7af93bff08891f9545 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Tue, 3 Sep 2024 21:34:46 +0100 Subject: [PATCH 3/4] Improve annotation in vvp code generation. --- tgt-vvp/vvp_scope.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index d5e543672..9ecff1669 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -719,10 +719,11 @@ static void draw_net_in_scope(ivl_signal_t sig) } fprintf(vvp_out, "v%p_%u .net%s v%p %u, %d %d, " - "v%p_%u; Alias to %s\n", sig, iword, + "v%p_%u; Alias to %s[%u]\n", sig, iword, datatype_flag, sig, iword, msb, lsb, nex_data->net, nex_data->net_word, - ivl_signal_basename(nex_data->net)); + ivl_signal_basename(nex_data->net), + nex_data->net_word); } } else { /* Finally, we may have an alias that is a word From ae78218c2f2c8c8defe8c4c3248d89afcb31b662 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Tue, 3 Sep 2024 21:38:09 +0100 Subject: [PATCH 4/4] Add regression test for issue #1155. --- ivtest/ivltests/br_gh1155.v | 34 +++++++++++++++++++++++++++++++++ ivtest/regress-vvp.list | 1 + ivtest/vvp_tests/br_gh1155.json | 4 ++++ 3 files changed, 39 insertions(+) create mode 100644 ivtest/ivltests/br_gh1155.v create mode 100644 ivtest/vvp_tests/br_gh1155.json diff --git a/ivtest/ivltests/br_gh1155.v b/ivtest/ivltests/br_gh1155.v new file mode 100644 index 000000000..7ab7d6dde --- /dev/null +++ b/ivtest/ivltests/br_gh1155.v @@ -0,0 +1,34 @@ +module test; + +// The test is sensitive to the order in which the code is generated for +// the individual assignments, which currently depends on the alphabetic +// order of the array names. So duplicate the test with the order reversed +// to protect against future compiler changes. + +wire [7:0] array1[0:1]; +wire [7:0] array2[0:0]; + +assign array2[0] = 8'h55; + +assign array1[0] = { array2[0] }; +assign array1[1] = { array2[0] }; + +wire [7:0] array3[0:0]; +wire [7:0] array4[0:1]; + +assign array3[0] = 8'haa; + +assign array4[0] = { array3[0] }; +assign array4[1] = { array3[0] }; + +initial begin + #0 $display("%h %h", array1[0], array1[1]); + #0 $display("%h %h", array4[0], array4[1]); + if (array1[0] === 8'h55 && array1[1] === 8'h55 && + array4[0] === 8'haa && array4[1] === 8'haa) + $display("PASSED"); + else + $display("FAILED"); +end + +endmodule diff --git a/ivtest/regress-vvp.list b/ivtest/regress-vvp.list index 6f3d6da74..0730ccfbf 100644 --- a/ivtest/regress-vvp.list +++ b/ivtest/regress-vvp.list @@ -58,6 +58,7 @@ br_gh1143e vvp_tests/br_gh1143e.json br_gh1143f vvp_tests/br_gh1143f.json br_gh1143g vvp_tests/br_gh1143g.json br_gh1143h vvp_tests/br_gh1143h.json +br_gh1155 vvp_tests/br_gh1155.json ca_time_real` vvp_tests/ca_time_real.json case1 vvp_tests/case1.json case2 vvp_tests/case2.json diff --git a/ivtest/vvp_tests/br_gh1155.json b/ivtest/vvp_tests/br_gh1155.json new file mode 100644 index 000000000..254478aed --- /dev/null +++ b/ivtest/vvp_tests/br_gh1155.json @@ -0,0 +1,4 @@ +{ + "type" : "normal", + "source" : "br_gh1155.v" +}