这是用于生成500MHz时钟的代码。
模块Clk_generator(
输入Clk_I10M,
输入Clk_Reset,
输出Clk_O50M,
输出Clk_Locked_50M,
输出Clk_O500M,
输出Clk_Locked_500M
);
//时钟倍数从10MHz到50MHz开始////////////////////
clk_wiz_I10M_O50M Uclk_wiz_I10M_O50M
(//端口时钟
.CLK_IN1(Clk_I10M),// IN
//输出端口
.CLK_OUT1(Clk_O50M),// OUT
//状态和控制信号
.RESET(Clk_Reset),// IN
.LOCKED(Clk_Locked_50M));
// OUT
//时钟倍数从10MHz到50MHz结束////////////////////
//从50MHz到500MHz的时钟倍数启动/////////////////
电线ClkFb_500M;
clk_wiz_I50M_O500M Uclk_wiz_I50M_O500M
(//端口时钟
.CLK_IN1(Clk_O50M),// IN
.CLKFB_IN(ClkFb_500M),// IN
//输出端口
.CLK_OUT1(Clk_O500M),// OUT
.CLKFB_OUT(ClkFb_500M),// OUT
//状态和控制信号
.RESET(Clk_Reset),// IN
.LOCKED(Clk_Locked_500M));
// OUT
//时钟倍数从50MHz到500MHz结束/////////////////
endmodule
然后我将500MHz时钟连接到以下模块。
我使用500MHz时钟来计算“Clk_O1Hz”和“GPS_1pps”之间的相位差,为不同的条件生成计数器启动,停止和重载的控制信号,我使用serverl寄存器作为布尔值。
为了在重新加载后保持计数器输出,我使用DFF来存储计数器值。
模块Phase_comparator(Clk_O1Hz,GPS_1pps,Clk_I500M,Clk_rst,Comp_out,Comp_Finish);
输入Clk_O1Hz;
输入GPS_1pps;
输入Clk_I500M;
输入Clk_rst;
输出[31:0] Comp_out;
输出Comp_Finish;
reg Comp_Start;
reg more180;
reg完成;
reg SCLR;
总是@(posedge Clk_I500M或posedge Clk_rst)
开始
if(Clk_rst)
开始
Comp_Start
我做了模拟,如果我将时钟从500MHz调到240MHz,电路就能正常工作。
仿真结果表明,如果时钟太快(例如500MHz),计数器输出变为“X”
我试图将控制信号替换为.ce(1)和.sclr(0)以使计数器自由运行,它可以承受的最大时钟约为350MHz。
但是,如果我使用我编写的控制逻辑,如果时钟快于240MHz,则“Comp_Start”和“SCLR”将输出“X”,然后计数器也将输出错误。
以上来自于谷歌翻译
以下为原文
Here is the code that for generate 500MHz clock.
module Clk_generator( input Clk_I10M, input Clk_Reset, output Clk_O50M, output Clk_Locked_50M, output Clk_O500M, output Clk_Locked_500M );// Clock multiple from 10MHz to 50MHz Start ////////////////////clk_wiz_I10M_O50M Uclk_wiz_I10M_O50M (// Clock in ports .CLK_IN1 (Clk_I10M), // IN // Clock out ports .CLK_OUT1 (Clk_O50M), // OUT // Status and control signals .RESET (Clk_Reset), // IN .LOCKED (Clk_Locked_50M)); // OUT // Clock multiple from 10MHz to 50MHz End ////////////////////// Clock multiple from 50MHz to 500MHz Start /////////////////wire ClkFb_500M;clk_wiz_I50M_O500M Uclk_wiz_I50M_O500M (// Clock in ports .CLK_IN1 (Clk_O50M), // IN .CLKFB_IN (ClkFb_500M), // IN // Clock out ports .CLK_OUT1 (Clk_O500M), // OUT .CLKFB_OUT (ClkFb_500M), // OUT // Status and control signals .RESET (Clk_Reset), // IN .LOCKED (Clk_Locked_500M)); // OUT// Clock multiple from 50MHz to 500MHz End /////////////////endmodule
Then I connect the 500MHz clock to the following module.
I use the 500MHz clock to counting the phase difference between "Clk_O1Hz" and "GPS_1pps", to generate the control signal for the counter start, stop and reload for different condition, I used serverl register to be the boolean. To keep the counter output after reload, I use a DFF to store the counter value.
module Phase_comparator(Clk_O1Hz, GPS_1pps, Clk_I500M, Clk_rst, Comp_out, Comp_Finish);input Clk_O1Hz;input GPS_1pps;input Clk_I500M;input Clk_rst;output [31:0] Comp_out;output Comp_Finish;reg Comp_Start;reg more180;reg Finished;reg SCLR;always@(posedge Clk_I500M or posedge Clk_rst)beginif (Clk_rst)beginComp_Start <= 0;more180 <= 0;Finished <= 0;SCLR <= 1;endelsebegin//Phase difference less than 180 degree, start counterif((GPS_1pps==1) && (Clk_O1Hz==0) && (Comp_Start==0) && (more180==0) && (Finished==0))beginComp_Start <= 1;more180 <= 0;Finished <= 0;SCLR <= 0;end//Phase difference less than 180 degree, stop counterelse if((GPS_1pps==1) && (Clk_O1Hz==1) && (Comp_Start==1) && (more180==0) && (Finished==0))beginComp_Start <= 0;more180 <= 0;Finished <= 1;end//Phase difference less than 180 degree, reload counterelse if((GPS_1pps==0) && (Clk_O1Hz==0) && (Comp_Start==0) && (more180==0) && (Finished==1))beginComp_Start <= 0;more180 <= 0;Finished <= 0;SCLR <= 1;end//Phase difference more than 180 degree, start counterelse if ((GPS_1pps==1) && (Clk_O1Hz==1) && (Comp_Start==0) && (more180==0) && (Finished==0))beginComp_Start <= 1;more180 <= 1;Finished <= 0;SCLR <= 0;end//Phase difference more than 180 degree, stop counterelse if ((GPS_1pps==0) && (Clk_O1Hz==1) && (Comp_Start==1) && (more180==1) && (Finished==0))beginComp_Start <= 0;more180 <= 1;Finished <= 1;end//Phase difference more than 180 degree, reload counterelse if ((GPS_1pps==0) && (Clk_O1Hz==1) && (Comp_Start==0) && (more180==1) && (Finished==1))beginComp_Start <= 0;more180 <= 0;Finished <= 0;SCLR <= 1;endendendassign Comp_Finish = !Comp_Start;wire [31:0] Comp_counter;Phase_Counter UPhase_Counter (.clk(Clk_I500M),.ce(Comp_Start),.sclr(SCLR),.q(Comp_counter)); // Bus [31 : 0] dff_32_async_reset Udff_32_async_reset (.data(Comp_counter),// Data Input.clk(Comp_Start),// Clock Input, negedge trigger.reset(Clk_rst),// Reset input .q(Comp_out));// Q outputendmodule
I have done simulation, the circuit work properly if I tune down the clock from 500MHz to 240MHz.
The simulation result show that the counter output become "X" if the clock is too fast (e.g. 500MHz)
I have tried to replace the control signal to .ce(1) and .sclr(0) to let the counter free running, the max clock it can suffer is around 350MHz.
However, if I use the control logic that I have written, the "Comp_Start" and "SCLR" will output "X" if the clock is faster than 240MHz and then counter will also output wrong.