原创 【博客大赛】Verilog奇数-小数分频

2013-8-14 10:51 5640 20 25 分类: FPGA/CPLD

 

1、半整数分频占空比不为50%

//说明:设计的史上最好用的半整数分频占空比不为50%,包含设计思路

module div_5(clk,clk_div,cnt1,cnt2,temp1,temp2);//N+0.5

input clk;

output clk_div;

output reg[31:0]cnt1,cnt2;

output reg temp1,temp2;

initial begin temp1=0;temp2=1;end   //首先进行初始化,temp1=0;temp2=1

parameter N=5;  //设定分频系数为N+0.5

always @(posedge clk)  //temp1上升沿跳变

begin

if(cnt1==2*N)  //2*N

begin cnt1[31:0]<=32'd0;end

else begin cnt1[31:0]<=cnt1[31:0]+32'd1;end

if(cnt1==32'd0) begin temp1<=1;end   //高电平时间为N+1;

if(cnt1==N+1) begin temp1<=0;end   //低电平时间为N;

end

always@(negedge clk)  //temp2下降沿跳变

begin

if(cnt2==2*N)  //2*N

begin cnt2[31:0]<=32'd0;end

else begin cnt2[31:0]<=cnt2[31:0]+32'd1;end

if(cnt2==32'd0) begin temp2<=0;end     //低电平时间为N;

if(cnt2==N) begin temp2<=1;end    //高电平时间为N+1;

end

assign clk_div=temp1&&temp2;  //逻辑与

endmodule

//如果要进行N+0.5分频

//思路:总的来说要进行N+1+N=2N+1次分频

//在时钟的上升沿和下降沿都进行跳变

//上升沿进行占空比为N+1比N的时钟temp1;

//下降沿进行占空比为N比N+1的时钟temp2;

//最后div=temp1&&temp2 即可得到所需要的半整数分频

分频5.5仿真结果

20130809201353404001.jpg

2、奇数分频占空比为50%

//说明:奇数分频。

module div_5(clk,clk_div,cnt1,cnt2,temp1,temp2);//

input clk;

output clk_div;

output reg[31:0]cnt1,cnt2;

output reg temp1,temp2;

parameter N=5;  //设定分频系数

always @(posedge clk)

begin

if(cnt1==N-1)  //N-1进行N计数

begin cnt1[31:0]<=32'd0;end

else begin cnt1[31:0]<=cnt1[31:0]+32'd1;end

if(cnt1==32'd0) begin temp1<=1;end   //

if(cnt1==(N-1)/2) begin temp1<=0;end   //当计数到(N-1)/2时翻转

end

always@(negedge clk)

begin

if(cnt2==N-1)  //N-1

begin cnt2[31:0]<=32'd0;end

else begin cnt2[31:0]<=cnt2[31:0]+32'd1;end

if(cnt2==32'd0) begin temp2<=1;end     //;

if(cnt2==(N-1)/2) begin temp2<=0;end    //当计数到(N-1)/2时翻转;

end

assign clk_div=temp1||temp2;  //逻辑或

endmodule

 

20130809201400985002.jpg

 

3任意小数分频    

      分数分频实现基本上都是靠吞脉冲方法实现,如5/2分频,就可以分成一个2分频,一个3分频接替出现,这样(2+3)/2就是5/2分频。

       下面以68/9为例介绍下怎么计算。

       68=9*7+5,即商为7,余数为5。可以推出68/9分频,可以看成5个8分频和4个7分频,即(5*8+4*7)/9=68/9。这个7分频和8分频中的数字7和8就是从商中得出来的。那5个8分频和4个7分频中的数字5和4就是从余数中的出来的,5是余数,4是(9-5)。

       分子:numerator。分母denominator。商quotient。余数remainder。(翻译不是很准确,表达下意思就行了,呵呵)。

       numerator=quotient*denominator+remainder.那么numerator/ denominator分频就可以通过remainder个(quotient+1)分频和(denominator -remainder)个quotient分频组成。

       还是以68/9为例。我们得出了5个8分频和4个7分频可以实现这个分数分频,但这5个8分频和4个7分频怎么放置呢?

       先放5个8分频,再放4个7分频,这样绝对是不行的。为了均匀的放置这两种频率,我从小数分频中学到一种方法。找个临时变量temp(程序中用的是sum)。初始化为0。每次分频完让它加上余数,判断是否大于分母,如果小于分母,择输出7分频,否则输出8分频,并且将这个值减去分母(让它小于分母)。这样temp值就变成了5 1 6 2 7 3 8 4 0 5……

分频值就成了7 8 7 8 7 8 7 8 8 7 8 7 8 7 8 7 8 8……可以统计一下7分频和8分频的比例就正好是4:5,这样就实现了分数分频。

       程序如下所示:

输入信号:clk,rst,clkin(要分频的时钟信号),numerator(分子), denominator,(分母)

输出信号:pulse

中间信号:quotient(商),remainder(余数)等

hightime为输出信号pulse输出高电平时间,可控制占空比

/*************************************************

 

//module name:fredivAB

 

//designer:kang

 

//date:2010-10-08

 

//version:1.00

 

*************************************************/

module fredivAB(

            //input signals

            clk,

            rst,

            clkin,

            numerator,      //fenzi

            denominator,    //fenmu

            //output signals

            pulse      

            );

input clk;

input rst;

input clkin;

input [15:0] numerator;

input [15:0] denominator;

 

output pulse;

reg pulse;

 

//parameter HIGHTIME=16'd2;

 

wire [15:0] quotient;   //shang

wire [15:0] remainder;  //yushu

reg ina;

reg inb;

reg upclk;

reg counter_clkin;

reg [15:0] counter;

reg [15:0] divnum;

reg [15:0] sum;

reg flag;

reg [15:0] counter_pulseh;

wire [15:0] hightime;

 

assign quotient=(denominator)?numerator/denominator:16'h0;

assign remainder=(denominator)?numerator%denominator:16'h0;

assign hightime={1'b0,quotient[15:1]};

//assign hightime=16'h1;

 

//save the prior and current state of clkin

always @(posedge clk or negedge rst)

    begin

    if(!rst)

        begin

        ina<=0;

        inb<=0;

        end

    else

        begin

        ina<=clkin;

        inb<=ina;

        end

    end

   

//check posedge pf clkin

always @(posedge clk or negedge rst)

    begin

    if(!rst) upclk<=0;

    else if(!inb&ina) upclk<=1'b1;

    else upclk<=0;

    end

 

//fre div counter

always @(posedge clk or negedge rst)

    begin

    if(!rst)

        begin

        counter<=0;

        end

    else if(counter==divnum) counter<=16'h0;

    else if(upclk) counter<=counter+1'b1;

    else counter<=counter;

    end

 

always @(posedge clk or negedge rst)

    begin

    if(!rst)

        begin

        sum<=0;

        flag<=0;

        end

    else if(counter==divnum)

        begin

        if((sum+remainder)>=denominator)        //fenmu

            begin

            sum<=sum+remainder-denominator;

            flag<=1;

            end

        else

            begin

            sum<=sum+remainder;

            flag<=0;

            end

        end

    end

       

always @(posedge clk or negedge rst)

    if(!rst) divnum<=0;

    else if(flag) divnum<=quotient+1'b1;

    else divnum<=quotient;

   

//counter_plush

always @(posedge clk or negedge rst)

    begin

    if(!rst) counter_pulseh<=hightime+16'h1;

    else if((counter==divnum)&&divnum) counter_pulseh<=0;

    else if(upclk) counter_pulseh<=counter_pulseh+1'b1;

    end

 

//pulse produce

always @(posedge clk or negedge rst)

    if(!rst) pulse<=1'b0;

    else if(counter_pulseh<=(hightime-1)) pulse<=1'b1;

    else pulse<=1'b0;

 

 

endmodule

 

 

 

 

 

 

 

 

 

 

 

文章评论5条评论)

登录后参与讨论

用户377235 2015-7-21 18:41

一种非常简单的方法能任意分频。思路很好,稍稍改一下可以作为一个标准的任意分频程序。谁要源码给我留言。

用户418606 2013-9-10 11:11

博主,我有一点不明,就是任意小数分频的最后两个always块似乎是用来产生高电平的,但是为什么要写的这么复杂,能详细解释一下吗?尤其是counter_pulseh这个变量,起到什么作用? always @(posedge clk or negedge rst) begin if(!rst) counter_pulseh<=hightime+16'h1; else if((counter==divnum)&&divnum) counter_pulseh<=0; else if(upclk) counter_pulseh<=counter_pulseh+1'b1; end //pulse produce always @(posedge clk or negedge rst) if(!rst) pulse<=1'b0; else if(counter_pulseh<=(hightime-1)) pulse<=1'b1; else pulse<=1'b0;

用户1529931 2013-8-15 14:40

学习

sunyzz 2013-8-15 14:03

现在也不迟啊

用户443267 2013-8-15 10:57

早点看见就好了
相关推荐阅读
sunyzz 2017-08-19 10:38
【博客大赛】AVALON总线介绍
1、AVALON总线简介Avalon总线是一种协议较为简单的片内总线,是ALTERA公司定义的片上互联总线,该总线可以将诸如NIOS II的CPU与其他外设连接起来,进而进行数据交换。AVALON总线...
sunyzz 2017-08-17 21:36
【博客大赛】不要轻易做职场滥好人
小A毕业于国内普通高校,但是他聪明,勤奋,能干,动手能力强,可是即便有这些优点也不能让小A轻轻松松找到一份好工作。这不,去年9月份小A好不容易找到一份工作,然后立马就入职了C公司,生怕C公司过两天不要...
sunyzz 2017-08-16 21:15
【博客大赛】IC设计低功耗技术四
五:工艺层面的降低功耗前面几节都是在讨论设计人员如何在前期阶段,中期阶段降低功耗,涉及到软件层面的,硬件层面的,这些技巧基本都是前辈总结出来的,或者根据理论推论出来的。但是到了后期,想降低功耗基本就要...
sunyzz 2017-08-14 22:35
【博客大赛】IC设计之低功耗技术三
四:RTL(寄存器传输)级的低功耗设计4.1 状态机的设计状态机编码中一般有两种方式,普通的二进制编码,特殊的格雷码,格雷码的特点是两个数据之间的跳变时只会有一个bit在toggle,显然比起多bit...
sunyzz 2017-08-12 16:51
【博客大赛】IC设计之低功耗技术二
三、架构层面的降低功耗系统的实现有很多的方式,每种方式对功耗的影响都不相同,本节主要介绍架构对功耗的影响。3.1 高级门口电路 在同步电路系统中,时钟占据了大部分的动态功耗,因而在一些情况下,如果有些...
sunyzz 2017-08-12 10:37
【博客大赛】IC 设计之低功耗技术一
一、前言随着计算机技术和微电子技术的迅速发展,嵌入式系统应用领域越来越广泛。节能是全球化的热潮,如计算机里的许多芯片过去用5V供电,现在用3.3V,1.8V,甚至更低的电压。目前的低功耗设计主要从芯片...
我要评论
5
20
关闭 站长推荐上一条 /2 下一条