实验案例-ALU设计

实例四 ALU设计(基于Robei的实验案例)

2.4.1. 本章导读

ALU(算数逻辑单元)是CPU的基本组成部分。设计要求掌握算术逻辑运算加、减操作原理,验证运算器的组合功能。
设计原理
ALU的基本结构如图2-4-1所示。我们所设计的ALU要实现最基本的加减运算,与或非和异或等功能。
实验案例-ALU设计_第1张图片
(1)加法运算包含2种类型,一种是不带进位的加法器,另外一种是带进位的加法器。不带进位的加法器的公式:
{D,R}=A+B (1)
带进位的可以进行加法器级联,实现更高位数的串行加法运算。带进位的加法器的公式:
{D,R}=A+B+F (2)
(2)减法运算也包含2种类型。不带借位的减法运算:
{D,R}=A-B (3)
带借位的减法运算:
{D,R}=A-B-F (4)
设计要求
设计一个8位ALU,并能实现数据与,或,非,异或,不带进位加法,带进位加法,不带借位减法和带借位减法运算。运算符采用3比特表示。A,B,R 均为8比特数据。用测试文件测试你的ALU功能,并用级联方式将4个8比特的ALU实现32 比特的ALU。

2.4.2. 设计流程

1. ALU模型设计

  1. 新建一个模型命名为alu,类型为module,同时具备4输入2输出。每个引脚的属性和名称参照图2-4-2进行对应的修改。
    实验案例-ALU设计_第2张图片
    图2-4-2 引脚属性
    实验案例-ALU设计_第3张图片
    图2-4-3 ALU界面图
  2. 添加代码。点击模型下方的Code(如图2-4-4所示)添加代码。
    实验案例-ALU设计_第4张图片图2-4-4 点击Code输入算法
    在代码设计区内输入以下Verilog代码:
    always @ (A or B or op or F)
    begin
    case ( op )
    3’b000: {D,R}=A&B; //实现与运算
    3’b001: {D,R}=A|B; //实现或运算
    3’b010: {D,R}=~A; //实现非运算
    3’b011: {D,R}=A^B; //实现异或运算
    3’b100: {D,R}=A+B; //实现不带进位的加运算
    3’b101: {D,R}=A+B+F; //实现带进位的加运算
    3’b110: {D,R}=A-B; //实现不带借位的减运算
    3’b111: {D,R}=A-B-F; //实现带借位的减运算
    default: {D,R}=A&B; //默认为与运算
    endcase
    end

(3)保存模型到一个文件夹中,运行并检查有无错误输出。

2. 测试文件设计

(1)新建一个4输入2输出的测试文件,记得将Module Type设置为“testbench”各个引脚配置如图2-4-5所示。
实验案例-ALU设计_第5张图片
图2-4-5 新建测试文件
(2)另存为测试文件。将测试文件保存到alu模型所在的文件夹下。
(3)加入模型。在Toolbox工具箱的Current栏里,会出现一个alu模型,单击该模型并在alutest上添加,并连接引脚,如图2-4-6所示。
实验案例-ALU设计_第6张图片
图2-4-6 添加模型
(4)输入激励。点击测试模块下方的“Code”,输入激励算法,如图2-4-7所示。激励代码在结束的时候要用$finish 结束。
initial begin
a=0;
b=0;
op=0;
cin=0;
#1
a=3;
b=1;
op=0;
#1
a=2;
b=1;
op=1;
#1
a=255;
b=0;
op=2;
#1
a=5;
b=6;
op=3;
#1
a=128;
b=128;
op=4;
#1
a=4;
b=5;
cin=1;
op=5;
#1
a=4;
b=5;
op=6;
#1
a=4;
b=5;
op=7;
#1
a=4;
b=5;
op=0;
#1
$finish;
end

实验案例-ALU设计_第7张图片
图2-4-7 激励代码
(5)执行仿真并查看波形。查看输出信息。检查没有错误之后查看波形。点击右侧Workspace中的信号,进行添加并查看分析仿真结果,如图2-4-8所示。对照真值表,查看设计波形输入输出是否一致。
实验案例-ALU设计_第8张图片
图2-4-8 查看波形

3. 16位ALU设计

