项目概述:
在FPGA开发中,第一步就是需要设计时钟复位管理模块,系统的复位树可分为硬件复位和软件复位,软件复位又可以通过打拍产生每个时钟的复位,这样一来,每个时钟均有自己的同步复位信号,这对于时序和程序稳定性有很大帮助。
设计思路
时钟管理IP核锁上后,locked
拉高,一般用该信号驱动硬件复位,这里设置复位时间1s。然后开始进行软件复位,软件系统复位sys_rst_n_r
通过寄存器信号sw_reset_n
和VIO信号vio_rst_n
共同控制。然后使用该系统复位信号继续产生每个时钟的同步复位信号。
部分代码如下:
localparam time_1s = 32'd49_999_999;
//---------------------------------------------------------------------
// PLL
//---------------------------------------------------------------------
PLL PLL_inst
(
// Clock out ports
.clk_100m (clk_100m ),// output clk_out1
.clk_50m (clk_50m ),// output clk_out2
// Status and control signals
.reset (1'b0 ),// input reset
.locked (locked ),// output locked
// Clock in ports
.clk_in1_p (SYSCLK100_P ),// input clk_in1_p
.clk_in1_n (SYSCLK100_N ) // input clk_in1_n
);
//---------------------------------------------------------------------
// FPGA硬件复位
//---------------------------------------------------------------------
always@(posedge clk_50m or negedge locked) begin
if(!locked)begin
hw_reset_n_r <= 1'b0;
hw_rst_cnt <= 32'd0;
end
else if(hw_rst_cnt >= time_1s) begin
hw_reset_n_r <= 1'b1;
hw_rst_cnt <= hw_rst_cnt;
end
else begin
hw_reset_n_r <= 1'b0;
hw_rst_cnt <= hw_rst_cnt + 1'b1;
end
end
//---------------------------------------------------------------------
// FPGA系统复位
//---------------------------------------------------------------------
// 软件和VIO复位
always@(posedge clk_50m or negedge hw_reset_n) begin
if(!hw_reset_n)
sys_rst_n_r <= 1'b0;
else
sys_rst_n_r <= sw_reset_n && vio_rst_n;
end
// 100M时钟复位
always@(posedge clk_100m) begin
clk_100m_rst_n_r1 <= sys_rst_n_r;
clk_100m_rst_n_r2 <= clk_100m_rst_n_r1;
end
// axi_250m时钟复位
always@(posedge axi_250m) begin
axi_250m_rst_n_r1 <= sys_rst_n_r;
axi_250m_rst_n_r2 <= axi_250m_rst_n_r1;
end