0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

通过Verilog实现对一个频率的任意占空比的任意分频

ZYNQ 来源:ZYNQ 2023-01-05 09:33 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

verilog程序设计中,我们往往要对一个频率进行任意分频,而且占空比也有一定的要求这样的话,对于程序有一定的要求,现在我在前人经验的基础上做一个简单的总结,实现对一个频率的任意占空比的任意分频。

比如:我们FPGA系统时钟是50M Hz,而我们要产生的频率是880Hz,那么,我们需要对系统时钟进行分频。我们很容易想到用计数的方式来分频:

50000000/880 = 56818

这个数字不是2的整幂次方,那么怎么办呢?我们可以设定一个参数,让它到56818的时候重新计数不就完了吗?呵呵,程序如下:

module div(clk, clk_div);

input clk;

output clk_div;

reg [15:0] counter;

always @(posedge clk)

if(counter==56817) counter <= 0;

else counter <= counter+1;

assign clk_div = counter[15];

endmodule

下面我们来算一下它的占空比:我们清楚地知道,这个输出波形在counter为0到32767的时候为低,在32767到56817的时候为高,占空比为40%多一些,如果我们需要占空比为50%,那么怎么办呢?不用急,慢慢来。

我们再设定一个参数,使它为56817的一半,使达到它的时候波形翻转,那不就完了吗?呵呵,再看看:

module div(clk, clk_div);
input clk;
output clk_div;
reg [14:0] counter;
always @(posedge clk)
if(counter==28408) counter <= 0;
else counter <= counter+1;
reg clk_div;
always @(posedge clk)
  if(counter==28408) clk_div <= ~clk_div;
endmodule

占空比是不是神奇地变成50%了呢?呵呵。

继续让我们来看如何实现任意占空比,比如还是由50 M分频产生880 Hz,而分频得到的信号的占空比为30%。

56818×30%=17045

module div(clk,reset,clk_div,counter);
input clk,reset;
output clk_div;
output [15:0] counter;
reg [15:0] counter;
reg clk_div;
always @(posedge clk)
if(!reset) counter <= 0;
else if(counter==56817) counter <= 0;
else counter <= counter+1;
always @(posedge clk)
if(!reset) clk_div <= 0;
else if(counter<17045) clk_div <= 1;
else clk_div <= 0;
endmodule

三分频的Verilog实现

//很实用也是笔试面试时常考的,已经经过仿真

占空比要求50%和不要求占空比差别会很大,先看一个占空比50%的描述

module div3(CLKIN,CLKOUT,RESETn);
input CLKIN,RESETn;
output CLKOUT;
 
//internal counter signals
reg[1:0] count_a;
reg[1:0] count_b;
reg      CLKOUT;
 
