数字电路中有关奇数偶数分频心得

文章介绍了如何使用Verilog编程语言设计偶数和奇数分频器。首先讲解了偶数分频的概念,如四分频,可以通过计数器简单实现。接着展示了一个8分频的Verilog程序设计,当计数到一半时翻转时钟。然后,文章提供了15分频器的设计,它结合了上升沿和下降沿敏感的信号来生成分频时钟。
摘要由CSDN通过智能技术生成

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 ; 
	end
	else 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) begin
        clk_8 <= 1'b0 ; 
    end
	else if(cnt == WIDTH/2 - 1) begin
	    clk_8 <=  ~clk_8 ;
	end
	else begin
	    clk_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,仿真精度单位1ps

module tb_even_divide_8(); // 定义仿真模块

//input signal 
reg                  sys_clk ; // 输入全局时钟
reg                  sys_rst_n ; //输入系统复位  

//output signal

wire                 clk_8 ; //输出八分频计数时钟

//对模块进行初始化操作

initial begin 
    sys_clk = 1'b0 ;
	sys_rst_n = 1'b0 ;
#200
    sys_rst_n = 1'b1 ;

end

always #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) begin
    if (!sys_rst_n) begin 
	   cnt <= 4'b0;
	end 
	else if ( cnt == N - 1'b1) begin
	    cnt <= 4'b0 ; // 如果计数满了则清零
	end
	else  begin
	    cnt <= 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 ;
	 end
	 else if ( cnt == N/2- 1) begin 
	     pos_clk_cnt <= 1'b1;
	 end
	 else if ( cnt == N-1 ) begin
	     pos_clk_cnt <= 1'b0 ;
     end
	 else 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 ) begin
	    neg_clk_cnt <= 1'b1 ;
	end 
	else if (cnt ==  N/2 -1 ) begin 
	    neg_clk_cnt <= 1'b0 ;
	end 
	else if (cnt == N-1 ) begin
	    neg_clk_cnt <= 1'b0;
	end 
	else begin
	    neg_clk_cnt <= neg_clk_cnt;
	end
end

endmodule 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值