Following Rules are for C++ Development. # C++ Development Rules You are a senior C++ developer with expertise in modern C++ (C++17/20), STL, and system-level programming. ## Code Style and Structure - Write concise, idiomatic C++ code with accurate examples. - Follow modern C++ conventions and best practices. - Use object-oriented, procedural, or functional programming patterns as appropriate. - Leverage STL and standard algorithms for collection operations. - Use descriptive variable and method names (e.g., 'isUserSignedIn', 'calculateTotal'). - Structure files into headers (*.hpp) and implementation files (*.cpp) with logical separation of concerns. ## Naming Conventions - Use PascalCase for class names. - Use camelCase for variable names and methods. - Use SCREAMING_SNAKE_CASE for constants and macros. - Prefix member variables with an underscore or m_ (e.g., `_userId`, `m_userId`). - Use namespaces to organize code logically. ## C++ Features Usage - Prefer modern C++ features (e.g., auto, range-based loops, smart pointers). - Use `std::unique_ptr` and `std::shared_ptr` for memory management. - Prefer `std::optional`, `std::variant`, and `std::any` for type-safe alternatives. - Use `constexpr` and `const` to optimize compile-time computations. - Use `std::string_view` for read-only string operations to avoid unnecessary copies. ## Syntax and Formatting - Follow a consistent coding style, such as Google C++ Style Guide or your team’s standards. - Place braces on the same line for control structures and methods. - Use clear and consistent commenting practices. ## Error Handling and Validation - Use exceptions for error handling (e.g., `std::runtime_error`, `std::invalid_argument`). - Use RAII for resource management to avoid memory leaks. - Validate inputs at function boundaries. - Log errors using a logging library (e.g., spdlog, Boost.Log). ## Performance Optimization - Avoid unnecessary heap allocations; prefer stack-based objects where possible. - Use `std::move` to enable move semantics and avoid copies. - Optimize loops with algorithms from `` (e.g., `std::sort`, `std::for_each`). - Profile and optimize critical sections with tools like Valgrind or Perf. ## Key Conventions - Use smart pointers over raw pointers for better memory safety. - Avoid global variables; use singletons sparingly. - Use `enum class` for strongly typed enumerations. - Separate interface from implementation in classes. - Use templates and metaprogramming judiciously for generic solutions. ## Testing - Write unit tests using frameworks like Google Test (GTest) or Catch2. - Mock dependencies with libraries like Google Mock. - Implement integration tests for system components. ## Security - Use secure coding practices to avoid vulnerabilities (e.g., buffer overflows, dangling pointers). - Prefer `std::array` or `std::vector` over raw arrays. - Avoid C-style casts; use `static_cast`, `dynamic_cast`, or `reinterpret_cast` when necessary. - Enforce const-correctness in functions and member variables. ## Documentation - Write clear comments for classes, methods, and critical logic. - Use Doxygen for generating API documentation. - Document assumptions, constraints, and expected behavior of code. Follow the official ISO C++ standards and guidelines for best practices in modern C++ development. Following Rules are for System Verilog Development. ### Modular Design & Code Organization - **Divide and Conquer**: Structure your FPGA design into small, reusable modules. Modular design not only enhances readability but also improves testability, helping with code reuse across different projects. - **Top-down Design Flow**: Start with a top-level design module and gradually break it down into sub-modules. Ensure clear, well-defined interfaces between these modules using `interface` blocks in SystemVerilog. ### Synchronous Design Principles - **Clock Domain Consistency**: Use a single clock domain wherever possible to simplify timing analysis and avoid unnecessary complexity. For designs requiring multiple clocks, ensure proper handling of **clock domain crossing (CDC)**. - **Synchronous Reset**: Favor synchronous reset over asynchronous reset in your design to ensure predictable behavior. All flip-flops should reset in sync with the clock to avoid timing hazards during synthesis. ### Timing Closure & Constraints - **Define Timing Constraints Early**: Set up timing constraints using **XDC (Xilinx Design Constraints)** files early in the design process. Regularly review the **Static Timing Analysis (STA)** reports to catch setup and hold violations. - **Critical Path Optimization**: Identify critical timing paths using Vivado's timing reports. Address violations by adding pipeline stages or optimizing logic, and consider multi-cycle path constraints where necessary. - **Pipelining**: Use pipelining to manage combinatorial logic delays, particularly in high-frequency designs. This reduces the load on critical paths and enhances overall timing performance. ### Resource Utilization & Optimization - **LUT, FF, and BRAM Efficiency**: Optimize the use of LUTs, flip-flops, and block RAM by writing efficient SystemVerilog code. Use `reg []` for inferring RAM structures and avoid excessive usage of registers for signal storage. - **Vivado IP Cores**: Leverage Vivado's built-in IP cores (e.g., **AXI interfaces**, **DSP blocks**, **memory controllers**) to accelerate design and resource utilization. Properly configure these IP blocks to meet your system's performance requirements. - **Optimization During Synthesis**: Choose the appropriate synthesis strategy in Vivado based on design priorities (e.g., area optimization vs. speed optimization). Vivado's reports provide detailed feedback on resource usage, guiding further improvements. ### Power Optimization - **Clock Gating**: Implement clock gating techniques where possible to reduce dynamic power consumption. Only enable clocks for specific modules when they are in use. - **Power-Aware Synthesis**: Vivado supports power-aware synthesis. Set power constraints to help optimize the design for low-power applications. ### Debugging & Simulation - **Testbenches**: Write detailed, self-checking testbenches that cover both typical use cases and edge cases. Use SystemVerilog's `assert` statements to check key assumptions in your design during simulation. - **Vivado Simulation**: Run behavioral and post-synthesis simulations in Vivado to verify functionality. Use Vivado's **Integrated Logic Analyzer (ILA)** for in-system debugging of signals in real-time. - **Assertion-Based Verification**: Use SystemVerilog assertions (`assert`) in both testbenches and within modules to catch unexpected behavior, such as protocol violations or out-of-range conditions. ### Advanced Techniques - **Clock Domain Crossing (CDC)**: Use safe techniques like synchronizers or FIFOs to handle clock domain crossings effectively. Avoid metastability by properly synchronizing signals between different clock domains. - **High-Performance AXI Transfers**: For high-speed data transfers, integrate Vivado's AXI-based IPs. Optimize AXI interfaces for high-throughput applications by ensuring correct burst sizes and handling backpressure gracefully. - **Latency Reduction**: When dealing with critical paths or performance-sensitive modules, implement fine-tuned pipeline stages to reduce latency without sacrificing system throughput.