奇、偶、小数时钟分频_verilog

1、偶分频

举例:将100MHz时钟信号4分频成25MHz。
创建一个计数值为0-3的循环计数器,时钟上升沿,当计数值小于2的时候置为高电平,大于等于2的时候置为低电平,即可得到一个4分频后、占空比为50%的时钟信号。
示意图

代码段

`timescale 1ns/1ps

//实现一个4分频,也就是将100MHz时钟信号4分频成25MHz
module vlg_design(
  input clk,					//100MHz
  input rst_n,

  output reg div_clk	//25MHz
);

  //计数器,从0计到3
  reg [2:0] cnt;
  localparam CNT_MAX = 4;

  always @(posedge clk or negedge rst_n)	
  if(!rst_n)
    cnt <= 'b0;
  else if(cnt < (CNT_MAX - 1'b1))
    cnt <= cnt + 1'b1;
  else
    cnt <= 'b0;

  //偶分频
  localparam DIV_CNT = 2;

  always @(posedge clk or negedge rst_n)
  if(!rst_n)
    div_clk <= 'b0;
  else if(cnt < DIV_CNT)
    div_clk <= 1'b1;
  else
    div_clk <= 'b0;

endmodule

仿真图

2、奇分频

举例:将100MHz时钟信号5分频成20MHz。
创建一个计数值为0-4的循环计数器,时钟上升沿,当计数值小于2的时候置为高电平,大于等于2的时候置为低电平,即可得到clk_1。时钟下降沿,当计数值小于2的时候置为高电平,大于等于2的时候置为低电平,即可得到clk_2。将clk_1和clk_2相或即可得到占空比为50%的奇分频信号。
示意图

代码段

`timescale 1ns/1ps

//实现一个5分频,也就是将100MHz时钟信号5分频成20MHz
module vlg_design(
	input clk,		//100MHz
	input rst_n,
	
	output div_clk	//20MHz
    );

//计数器,从0计到4
reg [2:0] cnt;
localparam CNT_MAX = 5;

always @(posedge clk or negedge rst_n)	
	if(!rst_n)
		cnt <= 'b0;
	else if(cnt < (CNT_MAX - 1'b1))
		cnt <= cnt + 1'b1;
	else
		cnt <= 'b0;
		
//奇分频,需要用2个寄存器相与得到输出时钟
reg clk_1;
reg clk_2;
localparam DIV_CNT = 2;

always @(posedge clk or negedge rst_n)
	if(!rst_n)
		clk_1 <= 'b0;
	else if(cnt < DIV_CNT)
		clk_1 <= 1'b1;
	else
		clk_1 <= 'b0;
		
always @(negedge clk or negedge rst_n)
	if(!rst_n)
		clk_2 <= 'b0;
	else if(cnt < DIV_CNT)
		clk_2 <= 1'b1;
	else
		clk_2 <= 'b0;

assign div_clk = clk_1 | clk_2;

endmodule

仿真图

3、小数分频(拼接法)

示意图

代码段

`timescale 1ns/1ps

//实现一个12.5分频,也就是将100MHz时钟信号12.5分频成8MHz
module vlg_design(
	input clk,		//100MHz
	input rst_n,
	
	output div_clk	//8MHz
    );
	/*
	12 < 12.5 <13
	
	x + y = 10
	12x + 13y = 125
	
	x = y = 5
	*/
    parameter M_N = 8'd125;
    parameter div_point = 8'd60;//时钟切换点
    parameter div_e = 5'd12;		//偶数周期
    parameter div_o = 5'd13;		//奇数周期

		reg [3:0] clk_cnt;	//用于产生分频输出。当div_flag==0时,计数最大值是div_e-1;
												//当div_flag==1时,计数最大值是div_o-1。
    reg [7:0] cyc_cnt;	//对clk_in进行计数,达到M_N后清零
												//也就是说cyc_cnt里面包含了x个div_e和y个div_o
    reg div_flag;				//奇偶标志
    reg div_clk_r;
    
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            clk_cnt <= 0;
        else if(~div_flag)
            clk_cnt <= clk_cnt==(div_e-1)? 0: clk_cnt+1;
        else
            clk_cnt <= clk_cnt==(div_o-1)? 0: clk_cnt+1;
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            cyc_cnt <= 0;
        else
            cyc_cnt <= cyc_cnt==(M_N-1)? 0: cyc_cnt+1;
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            div_flag <= 0;
        else
            div_flag <= cyc_cnt==(M_N-1)||cyc_cnt==(div_point-1)? ~div_flag: div_flag;
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            div_clk_r <= 0;
        else if(~div_flag)
            div_clk_r <= clk_cnt<=((div_e>>2)+1);
        else
            div_clk_r <= clk_cnt<=((div_o>>2)+1);
    end
    
    assign div_clk = div_clk_r;

endmodule

仿真图

分解成5个12分频、5个13分频image.png

posted on 2023-06-12 17:42  naive156  阅读(14)  评论(0编辑  收藏  举报  来源

导航