## 2位串行累加器
### 实验目的
* (1)熟悉和掌握FPGA开发流程和Lattice Diamond软件使用方法;
* (2)通过实验了解累加器的意义及原理方法
* (3)掌握使用Verilog HDL语言基于FPGA实现累加器的原理及实现方法
### 实验任务
设计一个4位串行累加器,电路原理框图如图所示,在开关K处设置串行输入数据,在CP端输入8个脉冲,将完成一次,两个四位串行数据的相加,结果存D-A中。\\
{{::4位串行累加器.png?nolink&600|}}
### 实验原理
根据上述电路框图,可以分割系统任务。\\
{{::4位串行累加器实验原理.png?nolink&1000|}}\\
累加器是一个具有特殊功能的二进制寄存器,可以存放计算产生的中间结果,省去了计算单元的读取操作,能加快计算单元的速度。串行累加器是由移位寄存器和全加器组成的一个求和电路。\\
由题目给出的要求可以分析组合逻辑电路一是一个全加器电路;组合逻辑电路二和组合逻辑电路三加上JK触发器组成了加法超前进位电路,D-A是储存结果的寄存器。\\
顶层模块由4个模块组成:\\
* Shift U1模块;输入的串行寄存器,把输入的串行数据转换成并行数据寄存\\
* Adder U2模块:一位的二进制全加器模块,输入的进位信号由超前进位逻辑产生\\
* Ahead U3模块:超前进位逻辑,根据题目要求用JK触发器产生超前进位\\
* Shift U4模块:一位全加器输出再移位输出保存在4位寄存器中
### Verilog HDL建模描述
设计文件accum4.v\\
module accum4
(
input wire datain, //数据输入
input wire clk,rst, //脉冲和复位输入信号
output wire [3:0] sum //累加结果
);
wire [3:0] adder; //寄存器1,存储输入加数内容
wire [3:0] sumer; //寄存器2,存储被加数内容
wire cin; //全加器超前进位信号
wire sumout; //全加器输出
assign sum = sumer; //累加结果输出
shift u1 //移位寄存器,把数据存入加数寄存器
(
.clk(clk),
.rst(rst),
.datain(datain),
.dataout(adder)
);
adder1 u2 //全加器,两个寄存器的最低位相加,进位由超前进位逻辑输出
(
.a(sumer[0]),
.b(adder[0]),
.cin(cin),
.sum(sumout),
.cout()
);
ahead u3 //超前进位逻辑,产生进位信号
(
.a(sumer[0]),.b(adder[0]),.clk(clk),.rst(rst),
.q(cin)
);
shift u4 //移位寄存器,将全加器结果存入被加数寄存器
(
.clk(clk),
.rst(rst),
.datain(sumout),
.dataout(sumer)
);
endmodule
顶层文件里面例化了shift.v、adder1.v、ahead.v等模块,其中全加器和移位寄存器的源码文件在前面章节有介绍\\
\\
\\
我们看看超前进位逻辑的源码ahead.v\\
// Description : 超前进位逻辑产生
// JK触发器:Qi+1=J!Qi+!KQi
// 全加器进位:Ci+1=AiBi+(Ai+Bi)Ci=AiBi!Ci+!(Ai+Bi)Ci
// 推导得出:J=AiBi,K=!(Ai+Bi)
//********************************************************
module ahead
(
input wire a,b,clk,rst,
output wire q
);
wire j,k;
jk_ff u1 //例化JK触发器
(
.clk(clk),.j(j),.k(k),.rst(rst),.set(),
.q(q),
.qb()
);
assign j = a&b; //根据推导得到J,K与加法器输入信号逻辑关系
assign k = ~(a|b);
endmodule
仿真文件accum4_tb.v\\
`timescale 1ns/100ps //仿真时间单位/时间精度
module accum4_tb();
reg clk,rst,datain;
reg [7:0] data;
wire [3:0]sum;
//初始化过程块
initial
begin
clk = 0;
rst = 0;
data <= 8'b00100001; //串行输入数据初值
#25
rst = 1;
end
always #10 clk = ~clk;
always @(posedge clk) //产生串行输入数据datain
if(!rst)
begin
datain <= 0;
end
else
begin
data <={0,data[7:1]};
datain <= data[0];
end
//module调用例化格式
accum4 u1 (
.clk (clk),
.rst (rst),
.datain (datain),
.sum (sum)
);
endmodule
### 实验步骤
- 打开Lattice Diamond,建立工程。
- 新建Verilog HDL设计文件,并键入设计代码,包括添加需要调用的模块文件。
- 根据仿真教程,实现对本工程的仿真,验证仿真结果是否与预期相符。
- 如果仿真无误,构建并输出编程文件,烧写至FPGA的Flash之中。
- 观察输出结果。
### 仿真结果和实验现象
仿真结果如下图所示:{{::4位串行累加器仿真结果.png?nolink&1300|}}\\
仿真文件的串行输入数据也是靠串行转并行移位寄存器输入,所以累加器计算的时钟要顺延8个clock得到结果。可以修改仿真文件中的串行输入数据初值验证累加器结果。