handle CpU exception
This commit is contained in:
parent
7241f83407
commit
8d039f4327
@ -31,8 +31,8 @@ Our awesome `MIPS` CPU written in `SystemVerilog` for Loongson Cup
|
|||||||
|
|
||||||
- [ ] 特权模式
|
- [ ] 特权模式
|
||||||
- [x] `CP0`寄存器`Status.UM` :heavy_check_mark:
|
- [x] `CP0`寄存器`Status.UM` :heavy_check_mark:
|
||||||
- [ ] 访存异常(考虑`in_kernel`状态切换带来的冒险) :hourglass:
|
- [x] 访存异常(考虑`in_kernel`状态切换带来的冒险) :heavy_check_mark:
|
||||||
- [ ] 特权指令异常 :clock3:
|
- [ ] 特权指令异常 :hourglass:
|
||||||
- [ ] 浮点运算单元
|
- [ ] 浮点运算单元
|
||||||
- [ ] ~~做一个真的`FPU`~~ :x:
|
- [ ] ~~做一个真的`FPU`~~ :x:
|
||||||
- [ ] 浮点运算指令报`Coprocessor Unusable`,同时`CP0`中新增`Cause.CE` :clock3:
|
- [ ] 浮点运算指令报`Coprocessor Unusable`,同时`CP0`中新增`Cause.CE` :clock3:
|
||||||
|
@ -34,6 +34,7 @@ module Controller (
|
|||||||
assign ctrl.J = ~inst[31] & ~inst[29] & ~inst[28] & inst[27];
|
assign ctrl.J = ~inst[31] & ~inst[29] & ~inst[28] & inst[27];
|
||||||
assign ctrl.BGO = ~inst[26] & (eq | inst[27] & ltz) | inst[26] & (~inst[27] & (~inst[28] & (inst[16] & ~ltz | ~inst[16] & ltz) | inst[28] & ~eq) | inst[27] & ~eq & ~ltz);
|
assign ctrl.BGO = ~inst[26] & (eq | inst[27] & ltz) | inst[26] & (~inst[27] & (~inst[28] & (inst[16] & ~ltz | ~inst[16] & ltz) | inst[28] & ~eq) | inst[27] & ~eq & ~ltz);
|
||||||
|
|
||||||
|
assign ctrl.PRV = inst[30] & ~inst[29];
|
||||||
assign ctrl.SYSCALL = ~inst[31] & ~inst[30] & ~inst[29] & ~inst[28] & ~inst[27] & ~inst[26] & inst[3] & inst[2] & ~inst[0];
|
assign ctrl.SYSCALL = ~inst[31] & ~inst[30] & ~inst[29] & ~inst[28] & ~inst[27] & ~inst[26] & inst[3] & inst[2] & ~inst[0];
|
||||||
assign ctrl.BREAK = ~inst[31] & ~inst[30] & ~inst[29] & ~inst[28] & ~inst[27] & ~inst[26] & inst[3] & inst[2] & inst[0];
|
assign ctrl.BREAK = ~inst[31] & ~inst[30] & ~inst[29] & ~inst[28] & ~inst[27] & ~inst[26] & inst[3] & inst[2] & inst[0];
|
||||||
assign ctrl.ERET = inst[30] & inst[4];
|
assign ctrl.ERET = inst[30] & inst[4];
|
||||||
|
@ -33,6 +33,7 @@ module Datapath (
|
|||||||
input word_t C0_ERETPC,
|
input word_t C0_ERETPC,
|
||||||
input logic C0_Bev,
|
input logic C0_Bev,
|
||||||
input logic [19:0] C0_EBase,
|
input logic [19:0] C0_EBase,
|
||||||
|
input logic C0_kernel,
|
||||||
|
|
||||||
//debug interface
|
//debug interface
|
||||||
output wire [31:0] debug_wb_pc,
|
output wire [31:0] debug_wb_pc,
|
||||||
@ -437,17 +438,29 @@ module Datapath (
|
|||||||
);
|
);
|
||||||
|
|
||||||
// TODO: Merge "pc[1:0] != 2'b00" into AddressError
|
// TODO: Merge "pc[1:0] != 2'b00" into AddressError
|
||||||
assign D.IA_ExcValid = D_IA_valid & (D.IA_pc[1:0] != 2'b00 | D_IA_TLBRefill | D_IA_TLBInvalid | D_IA_AddressError | ~D_IA_iv | D.IA.SYSCALL | D.IA.BREAK | D.IA.ERET);
|
assign D.IA_ExcValid = D_IA_valid & ( D.IA_pc[1:0] != 2'b00
|
||||||
|
| ~D_IA_iv
|
||||||
|
| D_IA_TLBRefill | D_IA_TLBInvalid
|
||||||
|
| D_IA_AddressError
|
||||||
|
| D.IA.SYSCALL | D.IA.BREAK | D.IA.ERET
|
||||||
|
| D.IA.PRV & ~C0_kernel);
|
||||||
assign D.IA_ERET = D_IA_valid & D.IA_pc[1:0] == 2'b00 & ~D_IA_TLBRefill & ~D_IA_TLBInvalid & ~D_IA_AddressError & D_IA_iv & D.IA.ERET;
|
assign D.IA_ERET = D_IA_valid & D.IA_pc[1:0] == 2'b00 & ~D_IA_TLBRefill & ~D_IA_TLBInvalid & ~D_IA_AddressError & D_IA_iv & D.IA.ERET;
|
||||||
assign D.IA_REFILL = D_IA_valid & D.IB_pc[1:0] == 2'b00 & D_IA_TLBRefill;
|
assign D.IA_REFILL = D_IA_valid & D.IB_pc[1:0] == 2'b00 & D_IA_TLBRefill;
|
||||||
assign D.IA_ExcCode = D.IA_pc[1:0] != 2'b00 | D_IA_AddressError ? `EXCCODE_ADEL
|
assign D.IA_ExcCode = D.IA_pc[1:0] != 2'b00 | D_IA_AddressError ? `EXCCODE_ADEL
|
||||||
: D_IA_TLBRefill ? `EXCCODE_TLBL
|
: D_IA_TLBRefill ? `EXCCODE_TLBL
|
||||||
: D_IA_TLBInvalid ? `EXCCODE_TLBL
|
: D_IA_TLBInvalid ? `EXCCODE_TLBL
|
||||||
: ~D_IA_iv ? `EXCCODE_RI
|
: ~D_IA_iv ? `EXCCODE_RI
|
||||||
: D.IA_inst[0] ? `EXCCODE_BP
|
: ~D.IA_inst[30] & D.IA_inst[0] ? `EXCCODE_BP
|
||||||
: `EXCCODE_SYS;
|
: ~D.IA_inst[30] & ~D.IA_inst[0] ? `EXCCODE_SYS
|
||||||
|
: `EXCCODE_CPU;
|
||||||
|
|
||||||
assign D.IB_ExcValid = D_IB_valid & (D.IB_pc[1:0] != 2'b00 | D_IB_TLBRefill | D_IB_TLBInvalid | D_IB_AddressError | ~D_IB_iv | D.IB.SYSCALL | D.IB.BREAK | D.IB.ERET | D.IB_Delay & D.IB.BJRJ);
|
assign D.IB_ExcValid = D_IB_valid & ( D.IB_pc[1:0] != 2'b00
|
||||||
|
| ~D_IB_iv
|
||||||
|
| D_IB_TLBRefill | D_IB_TLBInvalid
|
||||||
|
| D_IB_AddressError
|
||||||
|
| D.IB.SYSCALL | D.IB.BREAK | D.IB.ERET
|
||||||
|
| D.IB_Delay & D.IB.BJRJ
|
||||||
|
| D.IB.PRV & ~C0_kernel);
|
||||||
assign D.IB_ERET = D_IB_valid & D.IB_pc[1:0] == 2'b00 & ~D_IB_TLBRefill & ~D_IB_TLBInvalid & ~D_IB_AddressError & D_IB_iv & D.IB.ERET & ~D.IB_Delay;
|
assign D.IB_ERET = D_IB_valid & D.IB_pc[1:0] == 2'b00 & ~D_IB_TLBRefill & ~D_IB_TLBInvalid & ~D_IB_AddressError & D_IB_iv & D.IB.ERET & ~D.IB_Delay;
|
||||||
assign D.IB_REFILL = D_IB_valid & D.IB_pc[1:0] == 2'b00 & D_IB_TLBRefill;
|
assign D.IB_REFILL = D_IB_valid & D.IB_pc[1:0] == 2'b00 & D_IB_TLBRefill;
|
||||||
assign D.IB_ExcCode = D.IB_pc[1:0] != 2'b00 | D_IB_AddressError ? `EXCCODE_ADEL
|
assign D.IB_ExcCode = D.IB_pc[1:0] != 2'b00 | D_IB_AddressError ? `EXCCODE_ADEL
|
||||||
@ -456,8 +469,9 @@ module Datapath (
|
|||||||
: ~D_IB_iv ? `EXCCODE_RI
|
: ~D_IB_iv ? `EXCCODE_RI
|
||||||
: D.IB.ERET ? `EXCCODE_RI
|
: D.IB.ERET ? `EXCCODE_RI
|
||||||
: D.IB_Delay & D.IB.BJRJ ? `EXCCODE_RI
|
: D.IB_Delay & D.IB.BJRJ ? `EXCCODE_RI
|
||||||
: D.IB_inst[0] ? `EXCCODE_BP
|
: ~D.IB_inst[30] & D.IB_inst[0] ? `EXCCODE_BP
|
||||||
: `EXCCODE_SYS;
|
: ~D.IB_inst[30] & ~D.IB_inst[0] ? `EXCCODE_SYS
|
||||||
|
: `EXCCODE_CPU;
|
||||||
assign D.IB_Delay = D.IA.BJRJ;
|
assign D.IB_Delay = D.IA.BJRJ;
|
||||||
|
|
||||||
// D.Dispatch
|
// D.Dispatch
|
||||||
|
@ -235,6 +235,7 @@ module mycpu_top (
|
|||||||
.C0_ERETPC (C0_ERETPC),
|
.C0_ERETPC (C0_ERETPC),
|
||||||
.C0_Bev (C0_Bev),
|
.C0_Bev (C0_Bev),
|
||||||
.C0_EBase (C0_EBase),
|
.C0_EBase (C0_EBase),
|
||||||
|
.C0_kernel (in_kernel),
|
||||||
|
|
||||||
.debug_wb_pc (debug_wb_pc),
|
.debug_wb_pc (debug_wb_pc),
|
||||||
.debug_wb_rf_wen (debug_wb_rf_wen),
|
.debug_wb_rf_wen (debug_wb_rf_wen),
|
||||||
|
@ -24,7 +24,9 @@
|
|||||||
`define EXCCODE_SYS 5'h08
|
`define EXCCODE_SYS 5'h08
|
||||||
`define EXCCODE_BP 5'h09
|
`define EXCCODE_BP 5'h09
|
||||||
`define EXCCODE_RI 5'h0A
|
`define EXCCODE_RI 5'h0A
|
||||||
|
`define EXCCODE_CPU 5'h0B
|
||||||
`define EXCCODE_OV 5'h0C
|
`define EXCCODE_OV 5'h0C
|
||||||
|
`define EXCCODE_TR 5'h0D
|
||||||
|
|
||||||
typedef logic [31:0] word_t;
|
typedef logic [31:0] word_t;
|
||||||
|
|
||||||
@ -101,6 +103,8 @@ typedef struct packed {
|
|||||||
} WCtrl_t;
|
} WCtrl_t;
|
||||||
|
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
|
logic PRV;
|
||||||
|
|
||||||
logic SYSCALL;
|
logic SYSCALL;
|
||||||
logic BREAK;
|
logic BREAK;
|
||||||
logic ERET;
|
logic ERET;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
with open('mctrl1.txt') as f:
|
with open('exc.txt') as f:
|
||||||
lines = f.readlines()
|
lines = f.readlines()
|
||||||
title = lines[0].split()
|
title = lines[0].split()
|
||||||
items = [x.split() for x in lines[1:]]
|
items = [x.split() for x in lines[1:]]
|
||||||
|
@ -127,6 +127,7 @@ for inst, name in table:
|
|||||||
ctrl['MCtrl1_MX'] = ~inst[28]
|
ctrl['MCtrl1_MX'] = ~inst[28]
|
||||||
ctrl['MCtrl1_TLBR'] = inst[30] & ~inst[29] & inst[25] & ~inst[3] & ~inst[1]
|
ctrl['MCtrl1_TLBR'] = inst[30] & ~inst[29] & inst[25] & ~inst[3] & ~inst[1]
|
||||||
ctrl['MCtrl1_TLBWI'] = inst[30] & ~inst[29] & inst[25] & ~inst[3] & inst[1]
|
ctrl['MCtrl1_TLBWI'] = inst[30] & ~inst[29] & inst[25] & ~inst[3] & inst[1]
|
||||||
|
ctrl['MCtrl1_TLBWR'] = inst[30] & ~inst[29] & inst[25] & ~inst[3] & (inst[2] | ~inst[1])
|
||||||
ctrl['MCtrl1_TLBP'] = inst[30] & ~inst[4] & inst[3]
|
ctrl['MCtrl1_TLBP'] = inst[30] & ~inst[4] & inst[3]
|
||||||
|
|
||||||
ctrl['WCtrl_RW'] = (~inst[30] & (~inst[29] & (inst[31] | ~inst[28] & (~inst[27] & (~inst[26] & (~inst[3] & (~inst[4] | ~inst[0]) | inst[3] & (inst[5] | ~inst[4] & ~inst[2] & inst[0])) | inst[26] & inst[20]) | inst[27] & inst[26])) | inst[29] & ~inst[31]) | inst[30] & ~inst[25] & ~inst[23])
|
ctrl['WCtrl_RW'] = (~inst[30] & (~inst[29] & (inst[31] | ~inst[28] & (~inst[27] & (~inst[26] & (~inst[3] & (~inst[4] | ~inst[0]) | inst[3] & (inst[5] | ~inst[4] & ~inst[2] & inst[0])) | inst[26] & inst[20]) | inst[27] & inst[26])) | inst[29] & ~inst[31]) | inst[30] & ~inst[25] & ~inst[23])
|
||||||
|
10
tools/exc.txt
Normal file
10
tools/exc.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
////-------------------------------- BREAK SYSCALL
|
||||||
|
32'b000000????????????????????001100 0 1 // SYSCALL
|
||||||
|
32'b000000????????????????????001101 1 0 // BREAK
|
||||||
|
32'b01000010000000000000000000011000 0 0 // ERET
|
||||||
|
32'b01000000000??????????00000000??? 0 0 // MFC0
|
||||||
|
32'b01000000100??????????00000000??? 0 0 // MTC0
|
||||||
|
32'b01000010000000000000000000000001 0 0 // TLBR
|
||||||
|
32'b01000010000000000000000000000010 0 0 // TLBWI
|
||||||
|
32'b01000010000000000000000000000110 0 0 // TLBWR
|
||||||
|
32'b01000010000000000000000000001000 0 0 // TLBP
|
63
tools/privilege.txt
Normal file
63
tools/privilege.txt
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
////-------------------------------- PRV
|
||||||
|
32'b00000000000???????????????000000 0 // SLL
|
||||||
|
32'b00000000000???????????????000010 0 // SRL
|
||||||
|
32'b00000000000???????????????000011 0 // SRA
|
||||||
|
32'b000000???????????????00000000100 0 // SLLV
|
||||||
|
32'b000000???????????????00000000110 0 // SRLV
|
||||||
|
32'b000000???????????????00000000111 0 // SRAV
|
||||||
|
32'b000000?????000000000000000001000 0 // JR
|
||||||
|
32'b000000?????00000?????00000001001 0 // JALR
|
||||||
|
32'b000000????????????????????001100 0 // SYSCALL
|
||||||
|
32'b000000????????????????????001101 0 // BREAK
|
||||||
|
32'b0000000000000000?????00000010000 0 // MFHI
|
||||||
|
32'b000000?????000000000000000010001 0 // MTHI
|
||||||
|
32'b0000000000000000?????00000010010 0 // MFLO
|
||||||
|
32'b000000?????000000000000000010011 0 // MTLO
|
||||||
|
32'b000000??????????0000000000011000 0 // MULT
|
||||||
|
32'b000000??????????0000000000011001 0 // MULTU
|
||||||
|
32'b000000??????????0000000000011010 0 // DIV
|
||||||
|
32'b000000??????????0000000000011011 0 // DIVU
|
||||||
|
32'b000000???????????????00000100000 0 // ADD
|
||||||
|
32'b000000???????????????00000100001 0 // ADDU
|
||||||
|
32'b000000???????????????00000100010 0 // SUB
|
||||||
|
32'b000000???????????????00000100011 0 // SUBU
|
||||||
|
32'b000000???????????????00000100100 0 // AND
|
||||||
|
32'b000000???????????????00000100101 0 // OR
|
||||||
|
32'b000000???????????????00000100110 0 // XOR
|
||||||
|
32'b000000???????????????00000100111 0 // NOR
|
||||||
|
32'b000000???????????????00000101010 0 // SLT
|
||||||
|
32'b000000???????????????00000101011 0 // SLTU
|
||||||
|
32'b000001?????00000???????????????? 0 // BLTZ
|
||||||
|
32'b000001?????10000???????????????? 0 // BLTZAL
|
||||||
|
32'b000001?????00001???????????????? 0 // BGEZ
|
||||||
|
32'b000001?????10001???????????????? 0 // BGEZAL
|
||||||
|
32'b000010?????????????????????????? 0 // J
|
||||||
|
32'b000011?????????????????????????? 0 // JAL
|
||||||
|
32'b000100?????????????????????????? 0 // BEQ
|
||||||
|
32'b000101?????????????????????????? 0 // BNE
|
||||||
|
32'b000110?????00000???????????????? 0 // BLEZ
|
||||||
|
32'b000111?????00000???????????????? 0 // BGTZ
|
||||||
|
32'b001000?????????????????????????? 0 // ADDI
|
||||||
|
32'b001001?????????????????????????? 0 // ADDIU
|
||||||
|
32'b001010?????????????????????????? 0 // SLTI
|
||||||
|
32'b001011?????????????????????????? 0 // SLTIU
|
||||||
|
32'b001100?????????????????????????? 0 // ANDI
|
||||||
|
32'b001101?????????????????????????? 0 // ORI
|
||||||
|
32'b001110?????????????????????????? 0 // XORI
|
||||||
|
32'b00111100000????????????????????? 0 // LUI
|
||||||
|
32'b01000000000??????????00000000??? 1 // MFC0
|
||||||
|
32'b01000000100??????????00000000??? 1 // MTC0
|
||||||
|
32'b01000010000000000000000000000001 1 // TLBR
|
||||||
|
32'b01000010000000000000000000000010 1 // TLBWI
|
||||||
|
32'b01000010000000000000000000000110 1 // TLBWR
|
||||||
|
32'b01000010000000000000000000001000 1 // TLBP
|
||||||
|
32'b01000010000000000000000000011000 1 // ERET
|
||||||
|
32'b011100???????????????00000000010 0 // MUL
|
||||||
|
32'b100000?????????????????????????? 0 // LB
|
||||||
|
32'b100001?????????????????????????? 0 // LH
|
||||||
|
32'b100011?????????????????????????? 0 // LW
|
||||||
|
32'b100100?????????????????????????? 0 // LBU
|
||||||
|
32'b100101?????????????????????????? 0 // LHU
|
||||||
|
32'b101000?????????????????????????? 0 // SB
|
||||||
|
32'b101001?????????????????????????? 0 // SH
|
||||||
|
32'b101011?????????????????????????? 0 // SW
|
Loading…
Reference in New Issue
Block a user