EDA设计:三八译码器
本次主要介绍一下关于EDA的实验:三八译码器。
文章目录
前言
本次主要介绍一下关于EDA的实验:三八译码器。
一、设计内容及原理
(1)基础任务:设计一个带有使能端的三八译码器,要求使能端输入有三个,一个高电平输入有效,两个低电平输入有效,输入端是高电平输入有效,输出端是低电平输出有效,即74LS138,拨码开关作为输入,发光二极管作为输出。
(2)提高任务:在基础任务的基础上,输出用一位数码管显示输出是第几位。
二、设计过程(及设计步骤)
2.1 基础任务
(1)源程序:
module decode(a,b,c,en,led); //声明模块名,端口信号
input [2:0] en; //三位使能端输入
input a; //三位拨码开关输入
input b;
input c;
output reg [7:0] led; //8位led输出
always@(a,b,c)
begin
if(en==3'b100) // 使能端输入100时,有效
case({a,b,c}) //三位拨码开关输入不同的值时,对应led的输出
3'd0:led = 8'b00000001;
3'd1:led = 8'b00000010;
3'd2:led = 8'b00000100;
3'd3:led = 8'b00001000;
3'd4:led = 8'b00010000;
3'd5:led = 8'b00100000;
3'd6:led = 8'b01000000;
3'd7:led = 8'b10000000;
endcase
else led = 8'b00000000; //使能端无效时,led不亮起
end
endmodule
(2)仿真程序:
module sim_decode;
reg [2:0] en;
reg a;
reg b;
reg c;
wire[7:0] led;
decode u0( //实例化三八译码器
.a(a),
.b(b),
.c(c),
.en(en),
.led(led)
);
initial begin
en=3'b100; //定义使能端有效
a=0;b=0;c=0; //初始值为0
end
always #10{a,b,c}={a,b,c}+1; //每隔10ns,对swi进行加1
endmodule
(3)约束程序:
set_property -dict {PACKAGE_PIN P3 IOSTANDARD LVCMOS33} [get_ports {en[0]}]
set_property -dict {PACKAGE_PIN P4 IOSTANDARD LVCMOS33} [get_ports {en[1]}]
set_property -dict {PACKAGE_PIN P5 IOSTANDARD LVCMOS33} [get_ports {en[2]}]
set_property -dict {PACKAGE_PIN R1 IOSTANDARD LVCMOS33} [get_ports c]
set_property -dict {PACKAGE_PIN N4 IOSTANDARD LVCMOS33} [get_ports b]
set_property -dict {PACKAGE_PIN M4 IOSTANDARD LVCMOS33} [get_ports a]
set_property -dict {PACKAGE_PIN K3 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
set_property -dict {PACKAGE_PIN M1 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
set_property -dict {PACKAGE_PIN L1 IOSTANDARD LVCMOS33} [get_ports {led[2]}]
set_property -dict {PACKAGE_PIN K6 IOSTANDARD LVCMOS33} [get_ports {led[3]}]
set_property -dict {PACKAGE_PIN J5 IOSTANDARD LVCMOS33} [get_ports {led[4]}]
set_property -dict {PACKAGE_PIN H5 IOSTANDARD LVCMOS33} [get_ports {led[5]}]
set_property -dict {PACKAGE_PIN H6 IOSTANDARD LVCMOS33} [get_ports {led[6]}]
set_property -dict {PACKAGE_PIN K1 IOSTANDARD LVCMOS33} [get_ports {led[7]}]
2.2 提高任务
(1)源程序:
module decode(a,b,c,en,wei,led,seg); //声明模块名,端口信号
input [2:0] en; //三位使能端输入
input a; //三位拨码开关输入
input b;
input c;
output reg wei;
output reg [7:0] led;
output reg [7:0] seg;
always@(a,b,c)
begin
if(en==3'b100) // 使能端输入100时,有效
case({a,b,c}) //三位拨码开关输入不同的值时,对应led的输出
3'd0:led = 8'b00000001;
3'd1:led = 8'b00000010;
3'd2:led = 8'b00000100;
3'd3:led = 8'b00001000;
3'd4:led = 8'b00010000;
3'd5:led = 8'b00100000;
3'd6:led = 8'b01000000;
3'd7:led = 8'b10000000;
endcase
else led = 8'b00000000; //使能端无效时,led不亮起
end
always@(a,b,c)
begin
wei= 1'b1;
if(en==3'b100) // 使能端输入100时,有效
case({a,b,c}) //三位拨码开关输入不同的值时,对应数码管的输出
0:seg=8'b11111100;
1:seg=8'b01100000;
2:seg=8'b11011010;
3:seg=8'b11110010;
4:seg=8'b01100110;
5:seg=8'b10110110;
6:seg=8'b10111110;
7:seg=8'b11100000;
endcase
else seg=8'b00000000; //使能端无效时,数码管显示0
end
endmodule
(2)仿真程序:
module sim_decode;
reg a;
reg b;
reg c;
reg [2:0] en;
wire[7:0] led;
wire[7:0] seg;
decode u0( //实例化三八译码器
.a(a),
.b(b),
.c(c),
.led(led),
.en(en),
.seg(seg)
);
initial begin
en=3'b100; //定义使能端有效
a=0;b=0;c=0; //初始值为0
end
always #10{a,b,c}={a,b,c}+1; //每延迟10,对abc进行加1,即在0-7之间循环
endmodule
(3)约束程序:
set_property -dict {PACKAGE_PIN P3 IOSTANDARD LVCMOS33} [get_ports {en[0]}]
set_property -dict {PACKAGE_PIN P4 IOSTANDARD LVCMOS33} [get_ports {en[1]}]
set_property -dict {PACKAGE_PIN P5 IOSTANDARD LVCMOS33} [get_ports {en[2]}]
set_property -dict {PACKAGE_PIN R1 IOSTANDARD LVCMOS33} [get_ports c]
set_property -dict {PACKAGE_PIN N4 IOSTANDARD LVCMOS33} [get_ports b]
set_property -dict {PACKAGE_PIN M4 IOSTANDARD LVCMOS33} [get_ports a]
set_property -dict {PACKAGE_PIN K3 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
set_property -dict {PACKAGE_PIN M1 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
set_property -dict {PACKAGE_PIN L1 IOSTANDARD LVCMOS33} [get_ports {led[2]}]
set_property -dict {PACKAGE_PIN K6 IOSTANDARD LVCMOS33} [get_ports {led[3]}]
set_property -dict {PACKAGE_PIN J5 IOSTANDARD LVCMOS33} [get_ports {led[4]}]
set_property -dict {PACKAGE_PIN H5 IOSTANDARD LVCMOS33} [get_ports {led[5]}]
set_property -dict {PACKAGE_PIN H6 IOSTANDARD LVCMOS33} [get_ports {led[6]}]
set_property -dict {PACKAGE_PIN K1 IOSTANDARD LVCMOS33} [get_ports {led[7]}]
set_property -dict {PACKAGE_PIN G2 IOSTANDARD LVCMOS33} [get_ports wei]
set_property -dict {PACKAGE_PIN B4 IOSTANDARD LVCMOS33} [get_ports {seg[7]}]
set_property -dict {PACKAGE_PIN A4 IOSTANDARD LVCMOS33} [get_ports {seg[6]}]
set_property -dict {PACKAGE_PIN A3 IOSTANDARD LVCMOS33} [get_ports {seg[5]}]
set_property -dict {PACKAGE_PIN B1 IOSTANDARD LVCMOS33} [get_ports {seg[4]}]
set_property -dict {PACKAGE_PIN A1 IOSTANDARD LVCMOS33} [get_ports {seg[3]}]
set_property -dict {PACKAGE_PIN B3 IOSTANDARD LVCMOS33} [get_ports {seg[2]}]
set_property -dict {PACKAGE_PIN B2 IOSTANDARD LVCMOS33} [get_ports {seg[1]}]
set_property -dict {PACKAGE_PIN D5 IOSTANDARD LVCMOS33} [get_ports {seg[0]}]
三、仿真结果
3.1 基础任务
结果分析:a,b,c表示三位拨码开关输入,8位led表示输出结果,仿真和预期相符。例如上面黄线所示:打开使能端(en=100),abc输入111时,输出应为7,led的第七位亮起。
3.2 提高任务
结果分析:a,b,c表示三位拨码开关输入,8位led表示输出结果,seg表示对应数码管的输出数字,仿真和预期相符。例如上面黄线所示:打开使能端(en=100),abc输入111时,输出应为7,led的第七位亮起,
四、 硬件验证
4.1 基础任务
结果分析:这是硬件仿真中的一个过程,拨码开关输入110时,对应的第6个led亮起。
4.2 提高任务
结果分析:这是硬件仿真中的一个过程,拨码开关输入111时,对应的第7个led亮起,数码管显示7。
五、 问题解决
1.问题:仿真时,显示仿真程序有好几个错误。
解决办法:我按照vivado下面的错误提示,一一对照,根本就没有发现错误,结果是实例化源程序时,最后一行的.seg(seg)后面加了一个逗号。
2.问题:仿真后出结果后,但是led一直显示0,没有变化,和预期结果不符。
解决办法:我发现是仿真文件中没有定义使能端的位数(reg en),导致默认en为一位,故一直没有打开使能端,输出led为0。
3.问题:编写的约束文件总是显示到某一行有错误。
解决办法:编写的约束文件时主要有三个地方需要注意:(1)约束文件的注释符和源文件不一样,应该用##,而不是//。(2)引脚间要注意有空格。(3)端口信号是一位时,不需要用{}。例如[get_ports {led}]是错误的,应该写成[get_ports led]。
六、 心得体会
编写三八译码器时,我做了基础任务和提高任务。在这个编写程序的过程中,还是遇到点麻烦。
首先就是使能端的添加,这里我在if语句中套用了一个case语句,如果使能端输入100时,就可以选择三位拨码开关对应输入不同的值,然后表示出led的输出。但是硬件仿真时,8个led一直是常亮的,后来才发现是忘记了添加led都是低电平的情况(led = 8’b00000000)。
还有就是仿真时显示仿真程序有好几个错误,我在这一步上花费了很长的时间。我按照vivado下面的错误提示,一一对照,根本就没有发现错误,结果是实例化源程序时,最后一行的.seg(seg)后面加了一个逗号。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)