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
-
保存指令的地址,以字节为单位
信号名 | 方向 | 描述 |
---|---|---|
CLK | I | 时钟信号 |
Reset | I | 异步复位信号 |
DI[31:0] | I | 32位输入 |
DO[31:0] | O | 32位输出(当前指令的地址) |
NPC
-
计算下一条指令的地址
信号名 | 方向 | 描述 |
---|---|---|
PC[31:0] | I | 32位输入 |
imm26[25:0] | I | 26位偏移(如jal) |
imm16[15:0] | I | 16位偏移(如beq) |
Reg[31:0] | I | 寄存器中保存着32位目标地址(如jr) |
cmp_sign | I | cmp输出的比较条件判定信号 |
NPCop[2:0] | I | NPC功能模式选择信号 000:PC+4 001:PC+4+sign_ext(imm16||00) 010:PC[31:28]||imm26||00 |
NPC[31:0] | O | 32位输出,下一条指令地址 |
IM
-
指令存储器
信号名 | 方向 | 描述 |
---|---|---|
instr_addr[4:0] | I | 指令的地址(以字为单位)PC的2-6位 |
instr[31:0] | O | 当前32位指令 |
GRF
-
寄存器堆包含32个寄存器
-
写使能信号极其重要 WE——RegWrite
-
对GRF的操作
-
从GRF中读取操作数
-
将数据回写入GRF
-
信号名 | 方向 | 描述 |
---|---|---|
A1[4:0] | I | 5位地址输入信号,指定32个寄存器中的一个,将其中存储的数据读出到RD1 |
A2[4:0] | I | 5位地址输入信号,指定32个寄存器中的一个,将其中存储的数据读出到RD2 |
A3[4:0] | I | 5位地址输入信号,指定32个寄存器中的一个作为写入的目标寄存器 |
RD1[31:0] | O | 输出A1指定的寄存器中的32位数据 |
RD2[31:0] | O | 输出A2指定的寄存器中的32位数据 |
WD[31:0] | I | 32位数据输入信号 |
WE | I | 写使能信号 1:可向GRF中写入数据 0:不可向GRF中写入数据 |
Reset | I | 异步复位信号 |
CLK | I | 时钟信号 |
ALU
-
提供32位加、减、或运算等功能
信号名 | 方向 | 描述 |
---|---|---|
A[31:0] | I | 输入ALU的第一个32位操作数 |
B[31:0] | I | 输入ALU的第二个32位操作数 |
S[4:0] | I | 补充运算数,一般为shamt |
C[31:0] | O | ALU输出32位计算结果 |
F[2:0] | I | ALU功能模式 000:A&B 001:A|B 010:A+B 011:A-B 100:保留(不做计算) |
EXT
-
功能:用于扩展数据。将原来的不规整的16位或者26位数据转换为目标32位数据。特别说明:我设计的EXT不涉及NPC中的立即数的扩展,所以,通常为16位立即数。
信号名 | 方向 | 描述 |
---|---|---|
imm_in[15:0] | I | 16位立即数输入 |
ext_sign[2:0] | I | 扩展功能模式 |
imm_out[31:0] | O | 32位扩展完成的立即数输出 |
CMP
-
原本的设计中是将CMP模块和ALU模块合并的,但是由于带条件的指令产生的判断信号会使得ALU模块变得复杂,所以特此设立CMP模块。用于beq,slt,bge等指令的执行。
-
功能:输出条件比较的结果
信号名 | 方向 | 描述 |
---|---|---|
A[31:0] | I | 第一个比较数 |
B[31:0] | I | 第二个比较数(和0比较时不需要) |
cmp_sign | O | 比较结果输出 |
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模块复杂化。
信号名 | 方向 | 描述 |
---|---|---|
CLK | I | 时钟信号 |
Reset | I | 异步复位信号 |
MemData[31:0] | I | DM输入的待处理的数据 |
Addr[31:0] | I | DM数据地址 |
Memout[31:0] | O | DM输出数据 |
MemWrite | I | 控制是否向DM写入数据 |
DMop[1:0] | I | 控制模式功能信号 00:不进行任何处理(以字为单位) 01:加载一个符号扩展字节(sb,lb)10:加载符号扩展半个字(sh,lh) |
3 控制器设计
-
首先,我来分析一下模块的本质要素:
-
输入
-
输出
-
是否发挥功能
-
发挥什么功能
-
-
看过qs哥哥的文章,引用他对控制信号理解的一句话:我认为好的控制信号有三种:
-
决定是否发挥功能的信号(对应是否发挥功能)
-
决定数据来源的信号(对应输入)
-
决定具体功能的信号(对应发挥什么功能)
-
-
本质上对控制信号的思考就是对指令过程的思考。对于一个指令,我们思考的只有三个问题:
-
哪个模块需要工作?(决定是否发挥功能的信号)
-
工作时处理的数据是什么?(决定数据来源的信号)
-
要如何处理数据?(决定具体功能的信号)
-
信号名 | 方向 | 描述 |
---|---|---|
op[5:0] | I | instr[31:26] |
func[5:0] | I | instr[4:0] |
cmp_sign | I | CMP模块的输出,条件判断信号 |
RegWrite | O | GRF模块写使能信号(是否向GRF写入数据)0:不能向GRF中写入数据 1:能向GRF中写入数据 |
MemWrite | O | DM模块写使能信号(是否向DM写入数据) 0:不能向DM中写入数据 2:能向DM中写入数据 |
EXTop[2:0] | O | EXT模块功能选择信号(选择哪种扩展) 000:符号扩展 001:0扩展 010:加载立即数至高位,低位补0 |
ALUop[2:0] | O | ALU模块功能选择信号(选择哪种计算) 000:A&B 001:A|B 010:A+B 011:A-B 100:保留原始数据,输出B |
CMPop[3:0] | O | CMP模块功能选择信号(选择哪种比较结果) 0000:A==B 0001:A>B 0010:A=B 0101:A<=B 0110:A==0 0111:A>0 |
NPCop[2:0] | O | NPC模块功能选择信号(选择那种跳转)000:PC+4 001:PC+4+sign_ext(imm16||00) 010:PC[31:28]||imm26||00 |
DMop[1:0] | O | DM模块功能选择信号(选择输出字,字节,半字) 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_Sel | O | 选择ALU的操作数B的数据来源 0:GRF的RD2 1:扩展后的32位立即数 |
指令控制信号表
指令 | RegWrite | MemWrite | GRFA3_Sel[1:0] | GRFWD_Sel[1:0] | ALUB_Sel | EXTop[2:0] | ALUop[2:0] | CMPop[3:0] | DMop[1:0] | NPCop[2:0] |
---|---|---|---|---|---|---|---|---|---|---|
lw | 1 | 0 | 00 | 01 | 1 | 000 | 010 | XXXX | 00 | 000 |
sw | 0 | 1 | XX | XX | 1 | 000 | 010 | XXXX | 00 | 000 |
addu | 1 | 0 | 01 | 00 | 0 | XXX | 010 | XXXX | XX | 000 |
subu | 1 | 0 | 01 | 00 | 0 | XXX | 011 | XXXX | XX | 000 |
beq | 0 | 0 | XX | XX | 0 | XXX | 010 | 0000 | XX | if(cmp_sign)001/else 000 |
ori | 1 | 0 | 00 | 01 | 1 | 001 | 001 | XXXX | XX | 000 |
lui | 1 | 0 | 00 | 00 | 1 | 010 | 100 | XXXX | XX | 000 |
nop | 0 | 0 | XX | XX | X | XXX | XXX | XXXX | XX | 000 |
4 指令的结构
4.1 R型指令
-
R型指令分为6个部分
op | rs | rt | rd | shamt | func |
---|---|---|---|---|---|
6bits | 5bits | 5bits | 5bits | 5bits | 6bits |
[31:26] | [25:21] | [20:16] | [15:11] | [10:6] | [5:0] |
4.2 I型指令
-
16位立即数,分为4个部分
op | rs | rt | offset or immediate |
---|---|---|---|
6bits | 5bits | 5bits | 16bits |
[31:26] | [25:21] | [20:16] | [15:0] |
4.3 J型指令
op | address |
---|---|
6bits | 26bits |
[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选择器前面。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!