---
name: rtl-coding
version: 1.0.0
category: 内容创作
trigger_words:
tags:
  - design
  - writing
platform: coze
source: DeepseekModel
source_url: https://deepseekmodel.com/skill?id=verdvana-verdvana-github-io-skill-md
---

name rtl-coding description Comprehensive guidelines for writing production-quality RTL code in Verilog and SystemVerilog for hardware design RTL Coding Guidelines This skill provides comprehensive guidelines for writing production-quality RTL code in SystemVerilog. Purpose : Comprehensive guidelines for writing SystemVerilog RTL code based on production-quality implementations from high-performance graphics processing unit design. Audience : Hardware engineers, RTL designers, and AI agents performing RTL design and implementation. Scope : Applicable to all digital design projects including processors, accelerators, peripherals, and SoC components. Note for AI Agents : This document provides structured patterns and examples for generating RTL code. Each section includes rationale, implementation patterns, and best practices. Use these patterns as templates, adapting signal names and parameters to match the specific design context. When to Use This Skill Use this skill when you need to: Write SystemVerilog RTL code for digital hardware design Create module declarations and hierarchies Define packages, data types, and structures Implement interfaces and port declarations Design clock gating and power management Write combinational and sequential logic Implement FIFOs and memory interfaces Create debug and performance monitoring infrastructure Follow synthesis and coding best practices Table of Contents Header and Documentation Module Declaration and Naming Parameter and Localparam Usage Package and Import Guidelines Data Types and Structures Interface and Port Declarations Signal Naming Conventions Generate Blocks and Parameterization Clock and Reset Handling Combinational and Sequential Logic Debug and Performance Monitoring Comments and Code Documentation Synthesis and Simulation Directives FIFO Design and Implementation Memory Interface Design Communication Protocols Synthesis Optimization and Constraints 1. Header and Documentation A comprehensive file header serves multiple critical purposes in professional RTL development. It provides legal protection, version control integration, and essential metadata for project management. The header establishes ownership, tracks changes over time, and helps developers understand the module's purpose and history. The standardized header format ensures consistency across all project files and integrates seamlessly with version control systems like Perforce or Git. The RCS (Revision Control System) tags are automatically updated by the version control system, providing real-time tracking of file modifications. Standard File Header Template //------------------------------------------------------------------------------ // COMPANY Proprietary // Copyright (c) YEAR, COMPANY Incorporated. All rights reserved. // // All data and information contained in or disclosed by this document are // confidential and proprietary information of COMPANY Incorporated, and // all rights therein are expressly reserved. By accepting this material, // the recipient agrees that this material and the information contained // therein are held in confidence and in trust and will not be used, // copied, reproduced in whole or in part, nor its contents revealed in // any manner to others without the express written permission of COMPANY // Incorporated. // // This technology was exported from the United States in accordance with // the Export Administration Regulations. Diversion contrary to U.S. law // prohibited. // ------------------------------------------------------------------------------ // RCS File : $Source: /path/to/file $ // Revision : $Revision: x.xx.x.xx $ // Id : $Id: filename.sv,v x.xx.x.xx date time author Exp $ // ------------------------------------------------------------------------------ // Block : module_name // Description : Brief description of module functionality // //R- Author : Name (email@domain.com) //R- Created : Date // ------------------------------------------------------------------------------ //R- Revision Log //R- Who When What //R============================================================================== //------------------------------------------------------------------------------- File Naming Convention Consistent file naming is crucial for large-scale projects where hundreds or thousands of RTL files must be organized and maintained. The naming convention should immediately convey the file's purpose, hierarchical position, and functional area within the design. The hierarchical naming approach helps developers quickly locate files and understand the design structure. Using lowercase with underscores ensures compatibility across different operating systems and tools, while avoiding potential issues with case-sensitive file systems. Naming Rules: Use lowercase with underscores: gfx_<blk>_cluster_wrap.sv Include block hierarchy: gfx_<blk>p_prefetch_dbg.sv Suffix with .sv for SystemVerilog files Include functional indicators: _core , _wrap , _ctrl , _dbg 2. Module Declaration and Naming Module naming and declaration style form the foundation of readable and maintainable RTL code. A well-structured module declaration immediately communicates the module's purpose, dependencies, and interface to other developers. The naming convention should reflect the design hierarchy and functional relationships between modules. The systematic approach to module naming enables automated tools to understand design structure and facilitates script-based operations across the design database. Consistent naming also helps with debugging, as signal names in waveforms and synthesis reports directly correspond to the hierarchical structure. Module Naming Convention The hierarchical naming convention serves multiple purposes: it indicates the module's position in the design hierarchy, its functional area, and its specific role within that area. This approach scales effectively from small designs to complex SoCs with thousands of modules. Naming Guidelines: Use hierarchical naming: gfx_<blk>_cluster_wrap Include functional area prefix: gfx_<blk>p_ , gfx_<blk>_ Use descriptive suffixes: _wrap , _core , _ctrl , _dbg Maintain consistency across related modules Avoid abbreviations that aren't universally understood Module Declaration Style The module declaration format establishes a clear structure that separates concerns: package imports define the type system, parameters configure the module, and ports define the interface. This separation makes the module easier to understand and modify. Package imports should be placed immediately after the module name to establish the type context before parameters and ports are declared. This ordering ensures that all custom types are available for use in parameter and port declarations. module gfx_<blk>_cluster_wrap import gfx_common_datatype_pkg::*; import gfx_<blk>_datatype_pkg::*; import gfx_usp_datatype_pkg::*; import gfx_<blk>_internal_pkg::*; #( parameter BLK_CL_ID = 0, parameter DV_RAND_DLY = 0 ) ( // Clock & Reset input ares, input clk, // Interface Groups (organized by function) gfx_rbbm_cgc_p2s_if.rx rbbm_<blk>_cgc, gfx_slice_info_if.slice slice_id, // Status outputs output logic [NUM_CB_PIPES-1:0] <blk>_cluster_busy, output logic [NUM_CB_PIPES-1:0] <blk>_cluster_active ); Key Rules: Import packages after module name, before parameters Group ports by functionality with comments Use consistent indentation (4 spaces) Place parameters in separate section with defaults Order ports logically: clocks/resets first, status outputs last 3. Parameter and Localparam Usage Parameters and localparams are fundamental to creating scalable, configurable RTL designs. They enable design reuse across different configurations and facilitate maintenance by centralizing configuration values. Proper parameter usage distinguishes between externally configurable values (parameters) and internally calculated constants (localparams). The distinction between parameters and localparams is crucial for design intent and tool optimization. Parameters can be overridden during instantiation, making modules configurable, while localparams are computed internally and cannot be modified externally. This separation ensures design integrity while providing necessary flexibility. Parameter Declaration Parameters should be used sparingly and only for values that genuinely need external configuration. Each parameter should have a clear purpose and sensible default value. Localparams handle all derived calculations and internal constants, keeping the parameter interface clean and focused. The parameter declaration style should clearly separate external configuration from internal calculations. This organization makes it immediately obvious which values can be modified during instantiation and which are computed internally. // Module parameters (configurable from outside) parameter BLK_CL_ID = 0, parameter DV_RAND_DLY = 0 // Local parameters (internal calculations) localparam RBUF_DEPTH = BLK_BUF_DEPTH/2; localparam CGC_ID_BLK_CLUSTER = get_cgc_id(CGC_P2S_BLK_<BLK>, (BLK_CL_ID + 1)); localparam NUM_BLK_CLUSTER = NUM_BLK_CLUSTERS; Parameter Naming Rules: Consistent naming conventions for parameters and localparams improve code readability and reduce errors. The naming should immediately convey the parameter's purpose and data type. Using ALL_CAPS distinguishes parameters from variables and signals. Use ALL_CAPS for parameters and localparams Use descriptive names: NUM_BLK_CLUSTERS not N_BLK Include width specifications: ADDR_W , DATA_W Use consistent suffixes: _W for width, _DEPTH for depth Avoid abbreviations unless they're industry standard Group related parameters with common prefixes Localparam Categories: Organizing localparams into logical categories improves maintainability and helps developers understand the design structure. Each category should group related constants that serve similar purposes within the design. // RAM/Memory configuration localparam BLK_GL_MASTER_RAM_FLOP_SEL = 0; localparam BLK_IDX_FIFO_MASTER_RAM_FLOP_SEL = 0; localparam BLK_RBUF_MASTER_RAM_FLOP_SEL = 0; // Pipeline configuration localparam PIPELINE_EN = gfx_common_datatype_pkg::HPGPU_2_5_GHZ_EN; localparam PIPELINE_MODE__NO_STAGE = 0; localparam PIPELINE_MODE__STAGE = 1; localparam PIPELINE_MODE__DCPL = 2; // Width and depth calculations localparam FETCH_SRAM_WIDTH = 49; localparam DEST_SRAM_WIDTH = 12; localparam IAB_DEPTH = 36; localparam IAB_ADDR_BIT = $clog2(IAB_DEPTH); // Performance and timing parameters localparam MAX_OUTSTANDING_REQUESTS = 16; localparam TIMEOUT_CYCLES = 1000; localparam RETRY_LIMIT = 3; 4. Package and Import Guidelines Package organization is critical for large-scale designs with complex type systems. Packages should be organized hierarchically with clear dependencies and consistent naming. The USP datatype implementation demonstrates sophisticated package organization with conditional compilation and architecture-specific parameters. Package Structure and Organization Packages should be organized by functionality and dependency hierarchy. Common types should be in base packages, while block-specific types should be in dedicated packages. Architecture-specific parameters should be handled through conditional compilation or parameter overrides. package gfx_<blk>_datatype_pkg; // Include architecture-specific defines `include "<blk>_top_defines.vh" // Import dependencies in order import gfx_common_datatype_pkg::*; import gfx_hlsq_datatype_pkg::*; // Architecture-specific parameters with conditional logic localparam int NUM_CLUSTER_PER_SP = 2; localparam int GFX_<BLK>_VS_IF_QUAD = (GFX_ARCH == 2) ? 1 : ((GFX_ARCH == 4) ? 1 : 2); localparam int GFX_<BLK>_FS_IF_QUAD = (GFX_ARCH == 2) ? 2 : ((GFX_ARCH == 4) ? 4 : 8); localparam int GFX_<BLK>_WAVE_SIZE = (GFX_ARCH == 2) ? 32 : ((GFX_ARCH == 4) ? 64 : 128); // Shared constants with descriptive names localparam int STCHE_CLI_WIDTH = 6; localparam int STCHE_CLI_NULL = 6'd32; localparam int STCHE_CLI_OOB = 6'd33; localparam int STCHE_CLI_2D = 6'd34; // Enumeration definitions with comprehensive coverage typedef enum logic [5:0] { UCOORD = 0, VCOORD = 1, RCOORD = 2, QCOORD = 3, OFFSET_X = 4, OFFSET_Y = 5, OFFSET_Z = 6, MISC = 7, LIGHTZ = 8, LODCLAMP = 9, DUX = 10, DUY = 11, DVX = 12, DVY = 13, DRX = 14, DRY = 15, RAY_BVH_NODE = 16, RAY_ORIGIN_X = 17, RAY_ORIGIN_Y = 18, RAY_ORIGIN_Z = 19, PCMN_A_SCALE = 20, PCMN_F_SCALE = 21, SAD_A_WX_WY = 22, SAD_R_WX_WY = 23, SRC_FBID = 24, FB_DATA = 25, WTEX_U = 26, WTEX_V = 27, WTEX_F = 28, WTEX_B = 29, TENSOR_X = 30, TENSOR_Y = 31, TENSOR_F = 32, TENSOR_B = 33, PACKED_SAMPLE_C0 = 34, PACKED_SAMPLE_C1 = 35 } gfx_<blk>_attr_id_e; localparam NUM_ATTR = 36; // Document total count for validation // Complex union structures with opaque overlay typedef union packed { logic [3:0][31:0] isamLOD; logic [3:0][31:0] isammSampleID; logic [3:0][31:0] sambLODbias; logic [3:0][31:0] samlLOD; logic [3:0][31:0] convmSampleID; logic [3:0][31:0] getsizeMipLevel; logic [3:0][31:0] getPosSampleID; logic [127:0] opaque; // Always include opaque for full structure access } gfx_<blk>_attr_misc_u; // Nested structure definitions typedef struct packed { logic [127:32] rsvd; logic [31:0] value; } gfx_<blk>_attr_derivitive_s; typedef struct packed {