【P7&Loongson】支持部分中断/异常处理

概况

常规单发射5级流水线cpu。新增支持指令{mtc0, mfc0, eret, syscall, break, bgezal, bltzal};新增异常处理{Int, AdEL, AdES, Ov, RI},其中Int中断包括软件、硬件、计时器中断(硬件中断未测);新增CP0寄存器{BadVAddr, Count, Compare, Status, Cause, EPC, PrID}。通过Loongson.SRAM功能测试。

(新增设计均为能暂停便暂停,无cache、tlb)
image

Thinking_Log

1.为何将 取指/访存 地址错误一并归到AdEL异常中?

如此写BadVAddr寄存器的操作又复杂了些

2.为何不约定eret存在延迟槽?

如此eret的相关硬件处理又复杂了些

Bug_Log

1.检测到异常后,未能完全将受害指令之后的指令影响消除

受害指令前后指令“假冲突”产生的阻塞

Stall与Req同时存在时,忽略了增添Req对F_pc写使能的影响,导致Stall单方面使F_pc不可写,F_pc未更新,异常跳转NPC失效。

例: 某时刻 D-E-M : mfhi-syscall-divu;下一周期stall和req同时存在
image
下方红圈处F_pc值未更新

解决: 顶层Req信号优先级最高,修正IFU的写使能We

错误开始的乘除槽

例: 某时刻 D-E-M : bnez-divu-syscall;req存在,div进入乘除槽HILO开始运算

解决: M级必定能检测出是否发生异常,只有在E级的乘除槽脱离管控;所以异常发生时,受害指令后的指令最多刚刚到乘除槽,所以只需要用Req信号限制乘除槽的运作即可

always @(posedge Clk) begin
	if(Rst == 1) begin
		HI <= 0;
		LO <= 0;
		Wait <= 0;
		Busy <= 0;
	end else if(Req != 1) begin	//Req limitation
		if(Wait == 0) begin
			case(HILOOp)
			...
	end

2.放走W级指令不意味着W级不需要Req清空

事实上,放走W级指令是只GRF处可以仍写。5级流水各级含义时间长了容易混淆;寄存器是组合信号的源头;顶层信号的来历要清楚(全是组合逻辑,有些搭配了fsm)

3.端口/信号的隐藏意义改变

最初的DMWr是区分Store和Load类指令的必要条件,因而最初设计用DMWr区分AdES和AdEL。
但后续设计令Req==1时强制将传入BE.DMWr端口的信号改0,导致BE.DMWr无法区分L/S指令,但自己仍认为DMWr信号具有相关功能,所以错判异常。
image
BE.DMWr非最初的CU.DMWr,而是CU.DMWr & ~Req

随着不断增加设计,传入信号的意义可能和最初端口命名的意义有所脱节,从而导致错误。要时刻熟悉设计的部件,同时端口/信号命名仍需完善!

类似问题:顶层寄存器控制信号Stall传入各流水级时,使用了端口名Reg_Rst,导致各级内Reg_Rst端口信号含义不清,需改进!

4.eret指令不存在延迟槽

看了测试程序给的异常处理程序断eret后跟了nop,想当然当作延迟槽了。
结果之后有一段程序,利用eret返回错误epc导致AdEL异常,同时eret后紧跟sw,提前修改了data_sram导致错误。

解决:将错就错,对eret增加清空延迟槽操作。

5.顶层寄存器控制信号冲突的担忧

需弄清各信号产生的逻辑和关联:①产生逻辑;②信号优先级

  • Stall
  • Req
  • linger
  • LoadDelay
  • Clr

6.由于读BRAM IP核在下一拍返回值,因而将D_instr改为的组合逻辑,不在寄存器中

D级指令的一些操作时,要记得这点

7.寄存器信号的可读写性

CP0各寄存器各个位的可读写性不尽相同。

重申了本质问题:寄存器的读/写/复位

posted @ 2022-02-11 01:53  Elucidator_xrb  阅读(97)  评论(0编辑  收藏  举报