FPGA设计超前进位与8421-BCD码全加器

简介: 本文介绍了FPGA设计超前进位与8421-BCD码全加器

设计一个16位二进制超前进位全加器模块

  1. 实验内容与原理说明

本实验设计一个16位二进制的超前进位全加器模块,用来实现16位二进制的加法,超前进位加法器的结构如下图。下图为一个四位超前进位加法器的结构图。信号经过pi和gi产生一级时延,经过计算C产生一级时延,则A,B输入一旦产生,首先经过两级时延算出第1轮进位值C’不过这个值是不正确的。C’再次送入加法器,进行第2轮2级时延的计算,算出第2轮进位值C,这一次是正确的进位值。这里的4个4位超前进位加法器仍是串行的,所以一次计算经过4级加法器,一级加法器有2级时延,因此1次计算一共经过8级时延,相比串行加法器里的16级时延,速度提高很多。

image.png

设计封装模块如下:

image.png

可以求得两个输出的表达式为:

image.png

image.png

对于i=0~3的代入,得到每一级的进位输出表达式如下:

image.png

  1. 实验模块程序代码和激励代码

(1)设计模块代码
//定义一位超前加法器
module bit1Advanced(ain,bin,cin,sum,gi,pi);
input ain;
input bin;
input cin;//定义进位信号
output sum;//输出信号
output gi;//每位的进位产生信号
output pi;//每位的进位传播信号

assign gi=ain&bin;//数据流的方式描述逻辑式
assign pi=ain|bin;//数据流的方式描述逻辑式

assign sum=ain^bin^cin;//数据流的方式描述逻辑式

endmodule

//定义四位超前加法器
module bit4Advanced(ain,bin,cin,sum,pm,gm,co);
input[3:0] ain;
input[3:0] bin;//定义两个四位的输入
input cin;//定义进位信号
output[3:0] sum;//定义输出信号
output gm;//定义进位产生信号
output pm;//定义进位传播信号
output co;//定义输出的进位信号

//定义三条wire类型,连接四个一位超前加法器之间的端口
wire[4:1] ci;
wire[3:0] pi;
wire[3:0] gi;

bit1Advanced u0(.ain(ain[0]),.bin(bin[0]),.cin(cin),.sum(sum[0]),.gi(gi[0]),.pi(pi[0]));
bit1Advanced u1(.ain(ain[1]),.bin(bin[1]),.cin(ci[1]),.sum(sum[1]),.gi(gi[1]),.pi(pi[1]));
bit1Advanced u2(.ain(ain[2]),.bin(bin[2]),.cin(ci[2]),.sum(sum[2]),.gi(gi[2]),.pi(pi[2]));
bit1Advanced u3(.ain(ain[3]),.bin(bin[3]),.cin(ci[3]),.sum(sum[3]),.gi(gi[3]),.pi(pi[3]));//对四个一位的超前加法器进行元件例化,并连接对应的端口
CLA_4 uut(.p(pi),.g(gi),.cin(cin),.ci(ci),.gm(gm),.pm(pm));//对CLA_4进行元件例化

assign co=ci[4];//赋值进位信号co

endmodule

module CLA_4(p,g,cin,ci,gm,pm);//定义CLA_4模块,也就是超前进位信号产生的模块
input[3:0] p;//定义输入的进位传播信号
input[3:0] g;//定义输入的进位产生信号
input cin;//定义模块的输入进位信号
output[4:1] ci;//定义模块的输出进位信号
output gm;//定义模块本身产生的进位产生信号
output pm;//定义模块本身产生的进位传播信号

assign ci[1]=g[0]|p[0]&cin;
assign ci[2]=g[1]|p[1]&g[0]|p[1]&p[0]&cin;
assign ci[3]=g[2]|p[2]&g[1]|p[2]&p[1]&g[0]|p[2]&p[1]&p[0]&cin;
assign ci[4]=g[3]|p[3]&g[2]|p[3]&p[2]&g[1]|p[3]&p[2]&p[1]&g[0]|p[3]&p[2]&p[1]&p[0]&cin;//根据对应的公式和对应的进位产生信号和进位传播信号赋值进位信号

assign gm=g[3]|p[3]&g[2]|p[3]&p[2]&g[1]|p[3]&p[2]&p[1]&g[0];
assign pm=p[3]&p[2]&p[1]&p[0];//根据对应的公式赋值模块本身的进位产生信号和进位传播信号

endmodule

