当前位置:   article > 正文

奇偶分频器(简介和Verilog实现)_奇数分频器

奇数分频器

偶数分频

级联触发器实现2^n偶数分频

采用触发器加反相器,可以构成简单的2分频电路,以这个基本单元进行级联就可以实现4 ,8 ,16 ,2^n 分频

Verilog实现

  1. module even_fre_div1( //偶数分频级联
  2. input clk ,
  3. input rst_n ,
  4. output wire clk_div2 ,
  5. output wire clk_div4 ,
  6. output wire clk_div8 ,
  7. );
  8. reg clk_div2_t ;
  9. reg clk_div4_t ;
  10. reg clk_div8_t ;
  11. //div2
  12. always @(posedge clk or negedge rst_n) begin
  13. if(!rst_n)
  14. clk_div2_t <= 1'b0;
  15. else
  16. clk_div2_t <= ~clk_div2_t ;
  17. end
  18. //
  19. always @(posedge clk or negedge rst_n) begin
  20. if(!rst_n)
  21. clk_div4_t <= 1'b0;
  22. else
  23. clk_div4_t <= ~clk_div4_t;
  24. end
  25. //
  26. always @(posedge clk or negedge rst_n) begin
  27. if(!rst_n)
  28. clk_div8_t <= 1'b0;
  29. else
  30. clk_div8_t <= ~clk_div8_t ;
  31. end
  32. //
  33. assign clk_div2 = clk_div2_t ;
  34. assign clk_div4 = clk_div4_t ;
  35. assign clk_div8 = clk_div8_t ;
  36. endmodule

 计数器实现2n偶数分频

  1. module even_fre_div2 #(
  2. parameter div_2n = 12
  3. )(
  4. input clk ,
  5. input rst_n ,
  6. output clk_div2n
  7. );
  8. reg [3:0] cnt ;
  9. reg clk_div2n_t ;
  10. //cnt
  11. always @(posedge clk ,negedge rst_n) begin
  12. if(!rst_n)
  13. cnt<= 1'b0;
  14. else if(cnt==div_2n/2 - 1)begin
  15. cnt <= 1'b0;
  16. end
  17. else
  18. cnt <= cnt+1'b1 ;
  19. end
  20. //out_clk
  21. always @(posedge clk ,negedge rst_n) begin
  22. if(!rst_n)
  23. clk_div2n_t <= 1'b0;
  24. else if(cnt==div_2n/2 - 1)
  25. clk_div2n_t <= ~clk_div2n_t;
  26. else
  27. clk_div2n_t <= clk_div2n_t ;
  28. end
  29. assign clk_div2n = clk_div2n_t ;
  30. endmodule

 奇数分频

相较于偶数分频,奇数分频知识点稍微多一些,有占空比50%和非50% ,占空比50%又是最长考的知识点,有相与,相或,相异或三种

奇数分频还涉及到双边计数器

奇数分频,占空比50% 

OR操作,2N+1奇数分频

 单计数器实现,只在上升沿计数,在上升沿和下降沿采用输出高低电平

  1. module odd_fre_or_div1 #(
  2. parameter DIV_CLK = 9
  3. )(
  4. input clk ,
  5. input rst_n ,
  6. output wire clk_div_odd
  7. );
  8. reg [3:0] cnt ;
  9. reg clkp_odd_r ;
  10. reg clkn_odd_r ;
  11. //cnt
  12. always @(posedge clk ,negedge rst_n) begin
  13. if(!rst_n)
  14. cnt <= 1'b0;
  15. else if(cnt==DIV_CLK - 1)
  16. begin
  17. cnt <= 1'b0 ;
  18. end
  19. else
  20. cnt <= cnt +1'b1 ;
  21. end
  22. //posedge clk_div
  23. always @( posedge clk ,negedge rst_n) begin
  24. if(!rst_n)
  25. clkp_odd_r <= 1'b0;
  26. else if(cnt== (DIV_CLK>>1) - 1)
  27. clkp_odd_r <= 1'b0;
  28. else if(cnt==DIV_CLK -1)
  29. clkp_odd_r <= 1'b1;
  30. else
  31. clkp_odd_r <= clkp_odd_r ;
  32. end
  33. //negedge clk_div
  34. always @( posedge clk ,negedge rst_n) begin
  35. if(!rst_n)
  36. clkn_odd_r <= 1'b0;
  37. else if(cnt== (DIV_CLK>>1) - 1)
  38. clkn_odd_r <= 1'b0;
  39. else if(cnt==DIV_CLK -1)
  40. clkn_odd_r <= 1'b1;
  41. else
  42. clkn_odd_r <= clkn_odd_r ;
  43. end
  44. //or
  45. assign clk_div_odd = clkp_odd_r | clkn_odd_r ;
  46. endmodule

