注意到所有和pc相关的指令比如jal和branch, label转化为的立即数都是走shift,必须左移
pc+4和pc+imm需要额外两个加法器计算。
中断
csrrw rd, csr, rs1 t <= CSRs[csr], CSRs[csr] <= x[rs1], x[rd] <= t
把rs1的写入csr,把csr的写入rd
csrrs rd, csr, rs1 t <= CSRs[csr], CSRs[csr] <= t | x[rs1], x[rd] <= t
set 把rs1和csr求或以后写入csr,把csr原来的值写入rd
csrrc rd, csr, rs1 t <= CSRs[csr], CSRs[csr] <= t & ~x[rs1], x[rd] <= t
clear 把csr和rs1求反以后求 and写入csr,把csr原来的值写入rd
csrrwi rd, csr, zimm[4:0] x[rd] <= CSRs[csr], CSRs[csr] <= zimm
cssrrsi rd,csr,zimm[4:0] t <= CSRs[csr], CSRs[csr] <= t | zimm; x[rd] <= t
csrrci rd, csr, zimm[4:0] t <= CSRs[csr], CSRs[csr] <= t&~zimm; x[rd] <= t
mret pc <= mepc, Mstatus.pie <= Mstatus.mpie
控制信号:
CauseWrite: mcause
EPCWrite: mepc
TVALWrite: mtval
异常触发条件: illegal instruction, load address misaligned, store address misaligned,只要出现异常就会触发,不关心mstatus.MIE
中断触发条件: mstatus.MIE = 1 && mie[i] = 1 && mip [i]= 1
异常和中断处理:
mepc <= PC( exception) or PC + 4 (interruption) 这个不是硬件做的
mcause <= set correspondent bit 赋值错误代码,是一个常数
mtval <= memory address or illegal instruction 赋值不合法指令或者错误的地址
Mstatus.mpie <= Mstatus.mie; Mstatus.mie <= 0;
PC <= address of process routine ( mtvec, ex. c0000000)
pipline
五级流水:
IF: 取指,修改PC,
ID: 访问寄存器堆,立即数扩展,
EX: 访问ALU
MEM: 访问内存
WB: 写回寄存器
What should be saved in the Latches of the pipeline.
数据传递
流水级 | 传递数据 |
---|---|
IF->ID | pc, inst |
ID->EX | rs1_val, rs2_val, rd, imm, fun3, fun7, WB, M, EX控制信号 |
EX->MEM | alu_res, pc+imm, WB, M控制信号, rs2_val, rd |
MEM->WB | rd, WB控制信号,rd, Mem_data, alu_res |
流水级 | 控制信号 | 含义 |
---|---|---|
WB | RegWrite | 寄存器写信号, |
WB | MemtoReg | 寄存器写回是alu还是mem_data |
M | MemRead | 这个不管了, |
M | MemWrite | Mem写信号 |
EX | ALUsrc | rs2选择信号 |
EX | ALUop | alu二级译码信号 |
冒险:
间隔两条以上的指令没有数据依赖
数据依赖只有四种:
XR: ID->EX的rs 和 EX->Mem的rd相同
XXR: ID->EX的rs 和Mem->WB的rd相同
XL:ID->EX的rs 和 EX->MEM的rd相同
XXL: ID->EX的rs 和MEM->WB的rd相同
解决方法:数据修改全部在EX级完成
XR用EX/MEM的数据替换
XXL, XXR用MEM/WB的数据替换
XL无法通过前递解决,需要在ID级插入气泡。XL在ID级检查出来,此时下一条指令在EX级
之后在ID级插入气泡,冲突变成了XXL,通过XXL的前递解决。
Could you draw the pipeline status graph running a program ?
IM->Reg->ALU->DM->Reg
如果寄存器被读,则后半部分画黑。如果寄存器被写,则前半部分画黑,ALU永远是黑色的。
寄存器的前部分永远是黑色的。
Without hazard detection, how to make it run correct using compiler
编译器插入nop指令
With detection, draw pipeline status graph
该条指令如果在ID级检查出来,则从EX级之后变成气泡
下一条指令还是从IM开始取该条指令。
With forwarding path, draw pipeline status graph
有两条前递路径:
1.EX->MEM的寄存器值替换EX级ALU的某个寄存器值
2.MEM->WB的寄存器值替换EX级ALU的某个寄存器值
ALU从EX->MEM前递和MEM->WB前递和正常传递值之间选择一个。
How to detect the data hazard ? How to stall ?
如果IF/ID级rs1和rs2与ID/EX级rd相同,而且MemWrite为1,需要stall,其他情况不stall
stall方式:PCWrite置0,IF/DWrite置0,ID/EX控制信号WB, M, EX全部置0
Hazard => stall => forwarding to improve performance =>still load stall => compiler scheduling