This commit is contained in:
Paul Pan 2021-07-30 21:51:20 +08:00
parent c487401438
commit a0a6e4c2f2
6 changed files with 121 additions and 61 deletions

View File

@ -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)

View File

@ -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
);

View File

@ -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]
& (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);
| 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;

View File

@ -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

View File

@ -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;

View File

@ -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 ? ? ? ? ?