verilog-code
编写和审查可综合的 Verilog RTL 代码。当用户要求编写、设计、实现、修复或审查任何 Verilog/RTL 模块、 硬件模块或数字逻辑时自动触发。触发词包括:写Verilog、写RTL、实现模块、设计电路、review代码、 审查Verilog、FSM、状态机、FIFO、pipeline、流水线、arbiter、仲裁器、counter、计数器、 shift register、移位寄存器、handshake、握手协议、AXI、APB、SPI、I2C、UART、 clock divider、分频器、debounce、去抖、edge detector、边沿检测、synchronizer、同步器、 dual-port RAM、双端口RAM。即使用户只说"写一个模块"或"实现这个功能"而没有显式提到"Verilog", 也应使用此 skill。涵盖新代码生成和已有 Verilog 代码的 review/debug。
DeepseekModel
Curated skill
Quality Good · 48
v1.0.0
Get
https://deepseekmodel.com/api/download.php?id=ljj05170930-verilog-code-plugin-skills-verilog-code-skill-md&format=skill
Download .skill
Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
name verilog-code description 编写和审查可综合的 Verilog RTL 代码。当用户要求编写、设计、实现、修复或审查任何 Verilog/RTL 模块、 硬件模块或数字逻辑时自动触发。触发词包括:写Verilog、写RTL、实现模块、设计电路、review代码、 审查Verilog、FSM、状态机、FIFO、pipeline、流水线、arbiter、仲裁器、counter、计数器、 shift register、移位寄存器、handshake、握手协议、AXI、APB、SPI、I2C、UART、 clock divider、分频器、debounce、去抖、edge detector、边沿检测、synchronizer、同步器、 dual-port RAM、双端口RAM。即使用户只说"写一个模块"或"实现这个功能"而没有显式提到"Verilog", 也应使用此 skill。涵盖新代码生成和已有 Verilog 代码的 review/debug。 user-invocable true Verilog RTL 编码指南 1. 模式检测 根据用户意图判断工作模式: WRITE 模式 (用户要求创建/实现/设计模块): 遵循下方所有编码规则 如果要实现的模块匹配已知设计模式(FSM、FIFO、pipeline 等),先读取 references/design-patterns.md 中对应章节作为起点 REVIEW 模式 (用户要求检查/审查/debug 已有代码): 读取 references/review-checklist.md ,按照结构化流程逐项审查 如果发现的问题匹配已知错误类型,参考 references/common-mistakes.md 2. 硬件思维 — Verilog 不是软件 这是写出正确 Verilog 的根基。在写每一行代码前,用以下思维替代软件的顺序执行模型: 并行执行 :每个 always 块是一个独立的硬件电路,所有 always 块同时运行。它们不是"按顺序执行的函数",而是"同时工作的独立电路"。 非阻塞赋值 <= (时钟块) :在 always @(posedge clk) 中,所有 RHS 在时钟沿 同时采样 ,然后所有 LHS 同时更新 。这意味着: always @(posedge clk) begin a <= b; // a 拿到的是 b 的旧值 b <= a; // b 拿到的是 a 的旧值 → 实现了交换 end 这不是"先执行第一行再执行第二行",而是一个寄存器组在时钟沿同时锁存。 阻塞赋值 = (组合块) :在 always @(*) 中使用,描述组合逻辑的连线关系。虽然有执行顺序,但综合结果是同一个门级电路。 绝对禁止混用 :同一个 always 块内不得同时出现 <= 和 = 。时钟块用 <= ,组合块用 = 。 wire 是导线, reg 是存储或组合输出 : reg 不一定是寄存器——在组合 always 块中的 reg 综合后是纯组合逻辑。关键在于它被 always 块驱动。 3. 可综合性规则 RTL 代码中 禁止使用 以下仿真专用语法: 禁止的语法 原因 替代方案 initial 块 无硬件对应物 使用复位信号初始化 #10 等延时 不可综合 用时钟周期控制时序 $display , $monitor , $finish 系统任务 仅在 TB 中使用 fork / join 无硬件对应物 用并行 always 块 force / release / deassign 不可综合 用正常赋值逻辑 必须遵守的规则 : 完整条件 :所有 if 必须有 else ,所有 case 必须有 default 。不完整的条件会推断出 latch,这几乎从来不是你想要的 敏感列表 :组合逻辑用 always @(*) ,不要手动列出信号。时序逻辑用 always @(posedge clk or negedge rst_n) (异步复位)或 always @(posedge clk) (同步复位) 复位 :每个触发器都必须有复位值。使用 active-low 异步复位 ( rst_n ) 作为项目惯例 单驱动 :同一信号只能在一个 always 块或一条 assign 中驱动,不可多驱动 无内部三态 :内部信号不要用三态,用 mux 代替 整数除法 :非 2 的幂的除法和取模通常不可综合,用移位代替 4. 模块结构模板 所有模块遵循以下统一结构,与项目现有风格保持一致: module module_name #( parameter DATA_WIDTH = 8, parameter ADDR_WIDTH = 4 ) ( input wire clk, input wire rst_n, // ---- Input ports ------------------------------------------------ input wire [DATA_WIDTH-1:0] data_in, input wire valid_in, // ---- Output ports ----------------------------------------------- output reg [DATA_WIDTH-1:0] data_out, output reg valid_out ); // ========================================================================= // Local parameters // ========================================================================= localparam DEPTH = 1 << ADDR_WIDTH; // ========================================================================= // Internal signals // ========================================================================= reg [DATA_WIDTH-1:0] data_reg; wire some_condition; // ========================================================================= // Combinational logic // ========================================================================= assign some_condition = /* ... */; // ========================================================================= // Sequential logic // ========================================================================= always @(posedge clk or negedge rst_n) begin if (!rst_n) begin data_reg <= {DATA_WIDTH{1'b0}}; data_out <= {DATA_WIDTH{1'b0}}; valid_out <= 1'b0; end else begin // 功能逻辑 end end endmodule 结构约定 : clk 和 rst_n 始终是前两个端口 端口用 // ---- 注释行 ---- 分组 模块内部按区域划分:Local parameters → Internal signals → Combinational → Sequential 区域之间用 // === 注释分隔(匹配项目现有风格) 参数名 UPPER_SNAKE_CASE ,信号名 snake_case ,模块名 snake_case Active-low 信号加 _n 后缀(如 rst_n , cs_n ) 时钟信号加 clk 前缀(如 clk , clk_div2 ) 5. 关键编码规则 5.1 计数器边界 计数器 wrap-around 比较 MAX_VAL - 1 ,不是 MAX_VAL 。这是最常见的 off-by-one 错误: // 正确:0 到 N-1 共 N 个计数 if (count == MAX_COUNT - 1) begin count <= {WIDTH{1'b0}}; end else begin count <= count + 1'b1; end 5.2 位宽匹配 显式指定所有字面量的位宽,不要使用无宽度字面量: // 错误 count <= count + 1; // 1 是 32 位整数 data <= 0; // 0 是 32 位整数 // 正确 count <= count + 1'b1; data <= {DATA_WIDTH{1'b0}}; 使用 $clog2() 从深度推导地址宽度: localparam ADDR_WIDTH = $clog2(DEPTH); 5.3 复位方法论 异步 active-low 复位,复位分支始终放在 if-else 的第一个分支: always @(posedge clk or negedge rst_n) begin if (!rst_n) begin // 所有寄存器的复位值 — 不要漏掉任何一个 state <= IDLE; count <= {WIDTH{1'b0}}; data_out <= {DATA_WIDTH{1'b0}}; valid_out <= 1'b0; end else begin // 正常功能逻辑 end end 5.4 FSM 编码 使用 localparam 定义状态,不要用 `define 。始终有 default 分支回到安全状态: localparam [1:0] S_IDLE = 2'd0, S_LOAD = 2'd1, S_PROC = 2'd2, S_DONE = 2'd3; reg [1:0] state, state_next; 组合逻辑中的 next-state 信号用 _next 后缀,寄存器版本不加后缀。 5.5 流水线规则 所有数据信号必须经过 相同级数 的流水线寄存器 valid 信号必须与数据 同步流水 添加反压(backpressure)时,stall 信号必须同时冻结数据和 valid 5.6 Valid/Ready 握手协议 valid 不能依赖 ready (发送端不看接收端是否准备好就可以发起请求) ready 可以依赖 valid valid 一旦拉高,在 ready 为低期间不得撤回 valid 为高期间数据必须保持稳定 5.7 内存/数组声明 // 正确:使用 [0:DEPTH-1] 显式声明范围 reg [DATA_WIDTH-1:0] mem [0:DEPTH-1]; // 读写模式 always @(posedge clk) begin if (wr_en) mem[wr_addr] <= wr_data; rd_data <= mem[rd_addr]; // 读优先,1 周期延迟 end 6. 输出自检清单 生成 Verilog 代码后,在呈现给用户之前,逐条对照以下清单验证: 每个 if 都有 else ,每个 case 都有 default 没有 initial 块、 #delay 、系统任务( $display 等) 复位分支中列出了所有寄存器的复位值,无遗漏 时钟 always 块只用 <= ,组合 always 块只用 = ,无混用 所有字面量显式指定位宽(无裸 0 、 1 等整数字面量) 组合逻辑敏感列表是 @(*) ,时序逻辑是 @(posedge clk or negedge rst_n) 计数器边界条件正确(比较 N-1 而不是 N,注意 off-by-one) 无多驱动信号(同一信号在多个 always/assign 中赋值) clk , rst_n 是模块的前两个端口 参数名 UPPER_SNAKE_CASE ,信号名 snake_case 组合 always 块中的信号在所有分支中都有赋值(防止 latch 推断) FSM 的 case 语句有 default 分支,且 default 回到安全状态 7. 参考文件 以下参考文件在需要时读取,不要每次都全部加载: references/design-patterns.md — 当实现的模块匹配以下任何模式时读取: FSM、FIFO、pipeline、handshake/skid buffer、arbiter、counter、shift register、 edge detector、debouncer、clock divider、dual-port RAM、synchronizer references/common-mistakes.md — 当调试综合错误、仿真不匹配、或需要理解某个 常见 Verilog 陷阱时读取 references/review-checklist.md — 在 REVIEW 模式下读取,按照结构化流程审查代码 8. Icarus Verilog 兼容性 RTL 代码使用 Verilog-2001/2005 语法,确保与 Icarus Verilog ( iverilog -g2012 ) 兼容: RTL 中使用 reg / wire ,不要用 SystemVerilog 的 logic 不要在 RTL 中使用 always_ff / always_comb / always_latch (这些是 SV 语法,仅 TB 中使用) $clog2() 在 -g2012 模式下支持 generate 块正常支持 TB 文件是 SystemVerilog ( .sv ),由 tb-creator skill 处理,本 skill 不管 TB 9. 项目工作流提示 生成 RTL 文件后,提醒用户: RTL 文件放在 RTL/ 目录下 运行 VS Code 的 "compile and run" 任务来编译和仿真 如果有新的 RTL 文件, gen_filelist.py 会自动扫描 RTL/ 目录
Keywords that activate this skill. Click one to copy it.
This skill does not provide trigger words.
The downloaded .skill package contains the following fields.
| Field | Description |
|---|---|
| format | Format tag (skill/v1) |
| skill_id | Unique skill ID |
| name | Skill name |
| version | Version |
| description | Description |
| category | Categories (array) |
| trigger_words | Trigger words |
| tags | Tags |
| source | Source |
| source_url | Source URL (this page) |
| exported_at | Exported at (set per download) |
| system_prompt | System prompt body |
| model_config | Model config: provider / model / temperature / max_tokens / top_p |
| examples | Examples |
| install_guide | Import guide for Coze / Dify / Claude / custom frameworks |
The same skill can be exported in different platform formats.