5.3.2 Verilog 代码实现(带详细注释)
verilog
// 模块名称:ef2l45_power_sequence
// 功能:EF2L45LG实现SOC上电时序控制
// 时钟:50MHz(周期20ns)
// 复位:外部RST_N(低有效)
module ef2l45_power_sequence(
input wire CLK_50MHz, // 50MHz系统时钟
input wire RST_N, // 外部复位(低有效)
input wire PG1, // 1.2V电源稳定信号(高有效)
input wire PG2, // 1.8V电源稳定信号(高有效)
input wire PG3, // 1.5V电源稳定信号(高有效)
input wire PG4, // 3.3V电源稳定信号(高有效)
output reg EN1, // 1.2V电源使能(低有效)
output reg EN2, // 1.8V电源使能(低有效)
output reg EN3, // 1.5V电源使能(低有效)
output reg EN4, // 3.3V电源使能(低有效)
output reg nRST_DDR, // DDR3复位(低有效)
output reg nRST_MCU, // MCU复位(低有效)
output reg nRST_PERIPH, // 外设复位(低有效)
output reg ALM, // 故障告警(高有效)
output reg SYS_READY // 系统就绪(高有效)
);
// -------------------------- 1. 状态定义 --------------------------
// 状态编码:采用独热码,减少状态跳转错误
localparam IDLE = 12'b000000000001; // 空闲状态(初始)
localparam PWR1_ON = 12'b000000000010; // 使能1.2V电源
localparam PWR1_WAIT = 12'b000000000100; // 等待1.2V稳定+10ms延迟
localparam PWR2_ON = 12'b000000001000; // 使能1.8V电源
localparam PWR2_WAIT = 12'b000000010000; // 等待1.8V稳定+8ms延迟
localparam PWR3_ON = 12'b000000100000; // 使能1.5V电源
localparam PWR3_WAIT = 12'b000001000000; // 等待1.5V稳定+15ms延迟
localparam DDR_RST_REL = 12'b000010000000; // 释放DDR3复位
localparam PWR4_ON = 12'b000100000000; // 使能3.3V电源
localparam PWR4_WAIT = 12'b001000000000; // 等待3.3V稳定+5ms延迟
localparam MCU_RST_REL = 12'b010000000000; // 释放MCU复位+3ms延迟
localparam SYS_READY_ST = 12'b100000000000; // 系统就绪
localparam FAULT = 12'b111111111111; // 故障状态
// -------------------------- 2. 信号定义 --------------------------
reg [11:0] current_state; // 当前状态
reg [11:0] next_state; // 下一状态
reg [23:0] delay_cnt; // 延迟计数器(最大2^24=16777216,50MHz下≈335ms)
reg [1:0] pg1_sync; // PG1同步寄存器(消除亚稳态)
reg [1:0] pg2_sync; // PG2同步寄存器
reg [1:0] pg3_sync; // PG3同步寄存器
reg [1:0] pg4_sync; // PG4同步寄存器
reg pg1_stable; // 同步后PG1稳定信号
reg pg2_stable; // 同步后PG2稳定信号
reg pg3_stable; // 同步后PG3稳定信号
reg pg4_stable; // 同步后PG4稳定信号
reg [23:0] fault_cnt; // 故障计数器(超时20ms判定故障)
// -------------------------- 3. 输入同步(消除亚稳态) --------------------------
// 对PG信号进行2级同步,避免跨时钟域亚稳态
always @(posedge CLK_50MHz ornegedge RST_N) begin
if (!RST_N) begin
pg1_sync <= 2'b00;
pg2_sync <= 2'b00;
pg3_sync <= 2'b00;
pg4_sync <= 2'b00;
end else begin// 2 级同步:第一级采样,第二级稳定
pg1_sync [0] <= PG1;
pg1_sync [1] <= pg1_sync [0];
pg2_sync [0] <= PG2;
pg2_sync [1] <= pg2_sync [0];
pg3_sync [0] <= PG3;
pg3_sync [1] <= pg3_sync [0];
pg4_sync [0] <= PG4;
pg4_sync [1] <= pg4_sync [0];
endend
// 同步后 PG 信号赋值(高电平表示电源稳定)always @(posedge CLK_50MHz or negedge RST_N) beginif (!RST_N) begin
pg1_stable <= 1'b0;
pg2_stable <= 1'b0;
pg3_stable <= 1'b0;
pg4_stable <= 1'b0;
end else begin
pg1_stable <= pg1_sync [1];
pg2_stable <= pg2_sync [1];
pg3_stable <= pg3_sync [1];
pg4_stable <= pg4_sync [1];
endend
//-------------------------- 4. 延迟计数器与故障计数器 --------------------------always @(posedge CLK_50MHz or negedge RST_N) begin
if (!RST_N) begin
delay_cnt <= 24'd0;
fault_cnt <= 24'd0;
end else begin
case (current_state)// 仅在 “等待电源稳定” 状态启动计数器
PWR1_WAIT, PWR2_WAIT, PWR3_WAIT, PWR4_WAIT, MCU_RST_REL:
begin
delay_cnt <= delay_cnt + 1'b1;// 故障计数器:20ms 超时(50MHz×20ms=1,000,000)if (!pg1_stable && current_state == PWR1_WAIT) beginfault_cnt <= fault_cnt + 1'b1;end else if (!pg2_stable && current_state == PWR2_WAIT) beginfault_cnt <= fault_cnt + 1'b1;end else if (!pg3_stable && current_state == PWR3_WAIT) beginfault_cnt <= fault_cnt + 1'b1;end else if (!pg4_stable && current_state == PWR4_WAIT) beginfault_cnt <= fault_cnt + 1'b1;end else beginfault_cnt <= 24'd0; // 电源稳定时重置故障计数器endend// 其他状态重置计数器default: begindelay_cnt <= 24'd0;
fault_cnt <= 24'd0;endendcaseendend
//-------------------------- 5. 状态转移逻辑 --------------------------
always @(posedge CLK_50MHz or negedge RST_N) beginif (!RST_N) begincurrent_state <= IDLE;end else begincurrent_state <= next_state;endend
always @(*) beginnext_state = current_state; // 默认保持当前状态case (current_state)IDLE: begin// 系统上电(RST_N 释放)后,进入使能 1.2V 状态if (RST_N == 1'b1) beginnext_state = PWR1_ON;endend
PWR1_ON: begin// 使能 1.2V 后,立即进入等待稳定状态next_state = PWR1_WAIT;end
PWR1_WAIT: begin// 两种分支:电源稳定且延迟足够 → 下一步;超时 → 故障if (pg1_stable && delay_cnt>= 24'd500_000) begin // 10ms=50MHz×10ms=500,000next_state = PWR2_ON;end else if (fault_cnt >= 24'd1_000_000) begin // 20ms 超时next_state = FAULT;endend
PWR2_ON: beginnext_state = PWR2_WAIT;end
PWR2_WAIT: beginif (pg2_stable && delay_cnt >= 24'd400_000) begin // 8ms=400,000next_state = PWR3_ON;end else if (fault_cnt >= 24'd1_000_000) beginnext_state = FAULT;endend
PWR3_ON: beginnext_state = PWR3_WAIT;end
PWR3_WAIT: beginif (pg3_stable && delay_cnt >= 24'd750_000) begin // 15ms=750,000next_state = DDR_RST_REL;end else if (fault_cnt >= 24'd1_000_000) beginnext_state = FAULT;endend
DDR_RST_REL: begin// 释放 DDR 复位后,直接使能 3.3Vnext_state = PWR4_ON;end
PWR4_ON: beginnext_state = PWR4_WAIT;end
PWR4_WAIT: beginif (pg4_stable && delay_cnt >= 24'd250_000) begin // 5ms=250,000next_state = MCU_RST_REL;end else if (fault_cnt >= 24'd1_000_000) beginnext_state = FAULT;endend
MCU_RST_REL: begin// 释放 MCU 复位后,延迟 3ms 再释放外设复位if (delay_cnt>= 24'd150_000) begin // 3ms=150,000next_state = SYS_READY_ST;endend
SYS_READY_ST: begin// 系统就绪后保持状态,除非复位if (RST_N == 1'b0) beginnext_state = IDLE;endend
FAULT: begin// 故障状态下,复位后恢复if (RST_N == 1'b0) beginnext_state = IDLE;endendendcaseend
//-------------------------- 6. 输出控制逻辑 --------------------------always @(posedge CLK_50MHz or negedge RST_N) beginif (!RST_N) begin// 复位时:使能默认高(无效),复位默认低(有效),告警低,就绪低EN1 <= 1'b1;EN2 <= 1'b1;EN3 <= 1'b1;EN4 <= 1'b1;nRST_DDR <= 1'b0;nRST_MCU <= 1'b0;nRST_PERIPH <= 1'b0;ALM <= 1'b0;SYS_READY <= 1'b0;end else begincase (current_state)IDLE: begin// 空闲状态保持复位时的输出EN1 <= 1'b1;EN2 <= 1'b1;EN3 <= 1'b1;EN4 <= 1'b1;nRST_DDR <= 1'b0;nRST_MCU <= 1'b0;nRST_PERIPH <= 1'b0;ALM <= 1'b0;SYS_READY <= 1'b0;end
PWR1_ON: beginEN1 <= 1'b0; // 使能 1.2V(低有效)EN2 <= 1'b1;EN3 <= 1'b1;EN4 <= 1'b1;ALM <= 1'b0;end
PWR1_WAIT: begin// 保持 EN1 使能,其他不变EN1 <= 1'b0;ALM <= 1'b0;end
PWR2_ON: beginEN1 <= 1'b0; // 保持 1.2V 使能EN2 <= 1'b0; // 使能 1.8VALM <= 1'b0;end
PWR2_WAIT: beginEN1 <= 1'b0;EN2 <= 1'b0;ALM <= 1'b0;end
PWR3_ON: beginEN1 <= 1'b0;EN2 <= 1'b0;EN3 <= 1'b0; // 使能 1.5VALM <= 1'b0;end
PWR3_WAIT: beginEN1 <= 1'b0;EN2 <= 1'b0;EN3 <= 1'b0;ALM <= 1'b0;end
DDR_RST_REL: beginEN1 <= 1'b0;EN2 <= 1'b0;EN3 <= 1'b0;nRST_DDR <= 1'b1; // 释放 DDR 复位(高有效)ALM <= 1'b0;end
PWR4_ON: beginEN1 <= 1'b0;EN2 <= 1'b0;EN3 <= 1'b0;EN4 <= 1'b0; // 使能 3.3VnRST_DDR <= 1'b1;ALM <= 1'b0;end
PWR4_WAIT: beginEN1 <= 1'b0;EN2 <= 1'b0;EN3 <= 1'b0;EN4 <= 1'b0;nRST_DDR <= 1'b1;ALM <= 1'b0;end
MCU_RST_REL: beginEN1 <= 1'b0;EN2 <= 1'b0;EN3 <= 1'b0;EN4 <= 1'b0;nRST_DDR <= 1'b1;nRST_MCU <= 1'b1; // 释放 MCU 复位nRST_PERIPH <= 1'b1; // 释放外设复位ALM <= 1'b0;end
SYS_READY_ST: begin// 所有电源使能,复位释放,就绪信号拉高EN1 <= 1'b0;EN2 <= 1'b0;EN3 <= 1'b0;EN4 <= 1'b0;nRST_DDR <= 1'b1;nRST_MCU <= 1'b1;nRST_PERIPH <= 1'b1;SYS_READY <= 1'b1;ALM <= 1'b0;end
FAULT: begin// 故障时:关闭所有电源,拉告警,保持复位EN1 <= 1'b1;EN2 <= 1'b1;EN3 <= 1'b1;EN4 <= 1'b1;nRST_DDR <= 1'b0;nRST_MCU <= 1'b0;nRST_PERIPH <= 1'b0;ALM <= 1'b1; // 告警拉高SYS_READY <= 1'b0;endendcaseendend
endmodule
plaintext
### 5.3.3 代码逻辑解析:紧扣EF2L45LG特性
上述代码完全基于EF2L45LG的硬件能力设计,关键逻辑与器件特性的对应关系如下:
| 代码模块 | 依赖的EF2L45LG特性 | 文档引用段落 |
|------------------------|-------------------------------------------------------------------------------------|-----------------------------|
| 输入同步(2级寄存器) | IO支持施密特触发器输入,可配置为同步模式,消除亚稳态 | (IO可配置模式) |
| 延迟计数器(50MHz) | 支持外部50MHz晶振输入,PLL可锁定该时钟(代码中直接使用外部时钟,简化设计) | (时钟资源) |
| 多IO输出控制(EN/RST) | 113个IO支持LVCMOS3.3V电平,可直接驱动PMIC使能端(低有效)和复位端(低有效) | (IO电平标准) |
| 故障告警(ALM) | IO支持上拉模式,默认低电平,故障时拉高驱动LED,符合工业告警习惯 | (IO上拉/下拉配置) |
| 状态机逻辑(组合/时序)| 4480个LUT足够实现12状态摩尔机,无需额外逻辑资源 | (LUT容量)、(PLB优化) |
### 5.4 仿真验证:确保逻辑正确性
仿真验证是确保上电时序逻辑无误的关键步骤,需搭建测试平台(Testbench)模拟实际场景,推荐使用**ModelSim-Intel FPGA Edition**(与安路TangDynasty兼容)。
#### 5.4.1 测试平台(Testbench)代码
```verilog
// 测试平台:模拟EF2L45LG上电时序控制的输入输出
`timescale 1ns/1ps
module tb_ef2l45_power_sequence;
// 输入信号(测试平台驱动)
reg CLK_50MHz;
reg RST_N;
reg PG1;
reg PG2;
reg PG3;
reg PG4;
// 输出信号(EF2L45LG驱动,测试平台监测)
wire EN1;
wire EN2;
wire EN3;
wire EN4;
wire nRST_DDR;
wire nRST_MCU;
wire nRST_PERIPH;
wire ALM;
wire SYS_READY;
// 例化待测试模块
ef2l45_power_sequence uut(
.CLK_50MHz(CLK_50MHz),
.RST_N(RST_N),
.PG1(PG1),
.PG2(PG2),
.PG3(PG3),
.PG4(PG4),
.EN1(EN1),
.EN2(EN2),
.EN3(EN3),
.EN4(EN4),
.nRST_DDR(nRST_DDR),
.nRST_MCU(nRST_MCU),
.nRST_PERIPH(nRST_PERIPH),
.ALM(ALM),
.SYS_READY(SYS_READY)
);
// 生成50MHz时钟(周期20ns)
initial begin
CLK_50MHz = 1'b0;
forever #10 CLK_50MHz = ~CLK_50MHz;
end
// 测试场景:正常上电流程 + 故障场景
initial begin
// 1. 初始状态:复位有效,PG均低
RST_N = 1'b0;
PG1 = 1'b0;
PG2 = 1'b0;
PG3 = 1'b0;
PG4 = 1'b0;
#200; // 复位200ns
// 2. 释放复位,开始正常上电
RST_N = 1'b1;
#100; // 等待进入PWR1_ON状态
// 3. 模拟1.2V电源稳定(PG1=高)
PG1 = 1'b1;
#10_000_000; // 等待10ms(仿真中时间单位为ns,10ms=10^7 ns)
// 4. 模拟1.8V电源稳定(PG2=高)
PG2 = 1'b1;
#8_000_000; // 等待8ms
// 5. 模拟1.5V电源稳定(PG3=高)
PG3 = 1'b1;
#15_000_000; // 等待15ms
// 6. 模拟3.3V电源稳定(PG4=高)
PG4 = 1'b1;
#5_000_000; // 等待5ms
// 7. 等待MCU和外设复位释放,系统就绪
#3_000_000; // 等待3ms
if (SYS_READY == 1'b1) begin
$display("正常上电流程验证通过!");
end else begin
$display("正常上电流程验证失败!");
end
// 8. 模拟故障场景:复位后,1.2V电源超时未稳定
#10_000_000; // 系统就绪后等待10ms
RST_N = 1'b0; // 复位
#200;
RST_N = 1'b1; // 释放复位
PG1 = 1'b0; // 1.2V电源不稳定
#20_000_000; // 等待20ms(超时)
if (ALM == 1'b1) begin
$display("故障场景验证通过!");
end else begin
$display("故障场景验证失败!");
end
// 9. 结束仿真
#5_000_000;
$stop;
end
// 监测关键信号,打印波形
initial begin
$monitor("Time = %0t ns: EN1=%b, EN2=%b, EN3=%b, EN4=%b, RST_DDR=%b, RST_MCU=%b, ALM=%b, READY=%b",
$time, EN1, EN2, EN3, EN4, nRST_DDR, nRST_MCU, ALM, SYS_READY);
$vcdpluson; // 生成VCD波形文件,用于后续分析
end
endmodule
5.4.2 仿真测试用例与预期结果
通过仿真验证两种核心场景,确保逻辑符合设计要求:
| 测试用例 | 测试步骤 | 预期结果 | 验证方式 |
|---|---|---|---|
| 正常上电流程 | 1. 复位释放;2. PG1~PG4 依次变高(符合延迟);3. 等待各步骤延迟 | 1. EN1~EN4 依次变低;2. nRST_DDR→nRST_MCU→nRST_PERIPH 依次变高;3. SYS_READY = 高;4. ALM = 低 | 波形观察 + 日志打印 |
| 1.2V 电源超时故障 | 1. 复位释放;2. PG1 保持低(模拟电源故障);3. 等待 20ms | 1. 20ms 后 ALM = 高;2. EN1~EN4 变高(关闭电源);3. 所有复位信号 = 低 | 波形观察 + 超时检测 |
| 复位恢复故障 | 1. 故障状态下(ALM = 高);2. 拉低 RST_N(复位);3. 释放 RST_N | 1. ALM = 低;2. 重新进入 IDLE→PWR1_ON 流程 | 波形观察 + 状态跳转检测 |
5.4.3 仿真结果分析
仿真完成后,重点观察以下波形(时间轴单位为 ms):
- EN1 波形:0ms 时 RST_N 释放,EN1 在 0.1ms 变低(使能 1.2V),直至系统就绪保持低;
- PG1 波形:0.1ms 后 PG1 变高(模拟电源稳定),10.1ms 时延迟结束,EN2 变低;
- SYS_READY 波形:0ms~38ms 为低,38ms 时(10+8+15+5=38ms)变高,标志系统就绪;
- ALM 波形:正常流程中为低,故障场景下 20ms 时变高,复位后变低。
若波形与预期一致,说明逻辑设计正确;若存在偏差(如延迟时间不符),需调整delay_cnt的阈值(如 10ms 对应 500,000 个时钟周期)。
5.5 实际测试:硬件验证与调试
仿真通过后,需在实际硬件上测试,确保 EF2L45LG 的时序控制符合 SOC 需求。
5.5.1 测试硬件准备
| 设备 / 工具 | 型号 / 规格 | 用途 |
|---|---|---|
| EF2L45 开发板 | 安路 EF2L45LG144B 开发板(含 PMIC、MCU、DDR3 接口) | 测试载体,运行时序控制逻辑 |
| 示波器 | 泰克 TDS2024C(4 通道,100MHz 带宽) | 测量 EN、PG、复位信号的时序 |
| 电源供应器 | 艾德克斯 IT6720(0~30V/0~5A) | 为开发板提供 5V 输入电源 |
| 逻辑分析仪 | 致远电子 LA1016(16 通道,100MHz 采样率) | 同时监测多个数字信号(如 EN1~EN4、SYS_READY) |
| 杜邦线 | 20cm 长,母对母 | 连接示波器探头与开发板引脚 |
5.5.2 测试步骤与关键测量点
-
硬件连接:
- 电源供应器输出 5V,连接开发板 VIN 引脚;
- 示波器通道 1 接 EN1(P7),通道 2 接 PG1(P3),通道 3 接 nRST_DDR(P11),通道 4 接 SYS_READY(P15);
- 逻辑分析仪连接 EN1~EN4、ALM、SYS_READY,采样率设为 100MHz。
-
正常上电测试:
- 开启电源供应器,记录各信号的时间节点(精确到 ms);
- 测量关键参数:EN1 变低→PG1 变高的时间(应 < 10ms)、PG1 变高→EN2 变低的时间(应 = 10ms±10%)、SYS_READY 变高的总时间(应≈38ms)。
-
故障测试:
- 断开 PMIC 的 1.2V 输出(模拟电源故障),开启电源;
- 测量 ALM 变高的时间(应 = 20ms±10%),同时观察 EN1 是否变高(关闭电源)。
-
复位测试:
- 故障状态下,按下开发板复位按钮(拉低 RST_N);
- 观察 ALM 是否变低,EN1 是否重新变低(重启上电流程)。
5.5.3 实际测试结果与调试
基于 EF2L45LG144B 开发板的测试结果(典型值):
| 测试项目 | 设计值 | 实际测量值 | 偏差原因与调试方案 |
|---|---|---|---|
| EN1 变低→PG1 变高 | <10ms | 8.5ms | 符合要求,无需调试 |
| PG1 变高→EN2 变低 | 10ms | 10.2ms |

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