//定义16位的超前进位加法器
module bit16Advanced(ain,bin,cin,sum,co,gm,pm);
input[15:0] ain;
input[15:0] bin;//定义两个加数
input cin;//定义输入的进位信号
output [15:0] sum;//定义输出的和信号
output co;//定义输出的进位信号
output gm;//定义进位产生信号
output pm;//定义进位传播信号

//定义三个wire类型的变量
wire[3:0] gi;
wire[3:0] pi;
wire[4:1] ci;

bit4Advanced U0(.ain(ain[3:0]),.bin(bin[3:0]),.cin(cin),.sum(sum[3:0]),.gm(gi[0]),.pm(pi[0]));
bit4Advanced U1(.ain(ain[7:4]),.bin(bin[7:4]),.cin(ci[1]),.sum(sum[7:4]),.gm(gi[1]),.pm(pi[1]));
bit4Advanced U2(.ain(ain[11:8]),.bin(bin[11:8]),.cin(ci[2]),.sum(sum[11:8]),.gm(gi[2]),.pm(pi[2]));
//根据实例化关系实例化三个模块,并且根据逻辑关系将其端口连接起来
bit4Advanced U3(.ain(ain[15:12]),.bin(bin[15:12]),.cin(ci[3]),.sum(sum[15:12]),.gm(gi[3]),.pm(pi[3]));

//将四位超前进位加法器产生的进位输出送到进位信号处理器中
//以产生新的进位信号
CLA_4 CLA_4(.p(pi),.g(gi),.cin(cin),.ci(ci),.gm(gm),.pm(pm));

assign co=ci[4];

endmodule

(2)激励模块代码
// Verilog Test Bench template for design : bit16Advanced
//
// Simulation tool : ModelSim (Verilog)
//

`timescale 1 ps/ 1 ps
module bit16Advanced_vlg_tst();
// constants
// general purpose registers
reg eachvec;
// test vector input registers
reg [15:0] ain;
reg [15:0] bin;
reg cin;
// wires
wire co;
wire gm;
wire pm;
wire [15:0] sum;

// assign statements (if any)
bit16Advanced i1 (
// port map - connection between master ports and signals/registers

.ain(ain),  
.bin(bin),  
.cin(cin),  
.co(co),  
.gm(gm),  
.pm(pm),  
.sum(sum)  

);
initial
begin
ain=16'b0001_1111_1010_0101;
bin=16'b1010_1010_1110_0110;
cin=0;
//50ps后停止

50 $stop;

end

always #10 ain={$random}%17'h10000;
always #10 bin={$random}%17'h10000;
always #10 cin={$random}%2;

endmodule

3.波形图

image.png

4.门级电路图

image.png

设计一个16-bit 8421-BCD码全加器模块
1.实验内容与原理说明

本实验实现一个16位二进制的BCD码全加器模块,用来实现16位二进制的加法,由于两个1位十进制数相加时,和的取值范围是0—18,将该范围内各数值对应的二进制数和8421BCD码列表,以便寻找何时应对结果修正以及如何修正。

实验封装设计框图如下:

image.png

同时,我们知道当两个BCD码相加时,如果得到的结果为10以内,则显示的BCD码即为相加得到的结果,比如0001+0010=0011即3;但是当两个BCD码相加结果大于10,则应当加上6,即为显示的BCD码,即1001+0001 =9+1=1010=10,但应当显示0,于是将1010+0110=10000=0000,即显示为0。

下面详细地列出了真值表:

image.png

  1. 实验模块程序代码和激励代码

(1)设计模块代码
//定义一位BCD码的加法器
module BCD1bit(co,sum,a,b,cin);
input cin;//定义进位信号
input[3:0] a;
input[3:0] b;//定义两个BCD码的加数
output reg [3:0] sum;//定义输出和
output reg co;//定义输出的进位信号
reg[4:0] temp;//定义一个寄存器temp用来暂存计算结果

always@(a,b,cin) begin//每当a,b或者cin变化时

temp<=a+b+cin;   //令temp为三者相加,也就是以二进制相加  

end

always@(temp) begin//每当temp变化时

if(temp>4'd9) begin//判断temp是否大于10  
    sum<=temp-10;//如果大于10需要减去10,同时输出进位信号,这也就是十进制体现所在  
    co<=1;  
end  
else begin  //如果不大于10  
    sum<=temp;  
    co<=0;//将进位信号清零,将temp送给输出sum  
end   

end
endmodule

//定义16位的BCD加法器
module BCD16bit(a,b,cin,sum,co);
//定义两个16位的输入信号
input[15:0] a;
input[15:0] b;
input cin;//定义输入进位信号
output[15:0] sum;//定义16位的加法之和
output co;//定义输出的进位信号

//定义三个wire类型的变量,作为端口之间的连接线
wire carry1,carry2,carry3;

BCD1bit U0(.co(carry1),.sum(sum[3:0]),.a(a[3:0]),.b(b[3:0]),.cin(cin));
BCD1bit U1(.co(carry2),.sum(sum[7:4]),.a(a[7:4]),.b(b[7:4]),.cin(carry1));
BCD1bit U2(.co(carry3),.sum(sum[11:8]),.a(a[11:8]),.b(b[11:8]),.cin(carry2));
BCD1bit U3(.co(co),.sum(sum[15:12]),.a(a[15:12]),.b(b[15:12]),.cin(carry3));//根据对应的连接线关系,将四个实例化之后的模块连接起来,形成16位的BCD加法器

endmodule

()激励模块代码
// Verilog Test Bench template for design : BCD16bit
//
// Simulation tool : ModelSim (Verilog)
//

`timescale 1 ps/ 1 ps
module BCD16bit_vlg_tst();
// constants
// general purpose registers
reg eachvec;
// test vector input registers
reg [3:0] a;
reg [3:0] b;
reg cin;
// wires
wire co;
wire [3:0] sum;

