用D触发器实现2倍分频的Verilog描述?
module divide2( clk , clk_o, reset);
input clk , reset;
output clk_o;
wire in;
reg out ;
always @ ( posedge clk or posedge reset)
if ( reset)
out <= 0;
else
out <= in;
assign in = ~out;
assign clk_o = out;
endmodule
用verilog实现分频的一点心得2007-08-04 22:40
在用verilog编写程序的过程中,将时钟进行11分频,花了好多的心思才将其搞定。通常实现偶数的分频比较容易,以十分频为例:
always @( posedge clk or posedge reset)
if(reset)
begin
k<=0;
clk_10<=0;
end
else
begin
k<=0;
clk_10<=~clk_10;
end
else
k<=k+1;
二分频最简单了,一句话就可以了:always @ (negedge clk) clk_2<=~clk_2;
若进行奇数分频,则稍微麻烦点,以11分频为例:
always @( posedge clk)
if(!reset)
begin
i<=0;
clk11<=0;
end
else
if(i==5)
begin
clk11<=~clk11;
i<=i+1;
end
else
if(i==10)
i<=0;
clk11<=~clk11;
end
else
i<=i+1;
以上语句虽然可以实现,但是逻辑有点繁,弄不好就出错了,建议使用两个always语句来实现:
always @( posedge clk)
if(!reset)
i<=0;
else
begin
if(i==10)
i<=0;
else
i<=i+1;
end
always @( posedge clk)
if(!reset)
clk11<=0;
else
if((i==5)|(i==10))
clk11<=~clk11;
两个always,一个用来计数,一个用来置数。另外,这个样子好像也可以,在时钟的上升沿和下降沿都计数,但是不被综合器综合,会提示敏感信号太复杂:
always @( posedge clk or negedge clk)
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 发
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
于2005-12-12 11:14:00
//很实用也是笔试面试时常考的,已经经过仿真
占空比要求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;
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
如果不考虑占空比,直接利用计数器来进行分频,则占空比会发生变化。下面程序实现1: 1的三分频。
module dev3_1(clkin,clkout);
input clkin;
output clkout;
reg [1:0]s1,s2;
always@(posedge clkin)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@(negedge clkin)begin
case(s1)
2'b00:s1<=2'b01;
2'b01:s1<=2'b10;
2'b10:s1<=2'b00;
default:s1<=2'b00;
endcase
end
assign clkout=~(s1[1]|s2[1]); endmodule
//偶数倍分频:偶数倍分频应该是大家都比较熟悉的分频,通过计数器计数是完全可以实现的。如进行N 倍偶数分频,那么可以通过由待分频的
//时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数。以此循
//环下去。这种方法可以实现任意的偶数分频。
module odd_division(clk,rst,count,clk_odd);
input clk,rst;
output clk_odd;
output[3:0] count;
reg clk_odd;
reg[3:0] count;
parameter N = 6;
always @ (posedge clk)
if(! rst)
begin
count <= 1'b0;
clk_odd <= 1'b0;
end
else
if ( count < N/2-1)
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分频时钟。
module even_division(clk,rst,count1,count2,clk_even);
input clk,rst;
output[3:0] count1,count2;
output clk_even;
reg[3:0] count1,count2;
reg clkA,clkB;
wire clk_even;
parameter N = 5;
assign clk_re = ~clk;
assign clk_even = clkA | clkB;
always @(posedge clk)
if(! rst)
begin
count1 <= 1'b0;
clkA <= 1'b0;
end
else
if(count1 < (N - 1))
begin
count1 <= count1 + 1'b1;
if(count1 == (N - 1)/2)
begin
clkA <= ~clkA;
end
end
else
begin
clkA <= ~clkA;
count1 <= 1'b0;
end
always @ (posedge clk_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