本文主要是介绍数字电路中有关奇数偶数分频心得,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1.1偶数分频简介
实现分频一般有两个方法,一个方法是直接使用 PLL 进行分频,比如 FPGA 或者 ASIC 设计中,都可
以直接使用 PLL 进行分频,但是这种分频倍数有时候受限于 PLL 本身的特性,比如输入 100Mhz 时钟,很
多 PLL 都实现不了分频到 1Mhz 的时钟,这个就是 PLL 本身特性限制的。还有一种实现方法就是直接使用
逻辑实现,即使用代码实现分频设计。我们本节介绍的是使用代码进行设计分频器。 本节我们先看下偶数分
频设计。
偶数分频,顾名思义,是说分频后的频率和分频前的频率比例是偶数,比如 100Mhz 时钟,进行二分频
后,就是 50Mhz。
实现偶数分频可通过一个简单计数器实现,而如果需要三分频,五分频,七分频等奇数分频,一个计数
器是不够的。
偶数分频实现比较简单,假设为 N(偶数)分频,只需计数到 N/2-1,然后时钟翻转、计数器清零,如
此循环就可以得到 N(偶)分频。 举个例子,比如晶振时钟是 100Mhz 时钟,想得到一个 25Mhz 的时钟,
那么这个是一个 100/25=4 的四分频设计, 那么按照我们刚说的计数到 4/2-1=1,然后时钟翻转、计数器清零,
就可以得到一个 24Mhz 的时钟。
2.1Verilog程序设计
//file name : even_divide_8.v
//file funciton :设计一个偶数分频器实现8分频的操作
//file date :2023/4/6
//file version : 1.0version
//author : ZihangNie//***************************************************module even_divide_8(//input signal input sys_clk , //输入系统时钟input sys_rst_n , //输入复位信号//output signal output reg clk_8 //输出8分频的时钟信号) ;//常量定义
parameter WIDTH = 8 ;//寄存器定义reg [2:0] cnt ; //定义一个分频计数器//****************************************************
//*******************main code************************
//****************************************************//计数模块
always @(posedge sys_clk or negedge sys_rst_n) begin if (!sys_rst_n) begin cnt <= 3'b0 ; endelse if ( cnt == WIDTH/2-1) begin cnt <= 0 ; // 计数器满了测清零end else begin cnt <= cnt + 1'b1 ; //计数器没有计数满了则加一end
end //分频模块always @(posedge sys_clk or negedge sys_rst_n) begin if (!sys_rst_n) beginclk_8 <= 1'b0 ; endelse if(cnt == WIDTH/2 - 1) beginclk_8 <= ~clk_8 ;endelse beginclk_8 <= clk_8 ;end
end
endmodule
2.testbench 仿真
//file name : tb_even_divide_8.v
//file function : 实现八分频偶数计数器的仿真
//file version :1.0version
//file date : 2023/4/6
//Author : ZihangNie//******************************************************************`timescale 1ns/1ps //f仿真时间单位1ns,仿真精度单位1psmodule tb_even_divide_8(); // 定义仿真模块//input signal
reg sys_clk ; // 输入全局时钟
reg sys_rst_n ; //输入系统复位 //output signalwire clk_8 ; //输出八分频计数时钟//对模块进行初始化操作initial begin sys_clk = 1'b0 ;sys_rst_n = 1'b0 ;
#200sys_rst_n = 1'b1 ;endalways #10 sys_clk = ~sys_clk ; //对八分频电路模块进行例化even_divide_8 u_even_divide_8(.sys_clk(sys_clk),.sys_rst_n(sys_rst_n),.clk_8(clk_8));
endmodule
3 modlesim仿真
从仿真结果上看实现了8分频操作
4 奇数分频器操作
//file name : odd_divide_15.v
//file function : 设计一个奇数分频器,分成15份
//file version : 1.0version
//file date : 2023/4/6
//Author :ZihangNie
//****************************************************************
//function description :
/*为 N分频,需从0计数到 N-1(一共N/2个基准时钟),一直循环
设计一个对基准时钟上升沿敏感的信号,每当计数到(N-1)/2-1时,时钟翻转;计数到计数器最大值时再反转
设计一个对基准时钟下降沿敏感的信号,每当计数到(N-1)/2-1时,时钟翻转;计数到计数器最大值时再反转
将 上升沿敏感的信号和 下降沿敏感的信号相与(&&)即N分频电路*/module odd_divide_15(// input signal input sys_clk , //输入全局时钟input sys_rst_n ,// 输入复位信号// output signal output clk_15 //输出15分频时钟
) ;
//parameter 参数定义parameter N = 15 ; //定义15分频参数//register 参数定义reg [3:0] cnt ;
reg pos_clk_cnt ;
reg neg_clk_cnt ;assign clk_15 = pos_clk_cnt && neg_clk_cnt ; //******************************************main code***************************************
//******************************************************************************************
//******************************************************************************************//计数模块
always @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n) begin cnt <= 4'b0;end else if ( cnt == N - 1'b1) begincnt <= 4'b0 ; // 如果计数满了则清零endelse begincnt <= cnt + 1'b1 ; // 如果计数没有满则加一操作end
end//上升沿敏感触发信号
always @ (negedge sys_clk or negedge sys_rst_n) begin if(!sys_rst_n) begin pos_clk_cnt <= 1'b0 ;endelse if ( cnt == N/2- 1) begin pos_clk_cnt <= 1'b1;endelse if ( cnt == N-1 ) beginpos_clk_cnt <= 1'b0 ;endelse begin pos_clk_cnt <= pos_clk_cnt ;end
end//下降沿敏感触发信号always @ (posedge sys_clk or negedge sys_rst_n) begin if (!sys_rst_n ) begin neg_clk_cnt <= 1'b0 ;end else if ( cnt == N/2 -1 ) beginneg_clk_cnt <= 1'b1 ;end else if (cnt == N/2 -1 ) begin neg_clk_cnt <= 1'b0 ;end else if (cnt == N-1 ) beginneg_clk_cnt <= 1'b0;end else beginneg_clk_cnt <= neg_clk_cnt;end
endendmodule
这篇关于数字电路中有关奇数偶数分频心得的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!