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 循环是生成硬件结构
相关推荐
xyx-3v7 小时前
SOC相对于版上系统的优势是什么?
fpga开发
Aaron15881 天前
RFSOC+VU13P+GPU 在6G互联网中的技术应用
大数据·人工智能·算法·fpga开发·硬件工程·信息与通信·信号处理
stars-he1 天前
基于 Design Compiler 的 UDP Payload 追加控制模块综合与门级后仿真
笔记·fpga开发·udp
林伟_fpga1 天前
FPGA助力激光增材制造的熔池实时干预、探索TC11钛合金的类“钢筋混凝土”晶粒结构的优化路径
fpga
尤老师FPGA2 天前
HDMI数据的接收发送实验(十)
fpga开发
逻辑诗篇2 天前
破核拆解:PCIE719——基于Xilinx Zynq UltraScale+的高性能SAS扩展卡设计
fpga开发·架构
逻辑诗篇2 天前
高性能存储扩展利器|PCIE719 基于Zynq UltraScale+的企业级可编程SAS方案
fpga开发
liuluyang5302 天前
SV主要关键词详解
fpga开发·uvm·sv
happyDogg_2 天前
验证环境采样rtl时序数据遇到的问题
fpga开发
unicrom_深圳市由你创科技2 天前
项目分析和FPGA器件选型外包服务包括哪些内容?别让选错芯片毁了整个项目
fpga开发