当前位置: 首页 > news >正文

[Verilog HDL]第五章 条件语句、循环语句、块语句、生成语句

本章全部语句属于行为级描述语句,仅能放置在initialalways过程块内部,模块顶层不能直接书写。本章语句分为两大类:可综合硬件语句(能生成真实电路)、仿真专用语句(仅用于 Testbench 测试,无法综合)。

学习目标:熟练使用 if/case 完成多路控制;区分仿真循环与硬件生成循环;掌握顺序 / 并行块仿真时序差异。


一、5.1 if-else 条件语句 ★

1. if 语句三种标准语法结构

1.1 格式 1:单 if 语句(无 else 分支)

适用场景:仅需要在特定条件下执行操作,其余状态无赋值

always @(*) begin if(en) out = in; end

缺陷:组合逻辑下缺少 else 分支会综合生成锁存器,时序逻辑无此风险。

1.2 格式 2:if-else 双分支语句

条件分为真假两路,完整覆盖所有情况,组合逻辑推荐使用,不会产生锁存器。

always @(*) begin if(sel) out = a; else out = b; end

1.3 格式 3:if-else if 多分支优先级语句

多层判断自带优先级,从上至下匹配,上层条件优先执行。

always @(*) begin if(addr == 0) data = 8'd1; else if(addr == 1) data = 8'd2; else data = 8'd0; end

2. 书写规范细节

  • 单条执行语句可省略begin-end;多条语句必须使用begin-end包裹复合块;
  • 判断表达式支持逻辑运算&& || !、比较运算== != > < >= <=
  • 简写写法:if(!rst_n)等价于if(rst_n == 0)

3. else 就近匹配规则(易错点)

else 永远匹配离它最近、未配对的 if,与缩进无关。

错误示例:

if(a) if(b) y=1; else y=0; // 匹配内层if(b),而非外层if(a)

解决方法:多层嵌套统一添加begin-end明确代码块边界。

4. 组合逻辑锁存器产生原理

组合逻辑always @(*)中,若变量在部分 if 分支中未赋值,综合工具会生成锁存器保存旧值,导致电路功能异常。 规避方案:

  • 完整书写 else 分支,给变量赋予默认值
  • 在块开头统一给输出赋默认值。

5. 硬件电路特性

多层 if 语句会生成带优先级的多路选择电路,适合优先级编码器、中断判断电路。\

二、case 多路分支语句 ★★

1. case 基础完整语法

case(控制信号) 分支1: 执行语句; 分支2: 执行语句; default: 默认语句; // 必须添加,防止锁存器 endcase
  • 所有分支取值必须互斥,禁止出现重叠条件;
  • default 分支作用:覆盖未枚举的 0/1/x/z 状态,消除锁存器。

2. case /casez/casex 匹配规则★★

  • case:严格逐位匹配,0 只能匹配 0、1 匹配 1、x 匹配 x、z 匹配 z。
  • casez:忽略高阻 z,?作为无关位通配符,仅严格匹配 0/1;常用于位屏蔽译码。
  • casex:同时忽略 x、z 不定态,仅识别 0/1,多用于仿真判断未知输入。

3. 硬件特性

case 所有分支优先级完全平等,无先后顺序,适合多路选择器。

4. 实操代码示例

3 位二进制译码器

reg [7:0] y; always @(*) begin case(addr) 3'b000: y = 8'b00000001; 3'b001: y = 8'b00000010; 3'b010: y = 8'b00000100; default: y = 8'b00000000; endcase end

三、if 与 case 语句核心对比总结

对比项if-elsecase
优先级自上而下,上层优先所有分支平等无优先级
适用电路优先级控制、中断判断多路选择器、译码器
不定态处理仅判断 0/1,无法屏蔽 x/z支持 casez/casex 处理无关位
锁存器风险漏 else 产生锁存器缺少 default 产生锁存器

四、多路分支电路实操案例

四选一多路选择器,完整综合代码

module mux4( input [1:0] sel, input a,b,c,d, output reg out ); always @(*) begin case(sel) 2'b00: out = a; 2'b01: out = b; 2'b10: out = c; 2'b11: out = d; default: out = 1'b0; // 规避锁存器 endcase end endmodule

