Verilog入门实战——第3讲:流程控制语句(if-else / case / 循环结构)

文章目录

  • 一、前言
  • [二、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
优先级 有优先级,前面条件优先 无优先级,并行判断
适用场景 条件有优先级、多分支判断 多路选择、译码器、状态机
代码结构 层级多,分支多时代码偏长 结构扁平,直观易读
综合电路 优先级编码器结构 并行选择器结构

六、高频避坑要点

  1. 流程控制语句必须写在 always 块内,不能直接在模块中裸写;
  2. 组合逻辑 always @(*) 中,if 建议配 else,case 建议配 default,防止产生意外锁存器;
  3. 时序逻辑中(posedge clk),if-else/case 都可以正常使用,变量用非阻塞赋值 <=;
  4. for 循环不要用来写"延时",那是软件思维,Verilog 循环是生成硬件结构。
相关推荐
星夜离尘561 天前
FPGA 32 位字拆成 8 位字节:keep、last 与 ready/valid 背压下的多拍序列化
fpga开发·verilog
花月mmc2 天前
【FPGA】神经网络内容简介预告
嵌入式硬件·深度学习·神经网络·fpga开发
LabVIEW开发4 天前
LabVIEW FPGA 编程:少编译几次的办法(系列 04/05)
fpga开发·labview
cmc10285 天前
318.关于在ip内部封装PLL,MMCM的注意事项
fpga开发
LabVIEW开发5 天前
LabVIEW CompactRIO 编程模式怎么选(系列 02/05)
fpga开发·labview
FPGA工程笔记5 天前
Xilinx Divider Generator IP 实战:64位有符号除法、Fractional 输出解析与定点数转换
verilog·fpga·vivado·xilinx·定点数·divider gen·fractional
FPGA小迷弟5 天前
FPGA 与千兆以太网校验和:从原理到 Verilog 实现
嵌入式硬件·fpga开发·无人机·ai编程·fpga
码农小韩6 天前
FPGA学习(二)——LED闪烁
fpga开发·verilog·fpga·led·组合逻辑·分频设计
9527华安7 天前
FPGA纯verilog实现DP视频接口,支持2K60帧分辨率,提供3套工程源码和技术支持
fpga开发·音视频·dp
ChaseVLSI7 天前
FPGA与ASIC的区别详解:内部结构、开发成本与适用场景,项目选型到底该选哪个
嵌入式硬件·fpga开发·硬件架构·硬件工程