资源描述
《计算机组成原理实验》
实验报告
(实验二)
学院名称
:
专业(班级)
:
学生姓名
:
学号
:
时间
:
2017
年
11
月
25
日
成绩
:
实验二
:
单周期CPU设计与实现
一. 实验目得
(1) 掌握单周期CPU数据通路图得构成、原理及其设计方法;
(2) 掌握单周期CPU得实现方法,代码实现方法;
(3) 认识与掌握指令与CPU得关系;
(4) 掌握测试单周期CPU得方法;
(5) 掌握单周期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 + (signextend)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 | (zeroextend)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位)
sa
reserved
功能:rd<-rt<<(zeroextend)sa,左移sa位 ,(zeroextend)sa
==>比较指令
(8) slt rd, rs, rt 带符号数
011100
rs(5位)
rt(5位)
rd(5位)
reserved
功能:if (rs<rt) rd =1 else rd=0, 具体请瞧表2 ALU运算功能表,带符号
==> 存储器读/写指令
(9)sw rt ,immediate(rs) 写存储器
100110
rs(5位)
rt(5位)
immediate(16位)
功能:memory[rs+ (signextend)immediate]←rt;immediate符号扩展再相加。即将rt寄存器得内容保存到rs寄存器内容与立即数符号扩展后得数相加作为地址得内存单元中。
(10) lw rt , immediate(rs) 读存储器
100111
rs(5位)
rt(5位)
immediate(16位)
功能:rt ← memory[rs + (signextend)immediate];immediate符号扩展再相加。
即读取rs寄存器内容与立即数符号扩展后得数相加作为地址得内存单元中得数,然后保存到rt寄存器中。
==> 分支指令
(11)beq rs,rt,immediate
110000
rs(5位)
rt(5位)
immediate(16位)
功能:if(rs=rt) pc←pc + 4 + (signextend)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 + (signextend)immediate <<2 else pc ←pc + 4
特别说明:与beq不同点就是,不等时转移,相等时顺序执行。
(13)bgtz rs,immediate
110010
rs(5位)
00000
immediate
功能:if(rs>0) pc←pc + 4 + (signextend)immediate <<2 else pc ←pc + 4
==>跳转指令
(14)j addr
111000
addr[27、、2]
==> 停机指令
(15)halt
111111
0000(26位)
功能:停机;不改变PC得值,PC保持不变。
三. 实验原理
1、时间周期:
单周期CPU指得就是一条指令得执行在一个时钟周期内完成,然后开始下一条指令得执行,即一条指令用一个时钟周期完成。电平从低到高变化得瞬间称为时钟上升沿,两个相邻时钟上升沿之间得时间间隔称为一个时钟周期。时钟周期一般也称振荡周期(如果晶振得输出没有经过分频就直接作为CPU得工作时钟,则时钟周期就等于振荡周期。若振荡周期经二分频后形成时钟脉冲信号作为CPU得工作时钟,这样,时钟周期就就是振荡周期得两倍。)
CPU在处理指令时,一般需要经过以下几个步骤:
(1) 取指令(IF):根据程序计数器PC中得指令地址,从存储器中取出一条指令,同时,PC根据指令字长度自动递增产生下一条指令所需要得指令地址,但遇到“地址转移”指令时,则控制器把“转移地址”送入PC,当然得到得“地址”需要做些变换才送入PC。
(2) 指令译码(ID):对取指令操作中得到得指令进行分析并译码,确定这条指令需要完成得操作,从而产生相应得操作控制信号,用于驱动执行状态中得各种操作。
(3) 指令执行(EXE):根据指令译码得到得操作控制信号,具体地执行指令动作,然后转移到结果写回状态。
(4) 存储器访问(MEM):所有需要访问存储器得操作都将在这个步骤中执行,该步骤给出存储器得数据地址,把数据写入到存储器中数据地址所指定得存储单元或者从存储器中得到数据地址单元中得数据。
(5) 结果写回(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得数据通路与必要得控制线路图,其中Ins、Mem为指令存储器,Data、Mem为数据存储器。访问存储器时,先给出内存地址,然后由读或写信号控制操作。对于寄存器组,先给出寄存器地址,读操作时,输出端就直接输出相应数据;而在写操作时,在 WE使能信号为1,在时钟边沿触发将数据写入寄存器。
4、控制信号:
控制信号得作用
控制信号名
状态“0”
状态“1”
Reset
初始化PC为0
PC接收新地址
PCWre
PC不更改,相关指令:halt
PC更改,相关指令:除指令halt外
ALUSrcA
来自寄存器堆data1输出,相关指令:add、sub、addi、or、and、ori、beq、bne、bgtz、slt、sw、lw
来自移位数sa,同时,进行(zeroextend)sa,即 {{27{0}},sa},相关指令:sll
ALUSrcB
来自寄存器堆data2输出,相关指令:add、sub、or、and、sll、slt、beq、bne、bgtz
来自sign或zero扩展得立即数,相关指令:addi、ori、sw、lw
DBDataSrc
来自ALU运算结果得输出,相关指令:add、addi、sub、ori、or、and、slt、sll
来自数据存储器(Data MEM)得输出,相关指令:lw
RegWre
无写寄存器组寄存器,相关指令:
beq、bne、bgtz、sw、halt、j
寄存器组写使能,相关指令:add、addi、sub、ori、or、and、slt、sll、lw
InsMemRW
写指令存储器
读指令存储器(Ins、 Data)
/RD
读数据存储器,相关指令:lw
输出高阻态
/WR
写数据存储器,相关指令:sw
无操作
RegDst
写寄存器组寄存器得地址,来自rt字段,相关指令:addi、ori、lw
写寄存器组寄存器得地址,来自rd字段,相关指令:add、sub、and、or、slt、sll
ExtSel
(zeroextend)immediate(0扩展),相关指令:ori
(signextend)immediate(符号扩展)
,相关指令:addi、sw、lw、bne、bne、bgtz
PCSrc[1、、0]
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+(signextend)immediate,相关指令:beq(zero=1)、
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种运算功能选择(000111),瞧功能表
ALU功能表
ALUOp[2、、0]
功能
描述
000
Y = A + B
加
001
Y = A – B
减
010
Y = B<<A
B左移A位
011
Y = A ∨ B
或
100
Y = A ∧ B
与
101
Y=(A<B)?1: 0
比较A与B
不带符号
110
if (A<B &&(A[31] == B[31] ))
Y = 1;
else if ( A[31] && !B[31) Y = 1;
else Y = 0;
比较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
指令
00
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代码:
1. module controlUnit(
2. input [5:0] opcode,
3. input zero,
4. input sign,
5. output reg PCWre,
6. output reg ALUSrcA,
7. output reg ALUSrcB,
8. output reg DBDataSrc,
9. output reg RegWre,
10. output reg InsMemRW,
11. output reg RD,
12. output reg WR,
13. output reg RegDst,
14. output reg ExtSel,
15. output reg [1:0] PCSrc,
16. output reg [2:0] ALUOp
17. );
18. initial begin
19. RD = 1;
20. WR = 1;
21. RegWre = 0;
22. InsMemRW = 0;
23. end
24. always (opcode) begin
25. case(opcode)
26. 6'b000000:begin // add
27. PCWre = 1;
28. ALUSrcA = 0;
29. ALUSrcB = 0;
30. DBDataSrc = 0;
31. RegWre = 1;
32. InsMemRW = 1;
33. RD = 1;
34. WR = 1;
35. RegDst = 1;
36. ALUOp = 3'b000;
37. end
38. 6'b000001:begin //addi
39. PCWre = 1;
40. ALUSrcA = 0;
41. ALUSrcB = 1;
42. DBDataSrc = 0;
43. RegWre = 1;
44. InsMemRW = 1;
45. RD = 1;
46. WR = 1;
47. RegDst = 0;
48. ExtSel = 1;
49. ALUOp = 3'b000;
50. end
51. 6'b000010:begin //sub
52. PCWre = 1;
53. ALUSrcA = 0;
54. ALUSrcB = 0;
55. DBDataSrc = 0;
56. RegWre = 1;
57. InsMemRW = 1;
58. RD = 1;
59. WR = 1;
60. RegDst = 1;
61. ALUOp = 3'b001;
62. end
63. 6'b010000:begin // ori
64. PCWre = 1;
65. ALUSrcA = 0;
66. ALUSrcB = 1;
67. DBDataSrc = 0;
68. RegWre = 1;
69. InsMemRW = 1;
70. RD = 1;
71. WR = 1;
72. RegDst = 0;
73. ExtSel = 0;
74. ALUOp = 3'b011;
75. end
76. 6'b010001:begin //and
77. PCWre = 1;
78. ALUSrcA = 0;
79. ALUSrcB = 0;
80. DBDataSrc = 0;
81. RegWre = 1;
82. InsMemRW = 1;
83. RD = 1;
84. WR = 1;
85. RegDst = 1;
86. ALUOp = 3'b100;
87. end
88. 6'b010010:begin // or
89. PCWre = 1;
90. ALUSrcA = 0;
91. ALUSrcB = 0;
92. DBDataSrc = 0;
93. RegWre = 1;
94. InsMemRW = 1;
95. RD = 1;
96. WR = 1;
97. RegDst = 1;
98. ALUOp = 3'b011;
99. end
100. 6'b011000:begin //sll
101. PCWre = 1;
102. ALUSrcA = 1;
103. ALUSrcB = 0;
104. DBDataSrc = 0;
105. RegWre = 1;
106. InsMemRW = 1;
107. RD = 1;
108. WR = 1;
109. RegDst = 1;
110. ALUOp = 3'b010;
111. end
112. 6'b011100:begin //slt
113. PCWre = 1;
114. ALUSrcA = 0;
115. ALUSrcB = 0;
116. DBDataSrc = 0;
117. RegWre = 1;
118. InsMemRW = 1;
119. RD = 1;
120. WR = 1;
121. RegDst = 1;
122. ALUOp = 3'b110;
123. end
124. 6'b100110:begin //sw
125. PCWre = 1;
126. ALUSrcA = 0;
127. ALUSrcB = 1;
128. RegWre = 0;
129. InsMemRW = 1;
130. RD = 1;
131. WR = 0;
132. ExtSel =1;
133. ALUOp = 3'b000;
134. end
135. 6'b100111:begin //lw
136. PCWre = 1;
137. ALUSrcA = 0;
138. ALUSrcB = 1;
139. DBDataSrc = 1;
140. RegWre = 1;
141. InsMemRW = 1;
142. RD = 0;
143. WR = 1;
144. RegDst = 0;
145. ExtSel = 1;
146. ALUOp = 3'b000;
147. end
148. 6'b110000:begin //beq
149. PCWre = 1;
150. ALUSrcA = 0;
151. ALUSrcB = 0;
152. RegWre = 0;
153. InsMemRW = 1;
154. RD = 1;
155. WR = 1;
156. ExtSel = 1;
157. ALUOp = 3'b001;
158. end
159. 6'b110001:begin //bne
160. PCWre = 1;
161. ALUSrcA = 0;
162. ALUSrcB = 0;
163. RegWre = 0;
164. InsMemRW = 1;
165. RD = 1;
166. WR = 1;
167. ExtSel = 1;
168. ALUOp = 3'b001;
169. end
170. 6'b110010:begin
171. PCWre = 1;
172. ALUSrcA = 0;
173. ALUSrcB = 0;
174. RegWre = 0;
175. InsMemRW = 1;
176. RD = 1;
177. WR = 1;
178. ExtSel = 1;
179. ALUOp = 3'b001;
180. end
181. 6'b111000:begin //j
182. PCWre = 1;
183. RegWre = 0;
184. InsMemRW = 1;
185. RD = 1;
186. WR = 1;
187. ALUOp = 3'b010;
188. end
189. 6'b111111:begin //halt
190. PCWre = 1;
191. RegWre = 0;
192. InsMemRW = 1;
193. RD = 1;
194. WR = 1;
195. end
196. default:begin
197. RD = 1;
198. WR = 1;
199. RegWre = 0;
200. InsMemRW = 0;
201. end
202. endcase
203. end
204. always(opcode or zero or sign) begin
205. if(opcode == 6'b111000) // j
206. PCSrc = 2'b10;
207. else if(opcode[5:3] == 3'b110) begin
208. if(opcode[2:0] == 3'b000) begin
209. if(zero == 1)
210. PCSrc = 2'b01;
211. else
212. PCSrc = 2'b00;
213. end
214. else if(opcode[2:0] == 3'b001) begin
215. if(zero == 0)
216. PCSrc = 2'b01;
217. else
218. PCSrc = 2'b00;
219. end
220. else begin
221. if(zero == 0 && sign == 0)
222. PCSrc = 2'b01;
223. else
224. PCSrc = 2'b00;
225. end
226. end
227. else begin
228. PCSrc = 2'b00;
229. end
230. end
231. endmodule
仿真截图:
(2)程序计数器(PC)
Verilog代码:
1. module PC(
2. input clk,
3. input [31:0] PCin,
4. input PCWre,
5. input Reset,
6. output reg [31:0] PCout
7. );
8. initial begin
9. PCout <= 0;
10. end
11. always(posedge clk) begin
12.
展开阅读全文