一、实验目的与任务
1.实验目的:熟悉实现流水线的VLSI结构设计
思想和所采用的结构设计优化技术,并进一步熟悉有关硬件描述语言的编程和EDA软件的使用。
2.实验任务:完成一个31位流水线加法器的FPGA设计与实现,包括系统结构设计、硬件语言逻辑描述,再进行程序调试、仿真分析等。
二、实验基本原理
在系统硬件设计中,采用流水线可提高系统的处理速度,但需增加硬件资源。而FPGA中由于每一个逻辑单元都包含一个触发器,这个触发器或者没有用到,或者用于存储布线资源,因此将流水线应用在FPGA的设计中,在提高系统处理速度的同时,只需要极少或根本不需要额外的硬件成本。图1.1是一个采用流水线的31位加法器的原理图,它采用流水线将一个31位的并行加法器分解成一个16位和一个15位的并行加法运算,在提高系统处理速度的同时,又充分利用了系统的有关触发器资源。
三、实验步骤
1.系统体系结构及主要功能电路的设计。
图7.1-1,整体结构由寄存器,加法器,输入输出组成。
图7.1-1 系统体系结构
2.各种VHDL源程序的设计。
(1)该程序是一个31位流水线加法器的FPGA设计,主要是实体说明,在实体里面定义总位宽是31,再定义两个子位宽分别是15和16位,用于做流水线结构,提高加法器的处理速度。
图 7.2-1 实体说明
(2)寄存器产生的因素:
语句 SIGNAL R1: STD_LOGIC_VECTOR(WIDTH1 DOWNTO 0);再给一个时钟上升沿WAIT UNTIL CLK = '1';
并置一个0使得L1和L2变成16位宽的原因:
R1 <= ('0' & L1) + ('0' & L2);因为L1和L2是X和Y输入值的(14 downto 0)位,如果两个十五位相加的值超过15位时,并置的那一位可以存储数据,保证最后数据不会出错。
图 7.2-1 结构体描述
3.源程序的编辑和编译。
4.逻辑综合和逻辑适配。
如图7.4-1,该程序的RTL图包含了三个周期,输入信号和L1-L4为第一个周期,ADD0、ADD1和R1,R2寄存器为第二个周期,ADD2、寄存器S1、S2和输出sum为第三个周期。因此,从输入端的X[31]、Y[31]到输出端Sum要经历三个时钟上升沿。图中的LBSS_CARRY是进位信号,只需要经历两个时钟上升沿就可以看出是否要进位,主要在仿真波形体现。
图7.4-1 RTL图
5.系统主要模块仿真和系统总体仿真以及有关结果分析。
如图7.5-1,流水线加法器的仿真结果,主要是设置时钟信号CLK,输入X和Y,为了体现出31位流水线加法,所以设置的数值应该偏大,让其产生进位信号,方便观察波形。图中产生了三个进位信号,LBS从低电平变成高电平,由于是第二个时钟上升沿产生的,所以倒退两个上升沿,对应的2W和3W两组的相加,以及最后一组数据相加。其原理是20000的低15位二进制数与30000的低15位二进制数相加后是16位,而第16位刚好是1,所以产生进位。
图7.5-1 流水线加法器的仿真结果
图7.5-1 产生进位
四、程序代码
本设计的参考程序如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY ADD_1P IS
GENERIC (WIDTH : INTEGER := 31; -- TOTAL BIT WIDTH
WIDTH1 : INTEGER := 15; -- BIT WIDTH OF LSBS
WIDTH2 : INTEGER := 16); -- BIT WIDTH OF MSBS
PORT (X,Y : IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
-- INPUTS
SUM : OUT STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
-- RESULT
LSBS_CARRY : OUT STD_LOGIC;
CLK : IN STD_LOGIC);
END ADD_1P;
ARCHITECTURE FPGA OF ADD_1P IS
SIGNAL L1, L2, S1 -- LSBS OF INPUTS
: STD_LOGIC_VECTOR(WIDTH1-1 DOWNTO 0);
SIGNAL R1 -- LSBS OF INPUTS
: STD_LOGIC_VECTOR(WIDTH1 DOWNTO 0);
SIGNAL L3, L4, R2, S2 -- MSBS OF INPUTS
: STD_LOGIC_VECTOR(WIDTH2-1 DOWNTO 0);
BEGIN
PROCESS -- SPLIT IN MSBS AND LSBS AND STORE IN REGISTERS
BEGIN
WAIT UNTIL CLK = '1';
-- SPLIT LSBS FROM INPUT X,Y
L1 <= X(WIDTH1-1 DOWNTO 0);
L2 <= Y(WIDTH1-1 DOWNTO 0);
-- SPLIT MSBS FROM INPUT X,Y
L3 <= X(WIDTH-1 DOWNTO WIDTH1);
L4 <= Y(WIDTH-1 DOWNTO WIDTH1);
-------------- FIRST STAGE OF THE ADDER ------------------
R1 <= ('0' & L1) + ('0' & L2);
R2 <= L3 + L4;
------------ SECOND STAGE OF THE ADDER --------------------
S1 <= R1(WIDTH1-1 DOWNTO 0);
-- ADD RESULT VON MSBS (X+Y) AND CARRY FROM LSBS
S2 <= R1(WIDTH1) + R2;
END PROCESS;
LSBS_CARRY <= R1(WIDTH1); -- ADD A TEST SIGNAL
-- BUILD A SINGLE OUTPUT WORD OF WIDTH = WIDTH1 + WIDHT2
SUM <= S2 & S1 ; -- CONNECT S TO OUTPUT PINS
END FPGA;