我是靠谱客的博主 从容飞鸟,最近开发中收集的这篇文章主要介绍FPGA试题练习--------任意整数分频器设计,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一.设计目标
对输入时钟信号进行1~N分频。
二.设计思路
从分频数来看,整个设计可分为三部分:1分频、奇数分频、偶数分频。
①1分频:可直接将输入时钟信号进行输出。
②偶数分频:使用一个计数器在上升沿或者下降沿进行计数,计数到N/2时,分频时钟进行跳变。
③奇数分频:由于奇数分频会在输入时钟信号的上升沿或者下降沿进行跳变输出,所以采用两个计数分别对上升沿和下降沿进行计数。
在这里插入图片描述
设计原理如上图所示,将奇数N分成三个部分,前(N-1)/2个Tclk、中间一个Tclk、后(N-1)/2个Tclk。从0时刻开始,在时钟下降沿时clk_n置高,在到达中间T时刻时进行置低;同理从0时刻开始,在时钟上升沿时clk_p置高,在到达中间T时刻时进行置低。对两个信号进行整合变得到所需分频时钟,即clk_p或上clk_n的值为clk_div。
完成对这三种情况进行编写代码,再整合到一起,框图如下:
在这里插入图片描述
控制模块主要协调三种分频情况,当DIV==奇数时,奇数分频模块工作,偶数分频模块失能;反之同理。选通信号根据DIV的值不同从而选通对应模块。
三.设计代码
①奇数分频

module odd_div(
clk,
rst,
enable,
div_in,
div_clk
);
input clk;
input rst;
input[7:0] div_in;
input enable;
output div_clk;
wire div_clk;
reg [7:0]cnt_p,cnt_n;
reg clk_p,clk_n;
always@(posedge clk or negedge rst)
begin
    if(!rst)
    begin
        clk_p <= 0;
        cnt_p <= 1;
    end
    else if(enable)
    begin
        if(cnt_p>=div_in)cnt_p <= 1;
        else cnt_p <= cnt_p + 1;
        
        if(cnt_p  == 1)clk_p <= ~clk_p;
        else if(cnt_p == (div_in>>1) + 1 )clk_p <= ~clk_p;
        else clk_p <= clk_p;        
    end
    else
    begin
        cnt_p <= 1;
        clk_p <= 0;
    end
end
always@(negedge clk or negedge rst)
begin
    if(!rst)
    begin
        cnt_n <= 1;
        clk_n <= 0;
    end
    else if(enable)
    begin
        if(cnt_n>=div_in)cnt_n <= 1;
        else cnt_n <= cnt_n + 1;
        
        if(cnt_n  == 1)clk_n <= ~clk_n;
        else if(cnt_n == (div_in>>1) + 1 )clk_n <= ~clk_n;
        else clk_n <= clk_n;
    end
    else
    begin
        cnt_n <= 1;
        clk_n <= 0;
    end
end
assign div_clk  = clk_n | clk_p;

endmodule

②偶数分频

module even_div(
clk,
rst,
enable,
div_in,
div_clk
);
input clk;
input rst;
input[7:0] div_in;
input enable;
output div_clk;
reg div_clk;
reg[7:0]cnt;
always@(posedge clk or negedge rst)
begin
    if(!rst)
    begin
        cnt <= 0;
        div_clk<=0;
    end
    else if(enable)
    begin
        if(cnt == div_in>>1)
        begin
            cnt <= 1;
            div_clk <= ~div_clk ;
        end
        else if(cnt == div_in)
        begin
            cnt <= cnt + 1;
            div_clk <= ~div_clk ;
        end
        else
        begin
            cnt <= cnt + 1;
            div_clk <= div_clk;
        end
    end
    else
    begin
        cnt <= 0;
        div_clk <= 0;
    end
end
endmodule

③控制

module control(
clk,
rst,
div,
odd_en,
out_div,
even_en,
clk_1,
sel
);
input clk;
input rst;
input [7:0]div;
output [7:0]out_div;
output odd_en;
output even_en;
output clk_1;
output [1:0]sel;

reg odd_en;
wire [7:0]out_div;
reg even_en;
wire clk_1;
wire [1:0]sel;
assign out_div = div;
assign sel   = (div==1)?( 0  ) : ( (div[0]==1)? 1 : 2 );
assign clk_1 = (div==1)?(clk ) : ( 0 );

reg[7:0]temp_div,temp_div2;
always@(posedge clk)
begin
    temp_div <= div;
    temp_div2 <= temp_div;
    if(div != temp_div2)
    begin
        odd_en <= 0;
        even_en <= 0;
    end
    else
    begin
        if(div[0]==1)
        begin        
            odd_en <= 1;
            even_en <= 0;
        end
        else
        begin
            odd_en <= 0;
            even_en <= 1;
        end
    end
end

endmodule

④三选一

module selet(
clk_1,
clk_odd,
clk_even,
sel,
clk_out
);
input clk_1;
input clk_odd;
input clk_even;
input [1:0]sel;
output clk_out;

wire clk_out;

assign clk_out= (sel==0) ? (clk_1) : ( (sel==1) ? clk_odd : clk_even);
endmodule

⑤顶层

module top(
clk,
rst,
div,
div_clk
);
input clk;
input rst;
input[7:0]div;
output div_clk;

wire div_clk;

wire clk;
wire rst;
wire [7:0]div;
wire [7:0]out_div;
wire odd_en;
wire even_en;
wire clk_1;
wire [1:0]sel;

control u0(
.clk(clk),
.rst(rst),
.div(div),
.out_div(out_div),
.odd_en(odd_en),
.even_en(even_en),
.clk_1(clk_1),
.sel(sel)
);
wire odd_clk;
odd_div u1(
.clk(clk),
.rst(rst),
.enable(odd_en),
.div_in(div),
.div_clk(odd_clk)
);
wire even_clk;
even_div u2(
.clk(clk),
.rst(rst),
.enable(even_en),
.div_in(div),
.div_clk(even_clk)
);

selet u3(
.clk_1(clk_1),
.clk_odd(odd_clk),
.clk_even(even_clk),
.sel(sel),
.clk_out(div_clk)
);

endmodule

⑥仿真文件

module simulation(
);
reg clk;
reg rst;
reg[7:0] div_in;
wire div_clk;
initial
begin
#0
    clk=0;
    rst=0;
    div_in=1;
#300
    rst=1;    
#1000
    while(1)
    begin
#500
    div_in = div_in + 1;        
    end   
end

top u0(
.clk(clk),
.rst(rst),
.div(div_in),
.div_clk(div_clk)
);
always #5 clk=~clk;
endmodule

四.结果仿真
在这里插入图片描述
在这里插入图片描述
局部放大图
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
从时序仿真可以看出,输出分频时钟符合设计。

最后

以上就是从容飞鸟为你收集整理的FPGA试题练习--------任意整数分频器设计的全部内容,希望文章能够帮你解决FPGA试题练习--------任意整数分频器设计所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部