From 4ddf234c324603d7a2882fca82f6d1fd5c0bbbf7 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 1 Jan 2023 18:46:17 -0800 Subject: [PATCH 1/2] vvp: Remove null-bytes when converting string literals to SV strings The `%pushi/str` and `%concati/str` instructions should remove null-bytes from the string literal when converting it to a string. This is defined in section 6.16 ("String data type") of the LRM (1800-2017). This is already handled correctly when converting a vector from the stack to a SV string, just not when converting a string literal to SV string. Signed-off-by: Lars-Peter Clausen --- vvp/vthread.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 135b20ea9..2b35315b0 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -399,7 +399,11 @@ static string filter_string(const char*text) cnt -= 1; ptr += 1; } - tmp[dst++] = byte; + + // null-bytes are supposed to be removed when assigning a string + // literal to a string. + if (byte != '\0') + tmp[dst++] = byte; // After the while loop above, the ptr points to the next character, // but the for-loop condition is assuming that ptr points to the last From 56baae11cc89ee8726260107caba5f022af1a952 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 2 Jan 2023 10:09:34 -0800 Subject: [PATCH 2/2] Add regression tests for null-byte handling when assigning to SV strings Check that when assigning or casting a string literal or vector to a SV string type that null-bytes are removed. Also check that writing a null-byte to an element of a string variable is ignored. Signed-off-by: Lars-Peter Clausen --- ivtest/ivltests/sv_string8.v | 43 ++++++++++++++++++++++++++++++++++++ ivtest/ivltests/sv_string9.v | 33 +++++++++++++++++++++++++++ ivtest/regress-sv.list | 2 ++ ivtest/regress-vlog95.list | 2 ++ 4 files changed, 80 insertions(+) create mode 100644 ivtest/ivltests/sv_string8.v create mode 100644 ivtest/ivltests/sv_string9.v diff --git a/ivtest/ivltests/sv_string8.v b/ivtest/ivltests/sv_string8.v new file mode 100644 index 000000000..94b07732b --- /dev/null +++ b/ivtest/ivltests/sv_string8.v @@ -0,0 +1,43 @@ +// Check that null-bytes are removed when converting to string type. + +module test; + + reg failed = 1'b0; + + `define check(val, exp) \ + if (val != exp) begin \ + $display("FAILED(%0d): Expected '%0s', got '%0s'.", `__LINE__, exp, val); \ + failed = 1'b1; \ + end + + string s; + reg [47:0] x; + + initial begin + s = "\000a\000b\000"; + `check(s, "ab"); + + s = string'("\000a\000b\000"); + `check(s, "ab"); + + s = string'(48'h0061006200); + `check(s, "ab"); + + x = 48'h0061006200; + s = string'(x); + `check(s, "ab"); + + s = "cd"; + s = {s, "\000a\000b\000"}; + `check(s, "cdab"); + + s = "cd"; + s = {"\000a\000b\000", s}; + `check(s, "abcd"); + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_string9.v b/ivtest/ivltests/sv_string9.v new file mode 100644 index 000000000..4f0eb020e --- /dev/null +++ b/ivtest/ivltests/sv_string9.v @@ -0,0 +1,33 @@ +// Check that null-bytes are ignored when assigning to an element of a string +// type variable. + +module test; + + reg failed = 1'b0; + + `define check(val, exp) \ + if (val != exp) begin \ + $display("FAILED(%0d): Expected '%0s', got '%0s'.", `__LINE__, exp, val); \ + failed = 1'b1; \ + end + + string s; + byte x; + + initial begin + s = "Test"; + + s[1] = 8'h00; // This should be ignored + `check(s, "Test"); + s[1] = "\000"; // This should be ignored + `check(s, "Test"); + x = 8'h00; + s[1] = x; // This should be ignored + `check(s, "Test"); + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index cc5a8ec25..93f31074b 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -753,6 +753,8 @@ sv_string5 normal,-g2009 ivltests sv_string6 normal,-g2009 ivltests sv_string7 normal,-g2009 ivltests sv_string7b normal,-g2009 ivltests +sv_string8 normal,-g2009 ivltests +sv_string9 normal,-g2009 ivltests sv_timeunit_prec1 normal,-g2005-sv ivltests sv_timeunit_prec2 normal,-g2009 ivltests sv_timeunit_prec3a normal,-g2005-sv ivltests gold=sv_timeunit_prec3a.gold diff --git a/ivtest/regress-vlog95.list b/ivtest/regress-vlog95.list index 76d299369..06d9e9baf 100644 --- a/ivtest/regress-vlog95.list +++ b/ivtest/regress-vlog95.list @@ -309,6 +309,8 @@ sv_string5 CE,-g2009 ivltests sv_string6 CE,-g2009,-pallowsigned=1 ivltests sv_string7 CE,-g2009,-pallowsigned=1 ivltests sv_string7b CE,-g2009,-pallowsigned=1 ivltests +sv_string8 CE,-g2009 ivltests +sv_string9 CE,-g2009 ivltests sv_ps_function6 CE,-g2009,-pallowsigned=1 ivltests sv_typedef_fwd_base CE,-g2009 ivltests vhdl_string_lim CE,-g2005-sv,-pallowsigned=1,ivltests/vhdl_string_lim.vhd ivltests