文章目录
前言
本次主要介绍一下关于EDA的实验:7人表决器。
一、设计内容及原理
(1)基础任务:选择7人的表决器,每个人用一位表示,1 表示同意,0 表示不同意,超过半数表示通过,由一位发光二极管显示输出,通过用 1 表示,发光二极管亮,不通过用0表示,发光二极管灭。
(2)提高任务:在基础任务的基础上,位数(人数)与所选基础任务一致,同时再显示出哪一个人通过,哪一个人不通过,用相应的拨码开关输入端上面的用发光二极管显示每个人的情况。
(3)拓展任务:在基础任务和提高任务的基础上,位数(人数)与所选基础任务一致,当一位发光二极管显示输出通过与否时,同时由数码管显示输出通过的人数。
二、设计过程(及设计步骤)
2.1 基础任务
(1)源程序:
module biaojueqi(swi,led); //声明模块名,端口信号
input[6:0] swi;
output reg led ;
reg [3:0] sum;
always@(swi)
begin
sum=4'b0000; //sum初值为0
if (swi[0]==1) //检测每个开关是否为高电平,并累加
sum=sum+1;
if (swi[1]==1)
sum=sum+1;
if (swi[2]==1)
sum=sum+1;
if (swi[3]==1)
sum=sum+1;
if (swi[4]==1)
sum=sum+1;
if (swi[5]==1)
sum=sum+1;
if (swi[6]==1)
sum=sum+1;
end
always@(sum)
begin //sum大于3,即7个人中有4个人同意时,led输出高电平
if (sum>4'b0011)
led=1;
else
led=0;
end
endmodule
(2)仿真程序:
module sim_biaojueqi(
);
reg[6:0]swi; //7位的寄存器
wire led ;
biaojueqi u1( //实例化7人表决源文件对象
.swi(swi),
.led(led)
);
initial begin
swi=7'b0000000; //初始值为0
end
always #10 {swi}=swi+1'b1; //每隔10ns,对swi进行加1
endmodule
(3)约束程序:
set_property -dict {PACKAGE_PIN R1 IOSTANDARD LVCMOS33} [get_ports {swi[0]}]
set_property -dict {PACKAGE_PIN N4 IOSTANDARD LVCMOS33} [get_ports {swi[1]}]
set_property -dict {PACKAGE_PIN M4 IOSTANDARD LVCMOS33} [get_ports {swi[2]}]
set_property -dict {PACKAGE_PIN R2 IOSTANDARD LVCMOS33} [get_ports {swi[3]}]
set_property -dict {PACKAGE_PIN P2 IOSTANDARD LVCMOS33} [get_ports {swi[4]}]
set_property -dict {PACKAGE_PIN P3 IOSTANDARD LVCMOS33} [get_ports {swi[5]}]
set_property -dict {PACKAGE_PIN P4 IOSTANDARD LVCMOS33} [get_ports {swi[6]}]
set_property -dict {PACKAGE_PIN K2 IOSTANDARD LVCMOS33} [get_ports led]
2.2 提高任务
(1)源程序:
module biaojueqi(swi,led,led1); //声明模块名,端口信号
input[6:0] swi;
output reg [6:0] led; //6位led显示哪一个人同意
output reg led1; //led1显示是否该事件通过
reg [3:0] sum;
always@(swi)
begin
led=swi; //确保led输出和swi一致
sum=4'b0000; //sum初值为0
if (swi[0]==1) //检测每个开关是否为高电平,并总计
sum=sum+1;
if (swi[1]==1)
sum=sum+1;
if (swi[2]==1)
sum=sum+1;
if (swi[3]==1)
sum=sum+1;
if (swi[4]==1)
sum=sum+1;
if (swi[5]==1)
sum=sum+1;
if (swi[6]==1)
sum=sum+1;
end
always@(sum)
begin //sum大于3,即7个人中有4个人同意时,led输出高电平
if (sum>4'b0011)
led1=1;
else
led1=0;
end
endmodule
(2)仿真程序:
module sim_biaojueqi1(
);
reg[6:0]swi; //7位的寄存器
wire led1;
wire [6:0] led;
biaojueqi u1( //实例化7人表决源文件对象
.swi(swi),
.led1(led1),
.led(led)
);
initial begin
swi=7'b0000000; //初始值为0
end
always #10 {swi}=swi+1'b1; //每隔10ns,对swi进行加1
endmodule
(3)约束程序:
set_property -dict {PACKAGE_PIN R1 IOSTANDARD LVCMOS33} [get_ports {swi[0]}]
set_property -dict {PACKAGE_PIN N4 IOSTANDARD LVCMOS33} [get_ports {swi[1]}]
set_property -dict {PACKAGE_PIN M4 IOSTANDARD LVCMOS33} [get_ports {swi[2]}]
set_property -dict {PACKAGE_PIN R2 IOSTANDARD LVCMOS33} [get_ports {swi[3]}]
set_property -dict {PACKAGE_PIN P2 IOSTANDARD LVCMOS33} [get_ports {swi[4]}]
set_property -dict {PACKAGE_PIN P3 IOSTANDARD LVCMOS33} [get_ports {swi[5]}]
set_property -dict {PACKAGE_PIN P4 IOSTANDARD LVCMOS33} [get_ports {swi[6]}]
set_property -dict {PACKAGE_PIN K1 IOSTANDARD LVCMOS33} [get_ports led1]
set_property -dict {PACKAGE_PIN K2 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
set_property -dict {PACKAGE_PIN J2 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
set_property -dict {PACKAGE_PIN J3 IOSTANDARD LVCMOS33} [get_ports {led[2]}]
set_property -dict {PACKAGE_PIN H4 IOSTANDARD LVCMOS33} [get_ports {led[3]}]
set_property -dict {PACKAGE_PIN J4 IOSTANDARD LVCMOS33} [get_ports {led[4]}]
set_property -dict {PACKAGE_PIN G3 IOSTANDARD LVCMOS33} [get_ports {led[5]}]
set_property -dict {PACKAGE_PIN G4 IOSTANDARD LVCMOS33} [get_ports {led[6]}]
2.3 拓展任务
(1)源程序:
module biaojueqi(swi,led,led1,wei,b); //声明模块名,端口信号
input[6:0] swi;
output reg [6:0] led; //6位led显示哪一个人同意
output reg led1; //led1显示是否该事件通过
reg [3:0] sum;
output reg wei; //数码管的位选
output reg [7:0] b; //数码管的段码
always@(swi)
begin
led=swi; //确保led输出和swi一致
sum=4'b0000; //sum初值为0
if (swi[0]==1) //检测每个开关是否为高电平,并总计
sum=sum+1;
if (swi[1]==1)
sum=sum+1;
if (swi[2]==1)
sum=sum+1;
if (swi[3]==1)
sum=sum+1;
if (swi[4]==1)
sum=sum+1;
if (swi[5]==1)
sum=sum+1;
if (swi[6]==1)
sum=sum+1;
end
always@(sum)
begin //sum大于3,即7个人中有4个人同意时,led输出高电平
if (sum>4'b0011)
led1=1;
else
led1=0;
end
always @(sum)
begin
wei= 1'b1; //打开数码管的位选
case(sum) //sum的大小代表同意人数,用数码管显示
0:b=8'b11111100;
1:b=8'b01100000;
2:b=8'b11011010;
3:b=8'b11110010;
4:b=8'b01100110;
5:b=8'b10110110;
6:b=8'b10111110;
7:b=8'b11100000;
endcase
end
endmodule
(2)仿真程序:
module sim_biaojueqi(
);
reg[6:0]swi; //7位的寄存器
wire led1;
wire [6:0] led;
wire [7:0] b;
biaojueqi u1( //实例化7人表决源文件对象
.swi(swi),
.led1(led1),
.b(b),
.led(led)
);
initial begin
swi=7'b0000000; //初始值为0
end
always #10 {swi}=swi+1'b1; //每隔10ns,对swi进行加1
endmodule
(3)约束程序:
set_property -dict {PACKAGE_PIN R1 IOSTANDARD LVCMOS33} [get_ports {swi[0]}]
set_property -dict {PACKAGE_PIN N4 IOSTANDARD LVCMOS33} [get_ports {swi[1]}]
set_property -dict {PACKAGE_PIN M4 IOSTANDARD LVCMOS33} [get_ports {swi[2]}]
set_property -dict {PACKAGE_PIN R2 IOSTANDARD LVCMOS33} [get_ports {swi[3]}]
set_property -dict {PACKAGE_PIN P2 IOSTANDARD LVCMOS33} [get_ports {swi[4]}]
set_property -dict {PACKAGE_PIN P3 IOSTANDARD LVCMOS33} [get_ports {swi[5]}]
set_property -dict {PACKAGE_PIN P4 IOSTANDARD LVCMOS33} [get_ports {swi[6]}]
set_property -dict {PACKAGE_PIN K1 IOSTANDARD LVCMOS33} [get_ports led1]
set_property -dict {PACKAGE_PIN K2 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
set_property -dict {PACKAGE_PIN J2 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
set_property -dict {PACKAGE_PIN J3 IOSTANDARD LVCMOS33} [get_ports {led[2]}]
set_property -dict {PACKAGE_PIN H4 IOSTANDARD LVCMOS33} [get_ports {led[3]}]
set_property -dict {PACKAGE_PIN J4 IOSTANDARD LVCMOS33} [get_ports {led[4]}]
set_property -dict {PACKAGE_PIN G3 IOSTANDARD LVCMOS33} [get_ports {led[5]}]
set_property -dict {PACKAGE_PIN G4 IOSTANDARD LVCMOS33} [get_ports {led[6]}]
set_property -dict {PACKAGE_PIN G2 IOSTANDARD LVCMOS33} [get_ports wei]
set_property -dict {PACKAGE_PIN B4 IOSTANDARD LVCMOS33} [get_ports {b[7]}]
set_property -dict {PACKAGE_PIN A4 IOSTANDARD LVCMOS33} [get_ports {b[6]}]
set_property -dict {PACKAGE_PIN A3 IOSTANDARD LVCMOS33} [get_ports {b[5]}]
set_property -dict {PACKAGE_PIN B1 IOSTANDARD LVCMOS33} [get_ports {b[4]}]
set_property -dict {PACKAGE_PIN A1 IOSTANDARD LVCMOS33} [get_ports {b[3]}]
set_property -dict {PACKAGE_PIN B3 IOSTANDARD LVCMOS33} [get_ports {b[2]}]
set_property -dict {PACKAGE_PIN B2 IOSTANDARD LVCMOS33} [get_ports {b[1]}]
set_property -dict {PACKAGE_PIN D5 IOSTANDARD LVCMOS33} [get_ports {b[0]}]
三、仿真结果
3.1 基础任务
结果分析:swi[6:0]代表7位表决的人数,同意为1,不同意为0,led代表最终表决结果,通过用1表示,反之0表示。通过观察,和预期结果相符。
3.2 提高任务
结果分析:swi[n]代表每位表决人的结果,同意则led[n]=1,反之led[n]=0(n为0-6),用另外的一个led1代表最终结果,1位同意,0为不同意。通过观察,和预期结果相符。
3.3 拓展任务
结果分析:swi[n]代表每位表决人的结果,同意则led[n]=1,反之led[n]=0(n为0-6),同时把n用共阴极数码管对应的8位二进制表示出来,最后用另外的一个led1代表最终结果,1位同意,0为不同意。通过观察,和预期结果相符。
四、 硬件验证
下图是均为7人表决器实物仿真中的一个过程,和预期结果相符。
4.1 基础任务
4.2 提高任务
4.3 拓展任务
五、 问题解决
1.问题:最开始编写7人表决器源代码时,我的方法是:列真值表,用与非门表示结果。但是用这种方法会到导致人数较多时,式子特别复杂,并不适用较多人数。
解决办法:我使用了7个if语句,对7个开关的高低电平依次验证,然后用sum累加开关高电平的个数,最后在用一个if语句,只用sum>3,输出的led即为高电平。
2.问题:编写的约束文件总是显示到某一行有错误。
解决办法:编写的约束文件时我犯过几个错误,主要有三个地方需要注意:(1)约束文件的注释符和源文件不一样,应该用##,而不是//。(2)引脚间要注意有空格。(3)端口信号是一位时,不需要用{}。例如[get_ports {led}]是错误的,应该写成[get_ports led]。
3.问题:程序最开始检测每个开关是否为高电平时,我用了采用if-else if结构,硬件仿真时也没有显示错误,但是就是和预期不符。
解决办法:采用if-else if结构会形成锁存器,当if中的条件不满足时执行else if语句,当if中的条件满足时则执行if中的语句,执行之后退出if-else if结构,不再执行下边的语句。采用if-if-else语句可避免这类问题。
4.问题:源文件定义位选为高电平(wei= 1’b1)时,报错。
解决办法:开始wei= 1’b1我写在了always之外,用的是assign wei= 1’b1,而我定义的是reg,因此显示错误。
5.问题:做提高任务输出对应的led时,开始我是在每一个if语句下面都加了一个led[n]=1(n为对应的开关),但是出来的结果是:7个led一直是亮的。
解决办法:因为开始只是设置开关对应的led的高电平(亮),没有设置对应的低电平(灭),后来我只是在前面程序加了一个led[n]=swi[n],就可以完美的控制led的亮灭。
六、 心得体会
除了第一个按图索骥的流水灯实验,这是我第一个自己编程源程序、仿真程序、约束程序的实验。在试验时,遇到了很多的麻烦,但是都顺利的解决了。在本次实验中收获了很多,主要有一下几点体会:
最开始编程表决器时,从书中查阅到的程序是用简单的与或非门表示输出结果。当然了,本来我也是这麽做的一个7人表决器,但是用与或非门写出的表达式结果太长了,不适用较多人数。后来我想着将7个开关一个一个的验证,所以使用了7个if语句,对7个开关的高低电平验证,然后用sum累加开关高电平的个数,最后在用一个if语句,只用sum>3,输出的led即为1。
然后在引用数码管表示同意的人数时,我并不会使用这个数码管,不明白其显示原理。查阅了很多资料,才知道,数码管分段选和位选,将需要使用的位选输入高电平时,才可以输入段选。段选可以输入7位二进制数(排除小数点),也可以输入8位二进制数。其中,板子中8个数码管分为2组,每组共用一个段选。但是我在使用时,也是遇到了一点小麻烦,板子上8个段选的引脚和我定义的端口信号连接反了,导致输出的结果不理想。
最后一点体会就是编写程序时一定严谨,例如约束程序编写时,引脚间要注意有空格,我在这一点上就卡了很长时间,明明就只是改了一下引脚的编号,结果一直显示该行错误,十分崩溃。