// assign statements (if any)
BCD16bit i1 (
// port map - connection between master ports and signals/registers

.a(a),  
.b(b),  
.cin(cin),  
.co(co),  
.sum(sum)  

);
initial
begin
a<=16'h0001;

b<=16'h0001;  
cin<=0;  

150 $stop;

end

always #10 a[3:0]={$random}%10;
always #10 a[7:4]={$random}%10;
always #10 a[11:8]={$random}%10;
always #10 a[15:12]={$random}%10;
always #10 b[3:0]={$random}%10;
always #10 b[7:4]={$random}%10;
always #10 b[11:8]={$random}%10;
always #10 b[15:12]={$random}%10;
//每经过10ps,对每一位十进制数进行复赋值
always #10 cin={$random}%2;
endmodule

3.波形图

image.png

4.门级电路图

image.png

【结果分析及思考】

本次实验分别对16位二进制全加器模块,16位超前进位二进制全加器模块,16-bit 8421-BCD码全加器模块进行了设计与实现。其中在设计16位二进制全加器模块的过程中,分别使用了按照行为描述的方式以及按照数据流的方式建模,让我从实践的角度理解了建模方式的不同,掌握了包括门级电路,数据流以及行为描述这三种建模方法。

全加器是常用的组合逻辑模块中的一种,对全加器的分析和对组合逻辑电路的分析一样。组合逻辑电路的分析,就是找出给定电路输入和输出之间的逻辑关系,从而了解给定逻辑电路的逻辑功能。组合逻辑电路的分析方法通常采用代数法,我的设计过程按照老师所给出的步骤进行:先根据所需要的功能,列出真值表。然后根据真值表,写出相应的逻辑函数表达式。再根据真值表或逻辑函数表达式,画出相应的组合逻辑电路的逻辑图。之后用编写程序在QuartusⅡ上进行仿真并在Modelsim上测试,分析结果的正确性。

印象较深的是在数据流描述中,通过层次化设计方法实现的结构,这个加法器是使用了16个全加器进行连接和信号传递组成的,而一位全加器是由两个半加器以及一个或门所构成,这个全加器的组成和描述频繁使用了元件例化语句,就是为了能够完整的描述这16个全加器在结构上的关系以及和所对应输入输出之间的关系。

全加器是组合逻辑电路中最常见也最实用的一种,考虑低位进位的加法运算就是全加运算,实现全加运算的电路称为全加器。它主要实现加法的运算,其中分为并行全加器和串行全加器,所谓并行就是指向高位进位时是并行执行的,而串行就是从低位到高位按顺序执行,为了提高运算,必须设法减小或消除由于进位信号逐级传递所消耗的时间,为了提高运算速度,制成了超前进位加法器,这是对全加器的一种创新。这也正是超前进位二进制全加器的思想。

在16位的BCD码加法器的设计中,用4个数与4个数进行加和,通过BCD码输出结果。但是实验中需要注意很多细节,例如BCD码的最大范围就是1001也就是9,因此需要将二进制改为10进制,判断得到的结果是否需要进位,如果不需要进位的话,显示的结果就为真实结果,如果需要进位,则应当将得到的结果加上6,即对数字进行修正,以此实现显示信号的输出。

