From 4bfaaea0d52c235bb51c4dc54b07fe301eebe473 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Fri, 20 May 2022 21:46:39 +0200 Subject: [PATCH] verilog: fix size and signedness of array querying functions genrtlil.cc and simplify.cc had inconsistent and slightly broken handling of signedness for array querying functions. These functions are defined to return a signed result. Simplify always produced an unsigned and genrtlil always a signed 32-bit result ignoring the context. Includes tests for the the relvant edge cases for context dependent conversions. --- CHANGELOG | 2 ++ frontends/ast/genrtlil.cc | 3 +- frontends/ast/simplify.cc | 2 +- tests/verilog/sign_array_query.ys | 52 +++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 tests/verilog/sign_array_query.ys diff --git a/CHANGELOG b/CHANGELOG index d64d592d2..4ee364a57 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,8 @@ Yosys 0.17 .. Yosys 0.17-dev - Fixed an issue where simplifying case statements by removing unreachable cases could result in the wrong signedness being used for comparison with the remaining cases + - Fixed size and signedness computation for expressions containing array + querying functions Yosys 0.16 .. Yosys 0.17 -------------------------- diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 6ef7da7a9..a569c5ae2 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1089,8 +1089,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun break; } if (str == "\\$size" || str == "\\$bits" || str == "\\$high" || str == "\\$low" || str == "\\$left" || str == "\\$right") { - width_hint = 32; - sign_hint = true; + width_hint = max(width_hint, 32); break; } if (current_scope.count(str)) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index c2adcafd0..2d9d6dc79 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -3450,7 +3450,7 @@ skip_dynamic_range_lvalue_expansion:; else { result = width * mem_depth; } - newNode = mkconst_int(result, false); + newNode = mkconst_int(result, true); goto apply_newNode; } diff --git a/tests/verilog/sign_array_query.ys b/tests/verilog/sign_array_query.ys new file mode 100644 index 000000000..f955450b7 --- /dev/null +++ b/tests/verilog/sign_array_query.ys @@ -0,0 +1,52 @@ +logger -expect-no-warnings + +read_verilog -formal <