在fpga如何实现任意分频呢?
偶数分频比较简单,而比较困难的是奇数分频。请看下图:
如上图所示是三分频的分析图,黑色的为两路时钟,相位差180°,可以取反获得其中的任意一路,最终的蓝色波形是输出波形,紫色的是计数器,假设计数3个也就是0 1 2,两个红色框是计数器表示2,黄色框其实就是我们需要的半个时钟,只要将两个红色框中的信号或起来就可以实现奇分频了,其他奇分频类似。代码如下:
module fenpin #(parameter YINZI = 8) ( input clk_p , input clk_n , input aclr, input [YINZI-1:0] fenpin, output reg out_clk ); reg [YINZI-1:0] cnt,cnt_n; reg flag_a,flag_b; //assign clk_n =!clk_p; always @(posedge clk_p,negedge aclr) if(!aclr) cnt <= 0; else if(cnt==fenpin-1) cnt <= 0; else cnt <= cnt+1; always @(posedge clk_p,negedge aclr) if(!aclr) flag_a <= 0; else if(cnt==fenpin-1) flag_a <= 0; else if(cnt==fenpin[YINZI-1:1]+fenpin[0]-1) flag_a <= 1; always @(posedge clk_n,negedge aclr) if(!aclr) cnt_n <= 0; else if(cnt_n==fenpin-1) cnt_n <= 0; else cnt_n <= cnt+1; always @(posedge clk_n,negedge aclr) if(!aclr) flag_b <= 0; else if(cnt_n==fenpin-1) flag_b <= 0; else if(cnt_n==fenpin[YINZI-1:1]+fenpin[0]-1) flag_b <= 1; //output always @( * ) if(fenpin[0]==1) //奇数 out_clk = flag_a | flag_b; else out_clk = flag_a; endmodule
仿真代码如下:
`timescale 1 ns / 1 ns module fenpin_tb; parameter PERIOD = 10; reg clk_p ; wire clk_n ; reg aclr; reg [7:0] fenpin; wire out_clk; fenpin fenpin_u0( .clk_p (clk_p ), .clk_n (clk_n ), .aclr (aclr ), .fenpin (fenpin ), .out_clk (out_clk) ); always begin clk_p = 0; #PERIOD; clk_p = 1; #PERIOD; end assign clk_n = !clk_p; initial begin #2; aclr = 0; fenpin = 5; #(10*PERIOD); aclr = 1; end endmodule
仿真图:
如上图所示,是五分频的仿真图,高低电平各位2.5个clk。欢迎大家一起交流,Q群:912014800。