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 循环是生成硬件结构
相关推荐
biubiuibiu4 小时前
工业机器人编程语言详解:多样化选择与应用
fpga开发·机器人
lf2824814314 小时前
04 DDS信号发生器
fpga开发
szxinmai主板定制专家5 小时前
基于 STM32 + FPGA 船舶电站控制器设计与实现
arm开发·人工智能·stm32·嵌入式硬件·fpga开发·架构
ARM+FPGA+AI工业主板定制专家15 小时前
基于ARM+FPGA+AI的船舶状态智能监测系统(二)软硬件设计,模拟量,温度等采集与分析
arm开发·人工智能·目标检测·fpga开发
szxinmai主板定制专家18 小时前
基于ZYNQ MPSOC船舶数据采集仪器设计(一)总体设计方案,包括振动、压力、温度、流量等参数
arm开发·人工智能·嵌入式硬件·fpga开发
FPGA小迷弟1 天前
高频时钟设计:FPGA 多时钟域同步与时序收敛实战方案
前端·学习·fpga开发·verilog·fpga
szxinmai主板定制专家1 天前
基于ZYNQ MPSOC船舶数据采集仪器设计(三)振动,流量,功耗,EMC,可靠性测试
arm开发·人工智能·嵌入式硬件·fpga开发
hoiii1871 天前
Vivado下Verilog交通灯控制器设计
fpga开发
嵌入式-老费1 天前
vivado hls的应用(开篇)
fpga开发