原创 奇数分频

2007-1-16 14:29 5864 6 6 分类: FPGA/CPLD

麻烦来了,突然通知我要盲审,真点背,有个同学说全学校没有几个,服了,呵呵,不过,凡事要变相的看待,是坏事也是好事,无所谓,知难而上,没有克服不了的困难。呵呵,得了,得改论文了,要做就做好,自己肯定可以的,哈哈,阿Q!


时间紧,但又怕以后又找不到这些资料了,所以先贴上来,没有整理,问题肯定很多,等忙完论文再整理,有问题别见怪,呵呵


整理自EDA论坛


N奇数分频思路总结 (精华贴)
N
奇数分频思路总结
N
奇数分频,要使占空比为50%,以如下思路实现:
A
、以原时钟周期的N倍作为一个处理周期;(用计数器计数的作用)
B
、生成占空比为N2 : N21(除法取整)的波形;(以计数器值采样)
C
、将B生成的波形相移原时钟的半个周期;(用负沿打的作用)
D
、若高电平占N2宽,输出将BC的波形相或;若高电平占N21宽,输出将BC的波形相与
其它的思路:
1
、用状态机实现,但感觉没有上面的方法直接;
2
、其它波形处理方式,大家可补充;
几个观念:
1
、并不是用了时钟的正沿和负沿打,就不能综合了,以上的代码均能正确进行综合实现;
2
、虽然原则上不建议一个设计中既用时钟的上沿打,又用时钟的负沿打,因为违反的时钟的归一性,但是根据具体情况可适当运用,这只是原则,不是说用了就是错!
三倍分频
方式一,行为描述:
module threediv(rst,clk,clkout,clkout1,clkout2);
input rst,clk;
output clkout,clkout1,clkout2;
reg clkout;
reg clk1o;
reg clkout1;
reg clk2o;
reg clkout2;
always@(posedge clk)
if(!rst)
clkout2<=0;
else
clkout2<=(~clk1o)^clkout2;
always@(posedge clk)
if(!rst)
clk1o<=0;
else
clk1o<=clkout2;
always@(negedge clk)
if(!rst)
clkout1<=0;
else
clkout1<=(~clk2o)^clkout1;
always@(negedge clk)
if(!rst)
clk2o<=0;
else
clk2o<=clkout1;
always@(clkout1 or clkout2 or rst)
if(!rst)
clkout=0;
else
clkout=clkout2|clkout1;
endmodule  

根据以上的逻辑,我用寄存器级描述了一下,更接近原理图的方式,可直接绘图,代码如下:
module dffdiv3(rst,clk,clko);
    input rst;
    input clk;
    output clko;
    dffp dp1(.rst(rst),.clk(clk),.din(feedp),.dout(wp1));
    dffp dp2(.rst(rst),.clk(clk),.din(wp1),.dout(wp2));
    assign feedp=~wp2^wp1;
   
    dffn dn1(.rst(rst),.clk(clk),.din(feedn),.dout(wn1));
    dffn dn2(.rst(rst),.clk(clk),.din(wn1),.dout(wn2));
    assign feedn=~wn2^wn1;
    assign clko="feedp|feedn";
endmodule
module dffp(rst,clk,din,dout);
    input rst;
    input clk;
    input din;
    output dout;
    reg dout;
    always @(negedge rst or posedge clk)
    if(!rst)
    dout<=0;
    else
    dout<=din;
endmodule
module dffn(rst,clk,din,dout);
    input rst;
    input clk;
    input din;
    output dout;
    reg dout;
    always @(negedge rst or negedge clk)
    if(!rst)
    dout<=0;
    else
    dout<=din;
endmodule
测试仿真代码:
`timescale 1ns/1ns
module dffdiv3_tp();
    reg rst,clk;
    wire clko;
dffdiv3 Dffdiv3(.rst(rst),.clk(clk),.clko(clko));
initial
begin
   rst=1;
   clk=0;
   #20;
   rst=0;
   #20;
   rst=1;
end
always #10 clk=~clk;
endmodule

//
以上的实现没有时钟双沿的问题,因为时钟的正负沿使用针对不同的数据流扩展到N奇数分频方式
m
odule odddiv(rst,clk,clkout);
    parameter N="3";  //
计数器的位数        N的最大计数值要大于或等于M
    parameter M="7";         //
要分频的模,取奇数
    input rst;
    input clk;
    output clkout;
    reg tempp,tempn;
    //assign clkp="clk";
    //assign clkn=~clk;
    reg [N-1:0] count;
    always @(negedge rst or posedge clk)
    if(!rst)
    begin
    count<=0;
    tempp<=0;
    end
    else
    begin
    count<=count+1;
    if(count==M/2)
    tempp<=1;
    else if(count==M-1)
    begin
    tempp<=0;

    count<=0;
    end
    end
    always @(negedge rst or negedge clk)
    if(!rst)
    tempn<=0;
    else
    tempn<=tempp;
    assign clkout="tempp|tempn";
endmodule
测试代码:
`timescale 1ns/1ns
module odddiv_tp();
    reg rst,clk;
    wire clkout;
odddiv Odddiv(.rst(rst),.clk(clk),.clkout(clkout));
initial
begin
   rst=1;
   clk=0;
   #20;
   rst=0;
   #20;
   rst=1;
end
always #10 clk=~clk;
endmodule
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


以上是占空比11的,对于不做要求的,一般计数器应该都可以满足的。个人感觉一下方法任意分频可以进行,不知道对不对,呵呵


以下是45分频:


       module divide_45(clk,rst,out);


       input              clk,rst;


       output     out;


       reg         [5:0] counter;


       always@(posedge clk)


       begin


              if(rst)


                     counter<=6'b00_0000;


              else


                     begin


                            if(counter==6'b10_1100)


                                   counter<=6'b00_0000;


                            else


                                   counter<=counter+6'b00_0001;


                     end


       end


       assign out="counter"[5]?1:0;


       endmodule


       module top;


   reg   clk,rst;


   wire  out;


   divide_45  divide(.clk(clk),.rst(rst),.out(out));


   initial clk="1"'b0;


   always #5 clk=~clk;


   initial


   begin


      rst=1'b1;


         #50 rst="1"'b0;


   end


   initial #10000 $finish;


   endmodule     

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
6
关闭 站长推荐上一条 /3 下一条