Fix dehash of a suffix after a hashed name (#8556)

This commit is contained in:
Ethan Sifferman
2026-09-30 19:51:19 -04:00
committed by GitHub
parent af1c668b99
commit 6438d977fa
4 changed files with 59 additions and 2 deletions
+9 -2
View File
@@ -656,7 +656,7 @@ string VHashSha512::digestSymbol24() {
| (static_cast<int>(binhash[pos + 2] & 0xc0) >> 6)];
result += digits[((binhash[pos + 2] & 0x3f))];
// Keep symbols short-ish, with 24 chars/144 bits we won't have hash collisions
if (result.size() >= 24) break;
if (result.size() >= DIGEST_SYMBOL24_LENGTH) break;
}
// Any leftover bits don't matter for our purpose
return result;
@@ -732,6 +732,7 @@ void VHashSha512::selfTest() {
string VName::dehash(const string& in) {
static constexpr const char VHSH[] = "__Vhsh";
static constexpr size_t VHSH_LEN = sizeof(VHSH) - 1 + VHashSha512::DIGEST_SYMBOL24_LENGTH;
static const size_t DOT_LEN = std::strlen("__DOT__");
std::string dehashed;
@@ -748,7 +749,11 @@ string VName::dehash(const string& in) {
const auto begin_vhsh
= std::search(search_begin, search_end, std::begin(VHSH), std::end(VHSH) - 1);
if (begin_vhsh != search_end) {
const std::string vhsh{begin_vhsh, search_end};
// V3SplitVar appends a bit range to a name hashedName already hashed, so the
// hash does not always reach the end of the component.
const auto end_vhsh
= begin_vhsh + std::min<size_t>(std::distance(begin_vhsh, search_end), VHSH_LEN);
const std::string vhsh{begin_vhsh, end_vhsh};
const auto& it = s_dehashMap.find(vhsh);
UASSERT(it != s_dehashMap.end(), "String not in reverse hash map '" << vhsh << "'");
// Is this not the first component, but the first to require dehashing?
@@ -760,6 +765,8 @@ string VName::dehash(const string& in) {
dehashed += std::string{search_begin, begin_vhsh};
// Append the bit that was lost to truncation but retrieved from the dehash map.
dehashed += it->second;
// Append what follows the hash, such as a split variable bit range.
dehashed += std::string{end_vhsh, search_end};
}
// This component doesn't need dehashing but a previous one might have.
else if (!dehashed.empty()) {
+4
View File
@@ -178,6 +178,10 @@ public:
}
~VHashSha512() = default;
// CONSTANTS
// Characters digestSymbol24 keeps, 6 bits each, so 144 bits and no collisions in practice
static constexpr size_t DIGEST_SYMBOL24_LENGTH = 24;
// METHODS
string digestBase64(); // Return digest formatted in Base64 (non-URL flavor)
string digestBinary(); // Return digest as 64 character binary
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of either the GNU Lesser General Public License Version 3
# or the Perl Artistic License Version 2.0.
# SPDX-FileCopyrightText: 2026 Wilson Snyder
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('simulator')
test.compile(verilator_flags2=['--trace-vcd'])
test.execute()
test.passes()
+28
View File
@@ -0,0 +1,28 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 Ethan Sifferman
// SPDX-License-Identifier: CC0-1.0
// Every name here is over the 128 character limit at which VName hashes it, so the
// passes that append to a name append to a hash: V3SplitVar a bit range or an element
// index, V3Class a package suffix.
class class_with_a_name_long_enough_that_verilator_replaces_it_with_a_hash_because_it_is_over_the_one_hundred_twenty_eight_character_limit;
int x;
endclass
module t;
logic [1:0] packed_signal_with_a_name_long_enough_that_verilator_replaces_it_with_a_hash_because_it_is_over_the_one_hundred_twenty_eight_char_limit /*verilator split_var*/;
logic unpacked_array_with_a_name_long_enough_that_verilator_replaces_it_with_a_hash_because_it_is_over_the_one_hundred_twenty_eight_char_limit [1:0] /*verilator split_var*/;
class_with_a_name_long_enough_that_verilator_replaces_it_with_a_hash_because_it_is_over_the_one_hundred_twenty_eight_character_limit obj;
always_comb packed_signal_with_a_name_long_enough_that_verilator_replaces_it_with_a_hash_because_it_is_over_the_one_hundred_twenty_eight_char_limit[0] = 1'b1;
always_comb unpacked_array_with_a_name_long_enough_that_verilator_replaces_it_with_a_hash_because_it_is_over_the_one_hundred_twenty_eight_char_limit[0] = 1'b1;
initial begin
obj = new;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule