【无标题】Verilog语言实现任意奇偶分频器(奇偶均可实现)

文章介绍了FPGA中分频器的作用,它是如何通过触发器和计数器来降低时钟信号频率的。接着,详细阐述了如何使用Verilog语言设计一个七倍分频器,包括两个always块分别检测时钟的上升沿和下降沿,以及如何通过中间时钟信号实现分频。最后,给出了一个五分频器的Verilog代码示例。
摘要由CSDN通过智能技术生成

一、分频器
在FPGA(可编程逻辑门阵列)中,分频器是一种用于将时钟信号的频率降低的电路或模块。它可以根据输入的时钟信号生成一个较低频率的输出时钟信号。

常见的分频器可以按照固定比例来进行分频,例如将输入时钟频率除以2、除以4等。因此,如果输入时钟信号的频率为100 MHz,并且使用一个除以2的分频器,那么输出时钟信号的频率将为50 MHz。这样就可以将高频的时钟信号降低到所需的较低频率,以满足电路设计中对时序和性能的要求。

FPGA中的分频器一般由触发器和计数器组成。触发器用于产生时钟信号的边沿触发,计数器用于对触发器的触发计数,并在达到一定计数值时生成输出时钟信号。通过调整计数器的初值和计数步长,可以实现不同的分频比例。

分频器在FPGA中非常常用,可以在时序控制、数据采样、状态机设计等方面起到重要作用。它可以帮助实现时钟域划分、减少功耗、减小时序延迟等功能。

二、Verilog实现任意倍分频器
2.1、Verilog源码
由于我们无法在一个always块中同时检测时钟的上升沿和下降沿,因此我们需要两个always块分别进行检测。同时博主引进了两个中间时钟信号分别是根据始终上升沿反转的clk_p,以及根据时钟下降沿进行反转的clk_n。

以本题为例,我们设计一个七倍分频器,因此我们需要在数到七个半个系统时钟周期时对输出的clk_out进行信号反转,因此对于计数器,我们只需要计数到7的一半,也就是3。

由于上升沿与下降沿相隔了半个时钟周期,因此我们可以通过对两个中间时钟信号想与从而获得相当于系统时钟周期的七个半个周期时钟信号。

而对于偶数倍分频器,相信已经大家十分熟悉,只需要计数时钟上升沿进行翻转即可

程序如下:(法1,五分频)

*********************************************************************************/
//---------<模块及端口声名>------------------------------------------------------
module 5div#(parameter N = 5)(  //分频系数,填入几代表数到几输出的时钟信号就要翻转一次
    input   wire     clk        , //系统时钟
    input   wire     rst_n      , //系统复位

    output  wire     clk_out     //分频时钟
);

reg     [N:0]   cnt_p           ; //时钟上升沿计数寄存器,计满信号反转
reg     [N:0]   cnt_n           ; //时钟下降沿计数寄存器,计满信号反转
reg             clk_p           ; //对时钟上升沿敏感的时钟信号
reg             clk_n           ; //对时钟下降沿敏感的时钟信号
//计数器加一条件
wire				add_cnt_p	;
wire				end_cnt_p	; 

wire				add_cnt_n	;
wire				end_cnt_n	;

//时钟上升沿敏感计数器
always @(posedge clk or negedge rst_n)begin 
   if(!rst_n)begin
        cnt_p <= 1'd0;
    end 
    else if(add_cnt_p)begin 
        if(end_cnt_p)begin 
            cnt_p <= 1'd0;
        end
        else begin 
            cnt_p <= cnt_p + 1'b1;
        end 
    end
end 

assign add_cnt_p = 1'b1;
assign end_cnt_p = add_cnt_p && cnt_p == N - 1'b1;
//对时钟上升沿敏感的信号反转                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        clk_p <= 1'b0;
    end
    else if(cnt_n <= (N >> 1))begin
        clk_p <= 1'b1;
    end
    else begin
        clk_p <= 1'b0;
    end
end
//时钟下降沿敏感计数器
always @(posedge clk or negedge rst_n)begin 
   if(!rst_n)begin
        cnt_n <= 'd0;
    end 
    else if(add_cnt_n)begin 
        if(end_cnt_n)begin 
            cnt_n <= 'd0;
        end
        else begin 
            cnt_n <= cnt_n + 1'b1;
        end 
    end
end 

assign add_cnt_n = 1'b1;
assign end_cnt_n = add_cnt_n && cnt_n == N - 1'b1;

//对时钟下降沿敏感的输出信号
always@(negedge clk or negedge rst_n)begin
    if(!rst_n)begin
        clk_n <= 1'b0;
    end
    else if(cnt_p <= (N >> 1))begin
        clk_n <= 1'b1;
    end
    else begin
        clk_n <= 1'b0;
    end
end

assign clk_out = (N==1) ? clk_p : N[0] ? (clk_p&clk_n) : clk_p;//在二进制中,奇数的第一位是1,偶数的第一位是0;
                                                               //N=1的情况,clk不变;N大于1,判断奇数偶数
                                                               //偶数的情况直接输出上升沿时的输出时钟
                                                               //奇数,则输出clk_p&clk_n;
                                                               //N[0]等效于N[0] == 1
                                                       
endmodule                         

 测试代


`timescale 1ns/1ns
module tb#(parameter N = 5)();
//激励信号定义
reg         clk         ;
reg         rst_n       ;
wire        clk_out     ; 
//模块例化
5div #(.N(N)) 5div_u(
    .clk       (clk    ),
    .rst_n     (rst_n  ),
    
    .clk_out   (clk_out)
);
//产生时钟	
always #10 clk = ~clk;
//产生激励
initial begin
    clk = 1'b0;
    rst_n = 1'b1;
    #20;
    rst_n = 1'b0;
    #20;
    rst_n = 1'b1;
    #1000;
    $stop;
end


endmodule

法二:

1、对端口说明和使用计数器

2、偶数分频器

3、两个奇数倍分频信号,两个奇数倍信号相获得到奇数分频器

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值