【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。

半整数分频器分析

利用时钟的双边沿逻辑,可以对时钟进行半整数的分频。但是无论怎么调整,半整数分频的占空比不可能是 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

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

时序测试

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值