diff --git a/src/CP0/CP0.sv b/src/CP0/CP0.sv index 7ce3a80..2c2c758 100644 --- a/src/CP0/CP0.sv +++ b/src/CP0/CP0.sv @@ -26,22 +26,6 @@ module CP0 ( rf_cp0 = {504'b0, 8'b10000010, 105'b0, 1'b1, 406'b0}; count_lo = 0; end else if (clk) begin - if (exception.ERET) rf_cp0.Status.EXL = 1'b0; - else begin - if (exception.ExcValid && rf_cp0.Status.EXL == 1'b0) begin - rf_cp0.Cause.ExcCode = exception.ExcCode; - if (exception.ExcCode == 4 || exception.ExcCode == 5) - rf_cp0.BadVAddr = exception.BadVAddr; - rf_cp0.Status.EXL = 1'b1; - if (~rf_cp0.Status.EXL) begin - rf_cp0.EPC = exception.EPC; - if (exception.delay) begin - rf_cp0.Cause.BD = 1'b1; - rf_cp0.EPC = rf_cp0.EPC - 4; - end else rf_cp0.Cause.BD = 1'b0; - end - end - end // count count_lo = count_lo + 1; if (count_lo == 1) rf_cp0.Count = rf_cp0.Count + 1; @@ -86,6 +70,19 @@ module CP0 ( default: begin end endcase + + if (exception.ERET) rf_cp0.Status.EXL = 1'b0; + else begin + if (exception.ExcValid && rf_cp0.Status.EXL == 1'b0) begin + rf_cp0.Cause.ExcCode = exception.ExcCode; + if (exception.ExcCode == 4 || exception.ExcCode == 5) + rf_cp0.BadVAddr = exception.BadVAddr; + rf_cp0.EPC = exception.EPC; + if (exception.delay) rf_cp0.EPC = rf_cp0.EPC - 4; + rf_cp0.Cause.BD = exception.delay; + rf_cp0.Status.EXL = 1'b1; + end + end end always_comb case (addr) diff --git a/src/Core/Controller.sv b/src/Core/Controller.sv index c792c24..3763aba 100644 --- a/src/Core/Controller.sv +++ b/src/Core/Controller.sv @@ -12,7 +12,7 @@ module Controller ( inst[15:11], 5'b11111, ctrl.RT, - {inst[31] | inst[29], inst[26]}, + {inst[31] | inst[30] & ~inst[26] | inst[29], inst[26]}, ctrl.RD ); diff --git a/src/Core/Datapath.sv b/src/Core/Datapath.sv index b6a48e0..a911e4a 100644 --- a/src/Core/Datapath.sv +++ b/src/Core/Datapath.sv @@ -46,7 +46,6 @@ module Datapath ( // Pre Fetch logic PF_go; - logic PF_req; word_t PF_pcp8; word_t PF_pcb; @@ -159,6 +158,8 @@ module Datapath ( // Memory logic M_go; + EXCEPTION_t M_exception; + logic [ 7:0] M_I1_Byte; logic [15:0] M_I1_Half; word_t M_I1_ByteX; @@ -178,6 +179,9 @@ module Datapath ( logic M_I0_FT_W_I1; word_t M_I0_ForwardT; + logic M_I1_RData_OK; + word_t M_I1_RData; + word_t HI; word_t LO; @@ -203,22 +207,22 @@ module Datapath ( `PCEXC, C0_EPC, `PCRST, - {~F_valid, C0_exception.ExcValid, ~D_IA_valid}, + {~F_valid, M_exception.ERET, M_exception.ExcValid, ~D_IA_valid}, PF.pc ); assign rstD = D.IA.PFCtrl.PCS != PCP8 & D_IA_can_dispatch; assign rstM = C0_exception.ExcValid; - assign PF_req = ~D.IA_ExcValid & ~D.IB_ExcValid & ~E.I0.ExcValid & ~E.I1.ExcValid; - assign PF_go = PF.pc[1:0] == 2'b00 & PF_req; - assign fetch_i.req = rst | C0_exception.ERET | C0_exception.ExcValid | ~D_IA_valid + assign PF_go = ~D.IA_ExcValid & ~D.IB_ExcValid & ~E.I0.ExcValid & ~E.I1.ExcValid & PF.pc[1:0] == 2'b00; + assign fetch_i.req = rst | M_exception.ExcValid | ~D_IA_valid | PF_go & (~D.IA.PFCtrl.BJRJ | D_IA_can_dispatch) - & ( ~IQ_valids[3] - | ~IQ_valids[2] & (PF.pc[2] | F.pc[2] | D_readygo | D_readygo1) - | ~IQ_valids[1] & (PF.pc[2] & (F.pc[2] | D_readygo | D_readygo1) | F.pc[2] & (D_readygo | D_readygo1) | D_readygo & D_readygo1) - | ~IQ_valids[0] & (PF.pc[2] & (F.pc[2] & (D_readygo | D_readygo1) | D_readygo & D_readygo1) | F.pc[2] & D_readygo & D_readygo1) - | IQ_valids[0] & PF.pc[2] & F.pc[2] & D_readygo & D_readygo1); + & (rstD + | ( ~IQ_valids[3] + | ~IQ_valids[2] & (PF.pc[2] | F.pc[2] | D_readygo | D_readygo1) + | ~IQ_valids[1] & (PF.pc[2] & (F.pc[2] | D_readygo | D_readygo1) | F.pc[2] & (D_readygo | D_readygo1) | D_readygo & D_readygo1) + | ~IQ_valids[0] & (PF.pc[2] & (F.pc[2] & (D_readygo | D_readygo1) | D_readygo & D_readygo1) | F.pc[2] & D_readygo & D_readygo1) + | IQ_valids[0] & PF.pc[2] & F.pc[2] & D_readygo & D_readygo1)); assign fetch_i.addr = {PF.pc[31:3], 3'b000}; //---------------------------------------------------------------------------// @@ -241,7 +245,7 @@ module Datapath ( F.pc ); - assign F.en = fetch_i.req & fetch_i.addr_ok; + assign F.en = PF.pc[1:0] != 2'b00 & D_IA_can_dispatch | fetch_i.req & fetch_i.addr_ok; //---------------------------------------------------------------------------// // Instr Queue // @@ -299,8 +303,8 @@ module Datapath ( .raddr2(D.IA.RT), .raddr3(D.IB.RS), .raddr4(D.IB.RT), - .we1(W.I0.WCtrl.RW), - .we2(W.I1.WCtrl.RW), + .we1(W.I0.WCtrl.RW & (W.I0.RD != W.I1.RD | W.A)), + .we2(W.I1.WCtrl.RW & (W.I0.RD != W.I1.RD | ~W.A)), .waddr1(W.I0.RD), .waddr2(W.I1.RD), .wdata1(W.I0.RDataW), @@ -360,12 +364,12 @@ module Datapath ( ); assign D.IA_ExcValid = D_IA_valid & (D.IA_pc[1:0] != 2'b00 | ~D_IA_iv | D.IA.SYSCALL | D.IA.BREAK | D.IA.ERET); - assign D.IA_ERET = D_IA_valid & D.IA.ERET; + assign D.IA_ERET = D_IA_valid & D_IA_iv & D.IA.ERET; assign D.IA_ExcCode = D.IA_pc[1:0] != 2'b00 ? `EXCCODE_ADDRR : ~D_IA_iv ? `EXCCODE_RI : D.IA.SYSCALL ? `EXCCODE_SYSCALL : `EXCCODE_BREAK; assign D.IA_Delay = 1'b0; assign D.IB_ExcValid = D_IB_valid & (D.IB_pc[1:0] != 2'b00 | ~D_IB_iv | D.IB.SYSCALL | D.IB.BREAK | D.IB.ERET | D.IB_Delay & D.IB.PFCtrl.BJRJ); - assign D.IB_ERET = D_IB_valid & D.IB.ERET & ~D.IB_Delay; + assign D.IB_ERET = D_IB_valid & D_IB_iv & D.IB.ERET & ~D.IB_Delay; assign D.IB_ExcCode = D.IB_pc[1:0] != 2'b00 ? `EXCCODE_ADDRR : ~D_IB_iv ? `EXCCODE_RI : D.IB.SYSCALL ? `EXCCODE_SYSCALL : D.IB.BREAK ? `EXCCODE_BREAK : `EXCCODE_RI; assign D.IB_Delay = D.IA.PFCtrl.BJRJ; @@ -416,7 +420,7 @@ module Datapath ( assign D.en0 = ~D_IA_valid | ~D_IB_valid | D_go & E.en; assign D.en1 = ~D_IA_valid | (~D_IB_valid | D_IB_can_dispatch) & D_go & E.en; - assign D_go = (~PF_req | D.IA.PFCtrl.PCS == PCP8 | fetch_i.req & fetch_i.addr_ok) & D_IA_can_dispatch | D.IA_ExcValid; + assign D_go = (~PF_go | D.IA.PFCtrl.PCS == PCP8 | fetch_i.req & fetch_i.addr_ok) & D_IA_can_dispatch | D.IA_ExcValid; assign D_IA_go = D_IA_valid & ~D.IA_ExcValid; assign D_IB_go = D_IB_valid & ~D.IB_ExcValid & D_IB_can_dispatch & ~D.IA_ExcValid; @@ -530,11 +534,17 @@ module Datapath ( ~D_go, {E_I0_PrevExcValid, E.I0.ERET, E_I0_PrevExcCode, E.I0.Delay, E.I0.OFA} ); - ffen #(5 + 5 + 32 + 32) E_I0_ST_ff ( + ffen #(5 + 5) E_I0_RST_ff ( clk, - {D.I0.RS, D.I0.RT, D.I0.S, D.I0.T}, + {D.I0.RS, D.I0.RT}, E.en, - {E.I0.RS, E.I0.RT, E.I0.S, E.I0.T} + {E.I0.RS, E.I0.RT} + ); + ffen #(32 + 32) E_I0_ST_ff ( + clk, + E.en ? {D.I0.S, D.I0.T} : {E_I0_ForwardS, E_I0_ForwardT}, + 1'b1, + {E.I0.S, E.I0.T} ); ffen #(32 + 5) E_I0_IS_ff ( clk, @@ -581,11 +591,17 @@ module Datapath ( ~D_go, {E_I1_PrevExcValid, E.I1.ERET, E_I1_PrevExcCode, E.I1.Delay, E.I1.OFA} ); - ffen #(5 + 5 + 32 + 32) E_I1_ST_ff ( + ffen #(5 + 5) E_I1_RST_ff ( clk, - {D.I1.RS, D.I1.RT, D.I1.S, D.I1.T}, + {D.I1.RS, D.I1.RT}, E.en, - {E.I1.RS, E.I1.RT, E.I1.S, E.I1.T} + {E.I1.RS, E.I1.RT} + ); + ffen #(32 + 32) E_I1_ST_ff ( + clk, + E.en ? {D.I1.S, D.I1.T} : {E_I1_ForwardS, E_I1_ForwardT}, + 1'b1, + {E.I1.S, E.I1.T} ); ffen #(32 + 5) E_I1_IS_ff ( clk, @@ -778,11 +794,17 @@ module Datapath ( ~E_go, {M.I0.ExcValid, M.I0.ERET, M.I0.ExcCode, M.I0.Delay} ); - ffen #(5 + 5 + 32 + 32) M_I0_ST_ff ( + ffen #(5 + 5) M_I0_RST_ff ( clk, - {E.I0.RS, E.I0.RT, E_I0_ForwardS, E_I0_ForwardT}, + {E.I0.RS, E.I0.RT}, M.en, - {M.I0.RS, M.I0.RT, M.I0.S, M.I0.T} + {M.I0.RS, M.I0.RT} + ); + ffen #(32 + 32) M_I0_ST_ff ( + clk, + M.en ? {E_I0_ForwardS, E_I0_ForwardT} : {M_I0_ForwardS, M_I0_ForwardT}, + 1'b1, + {M.I0.S, M.I0.T} ); ffen #(32 * 9) M_I0_ALUOut_ff ( clk, @@ -840,12 +862,6 @@ module Datapath ( ~E_go, {M.I1.ExcValid, M.I1.ERET, M.I1.ExcCode, M.I1.BadVAddr, M.I1.Delay} ); - ffen #(5 + 32) M_I1_T_ff ( - clk, - {E.I1.RT, E_I1_ForwardT}, - M.en, - {M.I1.RT, M.I1.T} - ); ffen #(32) M_I1_ALUOut_ff ( clk, E.I1.ALUOut, @@ -871,11 +887,19 @@ module Datapath ( // M.Exc assign M.I0.BadVAddr = M.I0.pc; - assign C0_exception = M.I1.ExcValid & M.A ? { + assign M_exception = ~M.I0.ExcValid | M.I1.ExcValid & M.A ? { M.I1.ExcValid, M.I1.Delay, M.I1.ExcCode, M.I1.BadVAddr, M.I1.pc, M.I1.ERET } : { M.I0.ExcValid, M.I0.Delay, M.I0.ExcCode, M.I0.BadVAddr, M.I0.pc, M.I0.ERET }; + assign C0_exception = { + M_exception.ExcValid & M.en, + M_exception.delay, + M_exception.ExcCode, + M_exception.BadVAddr, + M_exception.EPC, + M_exception.ERET & M.en + }; // M.I0.HILOC0 mux4 #(32) M_I0_RDataW_mux ( @@ -923,16 +947,16 @@ module Datapath ( // M.I1.MEM mux4 #(8) M_I1_Byte_mux ( - mem_i.rdata[7:0], - mem_i.rdata[15:8], - mem_i.rdata[23:16], - mem_i.rdata[31:24], + M_I1_RData[7:0], + M_I1_RData[15:8], + M_I1_RData[23:16], + M_I1_RData[31:24], M.I1.ALUOut[1:0], M_I1_Byte ); mux2 #(16) M_I1_Half_mux ( - mem_i.rdata[15:0], - mem_i.rdata[31:16], + M_I1_RData[15:0], + M_I1_RData[31:16], M.I1.ALUOut[1], M_I1_Half ); @@ -949,7 +973,7 @@ module Datapath ( mux3 #(32) M_I1_MData_mux ( M_I1_ByteX, M_I1_HalfX, - mem_i.rdata, + M_I1_RData, M.I1.MCtrl.SZ, M_I1_MData ); @@ -960,8 +984,17 @@ module Datapath ( M.I1.RDataW ); + buffer #(32) M_I1_RData_buffer ( + clk, rst, + mem_i.data_ok, + mem_i.rdata, + M.en, + M_I1_RData_OK, + M_I1_RData + ); + assign M.en = M_go & W.en; - assign M_go = ~M.I1.MCtrl.MR | mem_i.data_ok; + assign M_go = (~M.I1.MCtrl.MR | M_I1_RData_OK) & (~M_exception.ExcValid | fetch_i.req & fetch_i.addr_ok); // M.Forwarding assign M_I0_FS_M_I1 = M.A & M.I1.WCtrl.RW & M.I0.RS == M.I1.RD; diff --git a/src/Gadgets.sv b/src/Gadgets.sv index 463a055..e84a7e4 100644 --- a/src/Gadgets.sv +++ b/src/Gadgets.sv @@ -168,3 +168,36 @@ module extender #( assign q = {{(OWIDTH - IWIDTH) {s & d[IWIDTH-1]}}, d}; endmodule + +module buffer #( + parameter WIDTH = 8 +) ( + input clk, + input rst, + input logic prev_valid, + input logic [WIDTH-1:0] prev_data, + input logic next_en, + output logic next_valid, + output logic [WIDTH-1:0] next_data +); + + logic valid; + logic [WIDTH-1:0] data; + + ffenr #(1) valid_ff ( + clk, + rst, + prev_valid, + prev_valid ^ next_en, + valid + ); + ffen #(WIDTH) data_ff ( + clk, + prev_data, + next_en, + data + ); + + assign next_valid = valid | prev_valid; + assign next_data = valid ? data : prev_data; +endmodule diff --git a/src/include/defines.svh b/src/include/defines.svh index 93bd80b..52dc86b 100644 --- a/src/include/defines.svh +++ b/src/include/defines.svh @@ -319,9 +319,6 @@ typedef struct packed { word_t BadVAddr; logic Delay; - logic [4:0] RT; - word_t T; - word_t ALUOut; MCtrl1_t MCtrl; diff --git a/tools/ctrl.txt b/tools/ctrl.txt index d01048e..5fc6a2d 100644 --- a/tools/ctrl.txt +++ b/tools/ctrl.txt @@ -45,7 +45,7 @@ 32'b001101?????????????????????????? 0 0 0 ? 0 0 0 1 1 0 0 RS IMM OR 0 0 0 ? ? RT 1 ALUOut 0 0 0 ? 32'b001110?????????????????????????? 0 0 0 ? 0 0 0 1 1 0 0 RS IMM XOR ? 0 0 ? ? RT 1 ALUOut 0 0 0 ? 32'b00111100000????????????????????? 0 0 0 ? 0 0 0 1 1 1 ? 0 IMM ADD 0 0 0 ? ? RT 1 ALUOut 0 0 0 ? -32'b01000000000??????????00000000??? 0 0 0 ? 0 0 0 1 0 ? ? 0 IMM ? ? 0 ? ? ? RD 1 C0 0 0 0 ? +32'b01000000000??????????00000000??? 0 0 0 ? 0 0 0 1 0 ? ? 0 IMM ? ? 0 ? ? ? RT 1 C0 0 0 0 ? 32'b01000000100??????????00000000??? 0 0 0 ? 0 0 0 1 0 ? ? 0 IMM ? ? 0 ? ? ? ? 0 ? 0 0 1 ? 32'b01000010000000000000000000011000 1 0 0 ? 0 0 0 1 1 ? ? 0 IMM ? ? 0 0 ? ? ? 0 ? 0 0 0 ? 32'b100000?????????????????????????? 0 0 0 ? 0 0 0 0 1 0 1 RS IMM ADD 0 0 1 0 1 RT 1 ? ? ? ? ?