FPGA中的分频与延时.docx

上传人:b****4 文档编号:12408617 上传时间:2023-04-18 格式:DOCX 页数:15 大小:31.04KB
下载 相关 举报
FPGA中的分频与延时.docx_第1页
第1页 / 共15页
FPGA中的分频与延时.docx_第2页
第2页 / 共15页
FPGA中的分频与延时.docx_第3页
第3页 / 共15页
FPGA中的分频与延时.docx_第4页
第4页 / 共15页
FPGA中的分频与延时.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

FPGA中的分频与延时.docx

《FPGA中的分频与延时.docx》由会员分享,可在线阅读,更多相关《FPGA中的分频与延时.docx(15页珍藏版)》请在冰豆网上搜索。

FPGA中的分频与延时.docx

FPGA中的分频与延时

FPGA中的分频

FPGA中的分频是很重要的一个内容,只要涉及时序电路,几乎都会有分频的情况出现。

但分频的语句却各有不同,以下就是不同写法,但不管怎样,分频一句话,就是用计数器来实现的。

下面我就几种不同的写法说说我的看法,在FPGA中是如何实现分频的。

不过再说之前首先的了解时钟。

我这里以系统时钟clk,f=50MH为例。

由此可知其T=20ns,f=50MH也就是说一秒内,时钟高低电平改变50M次。

这里我用verilog为例,对于vhdl类同。

讲解时只取分频部分语句后面附有

完正的程序

第一种写法:

always@(posedgeclkornegedgerst)

begin。

if(!

rst)begin

clk_div1<=0;

end

elsebegin

if(clk_div1!

=11)

clk_div1<=clk_div1+1;

else

clk_div1<=0;

end

end

always@(posedgeclkornegedgerst)

begin

if(!

rst)begin

clk_div2<=0;

state<=0;

cnt<=0;

out<=0;

end

elseif(clk_div1==11)begin

//执行什么功能

注意在这里此语句中,我没有写完整,只是把分频的关键地方写出来了,特别是红色标注的地方。

这里暂时不管定义的rst,state。

这些变量。

关键是此句话

if(clk_div1!

=11)

clk_div1<=clk_div1+1;

else

clk_div1<=0;

此句话可知计数器clk_divl对系统时钟进行计数,并且只计数到11,clk_divl变等于0。

这里有点类似于延时,下面以图形来说明。

由上图可知,clk=5MH的时钟,在计数器clk_divl下计数11,产生约4MH的时钟,此后系统便在4MH的频率下工作。

这里他并未把新时钟提出来,而是在原来的时钟上分出4MH情况来工作。

第二种写法:

always@(posedgeclk_50M)

begin

if(count==25000000)//此处也可写成24999999

begin

div_clk<=~div_clk;

end

else

count<=count+1;

led_out<=div_clk;

end

在这里我们也不去关注分频以外的东西,关键此语句

if(count==25000000)

begin

div_clk<=~div_clk;

end

else

count<=count+1;

我们看到这里实际上定义了一个新时钟名:

div_clk,系统此后便可以以此时钟来工作,在这里只要明白这样的解释就行了。

--

(1)如进行N倍偶数、占空比为50%的分频,那么可以通过由待分频的时钟触发计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,以此循环下去。

--

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

一个公式就是:

N为分频数,M为计数器的计数值。

N/2-1=M。

此时为,进行N倍偶数、占空比为50%的分频。

N-1=M。

此时进行N倍偶数、占空比为1/N的分频。

例如一个50MH的分频其图为:

其计数值M为25000000或24999999

对于基数的分频:

对于实现占空比为50%的N倍奇数分频,首先进行上升沿触发进

行模N计数,计数到(N-1)/2进行输出时钟翻转,然后经过(N-1)/2(即计数到N-1时)再次进行翻转得到一个占空比非50%奇数n分频时钟。

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

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

第三种写法:

always@(posedgeclk,negedgeres)

begin

if(!

res)

begin

led<=6'b000000;

end

else

begin

case(count[26:

23])

4'd0:

led<=6'b111110;//Xmiao

4'd1:

