很多初学者在写Verilog时,总觉得if/else和case是写代码的"万能钥匙",结果综合出来的电路跟自己想的一点都不对。今天我们就来聊聊FPGA编程中最基础、也最容易踩坑的两个控制语句。
在FPGA中,不是所有if/else都能综合成硬件电路。我们来看一个标准写法:
always @(posedge clk or posedge rst) begin
if (!rst) begin
out <= 0;
end else if (ena) begin
out <= data;
end
end
要点:
时序逻辑中的if/else必须用阻塞赋值(<=)
要有完整的reset分支
每个分支都要覆盖所有情况,否则会产生锁存器
这是新手最常犯的错误。当你写这样的代码时:
always @(a or b) begin
if (a) begin
y = 1'b1;
end
end
问题来了:当a=0时,y该是什么值?综合工具会推断出一个锁存器(Latch),这在FPGA中是大忌——它会引入不可预测的时序问题。
正确写法:用else补全所有情况。
always @(posedge clk) begin
case (state)
IDLE: next_state <= WAIT;
WAIT: next_state <= RUN;
RUN: next_state <= IDLE;
default: next_state <= IDLE;
endcase
end
关键点:
一定要加default分支
覆盖所有可能的状态值
case语句通常比if/else更清晰,适合状态机
对于某些特殊场景,你可以用casez和casex:
casez:把z当作"不 care"
casex:把x和z都当作"不 care"
always @() begin
casez (addr[15:0])
16'bxxxxxxxxxxxxxxxx: sel = 4'd0;
16'bxxxxxxxx00000000: sel = 4'd1;
default: sel = 4'd0;
endcase
end
| 错误类型 | 错误示例 | 后果 |
|---|---|---|
| 忘记else/default | if中缺少else分支 | 产生锁存器 |
| 使用非阻塞赋值 | 组合逻辑用<= |
综合出错 |
| case分支不完整 | 缺少default或遗漏状态 | 推断锁存器 |
if/else和case是FPGA编程的基石,但它们的使用有严格的规则。记住一条铁律:时序逻辑用非阻塞赋值,组合逻辑用阻塞赋值;永远不要留下"未定义"的分支。
> 思考题:下面这段代码有什么问题?如何修改?
>
> always @() begin
> if (enable) begin
> result = data_in;
> end
> end
>
欢迎在评论区留下你的答案,或者直接私信咨询。
如果你觉得FPGA学习难度大、知识点零散,宸极教育提供系统化FPGA培训课程,从Verilog基础到项目实战,手把手带你入门。课程涵盖ASIC设计流程、高速接口开发等内容,帮助你快速掌握FPGA开发技能。想了解更多?欢迎私信或点击链接了解详情!
未经许可,禁止转载!
下一篇:没有了