首页 > 代码库 > 【FPGA】006 【优化设计FPGA全局时钟管理模块】
【FPGA】006 【优化设计FPGA全局时钟管理模块】
- 1.rst_n--异步复位设计
1 `timescale 1ns/1ns 2 module FPGA_temp 3 ( 4 input clk, 5 input rst_n, 6 7 input a, 8 output reg b 9 );10 always@(posedge clk or negedge rst_n)11 begin12 if(!rst_n)13 b <= 0;14 else 15 b <= a;16 end17 endmodule
没有对复位信号进行处理,当异步复位信号到来时,马上进行复位
优点:设计简单,节省资源。
缺点:容易使寄存器出现亚稳态问题;复位信号容易受到毛刺的影响
- 2.rst_n--同步复位设计
1 `timescale 1ns/1ns 2 module FPGA_temp 3 ( 4 input clk, 5 input rst_n, 6 7 input a, 8 output reg b 9 );10 always@(posedge clk )11 begin12 if(!rst_n)13 b <= 0;14 else 15 b <= a;16 end17 endmodule
将rst_n作为外部信号去采样(而非时钟信号)不再作为D触发器的复位端口,这样不存在
竞争--冒险问题,因为全部都是clk说了算(rst_n由全局时钟clk采样)
优点:降低亚稳态的出现概率;系统成了100%同步时序;因为只在时钟有效沿到来时才有效,所以可以滤除高于时钟频率的毛刺。
缺点:复位信号的有效时长必须大于时钟周期,才能真正的被系统识别并完成复位任务,还要考虑clk skew 、组合逻辑路径延时、复位延时等因素;消耗较多的组合逻辑资源。
- 3.异步rst_n信号的同步化设计
1 `timescale 1ns/1ns 2 module FPGA_temp 3 ( 4 input clk, 5 input rst_n, 6 7 input a, 8 output reg b 9 );10 //------------------------------------------------------------------11 reg sys_rst_n;12 always@(posedge clk)13 begin14 if(!rst_n)15 sys_rst_n <= 0;16 else 17 sys_rst_n <= rst_n;18 End19 //---------------------------------------------------------20 always@(posedge clk or negedge sys_rst_n)21 begin22 if(!sys_rst_n)23 b <= 0;24 else 25 b <= a;26 end27 endmodule
异步信号的同步化,同步化后的复位信号sys_rst_n作为D触发器的复位信号。
D触发器有异步复位专用的端口,采用异步复位端口无须额外增加器件资源消耗。
我们希望处理外部复位信号rst_n,以实现直接或间接控制D触发器的复位端口,这样充分利用了D触发器,同时减少了组合逻辑电路的消耗。因此,可以在将rst_n作为使能时钟的基础上,人为的生成另一个同步化后的“同步复位信号”。这需要我们用D触发器打一拍,然后直接提供给剩下的时序电路使用。
首先:第一个D触发器将rst_n打了一拍(通过DFF将rst_n同步到clk上去),这一过程将rst_n信号同步到了clk时钟域;接着输出的sys_rst_n信号直接作为第二个D触发器的复位信号。 这样设计只用了一个D触发器便实现了异步复位信号的同步化,同时减少了组合逻辑的使用。
“异步复位,同步释放”
(1)“异步复位”: 对D触发器的复位端口,它是异步的(但在设计中已经同步了异步复位信号,所以这只是某种意义上的‘异步复位’)
(2)“同步释放” : 我们设计了同步逻辑电路,外部复位信号不会在出现释放时与clk信号竞争,整个系统将与全局时钟clk信号同步。
- 4.无PLL的全局时钟管理模块设计
1 `timescale 1 ns / 1 ns 2 module system_ctrl 3 ( 4 //global clock 5 input clk, 6 input rst_n, 7 8 //synced signal 9 output clk_ref, //clock output 10 output sys_rst_n //system reset11 );12 //----------------------------------------------13 //rst_n sync, only controlled by the main clk14 reg rst_nr1, rst_nr2;15 always @(posedge clk)16 begin17 if(!rst_n)18 begin19 rst_nr1 <= 1‘b0;20 rst_nr2 <= 1‘b0;21 end22 else23 begin24 rst_nr1 <= 1‘b1;25 rst_nr2 <= rst_nr1;26 end27 end28 //----------------------------------29 //component instantiation for system_delay30 wire delay_done; //system init delay has done31 system_init_delay32 #(33 .SYS_DELAY_TOP (24‘d2500000)34 // .SYS_DELAY_TOP (24‘d256) //Just for test35 )36 u_system_init_delay37 (38 //global clock39 .clk (clk),40 .rst_n (1‘b1), //It don‘t depend on rst_n when power up41 //system interface42 .delay_done (delay_done)43 );44 assign clk_ref = clk;45 assign sys_rst_n = rst_nr2 & delay_done; //active High46 Endmodule
输入clk和rst_n,封装输出clk_ref,并同步sys_rst_n
为了信号的最优化,通过两个D触发器来连续同步异步复位信号(通过寄存器多次触发能达到一定的滤波效果)。这种方式在异步信号的同步及边沿信号的采样中经常用到
- 5.系统延时设计
1 复位启动延时电路实现如下: 2 //---------------------------------------------------------------------------------------------//code 3 `timescale 1 ns / 1 ns 4 module system_init_delay 5 #( 6 parameter SYS_DELAY_TOP = 24‘d2500000 //50ms system init delay 7 ) 8 ( 9 //global clock10 input clk, //50MHz11 input rst_n,12 13 //system interface14 output delay_done15 );16 //------------------------------------------17 //Delay 50ms for steady state when power on18 reg [23:0] delay_cnt = 24‘d0;19 always@(posedge clk or negedge rst_n)20 begin21 if(!rst_n)22 delay_cnt <= 0;23 else if(delay_cnt < SYS_DELAY_TOP - 1‘b1)24 delay_cnt <= delay_cnt + 1‘b1;25 else26 delay_cnt <= SYS_DELAY_TOP - 1‘b1;27 end28 assign delay_done = (delay_cnt == SYS_DELAY_TOP - 1‘b1)? 1‘b1 : 1‘b0;29 Endmodule
?电源芯片转换需要一定时间
‚FPGA启动到稳定需要一定时间
ƒ外围电路IC的启动需要一定时间
- 仿真代码
1 `timescale 1ns/1ns 2 module System_Ctrl_TB; 3 //----------------------//clk generate module 4 reg clk; 5 reg rst_n; 6 localparam period = 20; 7 8 initial 9 begin10 clk = 0;11 forever #(period/2)12 clk = ~clk;13 end 14 task task_reset;15 begin16 rst_n = 0;17 repeat(2)@(posedge clk)18 rst_n = 1;19 end20 endtask21 //---------------------------------------------------------22 wire clk_ref;23 wire sys_rst_n;24 system_ctrl u_system_ctrl25 (26 .clk (clk), //50MHz27 .rst_n (rst_n), //global reset28 29 .clk_ref (clk_ref), //clock output 30 .sys_rst_n (sys_rst_n) //system reset31 );32 //------------------------------------------------------------------------33 task task_sysinit;34 begin35 36 end37 endtask38 //--------------------------------------------------------------39 initial40 begin41 task_sysinit;42 task_reset;43 44 rst_n = 0;45 #896;46 rst_n = 1;47 #1911;48 rst_n = 0;49 #853;50 rst_n = 1;51 #2099;52 rst_n = 0;53 #136;54 rst_n = 1;55 end 56 endmodule
Delay_done无效时,sys_rst_n均为低电平
Delay_done有效时,sys_rst_n随rst_n变化(打了两排拍)
仿真时遇到的错误(卡了好几个小时):
本该是:else if (delay_cnt < SYS_DELAY_TOP - 1‘b1)
写成了:else if (delay_done < SYS_DELAY_TOP - 1‘b1)
【FPGA】006 【优化设计FPGA全局时钟管理模块】