双计数器实现

在上升沿和下降沿计数,在上升沿和下降沿采用输出高低电平

  1. module odd_fre_or_div2 #(
  2. parameter DIV_CLK = 9
  3. )(
  4. input clk ,
  5. input rst_n ,
  6. output wire clk_div_odd
  7. );
  8. reg [3:0] cnt_n ;
  9. reg [3:0] cnt_p ;
  10. reg clkp_odd_r ;
  11. reg clkn_odd_r ;
  12. //pos cnt
  13. always @(posedge clk ,negedge rst_n) begin
  14. if(!rst_n)
  15. cnt_p <= 1'b0;
  16. else if(cnt_p==DIV_CLK - 1)
  17. begin
  18. cnt_p <= 1'b0 ;
  19. end
  20. else
  21. cnt_p <= cnt_p +1'b1 ;
  22. end
  23. //neg cnt
  24. always @(posedge clk ,negedge rst_n) begin
  25. if(!rst_n)
  26. cnt_n <= 1'b0;
  27. else if(cnt_n == DIV_CLK - 1)
  28. begin
  29. cnt_n <= 1'b0 ;
  30. end
  31. else
  32. cnt_n <= cnt_n +1'b1 ;
  33. end
  34. //posedge clk_div
  35. always @( posedge clk ,negedge rst_n) begin
  36. if(!rst_n)
  37. clkp_odd_r <= 1'b0;
  38. else if(cnt_p == (DIV_CLK>>1) - 1)
  39. clkp_odd_r <= 1'b0;
  40. else if(cnt_p == DIV_CLK -1)
  41. clkp_odd_r <= 1'b1;
  42. else
  43. clkp_odd_r <= clkp_odd_r ;
  44. end
  45. //negedge clk_div
  46. always @( posedge clk ,negedge rst_n) begin
  47. if(!rst_n)
  48. clkn_odd_r <= 1'b0;
  49. else if(cnt_n == (DIV_CLK>>1) - 1)
  50. clkn_odd_r <= 1'b0;
  51. else if(cnt_n == DIV_CLK -1)
  52. clkn_odd_r <= 1'b1;
  53. else
  54. clkn_odd_r <= clkn_odd_r ;
  55. end
  56. //or
  57. assign clk_div_odd = clkp_odd_r | clkn_odd_r ;
  58. endmodule

AND操作 2N+1计数分频

 单计数器实现

只在上升沿计数,在上升沿和下降沿采用输出高低电平

  1. module odd_fre_or_div3 #(
  2. parameter DIV_CLK = 9
  3. )(
  4. input clk ,
  5. input rst_n ,
  6. output wire clk_div_odd
  7. );
  8. reg [3:0] cnt_p ;
  9. reg clkp_odd_r ;
  10. reg clkn_odd_r ;
  11. //pos cnt
  12. always @(posedge clk ,negedge rst_n) begin
  13. if(!rst_n)
  14. cnt_p <= 1'b0;
  15. else if(cnt_p==DIV_CLK - 1)
  16. begin
  17. cnt_p <= 1'b0 ;
  18. end
  19. else
  20. cnt_p <= cnt_p +1'b1 ;
  21. end
  22. //posedge clk_div
  23. always @( posedge clk ,negedge rst_n) begin
  24. if(!rst_n)
  25. clkp_odd_r <= 1'b0;
  26. else if(cnt_p == (DIV_CLK>>1) )
  27. clkp_odd_r <= 1'b0;
  28. else if(cnt_p == DIV_CLK -1)
  29. clkp_odd_r <= 1'b1;
  30. else
  31. clkp_odd_r <= clkp_odd_r ;
  32. end
  33. //negedge clk_div
  34. always @( posedge clk ,negedge rst_n) begin
  35. if(!rst_n)
  36. clkn_odd_r <= 1'b0;
  37. else if(cnt_p == (DIV_CLK>>1) )
  38. clkn_odd_r <= 1'b0;
  39. else if(cnt_p == DIV_CLK -1)
  40. clkn_odd_r <= 1'b1;
  41. else
  42. clkn_odd_r <= clkn_odd_r ;
  43. end
  44. //and
  45. assign clk_div_odd = clkp_odd_r && clkn_odd_r ;
  46. endmodule

