祭祖07
brief
本文将讲解包含(R型指令,load/store,beq)的数据通路和CU的设计方法(J型指令要放到后文了)
时序信号
CPU在时钟周期下工作
一条指令->一些周期,将任务分配到每个周期里。
本文之后涉及的指令均为单周期指令, 将一个周期长度设置成最耗时指令的长度,保证一个周期内可以完成所有的指令。
组合单元
与门、非门、ALU这种执行某一个操作,无法保存信息,输入变化,输出会立刻变化。
状态单元
采用边缘触发的D型触发器
为什么不用锁存器做状态单元
https://blog.csdn.net/weixin_45264425/article/details/130310971
高电平触发,时间太长会还原
组合单元的输入为保持稳定需来自状态单元,输出接状态单元,否则结果会被后输入覆盖?
状态单元可输出到状态单元
数据通路设计(需要哪些组合单元和状态单元)
存储程序原理(取指令,执行)
- 取指令 PC -> IM(指令存储器),这两个都是状态单元
- PC + 4 -> PC(一般都是上升檐触发)
R型指令
如何知道是什么指令,通过指令前6位的op code(mips指令集的指令定长32位)以及最后6位的功能码
- 译码 op code和func->CU
- 取操作数(rs,rt)读寄存器
- 计算
- 写回rd
注意Register File并不会在每个周期里都写入(例如sw),所以需要一个显形的写入控制信号(RegWri)给RF
ALU Control控制了ALU单元做什么运算,这里add指令是加法,如何控制会在后文讲述
Load指令
基址rs + 16bit的偏移。
- 译码,只需要op code->CU
- 读rs
- 计算地址(需要用到符号扩展将16位的偏移地址符号扩展为32位的带符号值)
- 从存储器中读数据
- 写回rt
rt = Memory[offset + rs]
store
与load类似,流程图同上
- 译码,只需要op code->CU
- 读rs
- 计算地址(需要用到符号扩展将16位的偏移地址符号扩展为32位的带符号值)
- 向存储器中写数据
控制信号并不是所有命令都会对DM进行读写
memread和memwri,
beq
- 译码
- 读rs,rt
- 在ALU中做减法
- 传出zero,如果zero为1,计算偏移地址并赋值给pc(pc + 4 + offset<<2)
- zero为0 pc+=4
这里zero怎么处理?后述
jump
- 译码
- PC[31,30,29,28] + offset<<2 (pc + 4不影响)
几乎完整的数据通路(不包含jump)
设计CU
- 选择要执行的操作 (ALU, Register File and Memory read/write)
- 控制数据流(multiplexor inputs)
- 从32位的指令中读出信息
对比
op field alwaysin bits 31-26
addr of two registers to be read are always specified by the rs and rt fields (bits 25-21 and 20-16)
base register for lw and sw always in rs (bits 25-21)
addr. of register to be written is in one of two places – in rt (bits 20-16) for lw; in rd (bits 15-11) for R-type instructions
offset for beq, lw, and sw always in bits 15-0
现在对照数据通路图完善cu吧
ALU控制单元
ALU操作基于inst中的opcode和funct
ALU control input | function |
---|---|
0000 | and |
0001 | or |
0010 | xor |
0011 | nor |
0110 | add |
1110 | subtract |
1111 | set on less than |
Notice that we are using different encodings than in the book
得到ALU control
ALUOp来自于主控制单元所生成的编码。也就是说,主控制逻辑生成ALUOp,然后ALU控制逻辑根据ALUOp来判断是内存指令、分支指令还是R类型指令。如果是R类型指令,则还需要参照funct域来进行判断。
ALU 控制单元生成ALU control
Instr op | funct | ALUOp | action | ALUcontrol |
---|---|---|---|---|
lw | xxxxxx | 00 | add | 0110 |
sw | xxxxxx | 00 | add | 0110 |
beq | xxxxxx | 01 | subtract | 1110 |
add | 100000 | 10 | add | 0110 |
sub | 100010 | 10 | subtract | 1110 |
and | 100100 | 10 | and | 0000 |
or | 100101 | 10 | or | 0001 |
xor | 100110 | 10 | xor | 0010 |
nor | 100111 | 10 | nor | 0011 |
slt | 101010 | 10 | slt | 1111 |
From the truth table can design the ALU Control logic
设计control unit
Instr | RegDst | ALUSrc | MemReg | RegWr | MemRd | MemWr | Branch | ALUOp |
---|---|---|---|---|---|---|---|---|
R-type 000000 | 1rs作为返回值 | 0rf作为加数 | 0 | 1写回寄存器 | 0 | 0 | 0pc+=4 | 10 |
Setting of the MemRd signal (for R-type, sw, beq) depends on the memory design (could have to be 0 or could be a X (don’t care))
Instr | RegDst | ALUSrc | MemReg | RegWr | MemRd | MemWr | Branch | ALUOp |
---|---|---|---|---|---|---|---|---|
sw 101011 | X | 1 | X | 0 | 0 | 1 | 0 | 00 |
Instr | RegDst | ALUSrc | MemReg | RegWr | MemRd | MemWr | Branch | ALUOp |
---|---|---|---|---|---|---|---|---|
lw100011 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 00 |
Instr | RegDst | ALUSrc | MemReg | RegWr | MemRd | MemWr | Branch | ALUOp |
---|---|---|---|---|---|---|---|---|
beq 000100 | X | 0 | X | 0 | 0 | 0 | 1 | 01 |
现在考虑加入Jump指令
很显然,为了获得新的pc
我们需要将现在的pc的高4位[31,30,29,28]和26位常数offset<<2相加
我们先忽略其他的部分,只考虑jump部分
很显然将inst的[31-28]左移2位是一个新的步骤,(之前只有offset也就是inst[15-0]左移两位作为beq的一个加数)
而为了选择pc+4还是我们现在jump产生的和那肯定要一个额外的多路选择器(之前的branch肯定是0了)
另外要注意的是beq的offset可正可负因为可以上跳或者下跳,而jump的inst[25-0]是直接跳转,所以魔改sign extend是行不通的,shift不能复用了?
这里笔者直接多添置一个shift left 2了
j的操作码是0x2
直接上ppt的图了,因为笔者画得丑
0 评论:
发表评论