P3 用Logisim搭建单周期CPU学习总结

1 教程中的设计与测试说明

经过因为没有好好读教程和题目说明导致P2挂了前车之鉴,小编决定好好阅读教程。

1.1 32位处理器

  • 32位指的是数据宽度,包括GRF里面的寄存器的位宽,指令的位宽,主存储器保存数据的位宽

1.2 什么是有效行为

  • NPC的计算

  • 对DM的操作

  • 对GRF的操作

1.3 PC的单位

  • PC的计数单位是byte

  • 1 byte=8 bit,1 word=4 byte

  • IM和DM的一个存储单位是1 word

  • 所以IM和DM的地址为PC/4 相当于取PC的2-6位

1.4对控制器的理解

  • 控制器分为两个部分

    • 和逻辑

      • 识别出是哪条指令

      • 输出信号除了该指令为1,其余指令都为0

    • 或逻辑

      • 根据指令的不同,生成不同的控制信号

      • 控制信号接在各个选择器的选择端,选择生成哪条通路

1.5EXT模块的理解

  • 通过控制信号选择对数的不同方式 高位零扩展,低位零扩展,高位符号扩展等

2 关键模块定义

2.1 我们需要那些模块

  • 小编认为执行一条指令相当于完成了一个大功能(所谓指令是功能的单位),而一条指令可以分解为几个基础功能。

  • 举例说明

    • lw:计算地址,读取DM数据到GRF

    • beq:比较操作数,分支跳转

    • addu:计算操作数的和,将结果存入GRF

  • 总结下来,所有指令可以表示为以下六个功能的线性组合:

功能描述主要涉及模块
写入寄存器(回写)GRF[num]<=GRF
存入主存(访存)Mem[Address]<=DM
计算ALU
跳转PC<=NPC
比较if(condition)CMP
extend(扩展)32-digit<=extend(not-32-digit)EXT
  • 综上所述,便可以得出我们需要哪些模块了。

2.2 关键模块介绍

PC

  • 保存指令的地址,以字节为单位

信号名方向描述
CLKI时钟信号
ResetI异步复位信号
DI[31:0]I32位输入
DO[31:0]O32位输出(当前指令的地址)

NPC

  • 计算下一条指令的地址

信号名方向描述
PC[31:0]I32位输入
imm26[25:0]I26位偏移(如jal)
imm16[15:0]I16位偏移(如beq)
Reg[31:0]I寄存器中保存着32位目标地址(如jr)
cmp_signIcmp输出的比较条件判定信号
NPCop[2:0]INPC功能模式选择信号 000:PC+4 001:PC+4+sign_ext(imm16||00) 010:PC[31:28]||imm26||00
NPC[31:0]O32位输出,下一条指令地址

IM

  • 指令存储器

信号名方向描述
instr_addr[4:0]I指令的地址(以字为单位)PC的2-6位
instr[31:0]O当前32位指令

 

GRF

  • 寄存器堆包含32个寄存器

  • 写使能信号极其重要 WE——RegWrite

  • 对GRF的操作

    • 从GRF中读取操作数

    • 将数据回写入GRF

信号名方向描述
A1[4:0]I5位地址输入信号,指定32个寄存器中的一个,将其中存储的数据读出到RD1
A2[4:0]I5位地址输入信号,指定32个寄存器中的一个,将其中存储的数据读出到RD2
A3[4:0]I5位地址输入信号,指定32个寄存器中的一个作为写入的目标寄存器
RD1[31:0]O输出A1指定的寄存器中的32位数据
RD2[31:0]O输出A2指定的寄存器中的32位数据
WD[31:0]I32位数据输入信号
WEI写使能信号 1:可向GRF中写入数据 0:不可向GRF中写入数据
ResetI异步复位信号
CLKI时钟信号

ALU

  • 提供32位加、减、或运算等功能

