T1 (Torrent-1) RISC-V Vector Implementation

repository·master·Indexed 43 days ago

https://github.com/chipsalliance/t1

A high-performance RISC-V Vector implementation designed for lane-based micro-architectures. T1 offers flexibility in configuring VLEN, DLEN, and memory subsystems for both high-efficiency and high-performance vector processing.

Tokens
22.2K
Snippets
61
Records
99
Agent score
55%

What's inside T1

  1. Overview of the T1 RISC-V Long Vector Machine Hardware Generator

    master

    T1 is a hardware generator built using the Chisel language designed to create RISC-V Long Vector Machines. It is compliant with the RISC-V Vector Spec 1.0 and supports specific extensions.

    Key architectural features include:

    • Integration: Can be integrated with any RISC-V scalar core using an Out-of-Order (OoO) write-back scheme.
    • Vector Function Unit (VFU): Fully pipelined.
    • Load Store Unit (LSU): Configurable.
    • Vector Register File (VRF): Based on Dual-port SRAM.

    The generator allows for microarchitecture tuning to balance bandwidth, area, and frequency. Performance tuning involves configuring parameters such as VLEN, memory type, required bandwidth, and vector cache size.

  2. Overview of T1 (Torrent-1) Architecture

    master

    T1 (Torrent-1) is a RISC-V Vector implementation inspired by the Cray X1 vector machine. It is designed for lane-based micro-architectures with intensive chaining support and SRAM-based Vector Register Files (VRFs).

    Key capabilities include:

    • RISC-V Support: Implements standard Zve32f and Zve32x. VLEN and DLEN can be scaled up to 64K.
    • Modular Design: Can be integrated with any RISC-V scalar core (currently uses a forked Rocket Core as the default scalar part).
    • Execution Model: Supports lane-based execution, intensive chaining (e.g., Load-to-Multiple-Exec to Store-to-Load), and pipelined/asynchronous Vector Function Units (VFU).
    • Memory Model: Features a configurable Load Store Unit (LSU) with instruction-level Out-of-Order (OoO) load/store and configurable outstanding sizes to mitigate latency.
    • Deployment: T1 only supports bare-metal program loading and execution. Test examples are located in the tests/ directory.
  3. Navigate the difftest directory structure

    master

    The difftest repository is organized into three main functional areas:

    1. Project Management & Environment

    • Cargo.toml / Cargo.lock: Rust project and dependency management.
    • default.nix: Nix configuration for building the project environment.
    • doc/: Project documentation.

    2. DPI Driver Directories (Emulator Interface)

    These directories contain the TestBench code and DPI (Direct Programming Interface) libraries used by emulators (VCS/Verilator):

    • dpi_common/: Shared library code used across all verification objects.
    • dpi_t1/: TestBench code and DPI library for the t1 object.
    • dpi_t1rocket/: TestBench code and DPI library for the t1rocket object.

    3. Difftest Directories (Verification Logic)

    These directories contain the logic for the verification framework:

    • offline_t1/ and offline_t1rocket/: Verification project files for t1 and t1rocket respectively, containing the difftest code.
    • spike_interfaces/: C++ interface definitions.
    • spike_rs/: Rust source files (lib.rs, runner.rs, spike_event.rs) providing methods and tools for the verification phase.
  4. Understand the riscv-opcodes project structure

    master

    The riscv-opcodes repository enumerates standard RISC-V instruction opcodes and CSRs. It uses a Python script (parse.py) to convert these definitions into various formats like C, Scala, LaTeX, Rust, and SystemVerilog. These artifacts are used by tools such as Spike, PK, and the RISC-V Manual.

    Key files include:

    • parse.py: The core script for instruction validation and artifact generation.
    • rv*: Instruction opcode files (ratified).
    • unratified/rv*: Instruction opcode files (not yet ratified).
    • encoding.h: The template file for C header generation.
    • Makefile: Used to orchestrate artifact generation.
  5. Handle cross-lane reads and writes

    master

    Cross-lane operations are determined by the operand type and the sew (Selected Element Width) configuration.

    Cross-lane Write Rules

    Write operations cross lanes based on the prefix applied to the width:

    • w prefix: 2sew = sew op sew (Cross-lane write occurs)
    • w.w prefix: 2sew = 2sew op sew (Cross-lane write occurs)
    • n.w prefix: sew = 2sew op sew (Does not cross lanes)

    Cross-lane Read Rules

    Read operations cross lanes based on the suffix applied to the width:

    • w suffix indicates a cross-lane read.

    For a normal cross-lane read at group index = n:

    • sew reads elements at indices [8n, 8n + 8].
    • 2sew reads elements at indices [16n, 16n + 16].
    • This is effectively reading one set from group index = 2n and another from group index = 2n + 1.

    Lane Mapping Example (2sew)

    When performing a 2sew operation, multiple lanes contribute to the target lane mapping:

    Descriptionlane0lane1lane2lane3lane4lane5lane6lane7
    sewnn + 1n + 2n + 3n + 4n + 5n + 6n + 7
    2sew(2n +)01234567
    89101112131415
    Target Lane00112233
    44556677

    Special Instructions

    • vrgather.vv and vrgatherei16.vv require special handling.
    • vrgatherei16.vv involves complex cross-lane reads and is currently a known complexity.
    • Certain requests (like LSU instructions) should be corrected to vsew to maximize read width, allowing the mask unit or LSU to handle splitting/assembly.
  6. Challenges in Offline Difftest: Memory and Undefined Behavior

    master

    Developers implementing offline difftest should be aware of two primary technical challenges:

    Memory Behavior Discrepancies

    Differences in memory access order between the DUT and the model can lead to behavioral discrepancies. Solutions include:

    • Implementing specialized alignment strategies.
    • Utilizing memory model simulation.

    Undefined Behavior Simulation

    Simulating undefined behavior is complex. A robust implementation requires:

    • A flexible interface that allows the simulator to inject undefined behavior when detected.
    • Mechanisms to record related traces for post-detection analysis.
  7. Understand the sail_impl architecture and components

    master

    The sail_impl project provides a Sail-implemented RISC-V execution model. It uses the Sail toolchain to generate C code from RISC-V ISA representations stored in csr/, inst/, and rvcore/.

    Key components include:

    • Sail: The underlying programming language and toolchain used for ISA representation.
    • sail_impl: This specific project providing the RISC-V execution model.
    • sailcodegen: A Scala-based code generator that produces the required Sail code based on march information.
    • boat: An emulator that uses sail_impl models to drive a RISC-V core.
    • Emulator side: Typically implemented in Rust, interacting with the Sail model via FFI.
  8. Define pseudo-instructions using $pseudo_op

    master

    Pseudo-instructions are aliases of regular instructions with specific restrictions. They use the $pseudo_op keyword.

    Syntax: $pseudo_op <extension>::<base-instruction> <instruction name> <instruction args> <bit-encodings>

    Restrictions:

    • The <base-instruction> must be a regular instruction (it cannot be a pseudo-op itself).
    • Pseudo-ops or already imported instructions cannot be imported.

    Example:

    $pseudo_op rv_zicsr::csrrs frflags rd 19..15=0 31..20=0x001 14..12=2 6..2=0x1C 1..0=3
    $pseudo_op rv_zicsr::csrrs frflags rd 19..15=0 31..20=0x001 14..12=2 6..2=0x1C 1..0=3
  9. Understand the VRF (Vector Register File) architecture

    master

    The VRF is a vector extension unit with an ELEN = 32, meaning the VRF width is 32. It is implemented as a register file with 2 read ports and 1 write port.

    Key architectural characteristics:

    • SEW Support: Supports sew values of 0, 1, and 2. For sew=0, the granularity is 8.
    • Register Layout: To support multiply-accumulate (MAC) operations requiring three source operands, the register file uses a scrambled/shuffled arrangement to reduce access conflicts, as a standard 2-read-port RF cannot provide three operands in a single cycle.
    • Chaining: Supports fine-grained RAW (Read-After-Write) checking to allow subsequent instructions to execute before a preceding instruction has fully completed, provided the write is not out-of-order and no exceptions are pending.
  10. Implementation strategies for permutation instructions

    master

    The T1 architecture handles permutation-type instructions using several distinct data paths depending on the instruction type:

    • mv (Scalar-to-Vector/Vector-to-Scalar): Moves data directly through lane0.
    • slide: Data is moved via the data bus in a queued fashion.
    • gather: Follows a multi-stage process:
      1. Pass through a mask check.
      2. Compare against max vlen via the ALU.
      3. If successful, feedback to the scheduler to re-access the register file (RF).
      4. Exchange data to the target lane via the data bus.
      5. Write to the RF. (Note: If max vlen comparison is sufficient, this can be handled directly in the Mask Unit).
    • (de)compress: Implementation should ideally occur within the Mask Unit.
    • vr move: Implemented as a direct read followed by a write.
  11. Understand the Vector Coprocessor Datapath Flow

    master

    The vector coprocessor (V) receives instructions via the V.request interface, which provides instruction, rs1Data, and rs2Data.

    Instruction Lifecycle:

    1. Latching: The instruction, rs1Data, rs2Data, and V.instructionCounter (used as a tag for recording) are latched into V.requestReg.
    2. Backpressure: The system maintains a 1-depth queue to handle backpressure.
    3. Enqueueing: In the following cycle, instructions are enqueued into slots. Most instructions are decoded and sent to each lane via entranceControl (which repackages the laneRequest and csr).
    4. Lane Execution: Inside the lane, an entranceControl state machine is initialized for each instruction group using initState.