当前位置:   article > 正文

【Verilog HDL实践】奇数、半整数分频实现_半整数与奇数分频器设计

半整数与奇数分频器设计

【Verilog HDL实践】奇数、半整数分频实现

使用芯片:Altera Cyclone® IV EP4CE22F17C6N FPGA
开发工具:Quartus Ⅱ
开发项目:七、设计奇数分频器、半整数分频器。

参考文章Verilog 时钟分频

奇数分频器分析

奇数分频可通过两个通过不同沿触发产生的偶数分频器或、与、异或产生
例如3分频:

clk01 01 01 01 01 01
timer111 00 00 11 00 00
timer201 10 00 01 10 00
output11 10 00 11 10 00

其中,timer1为上升沿触发,可以看到它每次在上升沿改变数值;timer2为下降沿触发;output为相或的结果。
如果想用相与, 可将timer的电平反转。

特点分析:
timer2落后timer1一个时钟电平长度,即半个时钟周期。
timer1和timer2周期长度与分频后结果一致,只是占空比不同
当使用相或时,timer1周期内处于低电平的长度等于分频数-1。因为timer2刚好落后一个小电平长度,这样相或即等效于原有基础+1。

代码展示
module Divider(clk, divider_3);
	input clk;
	output divider_3;
	
	parameter cycle_one = 2'b11; //3分频
	parameter duty_zero = (cycle_one+1)/2; //电平为低周期为2 则低:高=2:1
	
	reg[3:0] timer1=4'b0, timer2=4'b0;
	reg timer_out1=1'b0, timer_out2=1'b1;
	
	assign divider_3 = timer_out1|timer_out2;
	
	always@(posedge clk) begin
		timer1 <= timer1+1;
		if(timer1 >= cycle_one-1)
			timer1 <= 4'b0;
		if(timer1 < duty_zero)
			timer_out1 <= 1'b0;
		else
			timer_out1 <= 1'b1;
	end
	
	always@(negedge clk) begin
		if(timer2 < cycle_one-1)
			timer2 <= timer2+1;
		else
			timer2 <= 4'b0;
		if(timer2 < duty_zero)
			timer_out2 <= 1'b0;
		else
			timer_out2 <= 1'b1;
	end
	
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

我看过一些其他人写的代码,如上边推荐链接内的代码,他们只用了一个计数器,综合效果可能更佳。(当时没想到 唉)

时序测试

三分频时序测试
其中第一行为输入时钟源
第二行为三分频输出
第三行为其中一个计数器的电平变化,可以看到 高电平:低电平=1:2。

半整数分频器分析

利用时钟的双边沿逻辑,可以对时钟进行半整数的分频。但是无论怎么调整,半整数分频的占空比不可能是 50%。
那该怎么办呢?可以参考一下最前边链接里的文章(哭,我没有自己的见解

特点分析:
只需要两个定时器,定时器在2*分频倍数周期内可分为两个阶段。
前半周期 timer1优先timer2一个电平,后半周期落后一个电平。

代码展示
module Half_Divider(rstn, clk, clk_div9p5);
	input rstn, clk;
	output clk_div9p5;
 
   parameter MUL2_DIV_CLK = 5;
	parameter DIV_HIGH = (MUL2_DIV_CLK>6)?(MUL2_DIV_CLK-3)/4:1; //最小为2.5
	
   reg [4:0] cnt = 5'b0;
   reg clk_ave_r ;
	reg clk_adjust_r ;
	
	assign clk_div9p5 = clk_adjust_r | clk_ave_r;
	
	always @(posedge clk or negedge rstn) begin
      if (!rstn)
         cnt    <= 'b0 ;
      else if (cnt == MUL2_DIV_CLK-1)
         cnt    <= 'b0 ;
      else
         cnt    <= cnt + 1'b1 ;
   end

   
   always @(posedge clk or negedge rstn) begin
      if (!rstn)
         clk_ave_r <= 1'b0 ;
      else if (cnt >= 0 & cnt <= DIV_HIGH-1)
         clk_ave_r <= 1 ;
      else if (cnt >= (MUL2_DIV_CLK/2+1) & cnt <= (MUL2_DIV_CLK/2+1)+DIV_HIGH-1)
         clk_ave_r <= 1 ;
      else
         clk_ave_r <= 0 ;
   end

   always @(negedge clk or negedge rstn) begin
      if (!rstn)
         clk_adjust_r <= 1'b0 ;
      else if (cnt >= 1 & cnt <= DIV_HIGH)
         clk_adjust_r <= 1 ;
      else if (cnt >= (MUL2_DIV_CLK/2+1) & cnt <= (MUL2_DIV_CLK/2+1)+DIV_HIGH-1)
         clk_adjust_r <= 1 ;
      else
         clk_adjust_r <= 0 ;
   end
	
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

这份代码是仿照上边链接写的,当时以为3.5分频可以实现等占空比,想了想觉得 绝无可能 ,嗯,然后就去网上转了一圈,得思路,略改之。

时序测试

3.5分频时序测试
正如之前所说的,它并不是等占空比的。

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

闽ICP备14008679号