实验1: 设计ALU单元
1.1 实验概述
运用quartus设计ALU单元,并模拟仿真。
1.2 实验内容
设计ALU单元,参照书中155页 图 5.13,根据不同的 ALUctr 控制信号选择不同的操作,结果通过波形图显示,包括测试加法等有没有溢出。
1.3 实验设计
根据图5.13确定输入输出,并逐步实现内部的位扩展、加法器、等功能。
1.4 实验过程
源码:
1 | module ALU( |
理论分析:
ALUctr=000,操作类型为addu
第一组数据-2147483648、-2147483648相加Result=0,zero=1,不判溢出
第二组数据1、2相加Result=3,zero=0,不判溢出
第三组数据2、3相加Result=5,zero=0,不判溢出
ALUctr=001,操作类型为add
数据为-2147483648、-2147483648相加Result=0,zero=1,判断溢出Overflow=1
数据为3、1相加Result=4,zero=0,判断溢出Overflow=0
ALUctr=010,操作类型为or
第一组数据5、2做或运算Result=7,zero=0,不判溢出
第二组数据6、2做或运算Result=7,zero=0,不判溢出
ALUctr=100,操作类型为subu
第一组数据6、7相减Result=-1,zero=0,不判溢出
第二组数据-2147483648、1相减Result=2147483647,zero=0,不判溢出
ALUctr=101,操作类型为sub
第一组数据8、6相减Result=2,zero=0,判溢出Overflow=0
第二组数据8、9相减Result=-1,zero=0,判溢出Overflow=0
第三组数据-2147483648、1相减Result=2147483647,zero=0,判溢出Overflow=1
ALUctr=110,操作类型为sltu
第一组数据10、11无符号数比较大小Result={32{1}},zero=0,不判溢出
第二组数据-2147483648、1无符号数比较大小Result=0,zero=0,不判溢出
第三组数据1、0无符号数比较大小Result=0,zero=0,不判溢出
ALUctr=110,操作类型为slt
第一组数据1、2带符号数比较大小Result={32{1}},zero=0,不判溢出
第二组数据-2147483648、1带符号数比较大小Result={32{1}},zero=0,不判溢出
1.5****实验结果
1.6****实验小结
通过本次实验更加熟悉quartus的使用和verilog的编写,也对ALU单元的原理理解的更为透彻。
实验2: 寄存器组和存储器模块设计
2.1 实验概述
运用quartus设计寄存器组和存储器模块,并模拟仿真。
2.2 实验内容
寄存器组和存储器模块设计,能够实现数据的读写功能。
2.3 实验设计
根据寄存器组的图和存储器模块的图确定输入输出,并逐步数据读写功能。
2.4 实验过程
寄存器源码:
1 | module RegFile(CLK,WE,RW,RA,RB,busW,busA,busB); |
存储器单元源码:
1 | module cache(CLK,WE,Address,Data_In,Data_Out); |
寄存器组理论分析:
RA,RB分别为两个寄存器地址,busA,busB分别为两个寄存器,RW为将要写入的寄存器的地址,busW为将要写入RW的值。
一开始RA,RB为1,2,寄存器中初始化为0,busW设置为10。在第一个时钟下降沿处,由于WE为低电平,即写使能无效,因此busW并没有写入RW也就是并没有2号寄存器中,仍然是0。
在第二个时钟下降沿处,WE为高电平,写使能有效,此时将busW=10写入2号寄存器中,可以看到busB对应的2号寄存器变成了10,写入成功。
后面同理,在第三个时钟下降沿处不将11写入1号寄存器,第四个下降沿写入,可以看到busA对应的1号寄存器变成了11,写入成功。
存储器单元及理论分析:
Address为将要写入的存储器地址,Data_In为将要写入的数据,Data_Out为从存储器读出的数据,WE为写使能,存储器内容按照存储器的地址初始化,即n号存储器内容为n。
在第一个时钟下降沿处,WE为低电平即写使能无效,Data_Out为Mem[Address]=1,Data_In不写入1号存储器。
在第二个时钟下降沿处,WE为高电平即写使能有效,此时将Data_In写入1号存储器,可以看到Data_Out对应的1号存储器内容变成-1,写入成功。
后面同理,在Address=2时的第一个时钟下降沿处不写入,Data_Out=2,第二个下降沿处写入,2号存储器值变为10,写入成功
2.5****实验结果
寄存器组实验结果截图:
存储器单元实验结果截图:
2.6****实验小结
通过本次实验更加熟悉quartus的使用和verilog的编写,也对寄存器组和存储单元单元的原理理解的更为透彻。
实验3: 取指令部件设计
3.1 实验概述
运用quartus设计取指令部件,并模拟仿真。
3.2 实验内容
完成对程序计数器(PC)、指令存储器及下地址逻辑的设计和实现。掌握取指部件原理与设计方法。
3.3 实验设计
PC是一个32位地址:
顺序执行时: PC<31:0> = PC<31:0> + 4
转移执行时: PC<31:0> = PC<31:0> + 4 + SignExt[Imm16] * 4
采用32位PC时,可用左移2位实现“*4”操作,计算转移地址用2个加法器
用更简便的方式实现如下:
MIPS按字节编址,每条指令为32位,占4个字节,故PC的值总是4的倍数,即后两位为00,因此,PC只需要30位即可。
PC采用30位后,其转移地址计算逻辑变得更加简单。
下地址计算逻辑简化为:
顺序执行时: PC<31:2> = PC<31:2> + 1
转移执行时: PC<31:2> = PC<31:2> + 1 + SignExt[Imm16]
取指令时: 指令地址 = PC<31:2> 串接 “00”
Using a 30-bit PC:
顺序执行时: PC<31:2> = PC<31:2> + 1
转移执行时: PC<31:2> = PC<31:2> + 1 + SignExt[Imm16]
取指令时: 指令地址 = PC<31:2> concat “00”
先根据当前PC取指令, 计算的下条指令地址在下一个时钟到来后才能写入PC!
3.4 实验过程
取指令部件源码:
1 | module Instruction(clk,run,branch,jump,zero,instruction,pc); |
理论分析:
Branch和zero用来控制是否进行转移指令,jump为是否跳转,instruction为当前的指令,指令存储器内容为n号指令内容为n。
在第一个时钟下降沿处,branch和zero都为1,jump为0即转移指令,转移后的地址为=