通过此次设计对全加器的设计和实现,积累和总结了不少的经验,锻炼了我的独立工作和实际动手能力,加深了对计算机中的全加器工作原理的认识,提高了对复杂的综合性实践环节具有分析问题、解决问题、概括总结的实际工作能力,对涉及全加器项目的开发、设计过程有初步认识。

目录
相关文章
|
人工智能 编译器 异构计算
FPGA(3)--VHDL及原理图--4位全加器
FPGA(3)--VHDL及原理图--4位全加器
667 0
FPGA(3)--VHDL及原理图--4位全加器
|
异构计算
FPGA(2)--例化语句--1位全加器
FPGA(2)--例化语句--1位全加器
215 0
FPGA(2)--例化语句--1位全加器
|
算法
FPGA-阵列乘法器的设计(利用全加器 基于CRA阵列乘法器)
FPGA-阵列乘法器的设计(利用全加器 基于CRA阵列乘法器)
285 0
FPGA-阵列乘法器的设计(利用全加器 基于CRA阵列乘法器)
FPGA-基本知识 设计一个一位(四位)半加器和一位(四位)全加器
FPGA-基本知识 设计一个一位(四位)半加器和一位(四位)全加器
578 0
FPGA-基本知识 设计一个一位(四位)半加器和一位(四位)全加器
|
异构计算
FPGA设计16位二进制全加器模块
本文主要采用FPGA设计16位二进制全加器模块
1074 0
FPGA设计16位二进制全加器模块
|
17天前
|
算法 数据安全/隐私保护 异构计算
基于FPGA的16QAM调制+软解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR
本项目基于FPGA实现了16QAM基带通信系统,包括调制、信道仿真、解调及误码率统计模块。通过Vivado2019.2仿真,设置不同SNR(如8dB、12dB),验证了软解调相较于传统16QAM系统的优越性,误码率显著降低。系统采用Verilog语言编写,详细介绍了16QAM软解调的原理及实现步骤,适用于高性能数据传输场景。
117 69
|
22天前
|
移动开发 算法 数据安全/隐私保护
基于FPGA的QPSK调制+软解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR
本文介绍了基于FPGA的QPSK调制解调系统,通过Vivado 2019.2进行仿真,展示了在不同信噪比(SNR=1dB, 5dB, 10dB)下的仿真效果。与普通QPSK系统相比,该系统的软解调技术显著降低了误码率。文章还详细阐述了QPSK调制的基本原理、信号采样、判决、解调及软解调的实现过程,并提供了Verilog核心程序代码。
54 26
|
28天前
|
算法 异构计算
基于FPGA的4ASK调制解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR
本文介绍了基于FPGA的4-ASK调制解调系统的算法仿真效果、理论基础及Verilog核心程序。仿真在Vivado2019.2环境下进行,分别测试了SNR为20dB、15dB、10dB时的性能。理论部分概述了4-ASK的工作原理,包括调制、解调过程及其数学模型。Verilog代码实现了4-ASK调制器、加性高斯白噪声(AWGN)信道模拟、解调器及误码率计算模块。
56 8
|
1月前
|
算法 物联网 异构计算
基于FPGA的4FSK调制解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR
本文介绍了基于FPGA的4FSK调制解调系统的Verilog实现,包括高斯信道模块和误码率统计模块,支持不同SNR设置。系统在Vivado 2019.2上开发,展示了在不同SNR条件下的仿真结果。4FSK调制通过将输入数据转换为四个不同频率的信号来提高频带利用率和抗干扰能力,适用于无线通信和数据传输领域。文中还提供了核心Verilog代码,详细描述了调制、加噪声、解调及误码率计算的过程。
58 11
|
1月前
|
算法 数据安全/隐私保护 异构计算
基于FPGA的1024QAM基带通信系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR
本文介绍了基于FPGA的1024QAM调制解调系统的仿真与实现。通过Vivado 2019.2进行仿真,分别在SNR=40dB和35dB下验证了算法效果,并将数据导入Matlab生成星座图。1024QAM调制将10比特映射到复数平面上的1024个星座点之一,适用于高数据传输速率的应用。系统包含数据接口、串并转换、星座映射、调制器、解调器等模块。Verilog核心程序实现了调制、加噪声信道和解调过程,并统计误码率。
46 1

热门文章

最新文章