Verilog分频器设计.docx

上传人:b****8 文档编号:9811734 上传时间:2023-02-06 格式:DOCX 页数:19 大小:18.89KB
下载 相关 举报
Verilog分频器设计.docx_第1页
第1页 / 共19页
Verilog分频器设计.docx_第2页
第2页 / 共19页
Verilog分频器设计.docx_第3页
第3页 / 共19页
Verilog分频器设计.docx_第4页
第4页 / 共19页
Verilog分频器设计.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

Verilog分频器设计.docx

《Verilog分频器设计.docx》由会员分享,可在线阅读,更多相关《Verilog分频器设计.docx(19页珍藏版)》请在冰豆网上搜索。

Verilog分频器设计.docx

Verilog分频器设计

Verilog分频器设计

moduleadder(clk,z);

outputz;

regq;

regz;

always@(posedgeclk)

begin

if(q%9==0)

z<=q;

else

q=q+1;

end

endmodule

modulecounter9(clk,datein,z);

outputz;

inputclk;

inputdatein;

regz;

reg[3:

0]q;

always@(posedgeclk)

begin

q<=q+1;

if(q==4'b1001)

begin

q<=4'b0000;

z<=datein;

end

end

endmodule

2008-11-0419:

58

分频器是FPGA设计中使用频率非常高的基本单元之一。

尽管目前在大部分设计中还广泛使用集成锁相环(如altera的PLL,Xilinx的DLL)来进行时钟的分频、倍频以及相移设计,但是,对于时钟要求不太严格的设计,通过自主设计进行时钟分频的实现方法仍然非常流行。

首先这种方法可以节省锁相环资源,再者,这种方式只消耗不多的逻辑单元就可以达到对时钟操作的目的。

偶数倍分频:

偶数倍分频应该是大家都比较熟悉的分频,通过计数器计数是完全可以实现的。

如进行N倍偶数分频,那么可以通过由待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数。

以此循环下去。

这种方法可以实现任意的偶数分频。

moduleodd_division(clk,rst,count,clk_odd);/*count没必要放在端口中,这里只是为了仿真时观察*/

inputclk,rst;

outputclk_odd;

output[3:

0]count;

regclk_odd;

reg[3:

0]count;

parameterN=6;/*6分频*/

always@(posedgeclk)

if(!

rst)

begin

count<=1'b0;

clk_odd<=1'b0;

end

else

if(count

begin

count<=count+1'b1;

end

else

begin

count<=1'b0;

clk_odd<=~clk_odd;

end

endmodule

奇数倍分频:

归类为一般的方法为:

对于实现占空比为50%的N倍奇数分频,首先进行上升沿触发进行模N计数,计数从零开始,到N-1)/2进行输出时钟翻转,然后经过(N+1)/2再次进行翻转得到一个占空比非50%奇数n分频时钟。

再者同时进行下降沿触发的模N计数,到和上升沿过(N-1)/2时,输出时钟再次翻转生成占空比非50%的奇数n分频时钟。

两个占空比非50%的n分频时钟相或运算,得到占空比为50%的奇数n分频时钟。

moduleeven_division(clk,rst,count1,count2,clk_even);/*count1,count2没必要放在端口中,这里只是为了仿真时观察*/

inputclk,rst;

output[3:

0]count1,count2;

outputclk_even;

reg[3:

0]count1,count2;

regclkA,clkB;

wireclk_even,clk_re;

parameterN=5;/*5分频*/

assignclk_re=~clk;

assignclk_even=clkA|clkB;

always@(posedgeclk)

if(!

rst)

begin

count1<=1'b0;

clkA<=1'b0;

end

else

if(count1<(N-1))

begin

count1<=count1+1'b1;/*这里是非阻塞赋值是先执行了下面的IF判断,最后才赋的值。

最初看这程序时没注意,想了好半天*/

if(count1==(N-1)/2)

begin

clkA<=~clkA;

end

end

else

begin

clkA<=~clkA;

count1<=1'b0;

end

always@(posedgeclk_re)

if(!

rst)

begin

count2<=1'b0;

clkB<=1'b0;

end

else

if(count2<(N-1))

begin

count2<=count2+1'b1;

if(count2==(N-1)/2)

begin

clkB<=~clkB;

end

end

else

begin

clkB<=~clkB;

count2<=1'b0;

end

endmodule

VerilogHDL的分频器设计

2009-12-0310:

22

用D触发器实现2倍分频的Verilog描述?

moduledivide2(clk,clk_o,reset);

inputclk,reset;

outputclk_o;

wirein;

regout;

always@(posedgeclkorposedgereset)

if(reset)

out<=0;

else

out<=in;

assignin=~out;

assignclk_o=out;

endmodule

用verilog实现分频的一点心得2007-08-0422:

40

在用verilog编写程序的过程中,将时钟进行11分频,花了好多的心思才将其搞定。

通常实现偶数的分频比较容易,以十分频为例:

always@(posedgeclkorposedgereset)

if(reset)

begin

  k<=0;

  clk_10<=0;

 end

else

 if(k==4)

  begin

   k<=0;

   clk_10<=~clk_10;

  end

else

k<=k+1;

  二分频最简单了,一句话就可以了:

always@(negedgeclk)clk_2<=clk_2;

若进行奇数分频,则稍微麻烦点,以11分频为例:

always@(posedgeclk)

if(!

reset)

 begin

  i<=0;

  clk11<=0;

 end

else

 if(i==5)

  begin

    clk11<=~clk11;

    i<=i+1;

  end

else

 if(i==10)

  begin

    i<=0;

    clk11<=~clk11;

 end

else

i<=i+1;

  以上语句虽然可以实现,但是逻辑有点繁,弄不好就出错了,建议使用两个always语句来实现:

always@(posedgeclk)

if(!

reset)

 i<=0;

else

 begin

  if(i==10)

    i<=0;

   else

    i<=i+1;

 end

always@(posedgeclk)

if(!

reset)

  clk11<=0;

else

  if((i==5)|(i==10))

     clk11<=~clk11;

  两个always,一个用来计数,一个用来置数。

另外,这个样子好像也可以,在时钟的上升沿和下降沿都计数,但是不被综合器综合,会提示敏感信号太复杂:

always@(posedgeclkornegedgeclk)

if(reset)

 begin

  k<=0;

  clk_11<=0;

 end

else

 if(k==10)

  begin

   k<=0;

   clk_11<=~clk_11;

  end

else

k<=k+1;

三分频的Verilog实现

rickywu发表于2005-12-1211:

14:

00

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

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

modulediv3(CLKIN,CLKOUT,RESETn);

inputCLKIN,RESETn;

outputCLKOUT;

//internalcountersignals

reg[1:

0]count_a;

reg[1:

0]count_b;

regCLKOUT;

always@(negedgeRESETnorposedgeCLKIN)

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@(negedgeRESETnornegedgeCLKIN)

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_aorcount_borRESETn)

