1. 分析指令集

  • 经过分类,指令共包含R型指令和I型指令
  • 列出其对应的32位机器码,寻找共性差异

R型指令:

Type Op Rs Rt Rd Shamt Func 解释
add 000000 (5) (5) (5) 00000 100000 相加(rs+rt->rd)
sub 000000 (5) (5) (5) 00000 100010 相减(rs-rt->rd)
and 000000 (5) (5) (5) 00000 100100 rs & rt -> rd
or 000000 (5) (5) (5) 00000 100101 rs | rt -> rd
slt 000000 (5) (5) (5) 00000 101010 rs < rt ? 1 : 0(signed)
sltu 000000 (5) (5) (5) 00000 101011 rs < rt ? 1 : 0(unsigned)
mfhi 000000 00000 00000 (5) 00000 010000 HI ->rd
mflo 000000 00000 00000 (5) 00000 010010 LO -> rd
Type Op Rs Rt 0 Func 解释
mult 000000 (5) (5) 0000000000 011000 rs * rt -> (HI, LO)(signed)
multu 000000 (5) (5) 0000000000 011001 rs * rt -> (HI, LO)(unsigned)
div 000000 (5) (5) 0000000000 011010 rs / rt -> (HI, LO)(signed)
divu 000000 (5) (5) 0000000000 011011 rs / rt -> (HI, LO)(unsigned)
Type Op Rs 0 Func 解释
mthi 000000 (5) 000000000000000 010001 rs -> HI
mtlo 000000 (5) 000000000000000 010011 rs -> LO

I型指令:

Type Op Rs Rt Immediate 解释
ori 001101 (5) (5) (16) 或运算(rs|immediate->rt)
lui 001111 00000 (5) (16) 立即数加载至高16位({immediate||{16{1’b0}}}->rt)
addi 001000 (5) (5) (16) rs + immediate -> rt
andi 001100 (5) (5) (16) rs & immediate -> rt
Type Op Rs Rt Offset 解释
lw 100011 (5) (5) (16) 加载字(rs+offset在memory中data->rt)
sw 101011 (5) (5) (16) 保存字(rt->rs+offset在memory中的data)
beq 000100 (5) (5) (16) rs与rt相等则PC偏移offset*4
lb 100000 (5) (5) (16) mem中rs +offset对应字节符号拓展 -> rt
lh 100001 (5) (5) (16) mem中rs +offset对应半字符号拓展 -> rt
sb 101000 (5) (5) (16) rt[7:0] -> mem(offset + rs)
sh 101001 (5) (5) (16) rt[15:0] -> mem(offset + rs)
bne 000101 (5) (5) (16) 不相等则跳转

J型指令

type Op instr_index 解释
jal 000011 (26) 跳转至index并且PC+4 -> $ra
type Op rs 0 0 func 解释
jr 000000 (5) {10{1’b0}} {5{1’b0}} 001000 跳转至$rs中的地址

2. 阶段分析


F阶段PC值已经确定,进行的是根据PC访存相应的Instruction操作。此时指令已经确定好了
D阶段是将instruction转换成对应的操作数、产生控制信号。
E阶段是将操作数转换成计算结果。
M阶段是方寸数据内存。
W阶段是写入GRF。

3.命名规则

采用首字母大写命名法,每个单词首字母大写。

4. PC设计

端口设计:

方向 name 位宽
input PcOp [3:0]
input BeqPc [31:0]
input JalPc [31:0]
input JrPc [31:0]
input reset 1
input clk 1
output Pc_F [31:0]
input BnePc [31:0]

转移设计:

PcOp 解释
0000 Pc_F <= Pc_F + 4
0001 Pc_F <= BeqPc
0010 Pc_F <= JalPc
0011 Pc_F <= JrPc
0100 Pc_F <= BnePc

5. CU控制信号分析

端口设计:

