Quick Start
- 准备 Vivado 2024.2 或更高版本(2026 年推荐使用 Vivado 2026.1 或 Vitis Unified IDE)。
- 新建 RTL 工程,选择目标器件(示例:Xilinx Artix-7 XC7A35T,低功耗场景可选 Spartan-7 或 UltraScale+)。
- 创建顶层模块
fsm_low_power,包含时钟、异步复位低有效、输入信号和输出信号。 - 编写三个 FSM 实现:二进制编码(Binary)、格雷编码(Gray)、One-Hot 编码,分别命名为
fsm_binary、fsm_gray、fsm_onehot。 - 添加时钟约束(
create_clock -period 10.000 [get_ports clk])和输入输出延迟约束。 - 运行综合(Synthesis),查看资源利用率报告(Report Utilization)。
- 运行实现(Implementation),查看时序报告(Report Timing Summary)和功耗报告(Report Power)。
- 对比三种编码的 Fmax、动态功耗、静态功耗和 LUT/FF 占用,记录于表格。
前置条件与环境
| 项目 | 推荐值 | 说明 | 替代方案 |
|---|---|---|---|
| 器件/板卡 | Xilinx Artix-7 XC7A35T-1CSG324C | 低功耗 28nm 工艺,适合对比 FSM 编码功耗 | Spartan-7 (28nm)、UltraScale+ (16nm) |
| EDA 版本 | Vivado 2026.1 | 2026 年最新版本,支持先进功耗分析 | Vivado 2024.2 或 2025.1 |
| 仿真器 | Vivado Simulator (xsim) | 内置于 Vivado,无需单独安装 | ModelSim/Questa、Verilator |
| 时钟/复位 | 时钟 100 MHz,异步复位低有效 | 典型同步设计基础 | 时钟 50 MHz 或 200 MHz |
| 接口依赖 | 无外部接口,纯逻辑验证仅需顶层输入输出 | 可添加 AXI-Stream 接口 | — |
| 约束文件 | XDC 文件:时钟周期 10 ns,输入延迟 2 ns,输出延迟 2 ns | 确保时序收敛 | 根据实际板级调整 |
目标与验收标准
- 功能点:三种 FSM 实现相同的状态转移逻辑(4 状态:IDLE, S1, S2, S3),输出相同。
- 性能指标:Fmax ≥ 100 MHz(时钟周期 10 ns),建立时间裕量 > 0.2 ns。
- 资源占用:记录 LUT、FF、Slice 数量,One-Hot 编码 LUT 数应比二进制多 30%~80%(示例数据,以实际综合为准)。
- 功耗对比:动态功耗(mW)格雷编码最低,One-Hot 次之,二进制最高(示例趋势,以实际工艺为准)。
- 验收方式:运行仿真验证功能正确;查看实现后时序报告和功耗报告;记录并对比表格。
实施步骤
工程结构与模块划分
// 文件结构示例
// src/
// fsm_top.v (顶层,实例化三个 FSM)
// fsm_binary.v (二进制编码 FSM)
// fsm_gray.v (格雷编码 FSM)
// fsm_onehot.v (One-Hot 编码 FSM)
// tb_fsm_top.v (测试平台)
// constraints/
// top.xdc (时序约束)逐行说明
- 第 1 行:注释,说明文件结构,便于工程管理。
- 第 2 行:src 目录存放所有 RTL 源文件。
- 第 3 行:顶层模块 fsm_top,负责连接三个 FSM 实例,共享时钟和复位。
- 第 4 行:二进制编码 FSM 模块文件。
- 第 5 行:格雷编码 FSM 模块文件。
- 第 6 行:One-Hot 编码 FSM 模块文件。
- 第 7 行:测试平台文件,用于仿真验证。
- 第 8 行:constraints 目录存放约束文件。
- 第 9 行:时序约束文件 top.xdc。
关键模块:二进制编码 FSM
module fsm_binary (
input wire clk,
input wire rst_n,
input wire start,
output reg [1:0] state_out
);
localparam IDLE = 2'b00;
localparam S1 = 2'b01;
localparam S2 = 2'b10;
localparam S3 = 2'b11;
reg [1:0] state, next_state;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
state <= IDLE;
else
state <= next_state;
end逐行说明
- 第 1 行:模块声明,名称为 fsm_binary,端口包括时钟 clk、异步复位 rst_n(低有效)、输入 start、输出 state_out(2 位)。
- 第 2 行:时钟输入端口声明。
- 第 3 行:复位输入端口声明,低有效。
- 第 4 行:启动信号输入端口声明。
- 第 5 行:状态输出端口声明,reg 类型,位宽 2 位。
- 第 6 行:空行,用于分隔端口声明与内部定义。
- 第 7 行:定义状态 IDLE 为 2’b00。
- 第 8 行:定义状态 S1 为 2’b01。
- 第 9 行:定义状态 S2 为 2’b10。
- 第 10 行:定义状态 S3 为 2’b11。
- 第 11 行:空行,用于分隔参数定义与寄存器声明。
- 第 12 行:声明当前状态寄存器 state 和下一状态寄存器 next_state,均为 2 位 reg 类型。
- 第 13 行:空行,用于分隔声明与 always 块。
- 第 14 行:时序 always 块,敏感列表为时钟上升沿或复位下降沿。
- 第 15 行:判断复位是否有效(rst_n 为低)。
- 第 16 行:复位有效时,当前状态赋值为 IDLE。
- 第 17 行:复位无效时,执行 else 分支。
- 第 18 行:当前状态更新为下一状态。
- 第 19 行:end 结束 always 块。
关键模块:格雷编码 FSM
module fsm_gray (
input wire clk,
input wire rst_n,
input wire start,
output reg [1:0] state_out
);
localparam IDLE = 2'b00;
localparam S1 = 2'b01;
localparam S2 = 2'b11;
localparam S3 = 2'b10;
reg [1:0] state, next_state;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
state <= IDLE;
else
state <= next_state;
end逐行说明
- 第 1 行:模块声明,名称为 fsm_gray,端口与二进制版本相同。
- 第 2 行:时钟输入端口声明。
- 第 3 行:复位输入端口声明,低有效。
- 第 4 行:启动信号输入端口声明。
- 第 5 行:状态输出端口声明,reg 类型,位宽 2 位。
- 第 6 行:空行。
- 第 7 行:定义状态 IDLE 为 2’b00。
- 第 8 行:定义状态 S1 为 2’b01。
- 第 9 行:定义状态 S2 为 2’b11(格雷编码相邻状态仅一位变化)。
- 第 10 行:定义状态 S3 为 2’b10。
- 第 11 行:空行。
- 第 12 行:声明当前状态和下一状态寄存器。
- 第 13 行:空行。
- 第 14 行:时序 always 块,敏感列表为时钟上升沿或复位下降沿。
- 第 15 行:判断复位是否有效。
- 第 16 行:复位有效时,当前状态赋值为 IDLE。
- 第 17 行:复位无效时,执行 else 分支。
- 第 18 行:当前状态更新为下一状态。
- 第 19 行:end 结束 always 块。
关键模块:One-Hot 编码 FSM
module fsm_onehot (
input wire clk,
input wire rst_n,
input wire start,
output reg [3:0] state_out
);
localparam IDLE = 4'b0001;
localparam S1 = 4'b0010;
localparam S2 = 4'b0100;
localparam S3 = 4'b1000;
reg [3:0] state, next_state;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
state <= IDLE;
else
state <= next_state;
end逐行说明
- 第 1 行:模块声明,名称为 fsm_onehot,端口与之前类似,但 state_out 位宽为 4 位。
- 第 2 行:时钟输入端口声明。
- 第 3 行:复位输入端口声明,低有效。
- 第 4 行:启动信号输入端口声明。
- 第 5 行:状态输出端口声明,reg 类型,位宽 4 位(One-Hot 编码需要每位对应一个状态)。
- 第 6 行:空行。
- 第 7 行:定义状态 IDLE 为 4’b0001。
- 第 8 行:定义状态 S1 为 4’b0010。
- 第 9 行:定义状态 S2 为 4’b0100。
- 第 10 行:定义状态 S3 为 4’b1000。
- 第 11 行:空行。
- 第 12 行:声明当前状态和下一状态寄存器,位宽 4 位。
- 第 13 行:空行。
- 第 14 行:时序 always 块,敏感列表为时钟上升沿或复位下降沿。
- 第 15 行:判断复位是否有效。
- 第 16 行:复位有效时,当前状态赋值为 IDLE。
- 第 17 行:复位无效时,执行 else 分支。
- 第 18 行:当前状态更新为下一状态。
- 第 19 行:end 结束 always 块。
状态转移逻辑(以二进制 FSM 为例)
always @(*) begin
next_state = state;
case (state)
IDLE: if (start) next_state = S1;
S1: next_state = S2;
S2: next_state = S3;
S3: next_state = IDLE;
default: next_state = IDLE;
endcase
end
assign state_out = state;
endmodule逐行说明
- 第 1 行:组合逻辑 always 块,敏感列表为所有输入信号(自动推导)。
- 第 2 行:默认保持当前状态(避免锁存器)。
- 第 3 行:case 语句,根据当前状态决定下一状态。
- 第 4 行:IDLE 状态下,若 start 有效则跳转到 S1,否则保持。
- 第 5 行:S1 状态下无条件跳转到 S2。
- 第 6 行:S2 状态下无条件跳转到 S3。
- 第 7 行:S3 状态下无条件跳转到 IDLE。
- 第 8 行:default 分支,覆盖未定义状态,回到 IDLE。
- 第 9 行:endcase 结束 case 语句。
- 第 10 行:end 结束 always 块。
- 第 11 行:空行。
- 第 12 行:将当前状态直接赋值给输出。
- 第 13 行:空行。
- 第 14 行:endmodule 结束模块。
时序约束文件 (top.xdc)
create_clock -period 10.000 [get_ports clk]
set_input_delay -clock [get_clocks clk] 2.0 [get_ports start]
set_output_delay -clock [get_clocks clk] 2.0 [get_ports state_out]逐行说明
- 第 1 行:创建时钟 clk,周期为 10 ns(对应 100 MHz)。
- 第 2 行:设置输入延迟,start 端口相对于时钟上升沿延迟 2 ns。
- 第 3 行:设置输出延迟,state_out 端口相对于时钟上升沿延迟 2 ns。
验证结果
运行仿真后,观察三个 FSM 的输出波形,应完全一致:在 start 有效后,状态依次从 IDLE → S1 → S2 → S3 → IDLE 循环。时序报告应显示所有路径建立时间裕量均大于 0.2 ns。功耗报告应显示格雷编码动态功耗最低,One-Hot 次之,二进制最高。资源占用方面,One-Hot 编码 LUT 数量约为二进制的 1.3~1.8 倍。
排障指南
- 时序不满足:检查时钟约束是否正确;尝试降低时钟频率或优化组合逻辑深度。
- 功能不正确:确认复位信号极性(低有效);检查状态转移条件是否写反。
- 功耗异常:确认是否开启了功耗分析(Report Power);检查是否有未使用的逻辑被综合掉。
- 资源占用差异不明显:确保三种 FSM 状态数相同(4 状态);检查综合选项是否优化了冗余逻辑。
扩展讨论
本指南以 4 状态 FSM 为例,实际设计中状态数可能更多(如 8、16 状态)。随着状态数增加,One-Hot 编码的资源开销会线性增长,但 Fmax 优势更明显;格雷编码在状态转移频繁的场景下动态功耗优势突出;二进制编码在资源受限时仍为首选。建议在项目早期进行多种编码的预综合对比,以选择最优方案。
参考
- Xilinx UG901: Vivado Design Suite User Guide (Synthesis)
- Xilinx UG906: Vivado Design Suite User Guide (Power Analysis)
- IEEE Std 1364-2001: Verilog Hardware Description Language
附录
附录 A:完整测试平台代码(tb_fsm_top.v)可参考 Vivado 示例模板。附录 B:功耗对比表格模板(动态功耗、静态功耗、总功耗,单位 mW)。附录 C:资源对比表格模板(LUT、FF、Slice 数量)。

评论 0