From 0aaca679cea2884feeab3e04d11824322368b7e6 Mon Sep 17 00:00:00 2001 From: Stan Lee Date: Fri, 27 Feb 2026 10:22:06 -0800 Subject: [PATCH] better but not ideal --- kernel/fstdata.cc | 103 +++++++++++++++++++--------------------------- kernel/fstdata.h | 4 +- 2 files changed, 43 insertions(+), 64 deletions(-) diff --git a/kernel/fstdata.cc b/kernel/fstdata.cc index 3e3e8d127..1ecf1f7e9 100644 --- a/kernel/fstdata.cc +++ b/kernel/fstdata.cc @@ -116,7 +116,8 @@ void FstData::extractVarNames() // Track current fork scope std::string current_fork_scope; - fstHandle next_virtual_handle = (fstHandle)-1; // forks get negative handle values for better identification + fstHandle next_fork_handle = 0x80000000; + std::map> fork_scopes; while ((h = fstReaderIterateHier(ctx))) { switch (h->htyp) { @@ -133,22 +134,13 @@ void FstData::extractVarNames() } case FST_HT_UPSCOPE: { if (!current_fork_scope.empty() && current_fork_scope == fst_scope_name) { - - // Create a virtual handle - fstHandle virtual_handle = next_virtual_handle--; - - // Map the scope to the virtual handle - name_to_handle[current_fork_scope] = virtual_handle; - virtual_to_fork[virtual_handle] = current_fork_scope; - - // Calculate total width of the struct and map it to the virtual handle - int total_width = 0; - for (fstHandle member : fork_scopes[current_fork_scope]) { - if (handle_to_var.find(member) != handle_to_var.end()) { - total_width += handle_to_var[member].width; - } - } - virtual_handle_widths[virtual_handle] = total_width; + fstHandle fork_handle = next_fork_handle++; + std::string normalized_fork_scope = current_fork_scope; + normalize_brackets(normalized_fork_scope); + + name_to_handle[normalized_fork_scope] = fork_handle; + fork_scope_members[fork_handle] = fork_scopes[current_fork_scope]; + current_fork_scope.clear(); } fst_scope_name = fstReaderPopScope(ctx); @@ -308,54 +300,43 @@ void FstData::reconstructAllAtTimes(std::vector &signal, uint64_t sta std::string FstData::valueOf(fstHandle signal) { - // Condition to check if the signal comes from a fork scope - if ((int)signal < 0 && virtual_to_fork.find(signal) != virtual_to_fork.end()) { - std::string fork_scope = virtual_to_fork[signal]; - if (fork_scopes.find(fork_scope) != fork_scopes.end()) { - - // Empty string to store the full struct values - std::string result; - - // Get the members of the fork scope - const std::vector& members = fork_scopes[fork_scope]; - for (auto it = members.rbegin(); it != members.rend(); ++it) { - fstHandle member = *it; - std::string member_val; - int expected_width = 0; - - // Get the width of the member - if (handle_to_var.find(member) != handle_to_var.end()) { - expected_width = handle_to_var[member].width; - } - - // Check if the member has a value - if (past_data.find(member) != past_data.end()) { - member_val = past_data[member]; - - // If the member value is shorter than the expected width, pad with zeros - if (expected_width > 0 && (int)member_val.length() < expected_width) { - member_val = std::string(expected_width - member_val.length(), '0') + member_val; - } - } else if (expected_width > 0) { - // If the member has no value, pad with x's - member_val = std::string(expected_width, 'x'); - } else { - member_val = "x"; - } - - // Add the member value to the result - result += member_val; + // Check if this is a fork scope (struct) + auto it = fork_scope_members.find(signal); + if (it != fork_scope_members.end()) { + std::string result; + const std::vector& members = it->second; + + // Iterate in REVERSE: first declared member is MSB in SystemVerilog packed structs + for (auto m = members.rbegin(); m != members.rend(); ++m) { + fstHandle member = *m; + std::string member_val; + int expected_width = 0; + + // Get the declared width of this member + if (handle_to_var.find(member) != handle_to_var.end()) { + expected_width = handle_to_var[member].width; } - return result; + + // Get the current value + if (past_data.find(member) != past_data.end()) { + member_val = past_data[member]; + // VCD drops leading zeros - must pad to full width + if (expected_width > 0 && (int)member_val.length() < expected_width) { + member_val = std::string(expected_width - member_val.length(), '0') + member_val; + } + } else if (expected_width > 0) { + // No value yet, use x's + member_val = std::string(expected_width, 'x'); + } else { + member_val = "x"; + } + + result += member_val; } - - // If the fork scope is not found, pad with x's based on the width - if (virtual_handle_widths.find(signal) != virtual_handle_widths.end()) { - return std::string(virtual_handle_widths[signal], 'x'); - } - return "x"; + return result; } + // Normal signal handling if (past_data.find(signal) == past_data.end()) { if (handle_to_var.find(signal) != handle_to_var.end()) { return std::string(handle_to_var[signal].width, 'x'); diff --git a/kernel/fstdata.h b/kernel/fstdata.h index b65681b00..ee421f9ac 100644 --- a/kernel/fstdata.h +++ b/kernel/fstdata.h @@ -69,9 +69,7 @@ private: uint64_t last_time; std::map past_data; uint64_t past_time; - std::map> fork_scopes; - std::map virtual_to_fork; - std::map virtual_handle_widths; + std::map> fork_scope_members; double timescale; std::string timescale_str; uint64_t start_time;