任意小数分频

任意小数分频

题目描述
请设计一个可以实现任意小数分频的时钟分频器,比如说8.7分频的时钟信号
注意rst为低电平复位
提示:
其实本质上是一个简单的数学问题,即如何使用最小公倍数得到时钟周期的分别频比。
设小数为nn,此处以8.7倍分频的时钟周期为例。
首先,由于不能在硬件上进行小数的运算(比如2.1个时钟这种是不现实的,也不存在3.3个寄存器),小数分频不能做到分频后每个时钟周期都是源时钟的nn倍,也无法实现占空比为1/2,因此,考虑小数分频,其实现方式应当为53个clkout时钟周期是10个clkin时钟周期的8.7倍。

信号示意图:
在这里插入图片描述
题目解读
其实本质上是一个简单的数学问题,即如何使用最小公倍数得到时钟周期的分别频比。
设小数为nn,此处以8.7倍分频的时钟周期为例。

首先,由于不能在硬件上进行小数的运算(比如2.1个时钟这种是不现实的,也不存在3.3个寄存器),小数分频不能做到分频后每个时钟周期都是源时钟的nn倍,也无法实现占空比为1/2,因此,考虑小数分频,其实现方式应当为87个clkout时钟周期是10个clkin时钟周期的8.7倍。

所以很简单,根据提示,我们可以进行如下假设:首先设置有两个整数分频电路,一个是奇数一个是偶数,设其分频比为a和b,然后其分别的时钟占N/M个周期。则我们可以得到:
aN+bM = 87
N+M = 10
如果使用 8 和 9分频,则有:
8N+9M = 87
N+M = 10
因此 M为7, N为3。

具体步骤:
1)设计一个计数次数87的计数器,即0-86
2)分别生成8分频和9分频的计数器,计数次数分别为0-6和0-2
3)输出波形根据总计数器和8、9分频计数器的数值控制输出脉冲翻转

`timescale 1ns/1ns


module div_M_N(
 input  wire clk_in,
 input  wire rst,
 output wire clk_out
);
parameter M_N = 8'd87; 
parameter c89 = 8'd24; // 8/9时钟切换点
parameter div_e = 5'd8; //偶数周期
parameter div_o = 5'd9; //奇数周期

reg [6:0] cnt;
reg [3:0] cnt_e;
reg [3:0] cnt_o;
reg clk_MN;
assign clk_out = clk_MN;

//总计数器
always @(posedge clk_in or negedge rst) begin
 if(!rst)
  cnt <= 6'b0;
 else begin
  if(cnt == M_N - 1'b1)
   cnt <= 6'b0;
  else
   cnt <= cnt + 1'b1;
 end 
end 


always @(posedge clk_in or negedge rst) begin 
 if(!rst) begin
  cnt_e <= 4'b0;
  cnt_o <= 4'b0;
 end 
 else if(cnt<=c89-1'b1) begin
  cnt_o <= 4'd0;
  if(cnt_e == div_e - 1'b1)
   cnt_e <= 4'd0;
  else
   cnt_e <= cnt_e + 1'b1;
 end 
 else if(cnt>c89-1'b1) begin
  cnt_e <= 4'd0;
  if(cnt_o == div_o - 1'b1)
   cnt_o <= 4'd0;
  else
   cnt_o <= cnt_o + 1'b1;
 end
end

always @(posedge clk_in or negedge rst) begin
 if(!rst)
  clk_MN <= 1'b0;
 else begin
 
	if(cnt<c89) begin
	  if(cnt_e == 4'd0 || cnt_e == div_e/2)
	   clk_MN <= ~clk_MN;
	end
	if(cnt>=c89) begin
	  if(cnt_o == 4'd0 || cnt_o == (div_o - 1'b1)/2)
	   clk_MN <= ~clk_MN;
	end
 end 
end


endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

傻童:CPU

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

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

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

打赏作者

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

抵扣说明:

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

余额充值