MIPS单周期CPU实验报告总结
时间:2020-10-31 16:20:43 来源:勤学考试网 本文已影响 人
《计算机组成原理实验》
实验报告
(实验二)
学 院 名 称 :
专业(班级) :
学 生 姓 名 :
学 号 :
时 间 : 2017 年 11 月 25 日
成 绩 :
实 验 二 : 单周期 CPU设计与实现
. 实验目的
掌握单周期 CPU数据通路图的构成、原理及其设计方法;
掌握单周期 CPU的实现方法,代码实现方法;
认识和掌握指令与 CPU的关系;
掌握测试单周期 CPU的方法;
掌握单周期 CPU的实现方法。
二.
实验内容
设计一个单周期的 MIPSCPU,使其能实现下列指令:
==> 算术运算指令
( 1) add
rd , rs, rt ( 说明:以助记符表示,是汇编指令;以代码表示,是机器指令
)
000000
rs(5 位 )
rt(5 位 )
rd(5 位 )
reserved
功能: rd ← rs + rt。
reserved 为预留部分,即未用,一般填“
0”。
( 2) addi
rt , rs ,immediate
000001
rs(5 位 )
rt(5 位 )
immediate (16 位 )
功能: rt ← rs + (sign-extend)immediate; immediate 符号扩展再参加“加”运算。
( 3) sub
rd , rs , rt
000010
rs(5 位 )
rt(5 位 )
rd(5 位 )
reserved
功能: rd ← rs - rt
==> 逻辑运算指令
( 4) ori
rt , rs ,immediate
010000
rs(5 位 )
rt(5 位 )
immediate (16 位 )
功能: rt ← rs | (zero-extend) immediate; immediate 做“ 0”扩展再参加“或”运算。
( 5) and
rd , rs , rt
010001
rs(5 位 )
rt(5 位)
rd(5 位 )
reserved
功能: rd ← rs & rt;逻辑与运算。
( 6) or
rd , rs , rt
010010
rs(5 位 )
rt(5 位 )
rd(5 位 )
reserved
功能: rd ← rs | rt;逻辑或运算。
==>移位指令
( 7) sll rd, rt,sa
011000 未用 rt(5 位 ) rd(5 位 )
功能: rd< - rt<<(zero-extend)sa ,左移 sa 位 , (zero-extend)sa
sa
reserved
==>比较指令
( 8) slt
rd, rs, rt
带符号数
011100
功能: if (rs<rt)
rs(5 位 ) rd =1 else
rt(5 位)
rd=0, 具体请看表
rd(5 位 ) reserved
2 ALU 运算功能表,带符号
==> 存储器读 / 写指令
( 9) sw rt , immediate( rs)
写存储器
100110
rs(5 位 )
rt(5 位 )
immediate (16 位 )
功能: memory[rs+ (sign-extend) immediate ]← rt; immediate 符号扩展再相加。即将
寄存器的内容保存到 rs 寄存器内容和立即数符号扩展后的数相加作为地址的内存单元中。
rt
( 10) lw
rt , immediate (rs)
读存储器
100111 rs(5 位 ) rt(5 位 ) immediate (16 位 )
功能: rt ← memory[rs + (sign-extend) immediate ];immediate 符号扩展再相加。
即读取 rs 寄存器内容和立即数符号扩展后的数相加作为地址的内存单元中的数,然后
保存到 rt 寄存器中。
==> 分支指令
( 11) beq
rs,rt, immediate
110000 rs(5 位 ) rt(5 位 ) immediate (16 位)
功能: if(rs=rt) pc ← pc + 4 + (sign-extend)immediate <<2 else pc ← pc + 4
特别说明: immediate 是从 PC+4 地址开始和转移到的指令之间指令条数 。
immediate
符号扩展之后左移 2 位再相加。为什么要左移 2 位由于跳转到的指令地址肯定是 4 的倍数(每
条指令占 4 个字节),最低两位是“ 00”,因此将 immediate 放进指令码中的时候,是右移
了 2 位的,也就是以上说的“指令之间指令条数”。
12) bne
rs,rt, immediate
110001
rs(5
位)
rt(5
位 )
immediate
功能: if(rs!=rt) pc ← pc + 4 + (sign-extend)immediate <<2 else pc
特别说明:与 beq 不同点是,不等时转移,相等时顺序执行。
← pc + 4
( 13) bgtz
rs,immediate
110010 rs(5 位 ) 00000 immediate
功能: if(rs>0) pc← pc + 4 + (sign-extend)immediate <<2 else pc
← pc + 4
==>跳转指令
14) j addr
111000 addr[27..2]
==> 停机指令
15) halt
111111 00000000000000000000000000(26 位 )
功能:停机;不改变 PC的值, PC保持不变。
三. 实验原理
1.时间周期:
单周期 CPU 指的是一条指令的执行在一个时钟周期内完成,然后开始下一条指令的执
行,即一条指令用一个时钟周期完成。 电平从低到高变化的瞬间称为时钟上升沿,
两个相邻
时钟上升沿之间的时间间隔称为一个时钟周期。时钟周期一般也称振荡周期(
如果晶振的输
出没有经过分频就直接作为
CPU的工作时钟, 则时钟周期就等于振荡周期。
若振荡周期经二分频后形成时
钟脉冲信号作为
CPU 的工作时钟,这样,时钟周期就是振荡周期的两倍。
)
CPU在处理指令时,一般需要经过以下几个步骤:
取指令 (IF):根据程序计数器 PC中的指令地址,从存储器中取出一条指令,同时,
PC 根据指令字长度自动递增产生下一条指令所需要的指令地址,但遇到“地址转移”指令
时,则控制器把“转移地址”送入 PC,当然得到的“地址”需要做些变换才送入 PC。
指令译码 (ID):对取指令操作中得到的指令进行分析并译码,确定这条指令需要完成的操作,从而产生相应的操作控制信号,用于驱动执行状态中的各种操作。
指令执行 (EXE):根据指令译码得到的操作控制信号,具体地执行指令动作,然后转移到结果写回状态。
存储器访问 (MEM ):所有需要访问存储器的操作都将在这个步骤中执行,该步骤给出存储器的数据地址, 把数据写入到存储器中数据地址所指定的存储单元或者从存储器中得到数据地址单元中的数据。
结果写回 (WB):指令执行的结果或者访问存储器中得到的数据写回相应的目的寄存
器中。
单周期 CPU,是在一个时钟周期内完成这五个阶段的处理。
对于不同的指令,需要执行的步骤是不同的,其中取字指令( lw )需要执行全部五个步
骤。因此, CPU的时间周期由取字指令决定。
2.指令类型:
MIPS的三种指令类型:
其中,
op:为操作码;
rs:只读。为第 1 个源操作数寄存器,寄存器地址(编号)是 00000~11111 , 00~1F;
rt :可读可写。为第 2 个源操作数寄存器,或目的操作数寄存器,寄存器地址(同上) ;
rd :只写。为目的操作数寄存器,寄存器地址(同上) ;
sa:为位移量( shift amt ),移位指令用于指定移多少位;
funct :为功能码,在寄存器类型指令中( R 类型)用来指定指令的功能与操作码配合使
用;
immediate :为 16 位立即数,用作无符号的逻辑操作数、 有符号的算术操作数、数据加
载( Load)/ 数据保存(Store)指令的数据地址字节偏移量和分支指令中相对程序计数器 ( PC)
的有符号偏移量;
address:为地址。
在本 CPU设计中,由于指令的类型较少,所以所有指令均由操作码( op)确定。在 R型
指令中,功能码( funct )为 000000。
3.控制线路图与数据通路:
上图为 CPU的数据通路和必要的控制线路图,其中为指令存储器,为数据存储器。访问
存储器时, 先给出内存地址,然后由读或写信号控制操作。对于寄存器组, 先给出寄存器地
址,读操作时,输出端就直接输出相应数据;而在写操作时,在 WE使能信号为 1,在时钟
边沿触发将数据写入寄存器。
4.控制信号:
控制信号的作用
控制信号名
Reset
PCWre
ALUSrcA
ALUSrcB
状态“ 0”
初始化 PC为 0
PC不更改,相关指令: halt
来自寄存器堆 data1 输出,相关指令:
add、sub、addi、or 、and、ori 、beq、 bne 、 bgtz、 slt、sw、 lw
来自寄存器堆 data2 输出,相关指令:add、 sub、 or 、and、 sll、 slt、 beq 、 bne 、 bgtz
状态“ 1”
PC 接收新地址
PC 更改,相关指令:除指令 halt 外来自移位数 sa,同时,进行 (zero-extend)sa ,即 {{27{0}},sa} ,相关
指令: sll
来自 sign 或 zero 扩展的立即数,相关指令: addi、 ori、 sw、 lw
DBDataSrc
来自 ALU 运算结果的输出,相关指 来自数据存储器( Data MEM )的输出,
令: add、 addi、 sub、 ori、 or、 and、 相关指令: lw slt、 sll
RegWre
InsMemRW
/RD
/WR
RegDst
ExtSel
无写寄存器组寄存器,相关指令:
beq 、 bne、 bgtz、 sw、 halt 、 j
写指令存储器
读数据存储器,相关指令: lw
写数据存储器,相关指令: sw
写寄存器组寄存器的地址,来自 rt 字段,相关指令: addi、 ori、 lw
(zero-extend) immediate ( 0 扩展 ),相关指令: ori
寄存器组写使能, 相关指令: add、addi 、sub、 ori、 or 、 and、slt、 sll 、lw
读指令存储器 (Ins. Data)
输出高阻态
无操作
写寄存器组寄存器的地址,来自 rd 字
段,相关指令: add、 sub、 and、 or 、slt、 sll
(sign-extend) immediate (符号扩展 )
,相关指令: addi 、sw、lw 、bne、bne 、
bgtz
00: pc<- pc+4,相关指令: add、 addi 、sub、 or 、ori 、 and、 slt、
sll、sw 、 lw 、beq(zero=0) 、 bne(zero=1)、 bgtz(sign=1,或 zero=1);
01: pc<- pc+4+(sign-extend)immediate ,相关指令: beq(zero=1) 、
PCSrc[1..0]
bne(zero=0) 、bgtz(sign=0,zero=0);
10: pc<- {(pc+4)[31..28],addr[27..2],0,0} ,相关指令: j;
11:未用
ALUOp[2..0] ALU 8 种运算功能选择 (000-111) ,看功能表
ALU功能表
ALUOp[2..0]
功能
描述
000
Y = A + B
加
001
Y = A – B
减
010
Y = B<<A
011
Y = A ∨ B
Y = A ∧ B
Y=( A<B) 1: 0
if (A<B &&(A[31] == B[31] ))
Y = 1;
110
else if ( A[31] && !B[31) Y = 1;
else Y = 0;
B 左移 A 位
或
与
比较 A 与 B
不带符号
比较 A 与 B
带符号
111 Y = A B 异或
附:本 CPU的指令集并未用到 ALU的全部功能。
5.主要模块接口说明:
Instruction Memory :指令存储器 ,
address,指令存储器地址输入端口
DataIn,指令存储器数据输入端口(指令代码输入端口)
DataOut ,指令存储器数据输出端口(指令代码输出端口)
InsMemRW ,指令存储器读写控制信号,为 0 写,为 1 读 Data Memory :数据存储器 ,
address,数据存储器地址输入端口
DataOut ,数据存储器数据输出端口
/RD,数据存储器读控制信号,为 0 读
/WR ,数据存储器写控制信号,为 0 写
Register File :寄存器组
Read Reg1,rs 寄存器地址输入端口
Read Reg2, rt 寄存器地址输入端口
Write Reg,将数据写入的寄存器端口,其地址来源 rt 或 rd 字段
Write Data ,写入寄存器的数据输入端口
Read Data1, rs 寄存器数据输出端口
Read Data2, rt 寄存器数据输出端口
WE,写使能信号,为 1 时,在时钟边沿触发写入
RST,寄存器清零信号,为 0 时寄存器清零
ALU: 算术逻辑单元
result , ALU 运算结果
zero,运算结果标志,结果为 0,则 zero=1;否则 zero=0
sign,运算结果标志,结果最高位为 0,则 sign=0,正数;否则, sign=1,负数
四. 实验器材
电脑一台, Xilinx Vivado 软件一套, Basys3板一块。
五. 实验过程与结果
1.各个指令对应的控制信号
指令
PCWre
ALUSrcA
ALUSrcB
DBDataSrc
RegWre
InsMemRW
RD
WR
RegDst
ExtSel
Add
1
0
0
0
1
1
1
1
1
X
Addi
1
0
1
0
1
1
1
1
0
1
Sub
1
0
0
0
1
1
1
1
1
X
Ori
1
0
1
0
1
1
1
1
0
0
And
1
0
0
0
1
1
1
1
1
X
Or
1
0
0
0
1
1
1
1
1
X
Sll
1
1
0
0
1
1
1
1
1
X
Slt
1
0
0
0
1
1
1
1
1
X
Sw
1
0
1
X
0
1
1
0
X
1
Lw
1
0
1
1
1
1
0
1
0
1
Beq
1
0
0
X
0
1
1
1
X
1
Bne
1
0
0
X
0
1
1
1
X
1
Bgtz
1
0
0
X
0
1
1
1
X
1
J
1
X
X
X
0
1
1
1
X
X
Halt
0
X
X
X
0
1
1
1
X
X
控制信号
ALUOp
Add
000
Addi
000
Sub
001
Ori
011
And
100
Or
011
Sll
010
Slt
110
Sw
000
Lw
000
Beq
001
Bne
001
Bgtz
101
J
010
Halt
XXX
除异或运算(
111)外, ALU所有功能均被使用。
PCSrc 指令
add、addi 、sub、or 、ori、and、slt、sll、sw、lw、beq(zero=0) 、bne(zero=1) 、bgtz(sign=1,或 zero=1)
01
beq(zero=1)、 bne(zero=0) 、bgtz(sign=0, zero=0)
10
j
2.主要模块代码及仿真
1)控制单元( control unit )
Verilog 代码:
modulecontrolUnit(
input[5:0]opcode,
inputzero,
inputsign,
outputregPCWre,
outputregALUSrcA,
outputregALUSrcB,
outputregDBDataSrc,
outputregRegWre,
outputregInsMemRW,
outputregRD,
outputregWR,
outputregRegDst,
outputregExtSel,
outputreg[1:0]PCSrc,
outputreg[2:0]ALUOp
);
initialbegin
RD=1;
WR=1;
RegWre=0;
InsMemRW=0;
end
always@(opcode)begin
case(opcode)
6'b000000:begin
试程序:
测试程序如下:
指令代码
地址
汇编程序
op
rs(5)
rt(5)
rd(5)/immediate
16 进制数代码
( 6)
(16)
0addi $1,$0,8
000001
00000
00001
0000 0000 0000 1000
0401 0008
0ori $2,$0,2
010000
00000
00010
0000 0000 0000 0010
4002 0002
0add $3,$2,$1
000000
00010
00001
00011 00000 000000
0041 1800
0x0000000C
sub $5,$3,$2
000010
00011
00010
00101 00000 000000
0862 2800
0and $4,$5,$2
010001
00011
00010
00100 00000 000000
4462 2000
0or $8,$4,$2
010010
00100
00010
01000 00000 000000
4882 4000
0sll $8,$8,1
011000
00000
01000
01000 00001 000000
6008 4040
0x0000001C
bne
$8,$1,-2
(≠,转
C501 FFFE
18)
110001
01000
00001
1111 1111 1111 1110
0slt $6,$2,$1
011100
00010
00001
00110 00000 000000
7041 3000
0slt $7,$6,$0
011100
00110
00000
00111 00000 000000
70C0 3800
0addi $7,$7,8
000001
00111
00111
0000 0000 0000 1000
04E1 0008
0x0000002C
beq
$7,$1,-2
(≠,转
C0E1 FFFE
28)
110000
00111
00001
1111 1111 1111 1110
0sw $2,4($1)
100110
00001
00010
0000 0000 0000 0100
9822 0000
0lw $9,4($1)
100111
00001
01001
0000 0000 0000 0100
9C29 0004
0bgtz
$9,2 (=0)
110010
01001
00000
0000 0000 0000 0010
C920 0002
0x0000003C
addi
$9,$0,15
000001
00000
01001
0000 0000 0000 1111
0409 000F
0j 0111000
00 0000 0000 0000 0000 0000 1110
E000 000E
0halt
111111
00 0000 0000 0000 0000 0000 0000
FC00 0000
机器代码(
.roe):
仿真截图:
(1) addi $1, $0, 8 至 bne $1, $8, -2
(2) slt $6, $2, $1 至 lw $9, 4($1)
3) bgtz $9, $2 至 halt
烧板
1) addi $1,$0,8:
当前 PC和下一条 PC:
Rs寄存器:
Rt寄存器:
ALU结果及写寄存器数据:
2) ori $2,$0,2
当前 PC和下一条 PC:
Rs寄存器:
Rt寄存器:
ALU结果及写寄存器数据:
3) add $3,$2,$1
当前 PC和下一条 PC:
Rs寄存器:
Rt寄存器:
ALU结果及写寄存器数据:
六. 实验心得
这次实验中,在设计
CPU中各个模块时,遇到的问题并不大。但是,在顶层模块中,由
于以前的 verilog 实验中中间变量的数量远远小于这一次,因而遇到了许多没有遇到过的问
题。比如寄存器堆的输出
ReadData2和数据存储单元的输入 DataIn是同一个变量,但在最早
的顶层模块代码中我声明了两个变量,导致
CPU在执行存字指令( sw)时出错。再比如在仿
真时,因为发现寄存器堆写寄存器时存在问题,
为了 debug,我为顶层模块增加了几个输出,
其中有一个输出的名称为
RD,对应指令中的 rd寄存器。但是,在 CPU中控制单元输出的控制
信号中有一个便被命名为
RD。因此,在很多次仿真中, RD都不能输出正确的结果,浪费了
大量的时间。
在实验中,我遇到的另一个主要的问题是在生成 bit 文件时多次报错( DRC 23-20 )。我
询问了很多位同学, 但都没有解决, 最后是在网上找到一篇提及这个错误的博客。 根据博客
的内容和软件提供的错误信息,我添加了一个文件,并加入了一条命令:
set_property SEVERITY {Warning} [get_drc_checks LUTLP-1]
从而解决了这个错误,生成 bit 文件。