关键知识点

  • 敏感列表@(*)自动包含 sel、a、b、c、d 所有输入。
  • default 分支不可省略,否则综合出现锁存器。
  • 综合后生成纯组合逻辑,无触发器。

五、 循环语句 ★

在Verilog HDL中存在着4种类型的循环语句,用来控制执行语句的执行次数。

统一约束:forever/repeat/while/for四类循环仅能写在 initial 仿真块。时序 / 组合 always 块中使用会报综合错误。

1. forever 语句

连续的执行语句。forever循环语句常用于产生周期性波形,用来作为仿真测试信号。

仿真示例:

initial begin clk = 0; forever #10 clk = ~clk; // 周期20ns时钟 end

2. repeat语句

连续执行一条语句n次。repeat语句中,其表达式通常为常量表达式。适合存储器初始化、批量激励赋值。

initial begin repeat(16) begin addr = addr + 1; #5; end end

3. while语句

执行一条语句直到某个条件不满足。先判断条件,条件为真才执行循环体;初始条件不成立则一次不运行。

initial begin cnt = 0; while(cnt < 8) begin cnt = cnt + 1; end end

4. for语句

4.1 一般形式

for(初始化;循环条件;更新语句)

执行语句;

4.2 执行过程

  • 先给控制循环次数的变量赋初值。
  • 判定控制循环的表达式的值,如为假,则跳出循环语句;如为真,则执行指定的语句后,转到第三步。
  • 执行一条赋值语句来修正控制循环变量次数的变量值,然后返回第二步。
initial begin for(i=0;i<16;i=i+1) begin mem[i] = 0; end end

六、顺序块与并行块 ★★

块语句作用:将多条语句打包为整体,统一管理执行时序,分为begin-end顺序块、fork-join并行块。

1. 顺序块 begin-end

  • 内部语句按书写顺序逐条执行,延时依次累加。
  • 无数据竞争,组合 / 时序逻辑块默认使用。
initial begin #10 a=1; #20 b=0; // 总延时30ns执行b赋值 end

2. 并行块 fork-join

  • 块内所有语句同一时刻同步启动,延时互不叠加。
  • 风险:同一时刻修改同一寄存器,产生数据竞争,仿真结果随机。
initial fork #10 a=1; #20 b=0; // a在10ns执行,b在20ns执行,互不干扰 join

3.特性

  • 嵌套块:顺序块、并行块可互相嵌套;
  • 命名块:给块自定义名称,内部可定义局部变量;
  • disable 关键字:强制终止指定命名块循环,用于仿真跳出循环。

七、生成块 generate ★★

唯一可综合的循环结构,编译阶段批量生成重复硬件电路,用于参数化总线、多位加法器、阵列电路;仅能写在模块顶层,禁止放入 always/initial 内部

1. generate 通用语法限制

  • generate 变量仅编译阶段有效,仿真运行不存在;
  • 内部可例化模块、门原语、assign 连续赋值,禁止时序延时#
  • 必须包裹在generate-endgenerate关键字之间。

2. 循环生成语句 generate for

批量例化相同子模块,实现 N 位硬件阵列。

示例:4 位逐进位加法器批量生成单元

genvar i; generate for(i=0;i<4;i=i+1) begin full_adder u_adder(.a(a[i]),.b(b[i]),.cin(cin[i]),.sum(sum[i]),.cout(cout[i])); end endgenerate

3. 条件生成语句

generate if

根据参数数值,选择性生成不同硬件结构。

应用场景:根据位宽参数选择慢速 / 高速加法器。

4. case 生成语句

generate case

多分支参数匹配,根据参数切换硬件架构。

八、综合实操案例

案例 1:四位同步计数器(时序逻辑 + if 语句)

module cnt4( input clk,rst_n, output reg [3:0] cnt ); always @(posedge clk) begin if(!rst_n) cnt <= 4'd0; // 同步复位 else cnt <= cnt + 1'b1; end endmodule

知识点:时序逻辑使用非阻塞赋值<=;if 实现同步复位,综合生成 4 组 D 触发器。