led<=6'b111101;//Ymiao

4'd2:

led<=6'b111011;

4'd3:

led<=6'b110111;

4'd4:

led<=6'b101111;

4'd5:

led<=6'b011111;

4'd6:

led<=6'b011111;

4'd7:

led<=6'b101111;

4'd8:

led<=6'b110111;

4'd9:

led<=6'b111011;

4'd10:

led<=6'b111101;

4'd11:

led<=6'b111110;

4'd12:

led<=6'b000000;

4'd13:

led<=6'b111111;

4'd14:

led<=6'b000111;

4'd15:

led<=6'b111000;

default:

led<=6'b000000;

endcase

在这里我们也不去关注分频以外的东西,关键此语句

case(count[26:

23])

实际上这里定义了一个26位的计数器,但实际上为后22位计数,前4位定义状态。

这种分频可用于数码管的动态显示或流水灯跑马灯等。

其具体分析为:

26位:

2524232221。

0

4'd0:

00000000000000000000000000//第一个状态

00001111111。

1X秒//计数满22位为80ms

4'd1:

00010000000000。

00000//第二个状态

00011111111。

11111Y秒//计数满22位为80ms

4’d2:

00100000000。

00000

00101111111.。

11111111111Z秒//计数满22位为80ms

4’d3:

00110000000。

00000000//第三个

001111111111111。

1111111111W秒//计数满22位为80ms

4’d15:

111000000000000000000。

000000//第四个

11101111111。

1111111111//计数满22位为80ms

从面可以看出每个状态停留的时间均为80ms,而每个状态在下一个时钟来时

又加一,从而转到下一个状态。

这样状态连续,而每个状态时间有一样,变可以实现动态显示和流水灯。

 

附以上三个完整程序:

第一个:

modulebuzzer(clk,rst,out);

inputclk,rst;

outputout;

regout;

reg[3:

0]clk_div1;//基频分频计数器,基频为4M

reg[12:

0]clk_div2;//音阶分频计数器,由基频分频产生各个音阶

reg[21:

0]cnt;//各音阶发声时间长短计数器

reg[2:

0]state;

parameterduo=3822,//各个音调的分频系数

lai=3405,

mi=3034,

fa=2865,

suo=2551,

la=2273,

xi=2024,

duo1=1911;

always@(posedgeclkornegedgerst)//这里采用了,分频的另一种手法,相当于延时。

begin//分频的实现方式有多种。

if(!

rst)begin

clk_div1<=0;

end

elsebegin

if(clk_div1!

=11)//在原来的时钟上分频,并未加入一个新的时钟。

及原来的时钟到11个时钟(波形)//才进行下一步做法。

clk_div1<=clk_div1+1;//相当于每4MH,做一次指令功能。

因为11个时钟为220ns,所以周期为220ns,//频率为

else//4MH。

及原来的时钟到11个时钟(波形)才进行下一步做法(计时11个波形)

clk_div1<=0;

end

end

always@(posedgeclkornegedgerst)

begin

if(!

rst)begin

clk_div2<=0;

state<=0;

cnt<=0;

out<=0;

end

elseif(clk_div1==11)begin

case(state)

3'b000:

begin//发“多”

cnt<=cnt+1;