type name 位宽 解释
input Op [5:0] 机器码高6位
input Func [5:0] 机器码低6位
output RegDst [1:0] GRF被写入寄存器是rt还是rd。0是rt,1是rd,10是$ra
output AluSrc [1:0] ALU第二个运算值是rt还是立即数。0是rt,1是立即数
output MemToReg [1:0] GRF写入值是ALUans还是DMans。0是ALUans,1是DMans,10是PC + 4
output RegWrite 1 是否写入GRF
output MemWrite 1 是否写入RAM
output PcSel [3:0] 当前指令是否是beq\jal\jr
output ExtOp [7:0] 扩展操作类型类型,详见Extender
output AluOp [7:0] ALU运算类型,详见ALU
output InstrType [7:0] 指令类型
output TNew_D [3:0] 从D级开始,经过多少周期该指令产生运算结果
output TUse1_D,TUse2_D [3:0] 从D级开始,经过多少周期要用到运算结果
output Multiply_D 1 是否进行乘法操作
output Divide_D 1 是否进行除法操作
  • 内部电路采用最小项表达式判断法,先判断Op,再判断Func

每种指令所需控制信号:

RegDst AluSrc MemToReg RegWrite MemWrite PcSel ExtOp AluOp TNew TUse1 TUse2
add 01 00 00 1 0 0000 ADD 2 1 1
sub 01 00 00 1 0 0000 SUB 2 1 1
ori 00 01 00 1 0 0000 0000 OR 2 1 10
lui 00 01 00 1 0 0000 0010 ADD 2 10 10
lw 00 01 01 1 0 0000 0001 ADD 3 1 10
sw 11 01 0 1 0000 0001 ADD 0 1 2
beq 11 00 0 0 0001 0011 EQUAL 0 0 0
jal 10 10 1 0 0010 0100 0 10 10
jr 11 00 0 0 0011 ADD 0 0 10

6. 流水线寄存器存储信息分析

F级:

name 位宽
Pc_F [31:0]
Instruction_F [31:0]

D级:

name 位宽
Pc_D [31:0]
RD1_D [31:0]
RD2_D [31:0]
WR_D [4:0]
ExtAns_D [31:0]
MemToReg_D [1:0]
RegWrite_D 1
AluSrc_D [1:0]
MemWrite_D 1
AluOp_D [7:0]
InstrType_D [7:0]
TNew_D [7:0]
Addr1_D [4:0]
Addr2_D [4:0]

E级:

name 位宽
Pc_E [31:0]
AluAns_E [31:0]
WR_E [4:0]
RD2_E [31:0]
MemToReg_E [1:0]
RegWrite_E 1
MemWrite_E 1
InstrType_E [7:0]
TNew_E [7:0]
Addr2_E [4:0]

M级:

name 位宽
Pc_M [31:0]
AluAns_M [31:0]
WR_M [4:0]
DmAns_M [31:0]
MemToReg_M 1
RegWrite_M 1
InstrType_M [7:0]
TNew_M [7:0]

W级:

name 位宽
Pc_W [31:0]
AluAns_W [31:0]
WR_W [4:0]
DmAns_W [31:0]
MemToReg_W [1:0]
RegWrite_W 1
InstrType_W [7:0]
TNew_W [7:0]

7. 流水线转发数据

E级:

instruction Data_E
add 0
sub 0
ori 0
lui 0
beq 0
jal Pc_E + 8
jr 0
lw 0
sw 0

M级:

instruction Data_M
add AluAns_M
sub AluAns_M
ori AluAns_M
lui AluAns_M
beq 0
jal Pc_M + 8
jr 0
lw 0
sw 0

W级:

instruction Data_W
add AluAns_W
sub AluAns_W
ori AluAns_W
lui AluAns_W
beq 0
jal Pc_W + 8
jr 0
lw DmAns_W
sw 0

8. 测试方案

针对每一条新添加的指令都进行测试,确保有符号、无符号的正确性,以及周期数的正确。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
3508000c
35290015
01095024
000a5820
35080010
35290019
01095025
01405820
2108ffff
2108ffff
2108fffe
310a0079
314a0015
000a582a
2009ffff
0120582a
0000582a
200afffe
012a582a
0149582a
012a582b
340c03e8
012c582a
012c582b
0169582b
14000007
20080001
20080002
20080003
14080003
20080004
20080005
20080006
20080003
2009fffe
200a0002
01090018
01090019
010a0018
0109001a
0109001b
010a001a
00004010
21080001
00004012
21080003
00004010
1100fff1
20090003
20090007
01200011
00005010
012a0018
01600013
00005812
016a5824
2008fffd
20090001
200a0002
200b0003
a0080000
a1280000
a1480000
a1680000
a4080004
a5480008
800c0004
218c0002
814c0004
218c000d
840c0004
218c0034
34080005
34090022
00084022
00094822
01280018
00005010
00005812

