赞
踩
MATLAB与FPGA数字信号处理(数字滤波器设计)、数字IC、无线通信、图像处理、信道编码系列
简单,只是注意时钟翻转的条件是(N/2)还是(N/2)-1,非阻塞赋值在下一个时钟才会更新值。
奇数分频比偶数分频复杂一些,当不要求分频的占空比时,对输入时钟clk上升沿计数,可以设置两个计数的翻转点,一个是(N-1)/2,一个是(N-1),计数到(N-1)时输出时钟翻转且将计数器清零,假设计数器计数0~(N-1)/2区间输出低电平,则输出时钟的低电平有(N-1)/2 + 1个clk周期,高电平的计数是(N-1)/2+1 ~ (N-1),共(N-1)/2个clk周期,可见不是50%占空比。
当要求占空比为50%时,对输入时钟clk的上升沿和下降沿分别计数,根据两个计数器得到两个错位输出的时钟,将两个时钟做“或”运算,可以弥补相差的时钟,达到50%占空比。
以7分频为例,代码如下:
/******************************************** 计数器实现 7 分频 *********************************************/ module Odd_Divider( input clk, input rst_n, output clk_divider ); reg [2:0] count_p; //上升沿计数 reg [2:0] count_n; //下降沿计数 reg clk_p; //上升沿分频 reg clk_n; //下降沿分频 //上升沿计数 always @ ( posedge clk or negedge rst_n ) begin if( !rst_n ) count_p <= 3'b0; else if( count_p == 3'd6 ) count_p <= 3'b0; else count_p <= count_p + 1'b1; end //上升沿分频 always @ ( posedge clk or negedge rst_n ) begin if( !rst_n ) begin clk_p <= 1'b0; end else begin if( count_p == 3'd3 || count_p == 3'd6 ) begin clk_p <= ~clk_p; end end end //下降沿计数 always @ ( negedge clk or negedge rst_n ) begin if( !rst_n ) count_n <= 3'b0; else if( count_n == 3'd6 ) count_n <= 3'b0; else count_n <= count_n + 1'b1; end //下降沿分频 always @ ( negedge clk or negedge rst_n ) begin if( !rst_n ) begin clk_n <= 1'b0; end else begin if( count_n == 3'd3 || count_n == 3'd6 ) begin clk_n <= ~clk_n; end end end assign clk_divider = clk_p | clk_n; endmodule
仿真如下:
N+0.5分频,如N=3时进行3.5分频。
先将clk时钟周期的一半记作clk_half,即一个高电平或一个低电平时间。
对2*(N+0.5) = 2N+1,这个数一定是奇数,按照奇数分频的思路做,也取clk_p和clk_n,但是计数值不一样,一个计数N个clk时钟周期(2N个clk_half周期),一个计数2N+2个clk_half,且两者的位置关系如图所示,这样,两者做“与”运算,则所得信号一个周期的高低电平共有2N+1个clk_half周期,即(N+0.5)个clk周期。
/******************************************** 计数器实现 3.5 分频,N=3,2N=6 *********************************************/ module Npoint5_Divider( input clk, input rst_n, output clk_divider ); reg [2:0] count_p; //上升沿计数 reg [2:0] count_n; //下降沿计数 reg clk_p; //上升沿分频 reg clk_n; //下降沿分频 //上升沿计数 always @ ( posedge clk or negedge rst_n ) begin if( !rst_n ) count_p <= 3'b0; else if( count_p == 3'd6 ) count_p <= 3'b0; else count_p <= count_p + 1'b1; end //上升沿分频 always @ ( posedge clk or negedge rst_n ) begin if( !rst_n ) begin clk_p <= 1'b0; end else begin if( count_p == 3'd4 || count_p == 3'd0 ) begin clk_p <= ~clk_p; end end end //下降沿计数 always @ ( negedge clk or negedge rst_n ) begin if( !rst_n ) count_n <= 3'b0; else if( count_n == 3'd6 ) count_n <= 3'b0; else count_n <= count_n + 1'b1; end //下降沿分频 always @ ( negedge clk or negedge rst_n ) begin if( !rst_n ) begin clk_n <= 1'b1; end else begin if( count_n == 3'd4 || count_n == 3'd1 ) begin clk_n <= ~clk_n; end end end assign clk_divider = clk_p & clk_n; endmodule
仿真结果:
MATLAB与FPGA数字信号处理(数字滤波器设计)、数字IC、无线通信、图像处理、信道编码系列
欢迎关注:FPGA探索者
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。