(1)下面我们来设计一个16位的ALU。这个设计中使用之前设计好的8位ALU模块,把输入的16位信号拆分为两个8位信号,经过8位ALU处理后再组合成最终的16位输出信号。
(2)split模块设计:该模块的功能是把输入的16位数据分解为两个8位数据。模块引脚设计如图2-4-9所示。
实验案例-ALU设计_第9张图片
图2-4-9 split模块引脚
实验案例-ALU设计_第10张图片
图2-4-10 split模块设计
模块设计好后,点击code标签,输入split模块的代码:
assign B=A[7:0];
assign C=A[15:8];
(3)merge模块设计:该模块的功能是把两个8位数据组合为一个16位数据。模块引脚设计如图2-4-11所示。
实验案例-ALU设计_第11张图片
图2-4-11 merge模块引脚
实验案例-ALU设计_第12张图片
图2-4-12 merge模块设计
模块设计好后,点击code标签,输入merge模块的代码:
assign C={B, A};
(4)接下来建立一个模块,命名为alu16,具有4输入和2输出,引脚设定如下图2-4-13所示:
实验案例-ALU设计_第13张图片
图2-4-13 alu16模块引脚设计
保存之后把之前设计好的ALU,split和merge模块添加进alu16模块,并进行连线。完成后的模块如图2-4-14所示:
实验案例-ALU设计_第14张图片
图2-4-14 alu16模块设计
(5)测试模块设计:新建一个模块,模块类型选择为testbench,引脚设计如图2-4-15所示。
实验案例-ALU设计_第15张图片
图2-4-15 alu16的测试模块引脚设计
保存后把之前设计的alu16模块添加进测试模块,并进行连线。连线后的测试模块如图2-4-16所示。
实验案例-ALU设计_第16张图片
图2-4-16 alu16的测试模块设计
点击code标签,输入测试模块的激励代码:
initial begin
a=0;
b=0;
op=0;
cin=0;
#1
a=24;
b=35;
op=0;
#1
a=56;
b=18;
op=1;
#1
a=96;
b=80;
op=2;
#1
a=51;
b=26;
op=3;
#1
a=128;
b=128;
op=4;
#1
a=64;
b=15;
cin=1;
op=5;
#1
a=74;
b=35;
op=6;
#1
a=24;
b=75;
op=7;
#1
a=24;
b=55;
op=0;
#1
$finish;
end

(6)运行后,点击Wave查看波形,如图2-4-17所示,检查设计的正确性。
实验案例-ALU设计_第17张图片
图2-4-17 alu16的测试模块仿真波形

4. 32位ALU设计

(1)我们利用8位的ALU级联来设计一个32位的ALU,这个设计需要先行注册Robei软件,否则不能进行仿真。
(2)创建一个新的模型,添加10个输入引脚,5个输出引脚,各个引脚的配置如图2-4-18所示。保存到alu模型所在的文件夹。
实验案例-ALU设计_第18张图片
图2-4-18 32位ALU引脚
(3)添加4个ALU连接引脚。如图2-4-19所示。4个8位的ALU进行级联,第一个输出的D连到下一级的F,最终的ALU的D连接到顶层的D引脚。第一个ALU的F连接到顶层模块的F。op都连接到顶层的op引脚上,A,B和R按照高低位进行连接。这样输入A3A2A1A0,B3B2B1B0和R3R2R1R0分别是32位ALU的输入和输出端。如图2-4-19所示。
实验案例-ALU设计_第19张图片
图2-4-19 32位ALU设计图
(4)创建一个测试文件,10个输入引脚5个输出,按照图2-4-20进行引脚配置并保存到与alu32bit模型同一个文件下。
实验案例-ALU设计_第20张图片
图2-4-20 32位ALU测试文件引脚配置
(5)从Toolbox里面的Current栏找alu32bit模型,并添加到测试模块上。对应引脚相连。如图2-4-21所示。
实验案例-ALU设计_第21张图片
图2-4-21 32位ALU测试引脚连接
(6)自己设计测试激励代码,并仿真查看结果。
实验案例-ALU设计_第22张图片
图2-4-22 32位ALU仿真波形
2.4.3. 问题与思考
1、不要使用8位ALU级联的方式,尝试直接用Verilog在Robei中实现一个32位或者64位ALU。
2、挑战题:在8位ALU设计上添加乘法功能,输出结果变成16位输出。利用这个ALU实现一个16位的乘法器。提示:16位乘法器分成低8位和高8位。如A[15:0]拆分成A[15:8]和A[7:0],同样拆分B。之后用4个乘法器分别实现:
A[7:0]×B[7:0]
A[7:0]×B[15:8]
A[15:8]×B[7:0]
A[15:8]×B[15:8]
然后进行适当移位,再用加法器实现相加。

你可能感兴趣的:(教育,高校,FPGA)