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

FPGA基础 -- Verilog行为级建模之alawys语句

Verilog 中的 always 语句块,这是行为级建模的核心结构之一,在 RTL 级设计中广泛用于时序逻辑组合逻辑的建模。


一、什么是 always 语句?

✅ 定义:

always 语句用于描述可综合的硬件行为逻辑,表示一个**“事件驱动”的过程块**,当敏感列表中某个信号发生变化时,always 块会立即触发执行。


二、基本语法格式

always @(sensitivity_list)begin// 过程性代码end

sensitivity_list 是触发该块执行的信号列表。


三、分类:三种常见 always 使用方式

类型敏感列表用途典型应用
时序逻辑posedge clk / negedge rst_n同步逻辑寄存器建模、状态机
组合逻辑(*) 或所有组合信号列出无时序行为算术逻辑单元(ALU)
异步逻辑posedge clk or negedge rst异步复位结构上电初始化控制

四、时序逻辑建模(推荐使用方式)

4.1 同步复位寄存器建模:

always @(posedge clk) beginif (!rst_n)q <= 0;elseq <= d;
end

✅ 非阻塞赋值 <=,确保“并行硬件”的表达。

4.2 异步复位建模:

always @(posedge clk or negedge rst_n) beginif (!rst_n)q <= 0;elseq <= d;
end

posedge clk or negedge rst_n:表示 rst_n 变化时立即响应。


五、组合逻辑建模

推荐使用 always @(*)

always @(*) begincase (sel)2'b00: y = a;2'b01: y = b;default: y = 0;endcase
end

✅ 使用 = 阻塞赋值。
✅ 确保对每个输出都完全赋值,否则综合工具会推断出 latch(锁存器)!


六、敏感列表详解

✅ 常见写法对比:

写法解释建议
always @(a or b or c)显式列出每个信号✅ 可控但冗长
always @(*)隐式敏感列表,表示所有用到的组合信号✅ 推荐用于组合逻辑
always @(posedge clk)上升沿触发(时序逻辑)✅ 推荐用于寄存器

七、阻塞/非阻塞赋值回顾(重点)

场景使用赋值类型示例
时序逻辑(同步时钟)非阻塞 <=q <= d;
组合逻辑阻塞 =y = a + b;

⚠️ 错误示例:混用赋值类型

always @(posedge clk) begina = b;   // ❌ 错误:阻塞赋值在时序逻辑中易引发竞态c <= a;  // 实际 c 得到的是旧值,不是当前周期的 b
end

八、综合注意事项(总结)

误用影响修正建议
@(*) 中漏掉信号可能漏更新,综合错误使用 @(*) 自动推导
混用 =<=引起竞态与不符合意图遵循赋值语义规则
不完全赋值可能推断 latch加默认路径 / default 分支
变量多处被赋值冲突或竞态避免变量在多个 always 中赋值

九、典型设计范式:分离时序与组合逻辑

// 状态寄存器
always @(posedge clk or negedge rst_n)if (!rst_n) state <= IDLE;else        state <= next_state;// 下一状态逻辑
always @(*) begincase (state)IDLE:      if (start) next_state = RUN;RUN:       if (done)  next_state = IDLE;default:             next_state = IDLE;endcase
end

✅ 这是 FSM 设计的推荐结构:组合逻辑决定 next_state,时序逻辑更新 state。


十、仿真辅助结构(testbench 中的 always

always #5 clk = ~clk;  // 每 5ns 翻转一次
  • 通常用于生成仿真用时钟;
  • 非综合代码,仅用于 initial 或 testbench。

十一、拓展:SystemVerilog 中的 always_ff / always_comb

类型SystemVerilog 替代特点
时序逻辑always_ff自动检查敏感列表,防止误用
组合逻辑always_comb自动推导敏感列表

✅ 更强语义检查,更安全可维护,但需要 SystemVerilog 工具支持。


十二、实战示例总结:组合 + 寄存器 + 状态机

// 组合逻辑:计数器是否达到最大值
always @(*) begindone = (cnt == 15);
end// 时序逻辑:计数器累加
always @(posedge clk or negedge rst_n) beginif (!rst_n)cnt <= 0;else if (en)cnt <= cnt + 1;
end

小结

内容核心要点
语义always 块是硬件中的过程行为
时序建模使用 posedge clk + 非阻塞赋值
组合建模使用 @(*) + 阻塞赋值,完整赋值
综合约束不可在综合逻辑中使用 #延迟
推荐实践将时序逻辑与组合逻辑分离建模,提高可读性与综合效果
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.dtcms.com/a/253981.html

相关文章:

  • FPGA基础 -- Verilog 行为级建模之条件语句
  • 爬虫技术:从数据获取到智能分析的进阶之路
  • Mac 安装 finalshell
  • WebFuture:PDF页面去掉下载按钮
  • 【算法 day06】LeetCode 454.四数相加II | 15. 三数之和 | 18. 四数之和
  • 23.查询增强
  • 【入门算法】枚举:有序穷举,分步排查
  • 【音视频】PJSIP库——pjsua命令使用详解
  • 嵌入式自学第四十二天
  • Java八股文——计算机网络「应用层篇」
  • 京东618带火四大消费 即时零售和生活服务迎来爆发
  • 一个.Net开发的功能强大、易于使用的流媒体服务器和管理系统
  • Redis 五种数据结构
  • keil新建工程文件结构和每个文件的作用解析(标准库版本)
  • 零知开源——STM32F4实现ILI9486显示屏UI界面系列教程(一):电子书阅读器功能
  • uniapp实现聊天中的接发消息自动滚动、消息定位和回到底部
  • QTableView为例:Qt模型视图委托(MVD)(Model-View-Delegate)
  • C# CSharpScript 的原理与应用
  • python校园拼团系统
  • Uniapp 中根据不同离开页面方式处理 `onHide` 的方法
  • uniapp的video遮盖了popup
  • Web安全性测试--超详细用例CASE整理总结
  • linux unix socket 通信demo
  • 理解RocketMQ顺序消息的全局有序消息和分区有序消息、延迟消息、事务消息
  • 英一真题阅读单词笔记 13年
  • JS数据类型检测方法总结
  • 大数据学习(140)-数仓概述分析
  • 你的下一把量化“瑞士军刀”?KHQuant适用场景全解析【AI量化第32篇】
  • FastAdmin退出登录不提示的修改方法
  • C#上位机通过WebApi对接DeepSeek