文章目录
- 一、前言
- [二、if-else 条件判断语句](#二、if-else 条件判断语句)
-
- [1. 基本语法](#1. 基本语法)
- [2. 关键规则](#2. 关键规则)
- [3. 实战案例:4选1多路选择器(if-else版)](#3. 实战案例:4选1多路选择器(if-else版))
- [三、case 分支选择语句](#三、case 分支选择语句)
-
- [1. 基本语法](#1. 基本语法)
- [2. 关键规则](#2. 关键规则)
- [3. 实战案例:3-8译码器(case版)](#3. 实战案例:3-8译码器(case版))
- [四、for 循环语句](#四、for 循环语句)
-
- [1. 基本语法](#1. 基本语法)
- [2. 关键规则](#2. 关键规则)
- [3. 实战案例:8位按位取反(for循环实现)](#3. 实战案例:8位按位取反(for循环实现))
- [五、if-else vs case 对比](#五、if-else vs case 对比)
- 六、高频避坑要点
一、前言
在Verilog中,流程控制用于实现条件判断、分支选择、循环逻辑 ,是编写复杂组合/时序电路的基础。与C语言等软件语言不同,Verilog的流程控制必须写在过程块(always/initial)内部,并且要严格遵守硬件综合规则,否则会生成无效电路或直接报错。
本篇只讲可综合、工程与实验常用的写法,不讲仿真专用语法,内容可直接用于Quartus工程。
二、if-else 条件判断语句
if-else 用于实现二分支/多分支条件选择,对应硬件中的多路选择器、优先级编码器结构。
1. 基本语法
verilog
// 单分支
if(条件表达式) begin
语句;
end
// 双分支
if(条件表达式) begin
语句1;
end else begin
语句2;
end
// 多分支
if(条件1) begin
语句1;
end else if(条件2) begin
语句2;
end else if(条件3) begin
语句3;
end else begin
默认语句;
end
2. 关键规则
- if-else 只能写在 always 块内部;
- 被赋值的变量必须定义为 reg 型;
- 多分支 if-else 自带优先级,写在前面的条件优先级更高;
- 组合逻辑建议必须写 else,避免产生锁存器(Latch)。
3. 实战案例:4选1多路选择器(if-else版)
verilog
module mux4_if(
input wire [1:0] sel, // 选择信号
input wire in0,
input wire in1,
input wire in2,
input wire in3,
output reg out
);
always @(*) begin // *代表敏感所有输入,组合逻辑专用
if(sel == 2'b00)
out = in0;
else if(sel == 2'b01)
out = in1;
else if(sel == 2'b10)
out = in2;
else
out = in3;
end
endmodule
三、case 分支选择语句
case 用于实现多对一平等分支选择,没有优先级,结构清晰,常用于译码器、状态机、多路选择器。
1. 基本语法
verilog
case(判断变量)
取值1: 语句1;
取值2: 语句2;
取值3: 语句3;
default: 默认语句;
endcase
2. 关键规则
- 同样只能在 always 块内使用;
- 建议必须加 default,防止综合出锁存器;
- 适合多路并行判断,逻辑比 if-else 更直观。
3. 实战案例:3-8译码器(case版)
verilog
module decoder3_8(
input wire [2:0] in,
output reg [7:0] out
);
always @(*) begin
case(in)
3'b000: out = 8'b00000001;
3'b001: out = 8'b00000010;
3'b010: out = 8'b00000100;
3'b011: out = 8'b00001000;
3'b100: out = 8'b00010000;
3'b101: out = 8'b00100000;
3'b110: out = 8'b01000000;
3'b111: out = 8'b10000000;
default: out = 8'b00000000;
endcase
end
endmodule
四、for 循环语句
Verilog 中的 for 循环不是软件式延时 ,而是用于批量生成硬件结构,如多位赋值、多位寄存器初始化、阵列运算等。
1. 基本语法
verilog
integer i; // 循环变量一般定义为integer
for(i = 0; i < N; i = i + 1) begin
语句;
end
2. 关键规则
- 同样只能在 always/initial 块内;
- 可综合,但循环次数必须是常量,不能是变量;
- 常用于对数组、多位寄存器批量操作。
3. 实战案例:8位按位取反(for循环实现)
verilog
module bit_reverse(
input wire [7:0] din,
output reg [7:0] dout
);
integer i;
always @(*) begin
for(i = 0; i < 8; i = i + 1) begin
dout[i] = ~din[i];
end
end
endmodule
五、if-else vs case 对比
| 特性 | if-else | case |
|---|---|---|
| 优先级 | 有优先级,前面条件优先 | 无优先级,并行判断 |
| 适用场景 | 条件有优先级、多分支判断 | 多路选择、译码器、状态机 |
| 代码结构 | 层级多,分支多时代码偏长 | 结构扁平,直观易读 |
| 综合电路 | 优先级编码器结构 | 并行选择器结构 |
六、高频避坑要点
- 流程控制语句必须写在 always 块内,不能直接在模块中裸写;
- 组合逻辑 always @(*) 中,if 建议配 else,case 建议配 default,防止产生意外锁存器;
- 时序逻辑中(
posedge clk),if-else/case 都可以正常使用,变量用非阻塞赋值<=; - for 循环不要用来写"延时",那是软件思维,Verilog 循环是生成硬件结构。