FPGA学习篇——Verilog学习之分频器的实现

PS: 目前手上仍然没有板子,按照野火视频的讲解,目前我们只能做到前面六步(其实第一步设计规划也是需要看板子的硬件的,但是现在没有板子就完全与野火传授的板子一致来看)

1 设计规划及波形绘制

1.1 分频器的原理:

分频器就是把输入信号的频率成倍数的降低后再进行输出。

比如说4分频器,就是把输入信号频率降低4倍再输出,可以理解成输入4个周期对应输出1个周期:

同理,12分频器,把输入信号频率降低12倍再输出,即输入12个周期对应输出1个周期。

倍频器原理:与分频器对应的就是倍频器,它是把输入信号的频率成倍数的升高后再进行输出(即即可以理解成N倍频器就是输入1个周期对应输出N个周期)

1.2 分频器的分类:

以倍数的奇偶分成奇分频器(3,5,7,9...)+偶分频器(2,4,6,8...)

1.3 波形绘制

1.3.1偶分频器

以4分频器为例(偶数分频器),按照偶分频器的原理可以看到,输出一个周期等于输入四个周期(图中红色虚线框起来部分),如何实现呢?

还记得我们上一节实现的计数器吗?看计数器的波形图(图1),其实就是一个分频器!输入25000000个周期等于一个输出周期!因此,我们可以仿照这个思想,通过计数来实现分频!调节计数值就可形成对应的分频器!

图1

那么按照上述思想,我们使得计数器取0~3(对应输入四个周期),又因为刚好为偶数,实际计数器取0和1即可,每到1的上升沿翻转一次,得到输出信号,如下图2所示。

图2

1.3.2 奇分频器

同样,我们使用计数的原理来实现奇分频器,但这里有一个问题,以5分频器为例,计数器取0~4(对应输入五个周期),我们要使得输出在2.5周期处翻转一次(这样输出在0~4才能形成一个周期),但我们计数cnt无法记到小数,那该怎么办呢?

这里有两种实现方法:

由图3波形图可以看到,如果在2的上升沿和4的上升沿 各翻转一次,得到Out1,输出的周期占空比就不是50%,同样,在2的下降沿和4的下降沿各翻转一次,得到Out2,输出的周期占空比也不是50%

(1)但是!若Out1或上Out2(即Out1 | Out2),就可以得到Out,满足输出占空比50%的周期

(2)或者,直接看Out,使得输出在2的下降沿和4的上升沿 各翻转一次,也能得到输出波形

图3

2 代码编写

2.1 偶分频器

复制代码
module Divider_4(
    input       sys_clk,
    input       sys_rst_n,

    output reg  Out
    );

reg     cnt ;

always @(posedge sys_clk or negedge sys_rst_n) begin
    if(sys_rst_n == 0)
        cnt <= 2'd0;
    else if(cnt == 2'd1)
        cnt <= 2'd0;
    else 
        cnt <= cnt + 1;
end

always @(posedge sys_clk or negedge sys_rst_n) begin
    if(sys_rst_n == 0)
        Out <= 1'b0;
    else  if(cnt == 2'd1)
        Out <= ~Out; 
    else 
        Out <= Out;
end


endmodule

2.2 奇分频器

方法(1):

复制代码
module Divider_5(
    input       sys_clk     ,
    input       sys_rst_n   ,


    output      Out 

    );
reg     [2:0]   cnt;
reg            Out1;
reg            Out2;

always @(posedge sys_clk or negedge sys_rst_n) begin
    
    if(!sys_rst_n)
        cnt <= 3'd0; 
    else if(cnt == 3'd4)
        cnt <= 3'd0;
    else
        cnt <= cnt + 1;
end

always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        Out1 <= 1'd0;
    else if(cnt == 3'd2)
        Out1 <= ~Out1;
    else if(cnt == 3'd4)
        Out1 <= ~Out1;
    else 
        Out1 <= Out1; 
end

always @(negedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        Out2 <= 1'd0;
    else if(cnt == 3'd2)
        Out2 <= ~Out2;
    else if(cnt == 3'd4)
        Out2 <= ~Out2;
    else 
        Out2 <= Out2; 

end

assign Out = (Out1 | Out2);



endmodule

方法(2):

复制代码
module Divider_5(
    input       sys_clk     ,
    input       sys_rst_n   ,

    output  reg Out 

    );
reg     [2:0]   cnt;


always @(posedge sys_clk or negedge sys_rst_n) begin
    
    if(!sys_rst_n)
        cnt <= 3'd0; 
    else if(cnt == 3'd4)
        cnt <= 3'd0;
    else
        cnt <= cnt + 1;
end




always @(negedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        Out <= 1'b0;
    else if(cnt == 3'd2)
        Out <= 1'b1;
    else 
        Out <= Out;
end


always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        Out <= 1'b0;
    else if(cnt == 3'd4)
        Out <= 1'b0;
    else 
        Out <= Out;
end

endmodule

3 逻辑仿真及波形验证

之前我们说到tb文件相当于模拟模块的输入情况,**由于这里的4分频(偶数)和5分频(奇数)的输入都只有两个信号,并且情况一样,所以代码完全一致,**修改对应的名称即可。

以下代码以5分频的仿真为例:

复制代码
module tb_Divider_5();

reg     tb_sys_clk      ;
reg     tb_sys_rst_n    ;

wire    tb_Out          ;

initial begin
    tb_sys_clk <= 1'b0;
    tb_sys_rst_n <= 1'b0;
    #10
    tb_sys_rst_n <= 1'b1;
end

always #20 tb_sys_clk <= ~tb_sys_clk;

// output declaration of module Divider_5


Divider_5 u_Divider_5(
    .sys_clk   	(tb_sys_clk    ),
    .sys_rst_n 	(tb_sys_rst_n  ),
    .Out       	(tb_Out        )
);


endmodule

由下列波形图可以看到,仿真验证通过。


(本贴仅是个人经验,参考哔哩哔野火视频: 19-第十四讲分频器---偶分频_哔哩哔哩_bilibili20-第十五讲-分频器---奇分频_哔哩哔哩_bilibili如有侵权请联系我~)

相关推荐
通信小呆呆3 小时前
FPGA 中的 AXI 总线介绍
fpga开发
Miki Makimura3 小时前
UDP可靠性传输指南:从基础机制到KCP协议核心解析
网络·网络协议·学习·udp
少年、潜行3 小时前
IMX6ULL学习笔记_Boot和裸机篇(6)--- IMX6ULL简单SHELL以及SEGGER ES的Printf和字节对齐问题
笔记·学习·imx6ull·字节对齐·printf格式化
亮锅锅来啦3 小时前
Vivado进阶-Fpga中的mem的综合和应用
fpga开发
。TAT。3 小时前
Linux - 命令行参数与环境变量
linux·学习
喵叔哟4 小时前
6. 从0到上线:.NET 8 + ML.NET LTR 智能类目匹配实战--渐进式学习闭环:从反馈到再训练
学习·机器学习·.net
2401_831501735 小时前
Python学习之Day07-08学习(Django网页Web开发)
python·学习·django
bnsarocket5 小时前
Verilog和FPGA的自学笔记5——三八译码器(case语句与锁存器)
笔记·fpga开发·verilog·自学
JJjiangfz7 小时前
杭电 神经网络与深度学习 学习笔记
深度学习·神经网络·学习