标签:
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 begin 12 if(!rst_n) 13 b <= 0; 14 else 15 b <= a; 16 end 17 endmodule
没有对复位信号进行处理,当异步复位信号到来时,马上进行复位
优点:设计简单,节省资源。
缺点:容易使寄存器出现亚稳态问题;复位信号容易受到毛刺的影响
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 begin 12 if(!rst_n) 13 b <= 0; 14 else 15 b <= a; 16 end 17 endmodule
将rst_n作为外部信号去采样(而非时钟信号)不再作为D触发器的复位端口,这样不存在
竞争--冒险问题,因为全部都是clk说了算(rst_n由全局时钟clk采样)
优点:降低亚稳态的出现概率;系统成了100%同步时序;因为只在时钟有效沿到来时才有效,所以可以滤除高于时钟频率的毛刺。
缺点:复位信号的有效时长必须大于时钟周期,才能真正的被系统识别并完成复位任务,还要考虑clk skew 、组合逻辑路径延时、复位延时等因素;消耗较多的组合逻辑资源。
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 begin 14 if(!rst_n) 15 sys_rst_n <= 0; 16 else 17 sys_rst_n <= rst_n; 18 End 19 //--------------------------------------------------------- 20 always@(posedge clk or negedge sys_rst_n) 21 begin 22 if(!sys_rst_n) 23 b <= 0; 24 else 25 b <= a; 26 end 27 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信号同步。
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 reset 11 ); 12 //---------------------------------------------- 13 //rst_n sync, only controlled by the main clk 14 reg rst_nr1, rst_nr2; 15 always @(posedge clk) 16 begin 17 if(!rst_n) 18 begin 19 rst_nr1 <= 1‘b0; 20 rst_nr2 <= 1‘b0; 21 end 22 else 23 begin 24 rst_nr1 <= 1‘b1; 25 rst_nr2 <= rst_nr1; 26 end 27 end 28 //---------------------------------- 29 //component instantiation for system_delay 30 wire delay_done; //system init delay has done 31 system_init_delay 32 #( 33 .SYS_DELAY_TOP (24‘d2500000) 34 // .SYS_DELAY_TOP (24‘d256) //Just for test 35 ) 36 u_system_init_delay 37 ( 38 //global clock 39 .clk (clk), 40 .rst_n (1‘b1), //It don‘t depend on rst_n when power up 41 //system interface 42 .delay_done (delay_done) 43 ); 44 assign clk_ref = clk; 45 assign sys_rst_n = rst_nr2 & delay_done; //active High 46 Endmodule
输入clk和rst_n,封装输出clk_ref,并同步sys_rst_n
为了信号的最优化,通过两个D触发器来连续同步异步复位信号(通过寄存器多次触发能达到一定的滤波效果)。这种方式在异步信号的同步及边沿信号的采样中经常用到
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 clock 10 input clk, //50MHz 11 input rst_n, 12 13 //system interface 14 output delay_done 15 ); 16 //------------------------------------------ 17 //Delay 50ms for steady state when power on 18 reg [23:0] delay_cnt = 24‘d0; 19 always@(posedge clk or negedge rst_n) 20 begin 21 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 else 26 delay_cnt <= SYS_DELAY_TOP - 1‘b1; 27 end 28 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 begin 10 clk = 0; 11 forever #(period/2) 12 clk = ~clk; 13 end 14 task task_reset; 15 begin 16 rst_n = 0; 17 repeat(2)@(posedge clk) 18 rst_n = 1; 19 end 20 endtask 21 //--------------------------------------------------------- 22 wire clk_ref; 23 wire sys_rst_n; 24 system_ctrl u_system_ctrl 25 ( 26 .clk (clk), //50MHz 27 .rst_n (rst_n), //global reset 28 29 .clk_ref (clk_ref), //clock output 30 .sys_rst_n (sys_rst_n) //system reset 31 ); 32 //------------------------------------------------------------------------ 33 task task_sysinit; 34 begin 35 36 end 37 endtask 38 //-------------------------------------------------------------- 39 initial 40 begin 41 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)
标签:
原文地址:http://www.cnblogs.com/WHaoL/p/5953116.html