9. 思考题汇总

  1. 鼠标和键盘的信号被CPU知晓的过程涉及到硬件中断、信号传输、以及操作系统的参与

鼠标信号被CPU知晓的过程

  1. 鼠标信号的产生:当鼠标移动或点击时,会产生相应的电信号或数字信号。这些信号代表了鼠标的位置、移动方向、点击动作等信息。
  2. 信号传输到计算机:这些信号通过鼠标线(有线鼠标)或无线方式(无线鼠标)传输到计算机的USB接口或其他类型的接口上。
  3. 中断请求:一旦鼠标信号到达计算机,它会触发一个硬件中断。这个中断请求会被送到中断控制器,中断控制器再将请求转发给CPU。
  4. CPU处理中断:CPU在接收到中断请求后,会暂停当前正在执行的任务,转而处理鼠标中断。CPU会读取鼠标控制器中的数据,这些数据包含了鼠标的位置信息和状态信息。
  5. 操作系统的角色:操作系统会进一步处理这些原始数据,将其转换为更高级别的事件,如鼠标移动事件或点击事件,并将这些事件传递给应用程序。

键盘信号被CPU知晓的过程

  1. 键盘信号的产生:当用户按下键盘上的某个键时,键盘内部的电路会产生一个相应的电信号。这个信号代表了被按下的键的位置信息。

  2. 信号编码:键盘控制器将这些电信号转换为键盘扫描码,这是一种二进制编码,用于表示键盘上每个键的唯一标识。

  3. 信号传输到计算机:键盘扫描码通过键盘线传输到计算机的USB接口或其他类型的接口上。

  4. 中断请求与CPU处理:与鼠标类似,键盘信号也会引起硬件中断。CPU在接收到中断请求后,会读取键盘控制器中的扫描码,并将其存储在特定的内存位置(如键盘缓冲区)中。

  5. 操作系统与驱动程序:操作系统和键盘驱动程序会进一步处理这些扫描码,将其转换为ASCII码或Unicode码等字符编码,以便应用程序能够理解和使用。

  6. 因为这样,我们就可以提前在该地址处书写异常处理程序;当异常发生时,只需要固定跳转到该地址,即可运行相对应的异常处理程序来处理异常。如果是用户自定义处理异常中断的入口地址,自己提供程序,那么CPU仍然可以正常提供异常中断修复的功能。但是这样的问题在于用户的自定义程序入口或自定义程序可能占用了DM的存储空间,导致DM空间不足或者访存指令出错。

  7. 因为每种外设的接口不同,格式不同,方寸方式也不同。如果不用Bridge,则CPU需要为每一种外设都新增新的方寸方式或者接口,这不利于维护CPU的正常工作。而Bridge可以解决这一问题,通过读取CPU的信号和外设的信号,来进行中间的交互,转移了工作量,有利于CPU的功能维护和扩展。

  8. 两种中断模式在计数为0后的行为不同。一种是自动填装初值再重新倒数,一种是保持为0直到使能信号置位再计数。![[810a3c13b390e6a91ad2365bd55281f.jpg]]
    ![[12ac7de1353c985830c21aa192065fc.jpg]]

  9. 会发生的问题是,空泡的PC和BD可能不是我们所期待的,从而导致eret指令返回地址异常。因此空泡指令需要保存原指令的PC和BD,如果在空泡时遇到了中断,也能根据PC和BD返回正确的指令。

  10. 因为会存在冒险。jalr指令的功能是跳转到对应寄存器中的地址,同时把PC+4(有延迟槽则PC+8)的值写入对应寄存器中。如果后面两个寄存器都是相同的,则先跳转再写入还是先写入再跳转就会产生两种不一样的结果。因此为了避免这种未知情况的发生,不能这样写。