FPGA-分频器

                               FPGA-分频器

当给你一个时钟,你觉得频率太快了,想进行就分频,就会使用到我们的分频器。非常简单且实用,且写的无聊。
写给出总体代码
module div_frequency(

input clk_i,
input rst_n_i,
output div2_o,
output div3_o,
output div4_o,
output div8_o
);

reg div2_o_r;
always@(posedge clk_i or negedge rst_n_i)
begin
if(!rst_n_i)
div2_o_r<=1’b0;
else
div2_o_r<=~div2_o_r;
end

reg [1:0] div_cnt1;
always@(posedge clk_i or negedge rst_n_i)
begin
if(!rst_n_i)
div_cnt1<=2’b00;
else
div_cnt1<=div_cnt1+1’b1;
end

reg div4_o_r;
reg div8_o_r;

always@(posedge clk_i or negedge rst_n_i)
begin
if(!rst_n_i)
div4_o_r<=1’b0;
else if(div_cnt12’b00 || div_cnt12’b10)
div4_o_r<=~div4_o_r;
else
div4_o_r<=div4_o_r;
end

always@(posedge clk_i or negedge rst_n_i)
begin
if(!rst_n_i)
div8_o_r<=1’b0;
else if(div_cnt1==2’b00)
div8_o_r<=~div8_o_r;
else
div8_o_r<=div8_o_r;
end

reg [1:0] pos_cnt;
reg [1:0] neg_cnt;
always@(posedge div2_o_r or negedge rst_n_i)
begin
if(!rst_n_i)
pos_cnt<=2’b00;
else if(pos_cnt==2’d2)
pos_cnt<=2’b00;
else
pos_cnt<=pos_cnt+1’b1;
end

always@(negedge div2_o_r or negedge rst_n_i)
begin
if(!rst_n_i)
neg_cnt<=2’b00;
else if(neg_cnt==2’d2)
neg_cnt<=2’b00;
else
neg_cnt<=neg_cnt+1’b1;
end

reg div3_o_r0;
reg div3_o_r1;
always@(posedge div2_o_r or negedge rst_n_i)
begin
if(!rst_n_i)
div3_o_r0<=1’b0;
else if(pos_cnt<2’d1)
div3_o_r0<=1’b1;
else
div3_o_r0<=1’b0;
end

always@(negedge div2_o_r or negedge rst_n_i)
begin
if(!rst_n_i)
div3_o_r1<=1’b0;
else if(neg_cnt<2’d1)
div3_o_r1<=1’b1;
else
div3_o_r1<=1’b0;
end
reg div2hz_o_r;

assign div2_o=div2_o_r;
assign div3_o=div3_o_r0 | div3_o_r1;
assign div4_o=div4_o_r;
assign div8_o=div8_o_r;

endmodule

一,2分频部分
reg div2_o_r;
always@(posedge clk_i or negedge rst_n_i)
begin
if(!rst_n_i)
div2_o_r<=1’b0;
else
div2_o_r<=~div2_o_r;
end
我们设输入时钟的周期为T,
由上面代码可知,每当输入时钟上升沿的时候,我们就会翻转。输入时钟一个周期只有一个上升沿,那么也就意味着2分频高低电平持续时间是一个输入时钟周期T,则2分频的周期就是2T。达到了分频的效果。
(明明很简单,写的却很罗里吧嗦,还没图

二,四分频
有了上面2分频思想,四分频不是有手就行
我们只需要将always@(posedge clk_i or negedge rst_n_i),这个里面 clk_i换成我们已经写好的2分频,四分频就出来了。那八分频不也简单的狠。
但是如果每次都那么一个一个的写,不是很麻烦吗
那么我就加个计数器
reg [1:0] div_cnt1;
always@(posedge clk_i or negedge rst_n_i)
begin
if(!rst_n_i)
div_cnt1<=2’b00;
else
div_cnt1<=div_cnt1+1’b1;
end

reg div4_o_r;
always@(posedge clk_i or negedge rst_n_i)
begin
if(!rst_n_i)
div4_o_r<=1’b0;
else if(div_cnt12’b00 || div_cnt12’b10)
div4_o_r<=~div4_o_r;
else
div4_o_r<=div4_o_r;
end
每当输入时钟上升沿,计数器开始计数,也就是每过T,我们开始计数,没过2T我们来翻转电平。那么周期为4T。那么
其他偶数分频不是有手就行。
三,奇数分频
我们以3分频为例,为什么呢?(因为上面写了)

reg [1:0] pos_cnt;
reg [1:0] neg_cnt;
always@(posedge div2_o_r or negedge rst_n_i)
begin
if(!rst_n_i)
pos_cnt<=2’b00;
else if(pos_cnt==2’d2)
pos_cnt<=2’b00;
else
pos_cnt<=pos_cnt+1’b1;
end

always@(negedge div2_o_r or negedge rst_n_i)
begin
if(!rst_n_i)
neg_cnt<=2’b00;
else if(neg_cnt==2’d2)
neg_cnt<=2’b00;
else
neg_cnt<=neg_cnt+1’b1;
end

reg div3_o_r0;
reg div3_o_r1;
always@(posedge div2_o_r or negedge rst_n_i)
begin
if(!rst_n_i)
div3_o_r0<=1’b0;
else if(pos_cnt<2’d1)
div3_o_r0<=1’b1;
else
div3_o_r0<=1’b0;
end

always@(negedge div2_o_r or negedge rst_n_i)
begin
if(!rst_n_i)
div3_o_r1<=1’b0;
else if(neg_cnt<2’d1)
div3_o_r1<=1’b1;
else
div3_o_r1<=1’b0;
end
assign div3_o=div3_o_r0 | div3_o_r1;
看了代码,我们三分频是基于2分频时钟,有两个计时器 pos_cnt;neg_cnt;
由代码我们可以看出,他们分别从二分频的上升沿和下降沿开始从0到2计数(显然时间间隔为T
div3_o_r0 和 div3_o_r1在pos_cnt;neg_cnt为0的时刻为1,在1,2时间为0。
则div3_o当出现0时为1,无0则为1
从0计数到2,时间为6T,则每个数字为持续时间为2T
我们将0用00计,则每个数字持续时间为T

pos_cnt001122001122001122001122
neg_cnt200112200112200112200112
div3_o1110001110001110001

(为什么不画个图?显然不会,而且图多了,反而不好看)
显然其周期为6T,是对2分频时钟进行三分频。(以此内推)

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值