Surelog Documentation

repository·master·Indexed 19 days ago

https://github.com/chipsalliance/surelog

Surelog is a complete SystemVerilog 2017 front-end featuring a preprocessor, parser, and elaborator. It supports open-source cores and generates a Universal Hardware Data Model (UHDM) for use by simulators, synthesis tools, and linters. Key capabilities include incremental compilation via Cap'n'Proto, multi-threaded parsing, a Python API for custom linting, and a C++ API for interacting with design and testbench data models.

Tokens
16.3K
Snippets
42
Records
70
Agent score
66%

What's inside Surelog

  1. Overview of Surelog features and capabilities

    master

    Surelog is a SystemVerilog 2017 front-end providing a preprocessor, parser, and elaborator for both design and testbench.

    Key features include:

    • Parser Engine: Uses Antlr 4.10 for preprocessor and parser generation.
    • Incremental Compilation: ASTs are made persistent on disk using Cap'n'Proto.
    • Performance: Built to be thread-safe with multi-threaded parsing and module/package splitting for large files.
    • Compliance: Supports IEEE Simulator-compliant project specifications and issues Errors/Warning/Info/Notes regarding language compliance.
    • Extensibility: A comprehensive Python API allows for custom linting rules (via Parser grammar or design data model), custom message formats, and message waiving.
    • Interoperability: Generates a UHDM (Universal Hardware Data Model) compiled database that can be read by 3rd party tools (Synthesis, Simulators, Linters, Formal) via the standard VPI API.
  2. Understand OVM testbench construction principles

    master

    The OVM (Open Verification Methodology) examples provide guidance on two primary areas of testbench construction:

    1. Mechanics: Focuses on the structural foundation of a testbench, including:

      • Constructing object hierarchies.
      • Connecting to hardware using virtual interfaces.
      • Implementing simple transaction-based producer-consumer models.
    2. TLM (Transaction Level Modeling): Focuses on communication between testbench components using TLM interfaces and channels to facilitate connectivity.

  3. Simulate USB 2.0 BULK transfers using TLM 2.0 nonblocking transport

    master

    This example demonstrates how to model USB 2.0 BULK transfers using UVM TLM 2.0 nonblocking transport methods (nb_transport_fw and nb_transport_bw). Instead of modeling individual packets, the transfer is modeled as a sequence of timing points using specific phase (ph) tokens and transaction (xfer) properties.

    Host-to-Device (OUT) Bulk Transfer Sequence

    To model a host-to-device transfer, follow these timing points until a UVM_TLM_COMPLETED sync value is received:

    1. Token Phase: Call nb_transport_fw(xfer, ph) where xfer.kind == OUT and ph == USB_TLM_TOKEN. The device responds with UVM_TLM_ACCEPTED or UVM_TLM_COMPLETED.
    2. Data Phase: Call nb_transport_fw(xfer, ph) where xfer.data contains the bulk data and ph == USB_TLM_DATA. The device responds with UVM_TLM_ACCEPTED, or UVM_TLM_COMPLETED (with xfer.status set to ACK/NAK/STALL/NYET and ph updated to USB_TLM_HANDSHAKE).
    3. Handshake Phase: Call nb_transport_bw(xfer, ph) where xfer.status is ACK/NACK/STALL/NYET and ph == USB_TLM_HANDSHAKE. The host responds with UVM_TLM_COMPLETED.
  4. Understand the Codec DUT specification

    master

    The Device Under Test (DUT) in this example is a full-duplex parallel-to-serial codec. It handles data transmission and reception with specific character insertion and escaping rules:

    Transmission Rules

    • Order: Bytes written to the TxFIFO are transmitted MSB-first.
    • Idle State: If no bytes are available, IDLE (0x81) is transmitted.
    • Sync Character: A SYNC character (0xB2) is inserted every 7 bytes.
    • Escaping: To transmit IDLE (0x81) or ESC (0xE7) as valid data, they must be preceded by an ESC character.

    Reception Rules

    • Filtering: SYNC, IDLE, and ESC characters are ignored by the receiver unless they are part of the valid data stream (handled via escaping).
    • Storage: Received bytes are added to the RxFIFO if it is not full.

    Register Map

    AddressBitsNameAccessDescription
    0x00000:0TxEmptyROTx FIFO is empty
    0x00001:1TxLowROTx is at or below low water mark
    0x00002:2TxFullROTx FIFO is full (32)
    0x00004:4RxEmptyRORx FIFO is empty
    0x00005:5RxHighRORx FIFO is at or above high water mark
    0x00006:6RxFullRORx FIFO is full (32)
    0x00008:8SAW1CSymbol alignment acquired/lost (Resets to b000010001)
    0x00048:0IntMaskRWInterrupt mask (0 masks source, resets to 0)
    0x00100:0TxEnRWEnable transmit path (Resets to 0)
    0x00144:0TxLWMRWTx FIFO low water mark (Resets to 8)
    0x00200:0RxEnRWEnable receive path
    0x00201:1ALIGNROSymbol alignment status (Resets to 0)
    0x00244:0RxHWMRWRx FIFO high water mark (Resets to 16)
    0x01007:0TxDataWOWrite data to TxFIFO
    0x01007:0RxDataRORead data from RxFIFO
  5. Understand the PPCache Mechanism

    master

    Surelog uses the PPCache class to persist preprocessor output and IncludeFileInfo records to disk using Cap'n Proto serialization. This enables performance gains through caching and supports incremental compilation.

    Key Operations

    • Saving: Triggered via PreprocessFile::saveCache() when not using a cached version.
    • Restoring: Attempted via cache.restore() using the current command line parser's settings (e.g., checking lowMem() or noCacheHash()).
    • Serialization: The cacheIncludeFileInfos() method iterates through the IncludeFileInfo vector to serialize context, action, and location information, including symbol and path IDs.
  6. Understand the Surelog Preprocessor Architecture

    master

    Surelog's preprocessor is a full ANTLR-based parser rather than a simple text-replacement engine. It uses a dedicated grammar to accurately track file locations, macro expansions, and includes.

    Preprocessing Strategy

    • Include files: Replaced by their actual content.
    • Macro definitions: Removed from output but replaced with equivalent whitespace to preserve line numbering.
    • Whitespace preservation: This intentional strategy ensures that line numbers in the preprocessed output maintain a direct correspondence with the original source, simplifying the reconstruction of file/line information during complex nested (imbricated) macro or include usage.

    Data Flow

    1. Parsing: ANTLR parses input using the preprocessor grammar.
    2. Tree Walking: SV3_1aPpTreeShapeListener processes directives and creates IncludeFileInfo records.
    3. Output Generation: Preprocessed text and IncludeFileInfo records are generated.
    4. Caching: Both are serialized to disk via Cap'n Proto.
    5. Parser Integration: The main SystemVerilog parser consumes the output and uses IncludeFileInfo to map errors back to original source locations.
  7. Understand UVM API annotations and categories

    master

    The UVM implementation uses specific annotations to identify the origin and status of APIs. This helps in identifying standard compliance and portability risks.

    API Categories

    1. Standard APIs: Annotated with @uvm-ieee 1800.2-2017 [section] to map directly to the IEEE standard.
    2. Potential Contributions: Identified by // @uvm-contrib Potential Contribution to 1800.2. These are being considered for the standard but are not yet part of it.
    3. Accellera Implementation-specific: Identified by // @uvm-accellera Accellera Implementation-specific API. These are not part of the IEEE standard and may not be portable to other 1800.2 implementations.
    4. Deprecated UVM 1.2 APIs: These are available only when the macro `ifdef UVM_ENABLE_DEPRECATED_API is defined. If this macro is not defined, any code referencing these APIs will fail to compile.

    Warning: Code leveraging non-standard APIs (categories 2 and 3) may lack portability across different 1800.2 implementations.

    // Example of a standard API annotation
    // @uvm-ieee 1800.2-2017 auto 16.5.3.2
    extern virtual function void get_packed_bits (ref bit unsigned stream[]);
    
    // Example of a contribution annotation
    // @uvm-contrib Potential Contribution to 1800.2
  8. Nonblocking TLM2 USB 2.0 BULK transfer sequence

    master

    This example demonstrates how to model a USB 2.0 BULK transfer using UVM TLM2 nonblocking transport methods (nb_transport_fw and nb_transport_bw). Instead of simulating individual packets, the model uses timing points (phase updates) to represent the exchange. The sequence continues until a UVM_TLM_COMPLETED synchronization value is received by either the host or the device.

    Host-to-Device (OUT) Bulk Transfer Sequence

    1. Token Phase: Call nb_transport_fw(xfer, ph) where xfer.kind == OUT and ph == USB_TLM_TOKEN. The device responds with UVM_TLM_ACCEPTED or UVM_TLM_COMPLETED.
    2. Data Phase: Call nb_transport_fw(xfer, ph) where xfer.data contains the bulk data and ph == USB_TLM_DATA. The device responds with UVM_TLM_ACCEPTED or UVM_TLM_COMPLETED. If completed, xfer.status is set to ACK/NAK/STALL/NYET and ph is updated to USB_TLM_HANDSHAKE.
    3. Handshake Phase: Call nb_transport_bw(xfer, ph) where xfer.status is ACK/NACK/STALL/NYET and ph == USB_TLM_HANDSHAKE. The host responds with UVM_TLM_COMPLETED.

    Device-to-Host (IN) Bulk Transfer Sequence

    1. Token Phase: Call nb_transport_fw(xfer, ph) where xfer.kind == IN and ph == USB_TLM_TOKEN. The device responds with UVM_TLM_ACCEPTED, UVM_TLM_UPDATED (with data and ph updated to USB_TLM_DATA), or UVM_TLM_COMPLETED (with xfer.status as NAK/STALL and ph updated to USB_TLM_HANDSHAKE).
    2. Data Phase: Call nb_transport_bw(xfer, ph) where xfer.data contains the bulk data and ph == USB_TLM_DATA. The host responds with UVM_TLM_ACCEPTED or UVM_TLM_COMPLETED (with xfer.status == ACK and ph updated to USB_TLM_HANDSHAKE).
    3. Handshake Phase: Call nb_transport_fw(xfer, ph) where xfer.status == ACK and ph == USB_TLM_HANDSHAKE. The device responds with UVM_TLM_COMPLETED.
  9. Load OVM into a design: Include vs Package methods

    master

    There are two primary methods for loading OVM into a SystemVerilog design. The preferred method depends on your IUS version.

    1. Include Methodology

    Include the OVM header directly into the scope where it will be used:

    `include "ovm.svh"

    When to use: Recommended for IUS versions prior to 8.2, or if you need to use svpp for handling parameterized types and specializations.

    2. Package Import Methodology

    Compile the OVM package first, then import it. This is the preferred method for IUS 8.2 and later because IUS 8.2+ natively supports parameterized classes without requiring svpp.

    Steps:

    1. Compile ovm_pkg.sv.
    2. Import the package and include the macros:
    import ovm_pkg::*;
    `include "ovm_macros.svh"

    Note: You must include ovm_macros.svh when using the package model to ensure access to OVM macro definitions.

    Scoping Note

    If you both import ovm_pkg and `include "ovm.svh" in the same scope, the local version (via include) takes precedence unless you use the scope resolution operator (ovm_pkg::).