双计数器实现

  1. module odd_fre_or_div4 #(
  2. parameter DIV_CLK = 9
  3. )(
  4. input clk ,
  5. input rst_n ,
  6. output wire clk_div_odd
  7. );
  8. reg [3:0] cnt_n ;
  9. reg [3:0] cnt_p ;
  10. reg clkp_odd_r ;
  11. reg clkn_odd_r ;
  12. //pos cnt
  13. always @(posedge clk ,negedge rst_n) begin
  14. if(!rst_n)
  15. cnt_p <= 1'b0;
  16. else if(cnt_p==DIV_CLK - 1)
  17. begin
  18. cnt_p <= 1'b0 ;
  19. end
  20. else
  21. cnt_p <= cnt_p +1'b1 ;
  22. end
  23. //neg cnt
  24. always @(posedge clk ,negedge rst_n) begin
  25. if(!rst_n)
  26. cnt_n <= 1'b0;
  27. else if(cnt_n == DIV_CLK - 1)
  28. begin
  29. cnt_n <= 1'b0 ;
  30. end
  31. else
  32. cnt_n <= cnt_n +1'b1 ;
  33. end
  34. //posedge clk_div
  35. always @( posedge clk ,negedge rst_n) begin
  36. if(!rst_n)
  37. clkp_odd_r <= 1'b0;
  38. else if(cnt_p == (DIV_CLK>>1) )
  39. clkp_odd_r <= 1'b0;
  40. else if(cnt_p == DIV_CLK -1)
  41. clkp_odd_r <= 1'b1;
  42. else
  43. clkp_odd_r <= clkp_odd_r ;
  44. end
  45. //negedge clk_div
  46. always @( posedge clk ,negedge rst_n) begin
  47. if(!rst_n)
  48. clkn_odd_r <= 1'b0;
  49. else if(cnt_n == (DIV_CLK>>1) )
  50. clkn_odd_r <= 1'b0;
  51. else if(cnt_n == DIV_CLK -1)
  52. clkn_odd_r <= 1'b1;
  53. else
  54. clkn_odd_r <= clkn_odd_r ;
  55. end
  56. //and
  57. assign clk_div_odd = clkp_odd_r && clkn_odd_r ;
  58. endmodule