信号名方向描述
A[31:0]I输入ALU的第一个32位操作数
B[31:0]I输入ALU的第二个32位操作数
S[4:0]I补充运算数,一般为shamt
C[31:0]OALU输出32位计算结果
F[2:0]IALU功能模式 000:A&B 001:A|B 010:A+B 011:A-B 100:保留(不做计算)

EXT

  • 功能:用于扩展数据。将原来的不规整的16位或者26位数据转换为目标32位数据。特别说明:我设计的EXT不涉及NPC中的立即数的扩展,所以,通常为16位立即数。

信号名方向描述
imm_in[15:0]I16位立即数输入
ext_sign[2:0]I扩展功能模式
imm_out[31:0]O32位扩展完成的立即数输出

CMP

  • 原本的设计中是将CMP模块和ALU模块合并的,但是由于带条件的指令产生的判断信号会使得ALU模块变得复杂,所以特此设立CMP模块。用于beq,slt,bge等指令的执行。

  • 功能:输出条件比较的结果

信号名方向描述
A[31:0]I第一个比较数
B[31:0]I第二个比较数(和0比较时不需要)
cmp_signO比较结果输出
CMPop[3:0]I比较功能模式信号,选择输出那种比较结果 0000:A==B 0001:A>B 0010:A=B 0101:A<=B 0110:A==0 0111:A>0 1000:A<0

DM

  • RAM应使用双RAM应使用双端口模式,应设置RAM的Data Interface属性为Separate load and store ports

  • 由于想添加sb,lb,sh,lh等信号,所以将DM模块复杂化。

信号名方向描述
CLKI时钟信号
ResetI异步复位信号
MemData[31:0]IDM输入的待处理的数据
Addr[31:0]IDM数据地址
Memout[31:0]ODM输出数据
MemWriteI控制是否向DM写入数据
DMop[1:0]I控制模式功能信号 00:不进行任何处理(以字为单位) 01:加载一个符号扩展字节(sb,lb)10:加载符号扩展半个字(sh,lh)

3 控制器设计

  • 首先,我来分析一下模块的本质要素:

    • 输入

    • 输出

    • 是否发挥功能

    • 发挥什么功能

  • 看过qs哥哥的文章,引用他对控制信号理解的一句话:我认为好的控制信号有三种:

    • 决定是否发挥功能的信号(对应是否发挥功能)

    • 决定数据来源的信号(对应输入)

    • 决定具体功能的信号(对应发挥什么功能)

  • 本质上对控制信号的思考就是对指令过程的思考。对于一个指令,我们思考的只有三个问题:

    • 哪个模块需要工作?(决定是否发挥功能的信号)

    • 工作时处理的数据是什么?(决定数据来源的信号)

    • 要如何处理数据?(决定具体功能的信号)

 

信号名方向描述
op[5:0]Iinstr[31:26]
func[5:0]Iinstr[4:0]
cmp_signICMP模块的输出,条件判断信号
RegWriteOGRF模块写使能信号(是否向GRF写入数据)0:不能向GRF中写入数据 1:能向GRF中写入数据
MemWriteODM模块写使能信号(是否向DM写入数据) 0:不能向DM中写入数据 2:能向DM中写入数据
EXTop[2:0]OEXT模块功能选择信号(选择哪种扩展) 000:符号扩展 001:0扩展 010:加载立即数至高位,低位补0
ALUop[2:0]OALU模块功能选择信号(选择哪种计算) 000:A&B 001:A|B 010:A+B 011:A-B 100:保留原始数据,输出B
CMPop[3:0]OCMP模块功能选择信号(选择哪种比较结果) 0000:A==B 0001:A>B 0010:A=B 0101:A<=B 0110:A==0 0111:A>0
NPCop[2:0]ONPC模块功能选择信号(选择那种跳转)000:PC+4 001:PC+4+sign_ext(imm16||00) 010:PC[31:28]||imm26||00
DMop[1:0]ODM模块功能选择信号(选择输出字,字节,半字) 00:字 01:符号扩展字节 10:符号扩展半字
GRFA3_Sel[1:0]O选择GRF的A3的数据来源 00:rt 01:rd 10:31(jal)
GRFWD_Sel[1:0]O选择GRF的写入数据WD的数据来源 00:ALU的C 01:DM的输出 10:PC+4(jal)
ALUB_SelO选择ALU的操作数B的数据来源 0:GRF的RD2 1:扩展后的32位立即数

