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