这一套【Verilog 工程规范编码模板】,适合写清晰、可维护、可综合的 RTL 代码,适用于 FPGA/ASIC 开发:
📘 Verilog 工程级编码规范模板
1️⃣ 模块结构规范
module my_module #(
parameter WIDTH = 8 // 模块参数
)(
input wire clk,
input wire rst_n,
input wire [WIDTH-1:0] data_in,
output reg [WIDTH-1:0] data_out
);
// ============ 内部信号定义 ============
reg [WIDTH-1:0] data_buf;
// ============ 组合逻辑块 ============
always @(*) begin
// 默认值(避免综合 latch)
data_buf = 0;
if (/* condition */)
data_buf = data_in + 1;
end
// ============ 时序逻辑块 ============
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
data_out <= 0;
else
data_out <= data_buf;
end
endmodule
2️⃣ 时序逻辑模板(寄存器写)
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
q <= 0;
else if (en)
q <= d;
end
3️⃣ 组合逻辑模板(纯组合,用于中间变量)
always @(*) begin
case (sel)
2'b00: out = a;
2'b01: out = b;
2'b10: out = c;
default: out = 0;
endcase
end
4️⃣ 状态机结构模板(推荐三段式)
// 状态编码
localparam IDLE = 2'd0,
LOAD = 2'd1,
WORK = 2'd2,
DONE = 2'd3;
reg [1:0] state, state_next;
// 状态跳转(组合)
always @(*) begin
case (state)
IDLE: state_next = start ? LOAD : IDLE;
LOAD: state_next = WORK;
WORK: state_next = done ? DONE : WORK;
DONE: state_next = IDLE;
default: state_next = IDLE;
endcase
end
// 状态寄存器(时序)
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
state <= IDLE;
else
state <= state_next;
end
// 输出逻辑(组合)
always @(*) begin
case (state)
IDLE: do_something = 0;
LOAD: do_something = 1;
WORK: do_something = 1;
DONE: do_something = 0;
default: do_something = 0;
endcase
end
5️⃣ 总线打拍与同步模板
// 1拍打拍
reg [7:0] signal_d1;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
signal_d1 <= 0;
else
signal_d1 <= signal_in;
end
6️⃣ 通用模块命名规范(推荐)
类型 | 前缀建议 | 说明 |
---|---|---|
输入信号 | in_ |
如:in_data , in_valid |
输出信号 | out_ |
如:out_data , out_ready |
中间寄存器 | _reg |
如:cnt_reg , state_reg |
状态机状态 | 全大写 | 如:IDLE , WAIT , DONE |
参数 | 全大写 | 如:DATA_WIDTH , BUF_DEPTH |
✅ 编码风格建议
每个
always
只负责一类功能:组合逻辑 or 时序逻辑不要在组合逻辑中写
<='(非阻塞赋值)
多个 if-else 控制一个变量时,一定要确保是互斥的,或统一组合后赋值
尽量避免推测 latch(即组合逻辑中没有默认值)
状态机推荐三段式写法(状态跳转 + 状态寄存器 + 输出逻辑分离)