25.verilog语法之always
一、always语句介绍
module是一个模块的语法,或者说是一个电路模块的语法,然后FPGA代码中见的最多的应该就是alwsys语句了。

到处都是alwsys,那么alwayls怎么意思呢?
例如最常用的一句:
always @(posedge clk or negedge rst_n)
关键字always就是一直的意思,就是上电后这个模块会一直运行下去。
@是探测变化的意思,就是小括号内的信号只要安装规定的动作变化就能被探测到。
小括号的内容就是该模块运行的条件,
关键字posedge是取上升沿的意思,posedge clk就是clk这个信号的上升沿是触发条件;negedge就是取下降沿的意思,negedge rst_n就是rst_n这个信号的下降沿是触发条件;or就是posedge clk和negedge rst_n这两个条件有一个达到这个模块就会运行。
于是乎,FPGA代码阅读就变得特别简单了。。。
always @(posedge clk or negedge rst_n)
begin
if (!rst_n)
begin
q <= 1'b0;
end
else
begin
q <= d;
end
end
二、FPGA 编码的「黄金规范」
时序逻辑(生成寄存器)
- 一个 always 块对应一个时钟域 + 一组强关联的时序动作,可赋值多个信号,拒绝「一个信号一个 always 块」;
- 必须用非阻塞赋值
<=,模拟硬件并行更新; - 触发列表必须包含时钟沿,异步复位需加复位沿,同步复位仅加时钟沿;
- 寄存器的更新 / 复位仅在触发沿到来时发生,非触发沿保持原值。
组合逻辑(无寄存器)
- 一个 always 块对应一个独立的组合逻辑功能,可赋值多个相关输出;
- 必须用阻塞赋值
=,模拟硬件实时连线; - 触发列表用
always @(*)(自动敏感列表),避免漏写输入导致的综合毛刺。
通用规则
- 不同时钟域、不同复位方式的逻辑,必须分开写 always 块;
- 寄存器信号必须在 always 块内赋值,且只能在一个 always 块内赋值(多驱动会导致硬件冲突,综合报错);
- 所有寄存器必须有复位值(避免上电后状态未知,FPGA 设计的硬性要求)。