XOP操作,2N+1奇数分频

  1. module odd_fre_xor_div #(
  2. parameter DIV_CLK = 9
  3. )(
  4. input clk ,
  5. input rst_n ,
  6. output wire clk_div_odd
  7. );
  8. reg [3:0] cnt ;
  9. reg clkp_odd_r ;
  10. reg clkn_odd_r ;
  11. //cnt
  12. always @(posedge clk ,negedge rst_n) begin
  13. if(!rst_n)
  14. cnt <= 1'b0;
  15. else if(cnt==DIV_CLK - 1)
  16. begin
  17. cnt <= 1'b0 ;
  18. end
  19. else
  20. cnt <= cnt +1'b1 ;
  21. end
  22. //posedge clk_div
  23. always @( posedge clk ,negedge rst_n) begin
  24. if(!rst_n)
  25. clkp_odd_r <= 1'b0;
  26. else if(cnt== (DIV_CLK-1)
  27. clkp_odd_r <= ~clkp_odd_r;
  28. else
  29. clkp_odd_r <= clkp_odd_r ;
  30. end
  31. //negedge clk_div
  32. always @( posedge clk ,negedge rst_n) begin
  33. if(!rst_n)
  34. clkn_odd_r <= 1'b0;
  35. else if(cnt== (DIV_CLK >>1)
  36. clkn_odd_r <= ~clkn_odd_r;
  37. else
  38. clkn_odd_r <= clkn_odd_r ;
  39. end
  40. //xor
  41. assign clk_div_odd = clkp_odd_r ^ clkn_odd_r ;
  42. endmodule

奇数分频,占空比非50%

 画出本题目的时序图,如图,可以发现,假如Clock是输入的时钟信号,Clock2是输出的50%占空比的三分频信号,那么对于计数器,Clock2实现的操作是:当采样边沿每次遇到count=0的时候进行翻转,每次遇到1的时候再次完成翻转,根据此,加上复位信号,我们即可完成RTL代码。

非50%占空比的三分频电路
  1. module f3(clk, rst_n,clk2);
  2. input clk;
  3. input rst_n;
  4. output clk2;
  5. reg clk2_r;
  6. assign clk2 = clk2_r;
  7. reg [2:0] count;
  8. parameter N = 3;
  9. always@(posedge clk or negedge rst_n)
  10. begin
  11. if(!rst_n || count == N-1)
  12. count <= 3'd0;
  13. else
  14. count <= count +1'd1;
  15. end
  16. always@(posedge clk or negedge rst_n)
  17. begin
  18. if(!rst_n)
  19. clk2_r <= 3'd0;
  20. else if (count == 3'd0 || count == 3'd1)
  21. clk2_r <= !clk2_r;
  22. else
  23. clk2_r <= clk2_r;
  24. end
  25. endmodule

 这里只需要修改N的值,即可改变分频,如N=5,同时改变count的位宽,即可实现五分频,以此类推,即可实现不要求占空比的任意分频电路

小数分频

小数分频不能精确到控制占空比,也没办法控制到精确的小数分频,而是平均频率的小数倍,小数分频涉及到奇数分频,偶数分频以及平均分布的方法

 

关键点:

完成奇偶分频,确定好分频的次数

确定分频次数后,要合理安排分频的顺序,确保平均

 Verilog实现

  1. // -----------------------------------------------------------------------------
  2. // Copyright (c) 2014-2022 All rights reserved
  3. // -----------------------------------------------------------------------------
  4. // Author : HFUT904 1320343336@qq.com
  5. // File : fre_fractional-n.v
  6. // Create : 2022-11-08 14:45:45
  7. // Revise : 2022-11-08 14:45:45
  8. // Editor : HFUT Integrated Circuit Design & Research Center
  9. // Verdion: v1.0
  10. // Description: 小数分频 8.4倍小数
  11. // -----------------------------------------------------------------------------
  12. module fre_fractional-n (
  13. #(
  14. parameter SOURCE_NUM = 84 , //Sorce clocks
  15. parameter DEST_NUM = 10 //div nums 8.4
  16. )
  17. (
  18. input rstn , //Asynchronous reset active low
  19. input clk , //Source Clock
  20. output clk_frac //fractional frequency division
  21. );
  22. parameter SOURCE_DIV = SOURCE_NUM/DEST_NUM ; //8-divisor
  23. parameter DEST_DIV = SOURCE_DIV + 1; //9-divisor
  24. parameter DIFF_ACC = SOURCE_NUM - SOURCE_DIV*DEST_NUM ;
  25. //reg
  26. reg [3:0] cnt_end_r ;
  27. reg [3:0] main_cnt ;
  28. reg clk_frac_r ;
  29. wire diff_cnt_en ;
  30. //difference counter
  31. reg [4:0] diff_cnt_r ;
  32. wire [4:0] diff_cnt ;
  33. //main_cnt
  34. always @(posedge clk or negedge rstn) begin
  35. if (!rstn) begin
  36. main_cnt <= 'b0 ;
  37. clk_frac_r <= 1'b0 ;
  38. end
  39. else if (main_cnt == cnt_end_r) begin
  40. main_cnt <= 'b0 ;
  41. clk_frac_r <= 1'b1 ;
  42. end
  43. else begin
  44. main_cnt <= main_cnt + 1'b1 ;
  45. clk_frac_r <= 1'b0 ;
  46. end
  47. end
  48. //diff_cnt
  49. always @(posedge clk or negedge rstn) begin
  50. if (!rstn) begin
  51. diff_cnt_r <= 0 ;
  52. end
  53. else if (diff_cnt_en) begin
  54. diff_cnt_r <= diff_cnt ;
  55. end
  56. end
  57. // cnt_end
  58. always @(posedge clk or negedge rstn) begin
  59. if (!rstn) begin
  60. cnt_end_r <= SOURCE_DIV-1 ;
  61. end
  62. else if (diff_cnt >= 10) begin
  63. cnt_end_r <= DEST_DIV-1 ;
  64. end
  65. else begin
  66. cnt_end_r <= SOURCE_DIV-1 ;
  67. end
  68. end
  69. //assign
  70. assign clk_frac = clk_frac_r ;
  71. assign diff_cnt_en = (main_cnt == cnt_end_r)?1'b1:1'b0 ;
  72. assign diff_cnt = diff_cnt_r >= DEST_NUM ?
  73. (diff_cnt_r -10 + DIFF_ACC)
  74. : (diff_cnt_r + DIFF_ACC) ;
  75. endmodule

 总结:

偶数分频不考虑占空比,是理想的50%

奇数分频需要考虑占空比是否50%,要求使用双边沿逻辑

小数分频涉及到奇数和偶数分频

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/519138
推荐阅读
相关标签
  

闽ICP备14008679号