if(cnt==22'h3fffff)

state<=3'b001;

if(clk_div2!

=duo)//+3822

clk_div2<=clk_div2+1;

elsebegin

clk_div2<=0;

out<=~out;

end

end

3'b001:

begin//发“来”

cnt<=cnt+1;

if(cnt==22'h3fffff)

state<=3'b010;

if(clk_div2!

=lai)

clk_div2<=clk_div2+1;//

elsebegin

clk_div2<=0;

out<=~out;

end

end

3'b010:

begin//发"米“

cnt<=cnt+1;

if(cnt==22'h3fffff)

state<=3'b011;

if(clk_div2!

=mi)

clk_div2<=clk_div2+1;

elsebegin

clk_div2<=0;

out<=~out;

end

end

3'b011:

begin//发"法“

cnt<=cnt+1;

if(cnt==22'h3fffff)

state<=3'b100;

if(clk_div2!

=fa)

clk_div2<=clk_div2+1;

elsebegin

clk_div2<=0;

out<=~out;

end

end

3'b100:

begin//发"梭“

cnt<=cnt+1;

if(cnt==22'h3fffff)

state<=3'b101;

if(clk_div2!

=suo)

clk_div2<=clk_div2+1;

elsebegin

clk_div2<=0;

out<=~out;

end

end

3'b101:

begin//发"拉“

cnt<=cnt+1;

if(cnt==22'h3fffff)

state<=3'b110;

if(clk_div2!

=la)

clk_div2<=clk_div2+1;

elsebegin

clk_div2<=0;

out<=~out;

end

end

3'b110:

begin//发"西“

cnt<=cnt+1;

if(cnt==22'h3fffff)

state<=3'b111;

if(clk_div2!

=xi)

clk_div2<=clk_div2+1;

elsebegin

clk_div2<=0;

out<=~out;

end

end

3'b111:

begin//发"多“(高音)

cnt<=cnt+1;

if(cnt==22'h3fffff)

state<=3'b000;

if(clk_div2!

=duo1)

clk_div2<=clk_div2+1;

elsebegin

clk_div2<=0;

out<=~out;

end

end

endcase

end

end

endmodule

第二个:

moduleledwater(clk_50M,led_out,f_led_out);

inputclk_50M;//系统时钟输入50M

//意味每一秒要变化50,000,000HZ

outputled_out;//每一秒闪烁一下

outputf_led_out;//每二秒闪烁一下

reg[24:

0]count;//分频计数器,25000000分频一秒

reg[24:

0]f_count;//分频计数器,12500000分频0.5秒

regdiv_clk,f_div_clk;

regled_out,f_led_out;

//分频计数器。

得到一秒的频率

always@(posedgeclk_50M)

begin

if(count==25000000)

begin//我们的时钟本身是每一秒要变化50,000,000HZ

//我们现在用count这个计数器让它自加到25,000,000HZ

div_clk<=~div_clk;//在这里我们就得到了0.5秒变化一次的信号。

//所以一个周期就是1Hz也就是一秒。

count<=0;//把计数器清零。

end

else

count<=count+1;//计数器自加。

led_out<=div_clk;//利用分频计数器得到显示一秒的闪烁效果

//在LED灯上面表现出来。

end

//分频计数器。

得到0.5秒的频率

always@(posedgeclk_50M)

begin

if(f_count==12500000)//我们现在用count这个计数器让它自加到12,500,000HZ

begin

f_div_clk<=~f_div_clk;//在这里我们就得到了0.25秒变化一次的信号。

//所以一个周期就是0.5也就是2HZ。

f_count<=0;

end

else

f_count<=f_count+1;//计数器自加。

f_led_out<=f_div_clk;//利用分频计数器得到显示一秒的闪烁效果

//在LED灯上面表现出来。

end

endmodule

第三个:

moduleledsan(clk,led,res);

inputclk;

output[5:

0]led;

inputres;

reg[26:

0]count;

reg[5:

0]led;

always@(posedgeclk)

begin

count<=count+1;

end

always@(posedgeclk,negedgeres)

begin

if(!

res)

begin

led<=6'b000000;

end

else

begin

case(count[26:

23])

4'd0:

led<=6'b111110;//Xmiao

4'd1:

led<=6'b111101;//Ymiao

4'd2:

led<=6'b111011;

4'd3:

led<=6'b110111;

4'd4:

led<=6'b101111;

4'd5:

led<=6'b011111;

4'd6:

led<=6'b011111;

4'd7:

led<=6'b101111;

4'd8:

led<=6'b110111;

4'd9:

led<=6'b111011;

4'd10:

led<=6'b111101;

4'd11:

led<=6'b111110;

4'd12:

led<=6'b000000;

4'd13:

led<=6'b111111;

4'd14:

led<=6'b000111;

4'd15:

led<=6'b111000;

default:

led<=6'b000000;

endcase

end

end

endmodule

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

当前位置:首页 > 党团工作 > 党团建设

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

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