版权说明:未经许可,不得转载
一.目的
1.掌握时序逻辑电路的设计方法。
2.了解FPGA在时序逻辑电路中的实现过程。
3.熟悉用Verilog描述触发器、计数器等简单的时序逻辑电路。
二.工具
1.Digilent Anvyl开发板
2.安装了 ISE Design Suite软件的PC机一台
3.USB数据线一根
三.简单上手实验
1.将100MHz的时钟输入进行100M分频后,得到一个间隔1秒的脉冲。
(1) 利用这个脉冲设计一个10进制计数器,并用一个7段数码管显示出来;
(2) 利用这个脉冲设计一个60进制计数器,并用两个7段数码管显示出来;
(3) 利用这个脉冲设计一个数字时钟,从左到右的6个7段数码管,2个显示小时,2个显示分钟,2个显示秒。(读者可以根据前两个题的思路,自行思考此题怎么实现,很简单的)
2. 用很快的速度(约1/30秒)依次点亮6个7段数码管,利用人眼的余晖效应,得到需要的效果(在6个7段数码管上显示“AbCdEF”)。
四.实验原理
这里我主要讲讲两个很关键的地方:
1.关于如何得到间隔大约1s的脉冲
Anvyl实验板上D11引脚具有100MHz时钟,其周期为10^-8s,按其频率计数10^8次,时间为1s。十进制数10^8对应的二进制为:101111101011110000100000000(27位)
2.关于如何得到间隔大约1s的脉冲
(1)用很快的速度(约1/30s)一次点亮6个7段数码管,利用人眼的余晖效应,得到需要的效果。其周期为1/30*1/6,约2^-8s,其频率计数约2^19次。(微闪)
(2)6个数码管依次显示完不同数字的时间控制在10ms以内,其周期为1/100*1/6,约2^-9s,其频率计数约2*18次。(基本不闪)
五.实验步骤及结果分析
实验1.1
设计过程:
1.首先将100MHz的时钟分频,使之时钟脉冲变为1s。
2.然后设置每个时钟脉冲加1,计数器也加1。
3.把计数器对应的7段数码管显示出来即可。
下面给出源程序:
.v文件:
module fpga1(
input wire clk,
input wire clr,
input [0:2] y,
output reg [0:6] z1,
output reg [5:0] z2
);
reg [26:0] i;
reg [3:0] q;
always@(posedge clk)
i <= i + 1;
always@(negedge i[26])
begin
q <= q + 1;
if(q==9)
q <= 0;
end
always@(q)
begin
case(q)
0:z1=7'b1111110;
1:z1=7'b0110000;
2:z1=7'b1101101;
3:z1=7'b1111001;
4:z1=7'b0110011;
5:z1=7'b1011011;
6:z1=7'b1011111;
7:z1=7'b1110000;
8:z1=7'b1111111;
9:z1=7'b1111011;
default z1=7'b1111110;
endcase
end
always@(*)
case(y)
0:z2=6'b000001;
1:z2=6'b000010;
2:z2=6'b000100;
3:z2=6'b001000;
4:z2=6'b010000;
5:z2=6'b100000;
default z2=6'b000001;
endcase
endmodule
.ucf文件:
NET clk LOC=D11;
NET z2<0> LOC=P16;
NET z2<1> LOC=M17;
NET z2<2> LOC=N16;
NET z2<3> LOC=P19;
NET z2<4> LOC=AA20;
NET z2<5> LOC=AB21;
NET z1<0> LOC=AA21;
NET z1<1> LOC=AA22;
NET z1<2> LOC=Y22;
NET z1<3> LOC=N15;
NET z1<4> LOC=AB19;
NET z1<5> LOC=P20;
NET z1<6> LOC=Y21;
NET y<0> LOC=R4;
NET y<1> LOC=P6;
NET y<2> LOC=P5;
实验结果截图如下:
上图为显示到7s的时刻
实验1.2
整个设计过程与上个实验相差不大,主要是需要并发的显示两个数码管。把时间控制在10ms以内即可实现。
源程序如下:
.v文件:
module fpga2(
input wire clk,
input wire clr,
output reg [0:6] z1,
output reg [5:0] z2
);
reg [3:0] led;
reg [26:0] i;
reg [18:0] j;
reg [3:0] gw;
reg [2:0] sw;
always@(posedge clk)
begin
i <= i + 1;
j <= j + 1;
end
always@(posedge j[18])
begin
led <= led + 1;
if(led==1)
led <= 0;
end
always@(negedge i[26])
begin
begin
gw <= gw + 1;
if(gw==9)
begin
gw <= 0;
sw <= sw + 1;
if(sw==5)
sw <= 0;
end
end
end
always@(*)
begin
if(led==1)
begin
case(gw)
0:z1=7'b1111110;
1:z1=7'b0110000;
2:z1=7'b1101101;
3:z1=7'b1111001;
4:z1=7'b0110011;
5:z1=7'b1011011;
6:z1=7'b1011111;
7:z1=7'b1110000;
8:z1=7'b1111111;
9:z1=7'b1111011;
default z1=7'b1111110;
endcase
end
else if(led==0)
begin
case(sw)
0:z1=7'b1111110;
1:z1=7'b0110000;
2:z1=7'b1101101;
3:z1=7'b1111001;
4:z1=7'b0110011;
5:z1=7'b1011011;
default z1=7'b1111110;
endcase
end
end
always@(*)
begin
case(led)
0:z2=6'b000001;
1:z2=6'b000010;
2:z2=6'b000100;
3:z2=6'b001000;
4:z2=6'b010000;
5:z2=6'b100000;
default z2=6'b000001;
endcase
end
endmodule
.ucf文件:
NET clk LOC=D11;
NET z2<0> LOC=P16;
NET z2<1> LOC=M17;
NET z2<2> LOC=N16;
NET z2<3> LOC=P19;
NET z2<4> LOC=AA20;
NET z2<5> LOC=AB21;
NET z1<0> LOC=AA21;
NET z1<1> LOC=AA22;
NET z1<2> LOC=Y22;
NET z1<3> LOC=N15;
NET z1<4> LOC=AB19;
NET z1<5> LOC=P20;
NET z1<6> LOC=Y21;
实验结果截图如下:
上图为时钟为25s时刻
上图为时钟为44s时刻
实验2
设计过程:此题与上一题有异曲同工之处,上一题是快速的点亮2个7段数码管,此题是快速的点亮6个7段数码管。并且对每个数码管分别进行编码,使之显示abcdef。
源程序:
.v文件:
module test31(
input wire clk,
input wire clr,
output reg [0:6] z1,
output reg [5:0] z2
);
reg [3:0] led;
reg [18:0] j;
reg [3:0] a;
reg [3:0] b;
reg [3:0] c;
reg [3:0] d;
reg [3:0] e;
reg [3:0] f;
always@(*)
begin
a <= 10;
b <= 11;
c <= 12;
d <= 13;
e <= 14;
f <= 15;
end
always@(posedge clk)
begin
j <= j + 1;
end
always@(posedge j[18])
begin
led <= led + 1;
if(led==5)
led <= 0;
end
always@(*)
begin
if(led==4)
begin
case(a)
0:z1=7'b1111110;
1:z1=7'b0110000;
2:z1=7'b1101101;
3:z1=7'b1111001;
4:z1=7'b0110011;
5:z1=7'b1011011;
6:z1=7'b1011111;
7:z1=7'b1110000;
8:z1=7'b1111111;
9:z1=7'b1111011;
'hA:z1=7'b1110111;
'hB:z1=7'b0011111;
'hC:z1=7'b1001110;
'hD:z1=7'b0111101;
'hE:z1=7'b1001111;
'hF:z1=7'b1000111;
default z1=7'b1111110;
endcase
end
else if(led==5)
begin
case(b)
0:z1=7'b1111110;
1:z1=7'b0110000;
2:z1=7'b1101101;
3:z1=7'b1111001;
4:z1=7'b0110011;
5:z1=7'b1011011;
6:z1=7'b1011111;
7:z1=7'b1110000;
8:z1=7'b1111111;
9:z1=7'b1111011;
'hA:z1=7'b1110111;
'hB:z1=7'b0011111;
'hC:z1=7'b1001110;
'hD:z1=7'b0111101;
'hE:z1=7'b1001111;
'hF:z1=7'b1000111;
default z1=7'b1111110;
endcase
end
else if(led==2)
begin
case(c)
0:z1=7'b1111110;
1:z1=7'b0110000;
2:z1=7'b1101101;
3:z1=7'b1111001;
4:z1=7'b0110011;
5:z1=7'b1011011;
6:z1=7'b1011111;
7:z1=7'b1110000;
8:z1=7'b1111111;
9:z1=7'b1111011;
'hA:z1=7'b1110111;
'hB:z1=7'b0011111;
'hC:z1=7'b1001110;
'hD:z1=7'b0111101;
'hE:z1=7'b1001111;
'hF:z1=7'b1000111;
default z1=7'b1111110;
endcase
end
else if(led==3)
begin
case(d)
0:z1=7'b1111110;
1:z1=7'b0110000;
2:z1=7'b1101101;
3:z1=7'b1111001;
4:z1=7'b0110011;
5:z1=7'b1011011;
6:z1=7'b1011111;
7:z1=7'b1110000;
8:z1=7'b1111111;
9:z1=7'b1111011;
'hA:z1=7'b1110111;
'hB:z1=7'b0011111;
'hC:z1=7'b1001110;
'hD:z1=7'b0111101;
'hE:z1=7'b1001111;
'hF:z1=7'b1000111;
default z1=7'b1111110;
endcase
end
else if(led==0)
begin
case(e)
0:z1=7'b1111110;
1:z1=7'b0110000;
2:z1=7'b1101101;
3:z1=7'b1111001;
4:z1=7'b0110011;
5:z1=7'b1011011;
6:z1=7'b1011111;
7:z1=7'b1110000;
8:z1=7'b1111111;
9:z1=7'b1111011;
'hA:z1=7'b1110111;
'hB:z1=7'b0011111;
'hC:z1=7'b1001110;
'hD:z1=7'b0111101;
'hE:z1=7'b1001111;
'hF:z1=7'b1000111;
default z1=7'b1111110;
endcase
end
else if(led==1)
begin
case(f)
0:z1=7'b1111110;
1:z1=7'b0110000;
2:z1=7'b1101101;
3:z1=7'b1111001;
4:z1=7'b0110011;
5:z1=7'b1011011;
6:z1=7'b1011111;
7:z1=7'b1110000;
8:z1=7'b1111111;
9:z1=7'b1111011;
'hA:z1=7'b1110111;
'hB:z1=7'b0011111;
'hC:z1=7'b1001110;
'hD:z1=7'b0111101;
'hE:z1=7'b1001111;
'hF:z1=7'b1000111;
default z1=7'b1111110;
endcase
end
end
always@(*)
begin
case(led)
0:z2=6'b000001;
1:z2=6'b000010;
2:z2=6'b000100;
3:z2=6'b001000;
4:z2=6'b010000;
5:z2=6'b100000;
default z2=6'b000001;
endcase
end
endmodule
.ucf文件:
NET clk LOC=D11;
NET z2<0> LOC=P16;
NET z2<1> LOC=M17;
NET z2<2> LOC=N16;
NET z2<3> LOC=P19;
NET z2<4> LOC=AA20;
NET z2<5> LOC=AB21;
NET z1<0> LOC=AA21;
NET z1<1> LOC=AA22;
NET z1<2> LOC=Y22;
NET z1<3> LOC=N15;
NET z1<4> LOC=AB19;
NET z1<5> LOC=P20;
NET z1<6> LOC=Y21;
实验结果截图如下:
六.实验总结
1.对时钟进行分频时,要注意分频的大小,太小的频段会让LED灯一直闪,使人眼很不舒服。
2.要注意对每个LED进行编码的时候,要用case语句或者if else语句对它分别进行编译,否则会出现类似的死锁问题。
ps:这篇博客本来昨天已经写好了的,结果晚上12点突然断网了,一直发不出去,然后不小心点了重新加载,就gg了,花了两个小时写的成果就没了。今天才抽空重新补写了一份。
由于笔者的知识和水平有限,文中不足之处在所难免,恳请各位读者赐正。
---------------------------------------@weekdawn 版权所有---------------------------------------------------