实验五 四位全加器实验
实验目的
- 掌握组合逻辑电路的基本分析和设计方法;
- 理解半加器和全加器的工作原理并掌握利用全加器构成不同字长加法器的各种方法;
- 学习元件例化的方式进行硬件电路设计;
- 学会利用软件仿真实现对数字电路的逻辑功能进行验证和分析。
实验内容
用硬件描述语言实现半加器和全加器,并使用自己设计的全加器等组件构建四位全加器,并使用软件进行功能仿真,然后下载到 FPGA 中进行验证。
设计需求
- 用元件例化的方式设计实现一个四位全加器;
- 使用两个开关模块分别作为全加器的输入
A
B
,进位输入Cin
使用时钟模块上的复位开关CLK
; - 使用开关模块上的发光二极管作为全加器的结果
F
和进位输出Cout
。
设计框图
flowchart LR
A[拨动开关]:::periph -- A ---> adder;
B[拨动开关]:::periph -- B ---> adder;
Cin[复位开关]:::periph -- Cin ---> adder;
subgraph FPGA
direction BT
adder[四位全加器 Adder]:::comb;
end
adder -- F --> seg[七段数码管]:::periph;
adder -- Cout --> led[发光二极管]:::periph;
classDef comb fill:#e8f5e9,stroke:#43a047; %% green
classDef seq fill:#ffecb3,stroke:#ffa000; %% orange
classDef periph fill:#e3f2fd,stroke:#2196f3; %% blue
linkStyle default opacity:1.0
原理图
全加器原理
半加器(Half Adder)是不考虑来自低位的进位信号,其输入为 1bit 的被加数和加数,输出为两位:本位的和以及向高一位的进位。
在二进制加法的运算只采用半加器是不够的,必须有低一位的进位才能完成正确地运算。考虑低位进位的 1 位二进制加法器称为全加器(Full Adder),其输入为被加数、加数以及低一位来的进位,输出为本位的和及向高一位的进位。
利用全加器级联可以构成多位二进制加法器,如图所示为四位二进制加法电路,低一位的进位输出作为高一位的进位输入,这种结构称为逐次进位加法器(Ripple Adder)。
超前进位加法器
由于逐次进位加法器的进位信号是在各级间逐级传递的,所以高位的输出必须等低位的进位输入稳定后才有效,这就使得逐次进位加法器的延时比较大,速度比较慢。为了提高加法器的运算速度,可以将进位提前产生,就是超前进位加法器,具体设计请自行查阅。
一位全加器 full_adder
先设计实现一位的全加器,输入为 An 、Bn 和 Cin,输出为 Fn 和 Cout,对应的逻辑表达式为:
$$ F_n = A_n \oplus B_n \oplus C_{in} \ $$
$$ C_{out} = A_n \cdot B_n + C_{in} \cdot (A_n \oplus B_n) $$
参考代码
module full_adder(A, B , Cin, F, Cout);
input wire A, B, Cin;
output wire F, Cout;
assign F = A ^ B ^ Cin;
assign Cout = (A & B) | (Cin & (A ^ B));
endmodule
四位全加器 Adder
四位全加器的功能是将 4 位的输入信号 A[3:0]
和 B[3:0]
相加,结果为 F[3:0]
,Cin
和 Cout
分别为进位输入和输出。
然后通过元件例化的方式组成四位全加器。
下面给出的代码仅供参考
module Adder (
input wire[3:0] A,
input wire[3:0] B,
input wire Cin,
output wire[3:0] F,
output wire Cout
);
wire[2:0] C;
full_adder adder0 (
.A(A[0]),
.B(B[0]),
.Cin(Cin),
.F(F[0]),
.Cout(C[0])
);
full_adder adder1 (
.A(A[1]),
.B(B[1]),
.Cin(C[0]),
.F(F[1]),
.Cout(C[1])
);
full_adder adder2 (
.A(A[2]),
.B(B[2]),
.Cin(C[1]),
.F(F[2]),
.Cout(C[2])
);
full_adder adder3 (
.A(A[3]),
.B(B[3]),
.Cin(C[2]),
.F(F[3]),
.Cout(Cout)
);
endmodule
仿真
对设计的四位加法器进行功能仿真,具体步骤请参考硬件代码的仿真和调试。
管脚绑定
使用可编程模块上的接插孔连接开关和七段数码管,其中 IO1 ~ IO4 作为输入 A[3:0]
,IO6 ~ IO9 作为输入 B[3:0]
,连接到开关模块;
IO5 作为进位输入 Cin
,连接到时钟模块;
IO17 ~ IO20 作为输出 F[3:0]
,连接七段数码管的a ~ f
;IO16 作为进位输出 Cout
,连接到开关模块上的发光二极管。
具体约束文件如下:
# A input
set_property -dict {PACKAGE_PIN M21 IOSTANDARD LVCMOS33} [get_ports A[3]]; #IO1接插孔
set_property -dict {PACKAGE_PIN N20 IOSTANDARD LVCMOS33} [get_ports A[2]]; #IO2接插孔
set_property -dict {PACKAGE_PIN N22 IOSTANDARD LVCMOS33} [get_ports A[1]]; #IO3接插孔
set_property -dict {PACKAGE_PIN P21 IOSTANDARD LVCMOS33} [get_ports A[0]]; #IO4接插孔
# B input
set_property -dict {PACKAGE_PIN T21 IOSTANDARD LVCMOS33} [get_ports B[3]]; #IO6接插孔
set_property -dict {PACKAGE_PIN U21 IOSTANDARD LVCMOS33} [get_ports B[2]]; #IO7接插孔
set_property -dict {PACKAGE_PIN R21 IOSTANDARD LVCMOS33} [get_ports B[1]]; #IO8接插孔
set_property -dict {PACKAGE_PIN R22 IOSTANDARD LVCMOS33} [get_ports B[0]]; #IO9接插孔
# Cin input
set_property -dict {PACKAGE_PIN P22 IOSTANDARD LVCMOS33} [get_ports Cin]; #IO5接插孔
# F output
set_property -dict {PACKAGE_PIN AB18 IOSTANDARD LVCMOS33} [get_ports F[3]]; #IO17接插孔
set_property -dict {PACKAGE_PIN AA20 IOSTANDARD LVCMOS33} [get_ports F[2]]; #IO18接插孔
set_property -dict {PACKAGE_PIN AB21 IOSTANDARD LVCMOS33} [get_ports F[1]]; #IO19接插孔
set_property -dict {PACKAGE_PIN AA21 IOSTANDARD LVCMOS33} [get_ports F[0]]; #IO20接插孔
# Cout output
set_property -dict {PACKAGE_PIN AA18 IOSTANDARD LVCMOS33} [get_ports Cout]; #IO16接插孔
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
实验步骤
- 使用 vivado2019.2 新建一个工程,编写 system verilog 代码,并进行综合;
- 进行功能仿真;
- 使用开关模块,可编程模块和时钟模块,进行电路连接;
- 管脚绑定,编译并下载,观察实验结果。
提高要求
- 设计实现超前进位的四位加法器;
- 使用 SystemVerilog 自带的加法运算实现四位全加器;
- 将结果采用十进制表示,并使用自带译码的七段数码管显示结果。
实验报告
- 整理出完整、清晰的代码,并详细添加注释说明电路的工作原理。
- 给出软件仿真的结果。
- 说明电路功能测试的结果,并与软件仿真的结果相比较。
- 总结调试中所遇到的问题及解决方法。