begin

if(RESETn==1'b0)

CLKOUT=1'b0;

elseif((count_a+count_b==4)||(count_a+count_b==1))

CLKOUT=~CLKOUT;

end

endmodule

012012

\//\\//\

012012

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

modulediv3(CLKIN,CLKOUT,RESETn);

inputCLKIN,RESETn;

outputCLKOUT;

wired;

regq1,q2;

wireCLKOUT;

always@(negedgeRESETnorposedgeCLKIN)

begin

if(RESETn==1'b0)

q1<=1'b0;

else

q1<=d;

end

always@(negedgeRESETnorposedgeCLKIN)

begin

if(RESETn==1'b0)

q2<=1'b0;

else

q2<=q1;

end

assignd=~q1&~q2;

assignCLKOUT=q2;

endmodule

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

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

占空比为50%的一个更好的实现。

modulediv3(CLKIN,CLKOUT,RESETn);

inputCLKIN,RESETn;

outputCLKOUT;

//internalcountersignals

reg[1:

0]count_a;

regb,c;

//regCLKOUT;

wireCLKOUT;

always@(negedgeRESETnorposedgeCLKIN)

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@(negedgeRESETnornegedgeCLKIN)

begin

if(RESETn==1'b0)

b<=1'b0;

else

if(count_a==2'b01)

b<=2'b0;

else

b<=1'b1;

end

always@(negedgeRESETnorposedgeCLKIN)

begin

if(RESETn==1'b0)

c<=1'b0;

else

if(count_a==2'b10)

c<=1'b1;

elseif(count_a==2'b01)

c<=1'b0;

end

assignCLKOUT=b&c;

endmodule

如果不考虑占空比,直接利用计数器来进行分频,则占空比会发生变化。

下面程序实现1:

1的三分频。

moduledev3_1(clkin,clkout);

inputclkin;

outputclkout;

reg[1:

0]s1,s2;

always@(posedgeclkin)begin

case(s2)

2'b00:

s2<=2'b01;

2'b01:

s2<=2'b10;

2'b10:

s2<=2'b00;

default:

s2<=2'b00;

endcase

end

always@(negedgeclkin)begin

case(s1)

2'b00:

s1<=2'b01;

2'b01:

s1<=2'b10;

2'b10:

s1<=2'b00;

default:

s1<=2'b00;

endcase

end

assignclkout=~(s1[1]|s2[1]);

endmodule

N倍偶数分频器.(Verilog)

N_bit_even_divider.v/Verilog

--------------------------------------------------------------------------------

moduleN_bit_even_divider(

inputi_clk,

inputrst_n,

outputrego_clk

);

parameterN=N_bit_even;

//bit_of_N:

N_bit_even的二进制位宽

//当N=2时,(bit_of_N-1)取2,仿真可观察到计数器变化;

//(bit_of_N-1)取1或0,不影响结果.

reg[(bit_of_N-1):

0]cnt;//计数器单元

//上升沿计数:

0~(N-1)

always@(posedgei_clk,negedgerst_n)

begin

if(!

rst_n)

cnt<=0;

else

begin

if(cnt==N-1)

cnt<=0;

else

cnt<=cnt+1;

end

end

//生成上升沿时钟

//0~(N/2-1)↑->1;(N/2)~(N-1)↑->0

always@(posedgei_clk,negedgerst_n)

begin

if(!

rst_n)

o_clk<=0;

else

begin

if(cnt<=(N/2-1))

o_clk<=1;

else

o_clk<=0;

end

end

endmodule

--------------------------------------------------------------------------------

仿真波形

图1.N_bit_even=2,(bit_of_N-1)取1或0)

图2.N_bit_even=2,(bit_of_N-1)取2)

图3.N_bit_even=4

图4.N_bit_even=6

N倍奇数分频器.(Verilog)

N_bit_odd_divider.v/Verilog

moduleN_bit_odd_divider(

inputi_clk,

inputrst_n,

outputo_clk

);

parameterN=N_bit_odd;//设置奇数(除1外)倍分频

//bit_of_N:

N_bit_odd的二进制位宽

reg[(bit_of_N-1):

0]cnt_p;//上升沿计数单位

reg[(bit_of_N-1):

0]cnt_n;//下降沿计数单位

regclk_p;//上升沿时钟

regclk_n;//下降沿时钟

assigno_clk=clk_n&clk_p;//按位与(作用:

掩码)

//上升沿计数器:

0~(N-1)

always@(posedgei_clkornegedgerst_n)

begin

if(!

rst_n)

cnt_p<=0;

else

begin

if(cnt_p==N-1)

cnt_p<=0;

else

cnt_p<=cnt_p+1;

end

end

//生成上升沿时钟

//0~(N>>1)↑->1;((N>>1)+1)~(N-1)↑->0

always@(posedgei_clkornegedgerst_n)

begin

if(!

rst_n)

clk_p<=0;

else

begin

if(cnt_p<=(N>>1))//0~(N>>1)

clk_p<=1;

else

clk_p<=0;

end

end

//下降沿计数器:

0~(N-1)

always@(negedgei_clkornegedgerst_n)

begin

if(!

rst_n)

cnt_n<=0;

else

begin

if(cnt_n==N-1)

cnt_n<=0;

else

cnt_n<=cnt_n+1;

end

end

//生成下降沿时钟

//0~(N>>1)↓->1;((N>>1)+1)~(N-1)↓->0

always@(negedgei_clkornegedgerst_n)

begin

if(!

rst_n)

clk_n<=0;

else

begin

if(cnt_n<=(N>>1))//0~(N>>1)

clk_n<=1;

else

clk_n<=0;

end

end

endmodule

仿真波

用Verilog设计一个5分频器

默认分类2009-06-1208:

29:

25阅读127评论0  字号:

大中小 订阅

.用Verilog设计一个5分频器。

       5分频,奇数分频都可以类似这么做,只需要改div1和div2的参数。

div1为奇数分频除2的余数。

采用上升延和下降延分别触发不同波形,最后叠加的方式产生奇数分频。

moduledivfreq(clk,clk1x,rst,clk1xpose,clk1xnege,coutpose,coutnege);

inputclk;

inputrst;

outputclk1x;

outputclk1xpose;

outputclk1xnege;

output[2:

0]coutpose;

output[2:

0]coutnege;

regclk1xpose;

regclk1xnege;

reg[2:

0]coutpose;

reg[2:

0]coutnege;

parameterdiv1=1,div2=4;  //div1=5/2,div2=5-1

assignclk1x=clk1xpose|clk1xnege;

always@(posedgeclkornegedgerst)

begin

  if(!

rst)

 

    clk1xpose=0;

  elseif(coutpose==div1)

    clk1xpose=~clk1xpose;

  elseif(coutpose==div2)

    clk1xpose=~clk1xpose;

  else

    clk1xpose=clk1xpose;

end

always@(negedgeclkornegedgerst)

begin

  if(!

rst)

 

    clk1xnege=0;

  elseif(coutnege==div1)

   clk1xnege=~clk1xnege;

  elseif(coutnege==div2)

   clk1xnege=~clk1xnege;

  else

   clk1xnege=clk1xnege;

end

always@(posedgeclkornegedgerst)

begin

  if(!

rst)

   coutpose=0;

  elseif(coutpose==div2)

   coutpose=0;

  else

   coutpose=coutpose+1;

end

always@(negedgeclkornegedgerst)

begin

  if(!

rst)

   coutnege=0;

  elseif(coutnege==div2)

   coutnege=0;

  else

   coutnege=coutnege+1;

end

endmodule

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 其它

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1