赞
踩
使用芯片:Altera Cyclone® IV EP4CE22F17C6N FPGA
开发工具:Quartus Ⅱ
开发项目:七、设计奇数分频器、半整数分频器。
参考文章Verilog 时钟分频
奇数分频可通过两个通过不同沿触发产生的偶数分频器或、与、异或产生
例如3分频:
clk | 01 01 01 01 01 01 |
---|---|
timer1 | 11 00 00 11 00 00 |
timer2 | 01 10 00 01 10 00 |
output | 11 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分频可以实现等占空比,想了想觉得 绝无可能 ,嗯,然后就去网上转了一圈,得思路,略改之。
正如之前所说的,它并不是等占空比的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。