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 循环是生成硬件结构
相关推荐
1560820721910 小时前
关于国微SQM7VX690T和复旦微JFM7VX690T调试
fpga开发
minglie11 天前
简易寄存器接口SMMR---正交编码器
fpga开发
神电测控1 天前
新品发布:32通道50MS/s同步并行14位采集模块PG-FMC9249(支持任意FPGA/ZYNQ,兼容LabVIEW FPGA软件开发)
fpga开发·labview·ni·神电测控·王电令·ad9249·32通道
Drgfd1 天前
半导体国产替代进入“深水区”:决战设备、材料、IP三大高地
网络·fpga开发
国产HT1621B1 天前
YL1650 LED驱动芯片详解:从原理到实战应用(附51单片机驱动代码)
stm32·单片机·嵌入式硬件·mcu·fpga开发·lcd驱动
szxinmai主板定制专家1 天前
驱控一体新范式:RK3576+FPGA+CODESYS工业实时AI控制架构全解
人工智能·嵌入式硬件·计算机视觉·fpga开发·架构·工业ai·驱控一体
国科安芯1 天前
ASC0101S自动双向电平转换原理深剖
单片机·嵌入式硬件·fpga开发·云计算·信息与通信
落chen1 天前
7 Series FPGAs Clocking Resources
fpga开发
落chen2 天前
基于FPGA的IIC协议通信-强化篇
fpga开发
梦开始的地方 �2 天前
实例化和句柄
fpga开发