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
(
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