往期学员作品
沉浸式做项目




累计培养万名工程师
成电国芯FPGA培训基地课程以80%实操为核心,依托400家企业参与课程开发,采用XILINX合作体系与双师教学,通过大量实战项目锤炼工程能力。


























在FPGA开发中,50%的时序问题源于糟糕的编码习惯。本文从企业级代码规范出发,提炼出10个立竿见影的Verilog编码技巧,配合真实工程案例,助你规避常见陷阱,提升代码质量。
文末免费领取《Verilog代码规范检查表》PDF(含Xilinx/Altera双版本),一键排查代码隐患!

verilog
// ❌ 糟糕示例
wire a, b, c;
// ✅ 优化示例
wire [7:0] adc_data_in; // 来自ADC的8位输入数据
wire uart_tx_en; // UART发送使能信号
企业规范:
_in,输出信号后缀_outclk_<功能>,复位信号rst_<作用域>_n(低有效)verilog
// ❌ 产生锁存器!
always @(*) begin
if (sel)
out = a;
// 缺少else分支!
end
// ✅ 安全写法:补全default
always @(*) begin
if (sel)
out = a;
else
out = 8'hFF; // 明确默认值
end
? 对比动图:
(左:不完整条件导致锁存器;右:补全分支生成纯组合逻辑)
verilog
// ✅ 同步复位标准写法
always @(posedge clk) begin
if (rst_n) begin
cnt <= 8'b0;
end else begin
cnt <= cnt + 1;
end
end
// ⚠️ 异步复位仅用于特殊场景(如时钟恢复)
always @(posedge clk or negedge async_rst_n) begin
if (!async_rst_n)
state <= IDLE;
else
state <= next_state;
end
关键点:
verilog
// ❌ 混合赋值导致仿真与综合不一致
always @(posedge clk) begin
a = b + c; // 阻塞赋值
d <= a; // 非阻塞赋值
end
// ✅ 严格区分使用场景
// 时序逻辑
always @(posedge clk) begin
data_ff <= data_in; // 非阻塞
end
// 组合逻辑
always @(*) begin
sum = a + b; // 阻塞
end
verilog
// ✅ 标准三段式状态机
localparam S_IDLE = 3'b001,
S_RUN = 3'b010,
S_DONE = 3'b100;
// 第一段:状态寄存器
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
state <= S_IDLE;
else
state <= next_state;
end
// 第二段:下一状态逻辑
always @(*) begin
case(state)
S_IDLE: next_state = start ? S_RUN : S_IDLE;
S_RUN: next_state = (cnt == 10) ? S_DONE : S_RUN;
S_DONE: next_state = S_IDLE;
default:next_state = S_IDLE;
endcase
end
// 第三段:输出逻辑
always @(posedge clk) begin
if (state == S_RUN)
cnt <= cnt + 1;
else
cnt <= 0;
end
verilog
// ❌ casex可能导致意外匹配
casex (sel)
4'b1??? : out = a;c// 可能匹配到sel=1000以外的值
endcase
// ✅ 添加default并限定匹配范围
case(sel[3:1]) // 明确匹配位宽
3'b100: out = a;
default:out = 8'h00;
endcase
企业规范:
full_case和parallel_case避免锁存器unique和priority关键字(SystemVerilog)verilog
// ✅ 功能拆分示例
module uart_tx (
input clk,
input [7:0] data_in,
output txd
);
module uart_rx (
input clk,
input rxd,
output [7:0] data_out
);
// 顶层模块仅例化
module top;
uart_tx u_tx(...);
uart_rx u_rx(...);
endmodule
优势:
verilog
// ❌ 无效注释
reg [3:0] cnt; // 定义4位计数器
// ✅ 有价值注释
// 波特率分频计数器:115200bps @ 50MHz
// 分频数 = 50e6 / (115200 * 16) ≈ 27
reg [4:0] baud_cnt; // 需覆盖0-26(5位足够)
translate_off注释verilog
// 仿真专用代码(不参与综合)
// synopsys translate_off
initial begin
$dumpfile("wave.vcd");
$dumpvars(0, tb_module);
end
// synopsys translate_on
工具链命令:
set_property -name {STEPS.SYNTH_DESIGN.ARGS.MORE OPTIONS} -value "-verilog_define SIMULATION" -objects [get_runs synth_1]verilog
// ❌ 直接使用除法运算符
reg [31:0] div = data_in / 10; // 综合成DSP48单元
// ✅ 位操作近似计算(误差<1%)
// 除以10 ≈ 右移3位(÷8) + 调整补偿
wire [31:0] div_opt = (data_in >> 3) + (data_in >> 5) - (data_in >> 7);
? 对比动图:
(左:直接调用除法器消耗18个DSP;右:位操作仅用逻辑资源)
立即获取《Verilog代码规范检查表》PDF,包含:
如果你希望:
✅ 掌握企业级FPGA代码规范
✅ 亲手完成千兆以太网加速器项目
✅ 获得华为/中兴资深工程师代码评审
立即免费试听 ? [Verilog七日进阶训练营试听链接]

通过规范编码,让你的代码一次编写,终身受用!