九、核心总结

  1. 语句分层:可综合语句(if/case/generate)、仿真专用循环(forever/for/repeat/while);
  2. 锁存器两大来源:组合逻辑 if 无 else、case 无 default;
  3. 电路选型口诀:优先级电路用 if,平等多路选择用 case;
  4. 循环两类区分:仿真 for(运行时循环)、generate for(编译生成硬件);
  5. 仿真块区分:begin 顺序执行、fork 并行执行,并行块易产生数据竞争。

十、思考题

  1. 组合逻辑 if/case 分支不全为什么会生成锁存器?如何规避?
  2. case、casez、casex 三者匹配规则有什么区别,分别适用什么场景?
  3. fork 并行块数据竞争如何产生,有哪些解决办法?
  4. generate 循环和仿真 for 循环本质区别是什么?能否互相替换?
  5. forever、repeat、while、for 四类仿真循环各自适用场景?

十一、重难点汇总

  1. 基础:if 就近匹配、锁存器产生条件、多路选择器、同步计数器;
  2. 重点:casez/casex 不定态匹配、fork 并行时序竞争、generate 编译展开原理;
  3. 高频易错:仿真循环用于综合报错、组合时序赋值符号混用、缺少 default/else 分支。
http://www.jsqmd.com/news/1146782/

相关文章:

  • Grype:容器镜像漏洞扫描,一条命令搞定
  • 计算机毕业设计之基于web的小型公司人事管理系统
  • 基于vLLM-Ascend的Qwen3.5-122B模型Atlas 800I A3单机混部部署实践
  • Gitee 企业版 MCP Server:让 AI 深度融入企业研发管理
  • 我国规上工业企业人工智能应用普及率已超30%,人形机器人加速进入制造场景
  • 配网自动化多网融合方案
  • Linux 5.4.18 文件描述符 fd 到 struct file 映射:从进程 task_struct 到文件操作 3 层结构解析
  • 终极方案:让2007-2017年的老旧Mac免费运行最新macOS系统
  • 第七次练习-Linux环境变量
  • MSC外泌体规模化生产中的培养基选择:从2D扩增到3D生物反应器与下游回收率优化
  • 用 LiveView 做一个实时聊天室:我以为省的是 JS,结果省的是一整套状态同步
  • 深度解析TegraRcmGUI:Windows平台Nintendo Switch注入工具的终极实现
  • Java计算机毕设之基于前后端分离的校园图书闲置流转平台的设计与实现 基于 SpringBoot 的二手书竞拍交易管理系统(完整前后端代码+说明文档+LW,调试定制等)
  • 数据仓库与数据挖掘 5 大核心算法:Apriori、k-Means、PageRank、ID3、DBSCAN 实战解析
  • ppt模板_0154_商务雾化
  • 这些都看懂了,你的数据库SQL注入就没问题了!网络安全零基础入门到精通教程!
  • Claude 3.5 Sonnet vs GPT-4o 性能对比:5项基准测试与3个真实场景分析
  • Free Claude Code代理搭建:低成本AI编程助手部署指南
  • MBTI-16型人格测试(200题完整版)免费 API 接口详解与调用教程
  • 数据治理和LLM结合后能解决哪些企业痛点?2026年实测效果分享
  • 我受够了做PPT,于是写了一个 Skill,让 AI 直接生成教程网页
  • 2026国内AI数字人软件TOP10盘点:全场景适配且合规靠谱之选
  • 想找正规高颜值入户门厂家?哪家靠谱这里给你揭秘!
  • Portainer 2.21.2 部署与 cpolar 内网穿透:3步实现远程 Docker 管理
  • 线下活动执行测评|千场落地经验,流程与细节表现稳定
  • 高温旺季空调产线满负荷运转:四类典型测控难题与应对方案
  • 腾讯 APIJSON:让后端 CRUD 写到怀疑人生的 ORM 工具
  • 鸿蒙多设备办公怎么协作?三个场景效率实打实提升
  • IIM-20670与MK20DN128VFM5高精度运动跟踪方案详解
  • 如何免费获取Steam创意工坊模组:WorkshopDL跨平台下载工具完整指南