【Verilog HDL】分频器

简介

分频器是用的最广的一种FPGA电路了,我最初使用的是crazybingo的一个任意分频器,可以实现高精度任意分频的一个通用模块,他的思想在于首先指定计数器的位宽比如32位,那么这个计数器的最大值就是2^32=4294967296。
假设系统时钟为50MHz,那么假如要想实现输出频率为fout,那么可以使用的频率控制字为:
在这里插入图片描述
那么设计计数器在每个时钟上升沿累加的值为K,当计数值为2^31时,clkout=1;否则clkout=0.最终即可以实现任意频率的输出,精度的计算方法为当K=1时,可以得到clkout=0.0116415321826934814453125Hz,也即是说可以输出的最小频率为0.011Hz。

偶数分频

最简单,要想得到分频系数为N的频率输出,设定一个计数器,这个计数器从零开始加1,当加到N/2-1时计数器清零,或者clkout翻转,以此循环,即可实现偶数倍分频。

module Freq_Even_Div(clk,clkout,rst);
parameter value=6; //更改value为分频值
input wire clk,rst;
output reg clkout;
reg [3:0] q; //更改计数值q的位数,使得q位数所允许的最大值>=value/2。
always @(posedge clk or posedge rst) begin
	if(rst)begin
		q<=0;
		clkout<=0;
	end
	elseif(q>=(value/2)) begin
		q=0; 
		clkout=~clkout;
	end
	else
		q<=q+1;
end
endmodule

奇数分频

1.分频系数为N,占总比不确定:以三(N)分频为例,上升沿触发计数,计数器计数到1(N-1)/2时输出时钟翻转,计数到2(N-1)时再次翻转.代码为产生1/11占空比为十一分频时钟:在计数值为9和10时均反转时钟,是产生抽样脉冲的有效方法:

always @(posedge clk or posedge rst) begin
              if(rst)begin   //复位
                     cnt<=0;
                     clk_div11<=0;
              end
              elseif(cnt==9) begin
                     clk_div11<=~clk_div11;   //时钟翻转
                     cnt<=cnt+1;    //继续计数
              end
              elseif(cnt==10) begin
                     clk_div11<=~clk_div11;   //时钟翻转
                     cnt<=0;    //计数清零
              end
              else
                     cnt<=cnt+1;
       end

2.占空比50% ,则可以在上面的基础上,加上一个下降沿触发计数,然后将上升沿和下降沿产生的时钟进行相或运算,即可得到奇数分频输出。

分频系数 N=3
	   reg clk1;
       reg[1:0]cnt1;
      always@(posedge clk or posedge rst) begin
              if(rst)begin   //复位
                     cnt1<=0;
                     clk1<=0;
              end
              elseif(cnt1==1) begin    //(N-1)/2
                     clk1<=~clk1;     //时钟翻转
                     cnt1<=cnt1+1;    //继续计数
              end
              elseif(cnt1==2) begin  //N-1
                     clk1<=~clk1;   //时钟翻转
                     cnt1<=0;     //计数清零
              end
              else
                     cnt1<=cnt1+1;
       end

       reg clk2;
       reg[1:0]cnt2;
      always@(negedge clk or posedge rst) begin
              if(rst)begin   //复位
                     cnt2<=0;
                     clk2<=0;
              end
              elseif(cnt2==1) begin    //(N-1)/2
                     clk2<=~clk2;     //时钟翻转
                     cnt2<=cnt2+1;    //继续计数
              end
              elseif(cnt2==2) begin  //N-1
                     clk2<=~clk2;   //时钟翻转
                     cnt2<=0;      //计数清零
              end
              else
                    cnt2<=cnt2+1;
       end

             assign clk_div3=clk1 | clk2;  //或运算

仿真电路、波形图
在这里插入图片描述在这里插入图片描述

  • 6
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

炼金怪z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值