// SPDX-FileCopyrightText: 2025-2026 Yu-Sheng Lin // SPDX-FileCopyrightText: 2025-2026 Yoda Lee // SPDX-License-Identifier: MIT // Project: libfstwriter // Website: https://github.com/gtkwave/libfstwriter #pragma once // direct include // C system headers // C++ standard library headers #include #include #include #include // Other libraries' .h files. // Your project's .h files. #if defined(MSC_VER_) || defined(FORCE_MSC_VER_) # define USE_GCC_INTRINSIC 0 // Note: we do not support MSVC intrinsic for now # define USE_MSVC_INTRINSIC 0 #elif defined(__GNUC__) || defined(__clang__) # define USE_GCC_INTRINSIC 1 # define USE_MSVC_INTRINSIC 0 #else # define USE_GCC_INTRINSIC 0 # define USE_MSVC_INTRINSIC 0 #endif // Remove these when we upgrade to C++20 #pragma GCC diagnostic ignored "-Wpragmas" #pragma GCC diagnostic ignored "-Wc++17-attribute-extensions" #pragma GCC diagnostic ignored "-Wc++20-attribute-extensions" namespace fst { typedef uint32_t Handle; typedef uint32_t EnumHandle; struct string_view_pair { const char *m_data = nullptr; size_t m_size = 0; // implicit conversion from const char*, std::string, std::string_view string_view_pair(const char *data) : m_data{data}, m_size{data == nullptr ? 0 : std::strlen(data)} {} string_view_pair(const char *data, size_t size) : m_data{data}, m_size{size} {} string_view_pair(const std::string &s) : m_data{s.c_str()}, m_size{s.size()} {} #if __cplusplus >= 201703L string_view_pair(std::string_view s) : m_data{s.data()}, m_size{s.size()} {} #endif }; [[maybe_unused]] static inline string_view_pair make_string_view_pair(const char *data) { if (!data) { return {nullptr, 0}; } return {data, std::strlen(data)}; } [[maybe_unused]] static inline string_view_pair make_string_view_pair(const char *data, std::size_t size) { return {data, size}; } enum class WriterPackType : uint8_t { ZLIB = 0, // not supported FASTLZ = 1, // not supported LZ4 = 2, // usually for testing, you should use eLz4 // This will turn off compression for geometry/hierarchy/wave data NO_COMPRESSION = 3, }; enum class FileType : uint8_t { VERILOG = 0, VHDL, VERILOG_VHDL, }; enum class EncodingType : uint8_t { BINARY = 0, // 1 bit per bit to represent 0,1 VERILOG = 1, // 2 bits per bit to represent X,Z VHDL = 2, // 4 bits per bit to represent H,U,W,L,-,? }; [[maybe_unused]] static inline constexpr unsigned bitPerEncodedBit(EncodingType type) { return 1 << static_cast(type); } [[maybe_unused]] static const char* kEncodedBitToCharTable = ( "01" // Binary "xzhu" // Verilog "wl-? " // Vhdl (padded with ' ') ); struct Hierarchy { enum class ScopeType : uint8_t { VCD_MODULE = 0, VCD_TASK = 1, VCD_FUNCTION = 2, VCD_BEGIN = 3, VCD_FORK = 4, VCD_GENERATE = 5, VCD_STRUCT = 6, VCD_UNION = 7, VCD_CLASS = 8, VCD_INTERFACE = 9, VCD_PACKAGE = 10, VCD_PROGRAM = 11, VHDL_ARCHITECTURE = 12, VHDL_PROCEDURE = 13, VHDL_FUNCTION = 14, VHDL_RECORD = 15, VHDL_PROCESS = 16, VHDL_BLOCK = 17, VHDL_FORGENERATE = 18, VHDL_IFGENERATE = 19, VHDL_GENERATE = 20, VHDL_PACKAGE = 21, SV_ARRAY = 22, }; enum class ScopeControlType : uint8_t { GEN_ATTR_BEGIN = 252, GEN_ATTR_END = 253, VCD_SCOPE = 254, VCD_UPSCOPE = 255, }; enum class VarType : uint8_t { VCD_EVENT = 0, VCD_INTEGER = 1, VCD_PARAMETER = 2, VCD_REAL = 3, VCD_REAL_PARAMETER = 4, VCD_REG = 5, VCD_SUPPLY0 = 6, VCD_SUPPLY1 = 7, VCD_TIME = 8, VCD_TRI = 9, VCD_TRIAND = 10, VCD_TRIOR = 11, VCD_TRIREG = 12, VCD_TRI0 = 13, VCD_TRI1 = 14, VCD_WAND = 15, VCD_WIRE = 16, VCD_WOR = 17, VCD_PORT = 18, VCD_SPARRAY = 19, VCD_REALTIME = 20, GEN_STRING = 21, SV_BIT = 22, SV_LOGIC = 23, SV_INT = 24, SV_SHORTINT = 25, SV_LONGINT = 26, SV_BYTE = 27, SV_ENUM = 28, SV_SHORTREAL = 29, }; enum class VarDirection : uint8_t { MIN = 0, IMPLICIT = 0, INPUT = 1, OUTPUT = 2, INOUT = 3, BUFFER = 4, LINKAGE = 5, MAX = 5, }; enum class AttrType : uint8_t { MIN = 0, MISC = 0, ARRAY = 1, ENUM = 2, PACK = 3, MAX = 3, }; enum class AttrSubType : uint8_t { // For AttrType::eMisc MISC_MIN = 0, MISC_COMMENT = 0, MISC_ENVVAR = 1, MISC_SUPVAR = 2, MISC_PATHNAME = 3, MISC_SOURCESTEM = 4, MISC_SOURCEISTEM = 5, MISC_VALUELIST = 6, MISC_ENUMTABLE = 7, MISC_UNKNOWN = 8, MISC_MAX = 8, // For AttrType::eArray ARRAY_MIN = 0, ARRAY_NONE = 0, ARRAY_UNPACKED = 1, ARRAY_PACKED = 2, ARRAY_SPARSE = 3, ARRAY_MAX = 3, // For AttrType::eEnum ENUM_MIN = 0, ENUM_SV_INTEGER = 0, ENUM_SV_BIT = 1, ENUM_SV_LOGIC = 2, ENUM_SV_INT = 3, ENUM_SV_SHORTINT = 4, ENUM_SV_LONGINT = 5, ENUM_SV_BYTE = 6, ENUM_SV_UNSIGNED_INTEGER = 7, ENUM_SV_UNSIGNED_BIT = 8, ENUM_SV_UNSIGNED_LOGIC = 9, ENUM_SV_UNSIGNED_INT = 10, ENUM_SV_UNSIGNED_SHORTINT = 11, ENUM_SV_UNSIGNED_LONGINT = 12, ENUM_SV_UNSIGNED_BYTE = 13, ENUM_REG = 14, ENUM_TIME = 15, ENUM_MAX = 15, // For AttrType::ePack PACK_MIN = 0, PACK_NONE = 0, PACK_UNPACKED = 1, PACK_PACKED = 2, PACK_SPARSE = 3, PACK_MAX = 3, }; enum class SupplementalVarType : uint8_t {}; enum class SupplementalDataType : uint8_t {}; }; struct Header { uint64_t m_start_time{uint64_t(-1)}; uint64_t m_end_time{0}; int64_t m_timezero{0}; // Match the original fstapi.c. Just for information, not used in FST. uint64_t m_writer_memory_use{1ull << 27}; uint64_t m_num_scopes{0}; uint64_t m_num_vars{0}; // #CreateVar calls, including aliases uint64_t m_num_handles{0}; // #unique handles, excluding aliases, shall be <= m_num_vars uint64_t m_num_value_change_data_blocks{0}; char m_writer[128]{}; char m_date[26]{}; FileType m_filetype{FileType::VERILOG}; int8_t m_timescale{-9}; }; static constexpr uint64_t kInvalidTime = uint64_t(-1); } // namespace fst