指令控制信号表

指令RegWriteMemWriteGRFA3_Sel[1:0]GRFWD_Sel[1:0]ALUB_SelEXTop[2:0]ALUop[2:0]CMPop[3:0]DMop[1:0]NPCop[2:0]
lw1000011000010XXXX00000
sw01XXXX1000010XXXX00000
addu1001000XXX010XXXXXX000
subu1001000XXX011XXXXXX000
beq00XXXX0XXX0100000XXif(cmp_sign)001/else 000
ori1000011001001XXXXXX000
lui1000001010100XXXXXX000
nop00XXXXXXXXXXXXXXXXX000

4 指令的结构

4.1 R型指令

  • R型指令分为6个部分

oprsrtrdshamtfunc
6bits5bits5bits5bits5bits6bits
[31:26][25:21][20:16][15:11][10:6][5:0]

4.2 I型指令

  • 16位立即数,分为4个部分

oprsrtoffset or immediate
6bits5bits5bits16bits
[31:26][25:21][20:16][15:0]

4.3 J型指令

opaddress
6bits26bits
[31:26][25:0]

5 如何添加一条新的指令

小编认为可以根据一条指令的执行的五个步骤来添加。五个步骤为:取指令、取操作数、执行、访存、回写。一个一个步骤顺序考虑该步骤需要用到的模块和控制信号。

添加指令的依据,是指令的描述和操作。

顺序过每一个步骤,检查该指令需要在这个步骤里完成什么操作。

5.1 取指令

取指令模块:NPC,IM

取指令要素

  • 读取IM

  • 计算NPC,更新PC的值

需要考虑的控制信号

  • NPCop

5.2 取操作数

取操作数模块:EXT、GRF

要素

  • 操作数据来源选择

  • 扩展数据来源选择

  • 如何扩展

需要考虑的控制信号

  • EXTop:如果有立即数扩展,选择扩展方式

5.3 执行

执行模块:ALU,CMP

执行三要素

  • ALU第一个操作数 A[31:0]来源选择

  • ALU第二个操作数 B[31:0]来源选择

  • ALU执行何种计算功能

  • CMP第一个操作数A'[31:0]来源选择

  • CMP第二个操作数B’[31:0]来源选择

  • CMP执行哪种判断功能

需要考虑的控制信号

  • ALUop

  • CMPop

  • ALUB_Sel

5.4 访存

访存模块:DM

访存要素

  • 写入地址数据来源

  • 写入数据 数据来源

  • 写使能,是否写入主存

  • 访存什么大小的数据:word?half byte?byte?

需要考虑的控制信号

  • MemWrite

  • DMop

5.5 回写

回写模块:GRF

回写三要素

  • 写入编号来源选择

  • 写入数据 来源选择

  • 是否写入GRF

需要考虑的控制信号

  • RegWrite

  • GRFWD_Sel

  • GRFA3_Sel

当五个步骤都考虑了一遍,基本上一条指令也添加完毕了。

6 可能出现的bug

  • 输出测试信号接错误:本题有七个输出测试信号,提供给评测机测试。

    • instr:当前正在执行的32位指令

    • RegWrite:GRF写使能信号

    • RegWrite:GRF的WD输入

    • MemWrite:DM写使能信号

    • MemAddr:DM输入五位地址

    • MemData:DM输入32位待处理数据

注意:一定一定要接对,不要接在mux选择器前面。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部