实验报告
实验目的:
- 学习多功能 ALU 的工作原理
- 掌握采用行为建模方式编程实现运算器的设计方法
- 学习利用顶层模块来协助实现板级验证的方法
逻辑程序设计
模块设计:
顶层模块为ALU_TOP,其中引入ALU_FUN和Display三个模块
以下为顶层模块输入输出信号,实例化另外两个模块的时候也使用顶层模块信号
输入 (Inputs):
- Clk,时钟信号(控制ABF输入信号的显示和选择、ALU_OP信号的激活)
- Button[2:0]: 选择信号,从2-0分别控制ABF三个的输入,
- Reset:复位信号,ABF全部归零便于不同数据的输入和调试
- Switch_reg[31:0]:32位信号,对应ABF,通过Button[2:0]来决定目前32位对应的信号是哪个;在选择到F的时候同时对应到ALU_OP信号来进行运算
输入 (Outputs)::
- Led[31:0]用于输出ZF OF信号(低二位)
- Enable:使能信号(默认为1,有效)
- Seg_decode[7:0]:译码后数码管分组显示信号的控制信号
逻辑程序源代码
OF考虑到溢出符号判断的第一种方法OF= C31⊕C32,AB操作数符号相同才可能发生溢出;通过F31判定符号位的同时结合C32判断进位完成溢出判定所以我们进行运算时留出32位来进行进位判定
分为三个模块
ALU_FUN模块:
|
|
Display:
|
|
分频这里cnt
是一个17位计数器,从0计数到124,999(共125,000个时钟周期),默认设置clk周期50mhz
-
扫描周期:
-
每个数码管显示时间 = 125,000 × 20ns = 2.5ms
-
8个数码管完整扫描周期 = 8 × 2.5ms = 20ms
-
-
刷新率:
- 整体刷新率 = 1/20ms = 50Hz(避免人眼看到闪烁)
ALU_TOP:
|
|
测试仿真设计
仿真程序源代码
|
|
这样的显示状态直接明了,也便于检测,我特地挑选了一些特殊的状态进行检测
仿真波形和结果
分析:
- 加法
- 基本加法如 1 + 2 = 3 正确执行,F=0x00000003,未溢出(OF=0)。
- 测试最大有符号数加 1(0x7FFFFFFF + 1)正确检测到溢出(OF=1),结果回绕为最小负数(F=0x80000000)表示溢出逻辑正确。
- 测试 -1 + 1 = 0(即 0xFFFFFFFF + 1 = 0x00000000)无溢出,零标志(ZF=1)设置正确。
- 减法(SUB)
- 基本减法如 3 - 2 = 1、1 - 1 = 0 等无符号溢出,溢出标志保持为 0(OF=0),零结果正确设置 ZF=1。
- 特别测试最小有符号数 -1(0x80000000 - 1)正确检测到溢出(OF=1),结果回绕为最大正数,说明减法溢出判断逻辑有效。
-
有符号比较(SLT) 测试 -1 < 1 正确判为真,F=1;2 > -2 判为假,F=0。说明有符号比较功能正确
-
无符号比较(SLTU)
- 测试 1 < 2 判为真,F=1;0xFFFFFFFF > 0x0FFFFFFF 判为假,F=0。验证无符号比较可以使用。
- 逻辑左移(SLL)
- 测试 1 « 4 = 0x10,0xFF00 « 8 = 0x00FF0000,移位操作正确,未影响溢出标志位(OF=0)。
- 逻辑右移(SRL)
- 测试 0x80 » 2 = 0x20;以及高位为 1 的数右移后不填充符号位,逻辑右移功能可以使用。
- 算术右移(SRA)
- 测试 -256 » 8 = -1,保持符号位,验证算术右移左侧符号填充正确;正数右移结果也正确。
- 位运算(XOR / OR / AND)
- XOR、OR、AND 运算结果匹配预期,例如相同数异或为 0,或全 1,可以正常使用,零标志设置正确。
- 特殊操作(INCA / INCB / OUTA / OUT0)
- A+1 与 B+1 功能正确,输出当前 A、B、零值等操作符合预设功能规格。
- 默认操作(DEFAULT)
- 默认 ALU_OP 0xF 情况下输出始终为 0,可以正常保存之前的状态。
- 状态位总结
- 零标志(ZF)能在结果为0时准确置为1,否则为0。
- 溢出标志(OF)仅在 ADD、SUB 的符号范围越界时置为1,其他操作保持为0
RTL电路图
顶层模块(直接用老师给的了)
RTL视图(ALU_TOP)
管脚约束
1. **管脚约束说明(输入输出变量的I/O管脚需求分析,及板级硬件资源配置理由)
将button[2:0]部分约束到提供的八个按钮的左竖列上:R4 AB6 V8
左竖列最后一个按钮设置复位信号RESET: V9
3:8译码器以及数码管部分的输入输出参照辅助实验 数码管动态扫描实验
led部分选取板子左上32位led部分
实验分析
实验结论
可以正确实现ALU多路运算器的功能并在烧录的HDU-XL-01板上显示ABF、以及运算的结果和OF ZF符号,并为之后实现更加完善的RISC-V相关ALU运算器拓展做好准备
出现的问题和解决方案
在一开始进行实验仿真的时候出现了OF不符合预期的结果,并且将8000_0000-0000_0001应为溢出的情况(即负数0-1)判定为了无溢出的错误情况,同时sub减法出现了OF在未溢出也出现0的情况
assign OF = (ALU_OP == 4'b0000 || ALU_OP == 4'b1000) ? (A[31] ^ B[31] ^ F[31] ^ C32) : 1'b0;
经过测试发现这个逻辑在加法和减法下的使用是不同的,我们在判定补码规则时,A与B符号相异要再写一个判断逻辑,改为
|
|
溢出符号可正常使用
思考与拓展部分
对于加法运算,当输入测试数据 A=0FFFFH,B=1H 时,该组数据相加产生什么结 果?请考虑,无符号加和有符号加,这两种情况下运算器硬件操作上有区别吗?无 符号数和有符号数是怎样识别的呢?
首先进行加法后会变为10000H;
在无符号加法角度是合法的,而有符号加法角度则因为符号位反转导致数字变为了范围外的负数,因此导致了溢出
仔细研究 RV32I 的核心指令集,结合本实验所实现的多功能 ALU,分析该 ALU 能 否实现 RV32I 核心指令集的所有指令?如果不能,请分析它还需要哪些运算功能
RV32I指令可分以上几类:算术指令 逻辑指令 移位指令和比较指令;
我们已经实现了大部分的需求指令,但是还缺失一部分关键指令:
-
相等判断指令 如
EQ=(A==B)
-
分支指令BEQ BNE BLT等
-
内存访问指令,如load store指令等
实验中的 ALU 实现了逻辑左移操作 sll,请考虑逻辑右移操作如何实现?考虑为何 RV32I 指令系统中没有算术左移指令
|
|
因为我们使用的计算系统为补码系统,逻辑左移和算术左移并不会产生冲突,因为低位的数会补充到高位进行符号填充,左移只是位移位、不干涉符号处理,并不会出现符号位的填充需求(右移因为产生了符号位的空出,如果不确定算术右移还是符号右移便会产生空缺
80X86CPU 除了 ZF 和 OF,还有其他标志位,试理解 80X86 的 3 个标志位 SF、CF 和 PF 的作用和逻辑,将这 3 个标志位实现到 RV32I 的多功能 ALU 中,并完成板级调试。
(1) SF:符号标志,运算结果为负数,则 SF=1;结果为正数,则 SF=0。实际上, 在计算机中定点整数(integer)是使用补码表示并进行计算的,因此,符号位 SF 就 是结果的最高位,即 SF=F[31]。
(2) PF:奇偶标志,运算结果中有偶数个“1”,则 PF=1;有奇数个“1”,则 PF=0。
(3) CF:进位/借位标志,它对无符号数运算有效。当进行加法运算时,当做进位 标志,表明无符号运算发生溢出,此时 C32=1,则 CF=1;C32=0,则 CF=0;当进 行减法运算时,当做借位标志,表明不够减,此时 C32=1,则 CF=0;C32=0,则 CF=1。
在ALU_FUN模块中添加了SF PF CF的计算,先进行导入
|
|
然后添加三个的计算逻辑
|
|
修改仿真文件进行测试
|
|
波形检测和仿真都测试无误