FPGA基础01-奇偶分频器
1.偶数分频
相对奇数分频,偶数分频相对较为简单,只需计数到N/2 - 1,其中N为分频数。如:要实现4分频,需要计数到1。代码如下:
1.1 代码
module divider //========================< 参数 >========================================== #( parameter N = 2 ) //========================< 端口 >========================================== ( //system -------------------------------------------- input wire clk , //时钟,50Mhz input wire rst_n , //复位,低电平有效 //output -------------------------------------------- output reg clk_div_N //输出out ); //========================< 信号 >========================================== reg [15:0] cnt ; wire add_cnt ; wire end_cnt ; //========================================================================== //== 偶数分频设计:cnt=N/2-1 //========================================================================== always @(posedge clk or negedge rst_n) begin if(!rst_n) cnt <= 'd0; else if(add_cnt) begin if(end_cnt) cnt <= 'd0; else cnt <= cnt + 1'b1; end end assign add_cnt = 1; assign end_cnt = add_cnt && cnt== N/2 -1; always @(posedge clk or negedge rst_n) begin if(!rst_n) begin clk_div_N <= 0; end else if(end_cnt) begin clk_div_N <= ~clk_div_N; end end endmodule
1.2 仿真波形
分析:当为2分频时,add_cnt和end_cnt始终为1。
2.奇数分频
对于奇数分频,利用待分频时钟上升沿计数,当clk = 0时,计数到N/2 + 1,clk0翻转;当clk = 1时,计数到N/2,输出clk0,以此往复...同理利用待分频时钟上升沿计数,输出clk1.
PS:如果想得到占空比为50%的时钟,只需要将clk0与clk1相或起来即可,即clk_50% = clk0|clk1。
2.1 代码
module divider #( parameter N = 3 ) ( input clk , input rst_n , // output wire clk_div_N ); //=====================================================================\ // ********** Define Parameter and Internal Signals ************* //=====================================================================/ //对于50%奇数分频器的设计,用到的思维是错位半个时钟并相或运算. //具体实现步骤如下: //(1)先利用待分频时钟的上升沿进行计数到N/2+1 时钟clk0翻转,再计数到N/2输出clk0. //(2)再利用待分频时钟的下降沿进行计数到N/2+1 时钟clk1翻转,再计数到N/2输出clk1. //最后将这两个时钟进行或运算即可,本例程是3分频。注:clk0和clk1均为奇数分频的时钟,只是占空比不是50%。 parameter COUNT = N/2 ; //cnt的位宽要与COUNT_5M匹配 reg [ 1: 0] cnt0 ; wire add_cnt0 ; wire end_cnt0 ; reg [ 1: 0] cnt1 ; wire add_cnt1 ; wire end_cnt1 ; reg clk0 ; reg clk1 ; reg [ 1: 0] cnt2 ; wire add_cnt2 ; wire end_cnt2 ; reg [ 1: 0] cnt3 ; wire add_cnt3 ; wire end_cnt3 ; //====================================================================== // *************** Main Code **************** //====================================================================== //====================clk0============================= //cnt0 always @(posedge clk or negedge rst_n)begin if(!rst_n)begin cnt0 <= 0; end else if(add_cnt0)begin if(end_cnt0) cnt0 <= 0; else cnt0 <= cnt0 + 1; end end assign add_cnt0 = clk0 == 0; assign end_cnt0 = add_cnt0 && cnt0 == COUNT; //cnt1 always @(posedge clk or negedge rst_n)begin if(!rst_n)begin cnt1 <= 0; end else if(add_cnt1)begin if(end_cnt1) cnt1 <= 0; else cnt1 <= cnt1 + 1; end end assign add_cnt1 = clk0 == 1; assign end_cnt1 = add_cnt1 && cnt1 == COUNT-1; //clk0 always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin clk0 <= 1'b0; end else if(end_cnt1|end_cnt0)begin clk0 <= ~clk0; end end //====================clk1============================= //cnt2 always @(negedge clk or negedge rst_n)begin if(!rst_n)begin cnt2 <= 0; end else if(add_cnt2)begin if(end_cnt2) cnt2 <= 0; else cnt2 <= cnt2 + 1; end end assign add_cnt2 = clk1 == 0; assign end_cnt2 = add_cnt2 && cnt2 == COUNT; //cnt3 always @(negedge clk or negedge rst_n)begin if(!rst_n)begin cnt3 <= 0; end else if(add_cnt3)begin if(end_cnt3) cnt3 <= 0; else cnt3 <= cnt3 + 1; end end assign add_cnt3 = clk1 == 1; assign end_cnt3 = add_cnt3 && cnt3 == COUNT-1; //clk1 always @(negedge clk or negedge rst_n)begin if(rst_n==1'b0)begin clk1 <= 1'b0; end else if(end_cnt2|end_cnt3)begin clk1 <= ~clk1; end end //clk_div_N assign clk_div_N = clk0 | clk1;
2.2 仿真波形
说明:上图的clk_div_N为占空比为分频系数为3且占空比为50%的波形,如果不要求占空比为50%,上图的clk0和clk1均是分频系数为3,但是占空比为1/3。