FPGA中韩彬(大神)的异步复位,同步释放方法

编程入门 行业动态 更新时间:2024-10-28 01:23:10

FPGA中韩彬(<a href=https://www.elefans.com/category/jswz/34/1768337.html style=大神)的异步复位,同步释放方法"/>

FPGA中韩彬(大神)的异步复位,同步释放方法

module system_ctrl//无PLL的全局时钟模块顶层(下面的那个模块是这个顶层模块的子模块)
(

input clk,
input rst_n,


output clk_ref, //输出时钟
output sys_rst_n //输出复位
);


//----------------------------------------------


reg     rst_nr1, rst_nr2;//打节拍,使其达到同步状态(异步:是指reset和clk这两个小信号原来不是一起触发;同步:是指这两个信号经过打一拍后变成了输出都取决于clk信号)
always @(posedge clk)//同步复位,打节拍使其只受clk控制
begin
if(!rst_n)
begin
rst_nr1 <= 1'b0;
rst_nr2 <= 1'b0;
end
else
begin
rst_nr1 <= 1'b1;
rst_nr2 <= rst_nr1;
end
end




//----------------------------------


wire delay_done; //例化延时模块,延时50ms
system_init_delay
#(
.SYS_DELAY_TOP (24'd2500000)//这里我有不懂为什么用这样写,不过我觉着可以自己直接定义一个常数就行
 )
u_system_init_delay
(
.clk (clk),
.rst_n (1'b1), //永远不复位,为的是就用一次这个延时50ms的模块
.delay_done (delay_done)
);


assign clk_ref = clk;
assign sys_rst_n = rst_nr2 & delay_done; //输出复位的条件


endmodule




module system_init_delay//延时50ms,作为全局时钟顶层中的子模块
#(
parameter SYS_DELAY_TOP = 24'd2500000 //50ms 定时
)
(

input clk, //50MHz
input rst_n,

output delay_done
);


//------------------------------------------


reg [23:0] delay_cnt = 24'd0;//因为永远不复位,所以这里要直接赋值为0
always@(posedge clk or negedge rst_n)//延时50ms的计数
begin
if(!rst_n)
delay_cnt <= 0;
else if(delay_cnt < SYS_DELAY_TOP - 1'b1)
delay_cnt <= delay_cnt + 1'b1;
else
delay_cnt <= SYS_DELAY_TOP - 1'b1;
end
assign delay_done = (delay_cnt == SYS_DELAY_TOP - 1'b1)? 1'b1 : 1'b0;//完成的标志


endmodule






//有PLL的复位模板,就是要把PLL作为输出的主时钟和复位要再做一次同步释放处理
//`timescale 1 ns / 1 ns
module system_ctrl_pll//系统的异步复位,同步处理模块
(

input clk,
input rst_n,



output clk_c0, //clock output 这里可以好几个经过pll输出的时钟,在同步时钟时选择其中频率最高的作为同步时钟,
output sys_rst_n //system reset
);


//----------------------------------


wire delay_done; //这是例化延时模块,以后这个快可以照搬,为了使FPGA上电后稳定,所以要延时50ms
system_init_delay
#(
.SYS_DELAY_TOP (24'd2500000)
// .SYS_DELAY_TOP (24'd256) //这个仅仅用于仿真操作
)
u_system_init_delay
(

.clk (clk),
.rst_n (1'b1), //用于不复位,因为复位就一次,不能再在个延时中使用

.delay_done (delay_done)
);
wire pll_rst = ~delay_done;// pll的复位,当延时完成时就复位




//-----------------------------------
//例化pll IP核
wire locked;//locked信号为PLL完成的标志
sys_pll u_sys_pll 
(
.inclk0 (clk),
.areset (pll_rst),
.locked (locked),
.c0 (clk_c0)
);


//----------------------------------------------
//异步复位,同步操作
reg     rst_nr1, rst_nr2;
always @(posedge clk_c0)//这个时钟用PLL例化后输出里的主时钟如果(输出多个时钟,自己看一下哪个是主时钟,就同步哪里主时钟),
begin
if(!rst_n)
begin
rst_nr1 <= 1'b0;
rst_nr2 <= 1'b0;
end
else
begin
rst_nr1 <= 1'b1;
rst_nr2 <= rst_nr1;
end
end
assign sys_rst_n = rst_nr2 & locked; //复位的条件!


endmodule


下面是等待时间,是上一个模块的子模块


`timescale 1 ns / 1 ns
module system_init_delay
#(
parameter SYS_DELAY_TOP = 24'd2500000 //  50ms延时,用于FPGA开机
)
(

input clk, //50MHz
input rst_n,

output delay_done
);


//------------------------------------------
//延时的计数器
reg [23:0] delay_cnt = 24'd0;//因为只有一次复位的机会,所以下面的那个复位就是个摆设而已,所以这个地方要直接赋值
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
delay_cnt <= 0;
else if(delay_cnt < SYS_DELAY_TOP - 1'b1)
delay_cnt <= delay_cnt + 1'b1;
else
delay_cnt <= SYS_DELAY_TOP - 1'b1;
end
assign delay_done = (delay_cnt == SYS_DELAY_TOP - 1'b1)? 1'b1 : 1'b0;


endmodule

更多推荐

FPGA中韩彬(大神)的异步复位,同步释放方法

本文发布于:2024-02-25 18:42:15,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1699926.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:大神   方法   FPGA   韩彬

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!