大家好,欢迎来到IT知识分享网。
分频:简单来说,二分频后的方波一个周期为标准方波高低电平循环两个周期,四分频为4个周期。分频后的时钟周期为原来的n倍,即为n分频。
频率和周期的关系:f=1/T
(1)简单的计数器
module test#(parameter N=3)( input clk, input rst_n, output clk_div ); reg [N-1:0] div_reg ;//分频计数器 always @(posedge clk or negedge rst_n) if (rst_n == 1'b0 ) div_reg <= 0 ; else div_reg <= div_reg + 1'b1 ; assign clk_div = div_reg[N-1] ; endmodule
module test#(parameter N=6)( input clk, input rst_n, output clk_div ); reg div_reg ; reg [N-1:0] div_cnt ;//分频计数器 always @(posedge clk or negedge rst_n) if (rst_n == 1'b0 )begin div_cnt <= 0 ; div_reg <= 0 ; end else if(div_cnt == (N/2 - 1))begin div_cnt <= 0; div_reg <= ~div_reg ; end else div_cnt <= div_cnt + 1'b1 ; assign clk_div = div_reg ; endmodule
(3)奇数倍分频
①占空比接近50%
第一种方法与上面的类似,先将奇数变成偶数,再除以2,计数完成进行时钟翻转。此时得出的分频接近50%,N越大越趋近于50%。
②占空比50%
第一个上升沿来临后,计数器从0开始自加1,同时输出1,第二个上升沿来临后,计数器值自加1,输出变为0,第三个上升沿来临计数为2,下一个上升沿来临时,计数器满足要求,开始翻转输出,这样循环。
下降沿采用同样思路编写代码。
module test#(parameter N=5)(//N分频 input clk, input rst_n, output clk_div ); reg sig_r ;//定义一个上升沿翻转的信号 reg sig_f ;//定义一个下降沿翻转的信号 reg [N-1:0] cnt_r;//上升沿计数器 reg [N-1:0] cnt_f;//下降沿计数器 wire clk_f ; assign clk_f = ~clk ;//用来触发下降沿计数器的时钟 //由于同时使用上升沿和下降沿触发器不好,因此我们为同一边沿,都使用上升沿触发 //只不过是将时钟进行反向 always @(posedge clk or negedge rst_n)begin//上升沿计数 if(rst_n == 1'b0)begin sig_r <= 0 ; cnt_r <= 0 ; end else if( cnt_r == (N-1)/2 )begin sig_r <= ~sig_r ; cnt_r <= cnt_r + 1 ; end else if ( cnt_r == (N-1) )begin sig_r <= ~sig_r ; cnt_r <= 0 ; end else cnt_r <= cnt_r + 1 ; end always @(posedge clk_f or negedge rst_n)begin//下降沿计数 if(rst_n == 1'b0)begin sig_f <= 0 ; cnt_f <= 0 ; end else if( cnt_f == (N-1)/2 )begin sig_f <= ~sig_f ; cnt_f <= cnt_f + 1 ; end else if ( cnt_f == (N-1) )begin sig_f <= ~sig_f ; cnt_f <= 0 ; end else cnt_f <= cnt_f + 1 ; end assign clk_div = sig_f || sig_r ; endmodule
module test #( parameter cfactor= 5)( input clk, input rst_n, output clk_div ); reg clk_loc; //reg [15:0] cnt;//allowed maximum clock division factor is 65536 reg [7:0] cnt;//allowed maximum clock division factor is 256 assign clk_div = (cfactor==1)? clk : clk_loc; //assign clk_div = ((rst==1) || (cfactor==1))? clk : clk_loc; always@(posedge clk or negedge rst_n) if(!rst_n)begin cnt <= 'd0; clk_loc = 1; end else begin cnt <= cnt + 1'b1; if(cnt==cfactor/2-1) clk_loc = 0; else if(cnt==cfactor-1) begin cnt <= 'd0; clk_loc = 1; end end endmodule
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/137698.html