always @(negedge RESETn or posedge CLKIN)
begin
    if (RESETn==1'b0)
        count_a<=2'b00;
    else
        if (count_a==2'b10)
            count_a<=2'b00;
        else
            count_a<=count_a+1;
end
 
always @(negedge RESETn or negedge CLKIN)
begin
    if (RESETn==1'b0)
        count_b<=2'b0;
    else
        if (count_b==2'b10)
            count_b<=2'b00;
        else
            count_b<=count_b+1;
end
 
always @(count_a or count_b or RESETn)
begin
 if (RESETn==1'b0)
   CLKOUT=1'b0;
 else if((count_a+count_b==4)||(count_a+ count_b==1))
   CLKOUT=~CLKOUT;
end
endmodule


0 1 2 0 1 2
/ / / /
0 1 2 0 1 2

下面是一个非50%的描述,只用了上升沿

module div3(CLKIN,CLKOUT,RESETn);
input CLKIN,RESETn;
output CLKOUT;
 
 
wire d;
reg     q1,q2;
wire         CLKOUT;
 
always @(negedge RESETn or posedge CLKIN)
begin
    if (RESETn==1'b0)
        q1<=1'b0;
    else
        q1<=d;
end
 
always @(negedge RESETn or posedge CLKIN)
begin
    if (RESETn==1'b0)
        q2<=1'b0;
    else
        q2<=q1;
end
assign d=~q1 & ~q2;
assign CLKOUT=q2;
endmodule

占空比不是50%,只用了单沿触发器,寄存器输出。

至于其他奇数要求50%的或者不要求的占空比的,都可以参照上面两个例子做出。
占空比为50%的一个更好的实现。

module div3(CLKIN,CLKOUT,RESETn);
input CLKIN,RESETn;
output CLKOUT;
//internal counter signals
reg[1:0] count_a;
reg            b,c;
//reg        CLKOUT;
wire CLKOUT;
always @(negedge RESETn or posedge CLKIN)
begin
    if (RESETn==1'b0)
        count_a<=2'b00;
    else
        if (count_a==2'b10)
            count_a<=2'b00;
        else
            count_a<=count_a+1;
end
always @(negedge RESETn or negedge CLKIN)
begin
    if (RESETn==1'b0)
        b<=1'b0;
    else
        if (count_a==2'b01)
            b<=2'b0;
        else
            b<=1'b1;
end
always @(negedge RESETn or posedge CLKIN)
begin
    if (RESETn==1'b0)
        c<=1'b0;
    else
        if (count_a==2'b10)
            c<=1'b1;
        else if (count_a==2'b01)
            c<=1'b0;
end
assign          CLKOUT=b & c;
endmodule

时钟选择器的Verilog写法!

CPRI有3种数据时钟,61.44M 122.88M 245.76M,需要模块能够根据外部的速率指示信号(一个2位的输入信号,由模块外部给定)选择其中的一种时钟作为模块的工作时钟

但由于所选用的FPGA工作频率关系,不能超过400M,无法通过寄存器方式实现时钟源的选择.

使用双边触发的方式将最高的频率进行分频,代码如下,已经通过ModelSim的仿真,可以实现。

module clk_div(
                  reset,        //复位信号
                  data_rate,    //数据速率指示
                  clk2,         //245.76M的时钟输入
                  time1,        //分频计数器
                  clk           //选择后的时钟输出
                  );
input       reset;
input [1:0] data_rate;
input       clk2;
output [1:0] time1;
output      clk;
reg [1:0] time1;
reg       clk;                  
                  
always@(clk2 or reset)
if(reset)
   begin
     time1=2'b00;
     clk=1'b0;
   end
else
   begin
     time1=time1+1'b1;
     case(data_rate)
       2'b00:if(time1==2'b00)
                clk=~clk;
             else
                clk=clk;  
       2'b01:if(time1[0]==1'b1)
                clk=~clk;
             else
                clk=clk;
       2'b10:clk=clk;
       2'b11:clk=~clk;
     endcase
   end
endmodule      

verilog 实现gray码计数器

//16位gray码计数器,gary码状态改变时候每次只改变一个bit
//,可以有效防止竞争和毛刺的产生。
module gray_counter(clk,clr,start,stop,q,cout);
 input clk;
 input clr;
 input start,stop;
 output reg [3:0] q;
 output reg cout;
 reg flag=1;
 reg [3:0] s,next_s;
 
 //parameter S0=0, S1=1, S2=2, S3=3, S4=4, S5=5, S6=6, S7=7;
 //parameter S8=8, S9=9, S10=10, S11=11, S12=12, S13=13, S14=14, S15=15;
 parameter s0=0000, s1=0001, s2=0011, s3=0010;
 parameter s4=0110, s5=0111, s6=0101, s7=0100;
 parameter s8=1100, s9=1101, s10=1111,s11=1110;
 parameter s12=1010, s13=1011, s14=1001, s15=1000;
 always @(posedge clk)
 begin
  if (clr) s <= s0;
  else   s <= next_s;
 end 
 /*always @(posedge start or posedge stop)
 begin
  if(start) flag=1;
  else if (stop) flag=0;
 end*/
 always @(s or flag)     /*该进程实现状态的转换*/
 begin    
  case (s)
   s0: begin
   if (flag)  next_s <=s1;
   // else       next_s <=s0;
    end
   s1: begin
   if (flag)    next_s <= s2;
   end
   s2: begin
   if (flag)   next_s <=s3;
   ////else        next_s <=s0;
   end
   s3: begin
   if (flag)    next_s <=s4;
   //else        next_s <=s3;
   end
   s4: begin
   if (flag)     next_s <= s5;
   end
   s5: begin
   if (flag)   next_s <=s6;
   //else        next_s <=s0;
   end
   s6: begin
   if (flag)   next_s <=s7;
   //else        next_s <=s3;
   end
   s7: begin
   if (flag)  next_s <=s8;
   //else       next_s <=s0;
   end
   s8: begin
   if (flag)    next_s <= s9;
   end
   s9: begin
   if (flag)   next_s <=s10;
   ////else        next_s <=s0;
   end
   s10: begin
   if (flag)    next_s <=s11;
   //else        next_s <=s3;
   end
   s11: begin
   if (flag)     next_s <= s12;
   end
   s12: begin
   if (flag)   next_s <=s13;
   //else        next_s <=s0;
   end
   s13: begin
   if (flag)   next_s <=s14;
   //else        next_s <=s3;
   end
   s14: begin
   if (flag)   next_s <=s15;
   ////else        next_s <=s0;
   end
   s15: begin
   if (flag)    next_s <=s0;
   //else        next_s <=s3;
   end
   default:    next_s <=s0;   /*default语句*/
  endcase
 end
 always @(s)          /*该进程定义组合逻辑(FSM的输出)*/  
 begin
  case(s)
  s0: q=0;
  s1: q=4;
  s2: q=2;
  s3: q=3;
  s4: q=4;
  s5: q=5;
  s6: q=6;
  s7: q=7;
  s8: q=8;
  s9: q=9;
  s10: q=10;
  s11: q=11;
  s12: q=12;
  s13: q=13;
  s14: q=14;
  s15: q=15;    
  default:q=0;     /*default语句,避免锁存器的产生*/
  endcase
 end
 always @(s)
    begin
   if (s==s15) cout=1;//assign cout=q;
   else cout=0;
 end
endmodule

审核编辑:郭婷

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1664

    文章

    22502

    浏览量

    639054
  • Verilog
    +关注

    关注

    31

    文章

    1374

    浏览量

    114713

原文标题:Verilog_实现任意占空比、任意分频的方法

文章出处:【微信号:ZYNQ,微信公众号:ZYNQ】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Spectrum 仪器推出 DDS 选件,大幅提升任意波形发生器灵活性

    德思特优质合作伙伴Spectrum仪器为其65xx系列任意波形发生器(AWG)推出全新DDS(直接数字频率合成)选件,为生成正弦信号、精细可调参考源、合成正弦波、波形序列、频率扫描及调制信号,提供了
    的头像 发表于 03-24 17:40 1150次阅读
    Spectrum 仪器推出 DDS 选件,大幅提升<b class='flag-5'>任意</b>波形发生器灵活性

    任意波形发生器选型时,哪个指标更关键?

    在电子测试与测量领域,任意波形发生器(AWG)的性能指标往往让人眼花缭乱。大多数工程师在初次选型时,最先关注的是采样率(Sampling Rate),追求极致的 GS/s。然而,在量子计算、复杂雷达
    的头像 发表于 03-16 11:47 174次阅读
    <b class='flag-5'>任意</b>波形发生器选型时,哪个指标更关键?

    函数信号发生器和任意波形信号发生器区别详解

    函数发生器提供了预置列表,里面列出了它可以生成的波形或码型。 在函数发生器中,用户可以更改频率、幅度和偏移等波形参数,还可添加简单的失真。 任意波形发生器更为复杂,能够仿真真实世界
    的头像 发表于 02-09 16:24 363次阅读
    函数信号发生器和<b class='flag-5'>任意</b>波形信号发生器区别详解

    Spectrum仪器超高速任意波形发生器新增DDS选项

    性能。该系列产品在AWG模式下可生成高达10 GS/s采样率、16位分辨率及3.9GH带宽的波形。在新开发的DDS模式下,63xx系列任意波形发生器可在生成通道输出64路独立正弦波,每路波形的
    的头像 发表于 11-05 14:48 719次阅读
    Spectrum仪器超高速<b class='flag-5'>任意</b>波形发生器新增DDS选项

    安捷伦agilent 33250a 函数发生器任意波形发生器

    任意波形比以前更加容易 新agilent 33250a的性能几乎比同等价格的任何其它发生器高倍。其80mhz带宽能适应各种各样的应用要求,它具有各种内置信号、自定义的任意波形和脉冲能力,能帮助您验证设计,检验新的构想。直接数字
    的头像 发表于 08-13 16:56 962次阅读
    安捷伦agilent  33250a 函数发生器<b class='flag-5'>任意</b>波形发生器

    MAX9377/MAX9378任意逻辑至LVPECL/LVDS转换器,引脚可设置四分频电路技术手册

    MAX9377/MAX9378是种全差分、高速、低抖动的任意电平到LVPECL/LVDS的转换器,具有有四分频选择引脚。其极低的传输延迟和高速等特性,尤其适合于多种高速网络路由和背板应用,在非
    的头像 发表于 05-16 15:12 4772次阅读
    MAX9377/MAX9378<b class='flag-5'>任意</b>逻辑至LVPECL/LVDS转换器,引脚可设置四<b class='flag-5'>分频</b>电路技术手册

    MAX9375单LVDS/任意逻辑至LVPECL转换器技术手册

    MAX9375是高速、全差分、任意电平到LVPECL的转换器,设计信号速率高达2GHz。其极低的传输延迟和高速等特性,尤其适合于多种高速网络路由和背板应用。
    的头像 发表于 05-16 15:07 1289次阅读
    MAX9375单LVDS/<b class='flag-5'>任意</b>逻辑至LVPECL转换器技术手册

    Spectrum仪器推出通过以太网控制生成宽带信号的任意波形发生器

    波形发生器(AWG),其输出速率高达10 GS/s,分辨率为16位。新产品采用以太网连接技术,可通过电脑、笔记本电脑以及企业网络直接控制。此次发布的新产品主要服务于自动化和远程测试领域,尤其适用于直流至2.5GHz宽带的信号生成。 产品视频链接 新款任意波形发生器(AWG
    的头像 发表于 05-14 14:29 796次阅读
    Spectrum仪器推出<b class='flag-5'>通过</b>以太网控制生成宽带信号的<b class='flag-5'>任意</b>波形发生器

    基于 FPGA 的任意波形发生器+低通滤波器系统设计

    在EGO1开发板上实现简易的任意波形发生器。该波形发生器能够产生正弦波、方波、三角波与锯齿波四种波形,可输出频率有:1MHz、100KH
    发表于 05-07 15:34

    ADF4007高频分频器/PLL频率合成器技术手册

    器/预分频器组成。分频器/预分频器值可以通过外部控制引脚设置为四值中的
    的头像 发表于 04-27 15:23 1207次阅读
    ADF4007高频<b class='flag-5'>分频</b>器/PLL<b class='flag-5'>频率</b>合成器技术手册

    ADF4156 6.2GHz小数N分频频率合成器技术手册

    ADF4156是款6.2 GHz小数N分频频率合成器,用来在无线接收机和发射机的上变频和下变频部分实现本振。它由低噪声数字鉴频鉴相器(PFD)、精密电荷泵和可编程参考分频器组成。它内
    的头像 发表于 04-27 09:43 1330次阅读
    ADF4156 6.2GHz小数N<b class='flag-5'>分频频率</b>合成器技术手册

    ADF4154小数N分频频率合成器技术手册

    ADF4154是款小数N分频频率合成器,用来在无线接收机和发射机的上变频和下变频部分实现本振。它由低噪声数字鉴频鉴相器(PFD)、精密电荷泵和可编程基准分频器组成。该器件内置
    的头像 发表于 04-27 09:36 1365次阅读
    ADF4154小数N<b class='flag-5'>分频频率</b>合成器技术手册

    ADF4150小数N/整数N分频PLL频率合成器技术手册

    兼容。VCO频率可进行1/2/4/8或16分频,因此用户可以产生低至31.25 MHz的RF输出频率。对于要求隔离的应用,RF输出级可以实现静音。静音功能既可以
    的头像 发表于 04-25 17:10 1575次阅读
    ADF4150小数N/整数N<b class='flag-5'>分频</b>PLL<b class='flag-5'>频率</b>合成器技术手册

    ADF4151小数N/整数N分频PLL频率合成器技术手册

    兼容、软件兼容。该器件由低噪声数字鉴频鉴相器(PFD)、精密电荷泵和可编程参考分频器组成。它内置Σ-Δ型小数插值器,能够实现可编程小数N分频
    的头像 发表于 04-25 15:15 1577次阅读
    ADF4151小数N/整数N<b class='flag-5'>分频</b>PLL<b class='flag-5'>频率</b>合成器技术手册

    ADF4153A小数N分频频率合成器技术手册

    ADF4153A是款小数N分频频率合成器,用来在无线接收机和发射机的上变频和下变频部分实现本振。它由低噪声数字鉴频鉴相器(PFD)、精密电荷泵和可编程参考分频器组成。该器件内置
    的头像 发表于 04-25 14:58 1233次阅读
    ADF4153A小数N<b class='flag-5'>分频频率</b>合成器技术手册