Verilog时钟分频(偶数分频、奇数分频、小数分频、半整数分频)

这篇具有很好参考价值的文章主要介绍了Verilog时钟分频(偶数分频、奇数分频、小数分频、半整数分频)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

偶数分频

偶数分频最容易实现,可以用计数器实现。计数值小的时候也可以使用DFF直接完成。这里使用计数器实现,计数达到分频系数一半的时候进行翻转(占空比为50%)。对应: 牛客 VL37 时钟分频(偶数)

/**
	使用计数方式实现了8分频
*/
module even_div(
    input     wire  rstn,
    input     wire  clk,
    output    reg   clk_out
);

reg [1:0] count;
/**
    count operation
*/
always @(posedge clk or negedge rstn) begin
    if(~rstn) begin
        count <= 2'b0;
    end
    else begin
        count <= count + 1'b1;
    end
end


always @(posedge clk or negedge rstn) begin
    if(~rstn) begin
        clk_out <= 1'b0;
    end
    else if(count == 2'b00) begin
        clk_out <= ~clk_out;
    end
end

endmodule

仿真结果如下
verilog时钟分频,FPGA学习,fpga开发

奇数分频

不要求占空比为50%的奇数分频

不要求占空比为50%,可以与偶数分频一样,根据计数值进行波形翻转。
对应: 牛客 VL42 无占空比要去的奇数分频

/**
	不要求占空比的奇数分频
	5分频 3低电平2高电平
	占空比 2/5
*/
module odd_div (    
    input     wire rstn,
    input     wire clk,
    output    reg clko
);

parameter N = 5;

reg [2:0] count;
always @(posedge clk or negedge rstn) begin
    if(~rstn) begin
        count <= 3'd0;
    end
    else if(count == N - 1) begin
        count <= 3'd0;
    end
    else begin
        count <= count + 1'b1;
    end 
end

always @(posedge clk or negedge rstn) begin
    if(~rstn) begin
        clko <= 1'b0;
    end
    else if(count == N - 1 || count == (N >> 1)) begin
        clko <= ~clko;
    end
    else begin
        clko <= clko;
    end
end

endmodule

仿真结果如下
verilog时钟分频,FPGA学习,fpga开发

要求占空比为50%奇数分频

无法单纯使用计数方式来实现,可以利用时钟双边沿特性产生两个占空比不为50%的时钟,然后将这两个时钟信号相与或者相或产生。

比如产生占空比为50%的5分频时钟,可以通过:

  1. 沿源时钟上升沿变化的,2cycle高电平,3cycle低电平,周期为5的时钟信号。
  2. 沿源时钟下降沿变化的,2cycle高电平,3cycle低电平,周期为5的时钟信号。
  3. 将上述两时钟信号相或得到占空比为50%的5分频时钟。

或者

  1. 沿源时钟上升沿变化的,3cycle高电平,2cycle低电平,周期为5的时钟信号。
  2. 沿源时钟下降沿变化的,3cycle高电平,2cycle低电平,周期为5的时钟信号。
  3. 将上述两时钟信号相与得到占空比为50%的5分频时钟。
/**
	产生	50%占空比 5分频的时钟
	1. 沿源时钟上升沿变化的,3cycle高电平,2cycle低电平,周期为5的时钟信号。
	2. 沿源时钟下降沿变化的,3cycle高电平,2cycle低电平,周期为5的时钟信号。
	3. 将上述两时钟信号相与得到占空比为50%的5分频时钟。
*/
module odd_div1(
    input       clk,
    input       rstn,
    output      clko
);

    parameter N = 5;

    reg [2:0] count;
    // 沿时钟上升沿变化的时钟信号 2低3高
    reg clkp;
    // 沿时钟下降沿变化的时钟信号
    reg clkn;
    assign clko = clkp & clkn;

    always @(posedge clk or negedge rstn) begin
        if(~rstn) begin
            count <= 3'b0;
        end
        else if(count == N - 1) begin
            count <= 3'b0;
        end
        else begin
            count <= count + 1'b1;
        end
    end

    
    always @(posedge clk or negedge rstn) begin
        if(~rstn) begin
            clkp <= 1'b0;
        end
        else if(count == 3'b1 || count == N - 1) begin
            clkp = ~clkp;
        end
        else begin
            clkp <= clkp;
        end
    end

    always @(negedge clk or negedge rstn) begin
        if(~rstn) begin
            clkn <= 1'b0;
        end
        else if(count == 3'b1 || count == N - 1) begin
            clkn = ~clkn;
        end
        else begin
            clkn <= clkn;
        end
    end

endmodule

仿真波形如下
verilog时钟分频,FPGA学习,fpga开发

小数分频

对应 牛客 VL41 任意小数分频

无法做到占空比为50%的小数分频,也无法做到分频后的每个时钟周期都是原时钟周期的小数倍(当然如果是x.5是可以做到的)。
因此转换思路,进行7.6倍分频可以理解成分频后的时钟周期 To = 7.6T ,那么 10To = 76T,也就是说只要满足76个原时钟周期等于10个分频后的时钟周期即可。
这时候我们使用7分频和8分频的时钟来实现7.6倍分频的时钟,假设 10个分频后的时钟 由N个7分频的时钟和M个8分频的时钟组成,那么可以得到

	M + N = 10
	N7T + M8T = 76T
	⇒ 
	M + N = 10
	7N + 8M = 76

可以得到N = 4, M = 6。
就是由4个7分频的时钟和6个8分频的时钟组成7.6倍分频的时钟。
那么可以有四种方法将这两种时钟进行混合:

1. 先4次7分频再进行6次8分频
2. 先6次8分频再进行4次7分频
3. 将6次8分频插入4次7分频中
4. 将4次7分频插入6次8分频中
/**
	实现8.7倍分频
	由3个8分频和7个9分频时钟组成10个分频后的时钟
	=》
	24个原时钟周期用于8分频
	63个原时钟周期用于9分频
	
	先进行 3次8分频 再进行 7次9分频
*/

module div_M_N(
   input  wire clk_in,
   input  wire rst,
   output wire clk_out
);

/*
   8N + 9M = 87
   N + M = 10
   M = 7, N = 3
   因此3个8分频时钟 和 7个9分频时钟构成 8.7分频时钟
*/    

/*
   3*8 = 24 
   87个原时钟周期里前24个周期 用来8分频
   7*9 = 63
   后63个时钟周期 用来9分频

   相当于10个8.7分频的时钟,前3个分频后的时钟周期由8分频组成,后7个由9分频组成
*/
parameter M_N = 8'd87; 
parameter c89 = 8'd24; // 8/9时钟切换点
parameter div_e = 5'd8; //偶数周期
parameter div_o = 5'd9; //奇数周期

reg clk_div;
assign clk_out = clk_div;

// 计数87
reg [6:0] cnt87;
// 计数8
reg [2:0] cnt8;
// 计数9
reg [3:0] cnt9;

always @(posedge clk_in or negedge rst) begin
   if(~rst) begin
      cnt87 <= 7'b0;
   end
   else if(cnt87 == M_N - 1'b1) begin
      cnt87 <= 7'b0;
   end
   else begin
      cnt87 <= cnt87 + 1'b1;
   end   
end

/*
   8/9分频时钟切换
*/
always @(posedge clk_in or negedge rst) begin
   if(~rst) begin
      cnt8 <= 3'b0;
      cnt9 <= 4'b0;
   end
   // 8分频
   else if(cnt87 < c89) begin
      cnt9 <= 4'b0;
      cnt8 <= cnt8 + 1'b1;
   end
   // 9分频
   else begin
      cnt8 <= 3'b0;
      if(cnt9 == div_o - 1) begin
         cnt9 <= 4'b0;
      end
      else begin
         cnt9 <= cnt9 + 1'b1;
      end
   end
end

always @(posedge clk_in or negedge rst) begin
   if(~rst) begin
      clk_div <= 1'b0;
   end
   // 8分频
   else if(cnt87 < c89) begin
      if (cnt8 == 3'b0 || cnt8 == 3'b100) begin
         clk_div <= ~clk_div;
      end   
      else begin
         clk_div <= clk_div;
      end
   end
   // 9分频
   else begin
      // 4高5低
      if (cnt9 == 3'b0 || cnt9 == 3'b100) begin
         clk_div <= ~clk_div;
      end   
      else begin
         clk_div <= clk_div;
      end
   end
end

endmodule

仿真波形如下
verilog时钟分频,FPGA学习,fpga开发

半整数分频

半整数分频实际上就是特殊一点的小数分频,可以按照小数分频的方法完成,也可以利用时钟的双边沿特性完成。

利用双边沿特性

假设要进行5.5倍分频,那么让分频后的时钟信号2.5个原周期为高电平,3个原时钟周期为低电平。这样的信号要由两个沿不同时钟沿变化的信号产生:

  1. 由5时钟周期(沿上升沿变化,2周期高电平,3周期低电平)和6时钟周期的信号(沿上升沿变化,2周期高电平,4周期低电平)组成。
  2. 由5时钟周期(沿下降沿变化,2周期高电平,3周期低电平)和6时钟周期的信号(沿下降沿变化,2周期高电平,4周期低电平)组成。
  3. 将信号1和信号2相或得到 5.5倍分频的信号。
module half_int_div(
    input  wire clk,
    input  wire rstn,
    output wire clko
);

    reg clkp;
    reg clkn;
    assign clko = clkp | clkn;

    reg [3:0] cnt;
    always @(posedge clk or negedge rstn) begin
        if(~rstn) begin
            cnt <= 4'b0;
        end
        else if(cnt == 4'b1010) begin
            cnt <= 4'b0;
        end
        else begin
            cnt <= cnt + 1'b1;
        end
    end

    always @(posedge clk or negedge rstn) begin
        if(~rstn) begin
            clkp <= 1'b0;
        end
        else if(cnt == 4'd0 || cnt == 4'd1 || cnt ==  4'd6 || cnt ==  4'd7) begin
            clkp <= 1'b1;
        end
        else begin
            clkp <= 1'b0;
        end
    end

    always @(negedge clk or negedge rstn) begin
        if(~rstn) begin
            clkn <= 1'b0;
        end
        else if(cnt == 4'd1 || cnt == 4'd2 || cnt ==  4'd6 || cnt ==  4'd7) begin
            clkn <= 1'b1;
        end
        else begin
            clkn <= 1'b0;
        end
    end

endmodule

仿真波形如下
verilog时钟分频,FPGA学习,fpga开发

利用小数分频的思路

假设要进行5.5倍分频,相当于在11个原时钟周期里进行了两次5.5分频。采用5分频和6分频来实现5.5分频。那么

	5N + 6M = 11
	N + M = 2
	=>
	N = 1, M = 1

也就是说在11个原时钟周期里进行了一次5分频和一次6分频。文章来源地址https://www.toymoban.com/news/detail-816500.html

到了这里,关于Verilog时钟分频(偶数分频、奇数分频、小数分频、半整数分频)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • verilog实现分频(奇数分频和偶数分频,通用版)

    大家好,最近写了一些分频器的设计,发现奇数分频和偶数分频是比较常用分频效果,所以写了一个比较简单的分频代码, 适用于奇数分频和偶数分频(不考虑占空比) ,代码已经经过测试,需要可自取。 一、上代码 二、上验证代码 三、上仿真结果 图1:6分频效果(mult

    2024年02月13日
    浏览(36)
  • 「Verilog学习笔记」时钟分频(偶数)

    专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点,刷题网站用的是牛客网

    2024年02月03日
    浏览(37)
  • 「Verilog学习笔记」任意奇数倍时钟分频

    专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点,刷题网站用的是牛客网

    2024年01月23日
    浏览(36)
  • 【FPGA & Verilog】奇数分频器 (50%)

    2.1 设计输⼊ 1. 模块名称:FrequencyDivider 2. 输⼊输出:CLK、RSTn、CLK_15 2.2 引脚约束 1. 输⼊端 ⾃定义 2. 输出端 ⾃定义 2.3 设计要求 1. 输出时钟的周期是输⼊时钟的15倍(15分频器) 2. 分别实现 7/15 占空⽐和 50% 占空⽐两种分频⽅式 3. 使⽤RTL View分析电路的区别 2.4 电路仿真1.

    2024年02月03日
    浏览(34)
  • FPGA学习——实现任意倍分频器(奇数/偶数倍分频器均可实现)

    在FPGA(可编程逻辑门阵列)中,分频器是一种用于将时钟信号的频率降低的电路或模块。它可以根据输入的时钟信号生成一个较低频率的输出时钟信号。 常见的分频器可以按照固定比例来进行分频,例如将输入时钟频率除以2、除以4等。因此,如果输入时钟信号的频率为10

    2024年02月05日
    浏览(38)
  • fpga时钟分频——奇数分频

    相比偶数分频,奇数分频相对复杂,下面我总结一下如何用verilog实现。以N(奇数)为例。 总结如下: a. 上升沿计数器和信号寄存器 : 设置一个计数长度为N的上升沿计数器(pos_cnt),并且设置一个信号寄存器(pos_clk)。 当上升沿计数器计数到时,信号寄存器翻转。 当上升沿计

    2024年04月17日
    浏览(59)
  • Verilog 时钟分频设计

    将触发器的反向输出端接到触发器的输入,可以构成简单二分频电路。 在此基础上,将二分频电路进行级联可以构成四分频,八分频电路。电路如下图所示:   对于任意偶数分频,或者系数较大的偶数分频,可以使用计数器循环计数来实现分频。当计数周期达到N/2(N为分频

    2024年02月11日
    浏览(43)
  • 时钟分频电路设计--verilog(2分频、3分频、4分频)

    module divider( input clk, input resetn, output reg clk_d2, output reg clk_d3_pos, output reg clk_d3_neg, output clk_d3, //reg型不能assign赋值? output reg clk_d4 ); reg [1:0]counter; reg [1:0]counter_3; always@(posedge clk or negedge resetn)begin //4分频计数器模块 if(~resetn) counter = 2’b0; else if(counter = 2’b11) counter = counter + 1’

    2024年02月06日
    浏览(40)
  • Verilog-实现时钟分频(1KHZ、奇、偶分频,占空比为50%)

    代码如下 1khz分频代码 1khz分频-testbench 仿真图如下 通过计数器实现,进行N倍偶数分频,通过时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,以此循环下去。(占空比为50%) ,以下代码实现8分频,可根据实际需求改变参数输出需要的时钟。 代码如下 偶

    2024年02月08日
    浏览(48)
  • 【实验室学习】时钟分频器,2、3、4、8分频 verilog实现

    记录时钟分频器的Verilog代码编写,主要掌握分频器设计思路 2、4、8分频设计较为容易: 2分频—设计一个1位的寄存器,当原时钟上升沿时取反即可 代码展示: 4分频与8分频—设计一个两位的计数器,4分频只需在计数器计数到00B或者10B时跳变电平即可,8分频只需在计数器计

    2024年02月11日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包