本帖最后由 luyaker 于 2013-12-25 16:56 编辑
我见特权同学写的SDRAM例程里面采用的全局时钟先经过PLL搞一下,进去50MHz,出来还是50MHz(当然还有100MHz),我也不知道这有没有必要。
异步复位同步释放的时候,如果采用PLL出来的时钟将异步复位用经过寄存器打一下,再反过来用来作为PLL的rst可能不大合适,所以特权干脆直接用晶振进来的时钟。
但是这样的话,就又采用了从FPGA外部进来的RST_N,这种异步复位同步释放是不是没有必要了呢?
而且这样做的话,时序约束的时候,SYSCLK的Minimum Pulse Width总是不满足时序要求。所以我把这个地方的同步释放去掉了,直接用RST_N复位,不知道有没有问题?
下面是特权同学的代码(也有可能是其他人的),请看红色部分有无必要:
module PLL(
SYSCLK,
RST_N,
SYS_RST_N,
CLK_50M,
CLK_100M,
SDRAM_CLK
);
input SYSCLK; //FPAG输入时钟信号50MHz
input RST_N; //FPGA输入复位信号
output SYS_RST_N; //系统复位信号,低有效
output CLK_50M; //PLL输出50MHz时钟
output CLK_100M; //PLL输出100MHz时钟
output SDRAM_CLK; //用于外部SDAM的时钟100M
wire LOCKED; //PLL输出有效标志位,高表示PLL输出有效
//----------------------------------------------
//PLL复位信号产生,高有效
//异步复位,同步释放
wire PLL_RST; //PLL复位信号,高有效
reg RST_REG,RST_REG_N;
always @(posedge SYSCLK or negedge RST_N)
if(!RST_N) RST_REG <= 1'b1;
else RST_REG <= 1'b0;
always @(posedge SYSCLK or negedge RST_N)
if(!RST_N) RST_REG_N <= 1'b1;
else RST_REG_N <= RST_REG;
assign PLL_RST = RST_REG_N;
//----------------------------------------------
//系统复位信号产生,低有效
//异步复位,同步释放
wire SYS_RST_N; //系统复位信号,低有效
wire SYS_RST_N_R0;
reg SYS_RST_N_R1,SYS_RST_N_R2;
assign SYS_RST_N_R0 = RST_N & LOCKED; //系统复位直到PLL有效输出
always @(posedge CLK_100M or negedge SYS_RST_N_R0)
if(!SYS_RST_N_R0) SYS_RST_N_R1 <= 1'b0;
else SYS_RST_N_R1 <= 1'b1;
always @(posedge CLK_100M or negedge SYS_RST_N_R0)
if(!SYS_RST_N_R0) SYS_RST_N_R2 <= 1'b0;
else SYS_RST_N_R2 <= SYS_RST_N_R1;
assign SYS_RST_N = SYS_RST_N_R2;
//----------------------------------------------
//例化PLL产生模块
PLL_CTL I_PLL_CTL(
.areset(PLL_RST), //PLL复位信号,高电平复位
.inclk0(SYSCLK), //PLL输入时钟,50MHz
.c0(CLK_50M), //PLL输出50MHz时钟
.c1(CLK_100M), //PLL输出100MHz时钟
.c2(SDRAM_CLK), //用于外部SDAM的时钟100M
.locked(LOCKED) //PLL输出有效标志位,高表示PLL输出有效
);
endmodule
|