1. 2alu overflow
2. TLB_ENABLE
This commit is contained in:
parent
400767053c
commit
0ecb075c42
@ -88,6 +88,27 @@ module CP0 (
|
||||
assign rf_cp0.EBase.CPUNum = 10'b0;
|
||||
assign rf_cp0.PRId = 32'h00004220;
|
||||
|
||||
`ifndef TLB_ENABLE
|
||||
assign rf_cp0.EntryHi.VPN2 = 19'b0;
|
||||
assign rf_cp0.EntryHi.ASID = 8'b0;
|
||||
assign rf_cp0.Wired.Wired = 3'b0;
|
||||
assign rf_cp0.Context.PTEBase = 9'b0;
|
||||
assign rf_cp0.Context.BadVPN2 = 19'b0;
|
||||
assign rf_cp0.EntryLo1.PFN = 20'b0;
|
||||
assign rf_cp0.EntryLo1.C = 3'b0;
|
||||
assign rf_cp0.EntryLo1.D = 1'b0;
|
||||
assign rf_cp0.EntryLo1.V = 1'b0;
|
||||
assign rf_cp0.EntryLo1.G = 1'b0;
|
||||
assign rf_cp0.EntryLo0.PFN = 20'b0;
|
||||
assign rf_cp0.EntryLo0.C = 3'b0;
|
||||
assign rf_cp0.EntryLo0.D = 1'b0;
|
||||
assign rf_cp0.EntryLo0.V = 1'b0;
|
||||
assign rf_cp0.EntryLo0.G = 1'b0;
|
||||
assign rf_cp0.Index.P = 1'b0;
|
||||
assign rf_cp0.Index.Index = 3'b0;
|
||||
assign rf_cp0.Random.Random = 3'b111;
|
||||
`endif
|
||||
|
||||
always_ff @(posedge clk)
|
||||
if (rst) begin
|
||||
rf_cp0.Config.K0 = 3'b011;
|
||||
@ -103,11 +124,14 @@ module CP0 (
|
||||
rf_cp0.Status.UM = 1'b0;
|
||||
rf_cp0.Status.EXL = 1'b0;
|
||||
rf_cp0.Status.IE = 1'b0;
|
||||
rf_cp0.Compare = 32'hFFFF_FFFF;
|
||||
rf_cp0.Compare = 32'h0;
|
||||
`ifdef TLB_ENABLE
|
||||
rf_cp0.EntryHi.VPN2 = 19'b0;
|
||||
rf_cp0.EntryHi.ASID = 8'b0;
|
||||
`endif
|
||||
rf_cp0.Count = 32'h0;
|
||||
rf_cp0.BadVAddr = 32'h0;
|
||||
`ifdef TLB_ENABLE
|
||||
rf_cp0.Wired.Wired = 3'b0;
|
||||
rf_cp0.Context.PTEBase = 9'b0;
|
||||
rf_cp0.Context.BadVPN2 = 19'b0;
|
||||
@ -124,6 +148,7 @@ module CP0 (
|
||||
rf_cp0.Index.P = 1'b0;
|
||||
rf_cp0.Index.Index = 3'b0;
|
||||
rf_cp0.Random.Random = 3'b111;
|
||||
`endif
|
||||
|
||||
rf_cp0.EBase.EBase = 18'b0;
|
||||
|
||||
@ -169,41 +194,56 @@ module CP0 (
|
||||
rf_cp0.Compare = wdata;
|
||||
end
|
||||
10: begin
|
||||
`ifdef TLB_ENABLE
|
||||
rf_cp0.EntryHi.VPN2 = wdata[31:13];
|
||||
rf_cp0.EntryHi.ASID = wdata[7:0];
|
||||
`endif
|
||||
end
|
||||
9: rf_cp0.Count = wdata;
|
||||
8: rf_cp0.BadVAddr = wdata;
|
||||
// 7: rf_cp0.HWREna = wdata;
|
||||
6: begin
|
||||
`ifdef TLB_ENABLE
|
||||
rf_cp0.Wired.Wired = wdata[2:0];
|
||||
rf_cp0.Random.Random = 3'b111;
|
||||
`endif
|
||||
end
|
||||
// 5: rf_cp0.PageMask.Mask = wdata[24:13];
|
||||
4: rf_cp0.Context.PTEBase = wdata[31:23];
|
||||
4: begin
|
||||
`ifdef TLB_ENABLE
|
||||
rf_cp0.Context.PTEBase = wdata[31:23];
|
||||
`endif
|
||||
end
|
||||
3: begin
|
||||
`ifdef TLB_ENABLE
|
||||
rf_cp0.EntryLo1.PFN = wdata[25:6];
|
||||
rf_cp0.EntryLo1.C = wdata[5:3];
|
||||
rf_cp0.EntryLo1.D = wdata[2];
|
||||
rf_cp0.EntryLo1.V = wdata[1];
|
||||
rf_cp0.EntryLo1.G = wdata[0];
|
||||
`endif
|
||||
end
|
||||
2: begin
|
||||
`ifdef TLB_ENABLE
|
||||
rf_cp0.EntryLo0.PFN = wdata[25:6];
|
||||
rf_cp0.EntryLo0.C = wdata[5:3];
|
||||
rf_cp0.EntryLo0.D = wdata[2];
|
||||
rf_cp0.EntryLo0.V = wdata[1];
|
||||
rf_cp0.EntryLo0.G = wdata[0];
|
||||
`endif
|
||||
end
|
||||
// 1: rf_cp0.Random = wdata;
|
||||
0: begin
|
||||
`ifdef TLB_ENABLE
|
||||
rf_cp0.Index.Index = wdata[2:0];
|
||||
`endif
|
||||
end
|
||||
default: begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
`ifdef TLB_ENABLE
|
||||
if (tlbr) begin
|
||||
rf_cp0.EntryHi.VPN2 = tlb_EntryHi.VPN2;
|
||||
rf_cp0.EntryHi.ASID = tlb_EntryHi.ASID;
|
||||
@ -224,6 +264,7 @@ module CP0 (
|
||||
rf_cp0.Index.P = tlb_Index.P;
|
||||
rf_cp0.Index.Index = tlb_Index.Index;
|
||||
end
|
||||
`endif
|
||||
|
||||
if (rf_cp0.Count == rf_cp0.Compare) rf_cp0.Cause.TI = 1;
|
||||
|
||||
@ -244,12 +285,14 @@ module CP0 (
|
||||
rf_cp0.BadVAddr = exception.BadVAddr;
|
||||
end
|
||||
|
||||
`ifdef TLB_ENABLE
|
||||
if ( exception.ExcCode == `EXCCODE_MOD
|
||||
| exception.ExcCode == `EXCCODE_TLBL
|
||||
| exception.ExcCode == `EXCCODE_TLBS) begin
|
||||
rf_cp0.Context.BadVPN2 = exception.BadVAddr[31:13];
|
||||
rf_cp0.EntryHi.VPN2 = exception.BadVAddr[31:13];
|
||||
end
|
||||
`endif
|
||||
|
||||
end
|
||||
end
|
||||
|
@ -79,10 +79,18 @@ module Controller (
|
||||
assign ctrl.MCtrl1.MX = ~inst[28];
|
||||
assign ctrl.MCtrl1.ALR = ALR_t'({inst[28] & inst[27] & ~inst[26], ~inst[28] & inst[27] & ~inst[26]});
|
||||
assign ctrl.MCtrl1.SZ = inst[27:26];
|
||||
|
||||
`ifdef TLB_ENABLE
|
||||
assign ctrl.MCtrl1.TLBR = ~inst[31] & inst[30] & ~inst[29] & inst[25] & ~inst[3] & ~inst[1];
|
||||
assign ctrl.MCtrl1.TLBWI = ~inst[31] & inst[30] & ~inst[29] & inst[25] & ~inst[3] & inst[1];
|
||||
assign ctrl.MCtrl1.TLBWR = ~inst[31] & inst[30] & ~inst[29] & inst[25] & ~inst[3] & (inst[2] | ~inst[1]);
|
||||
assign ctrl.MCtrl1.TLBP = ~inst[31] & inst[30] & ~inst[4] & inst[3];
|
||||
`else
|
||||
assign ctrl.MCtrl1.TLBR = 1'b0;
|
||||
assign ctrl.MCtrl1.TLBWI = 1'b0;
|
||||
assign ctrl.MCtrl1.TLBWR = 1'b0;
|
||||
assign ctrl.MCtrl1.TLBP = 1'b0;
|
||||
`endif
|
||||
|
||||
assign ctrl.MCtrl1.CACHE_OP = CacheOp_t'({inst[29] & inst[28] & inst[26] & inst[16], inst[29] & inst[28] & inst[26] & ~inst[20], inst[29] & inst[28] & inst[26] & ~inst[18] & (inst[20] | inst[19] | ~inst[16])});
|
||||
|
||||
|
@ -155,10 +155,12 @@ module Datapath (
|
||||
logic E_I0_Overflow;
|
||||
WCtrl_t E_I0_NowWCtrl;
|
||||
logic E_I0_NowExcValid;
|
||||
logic E_I0_NowExcValidWithoutOF;
|
||||
logic E_I0_PrevExcValid;
|
||||
logic [4:0] E_I0_PrevExcCode;
|
||||
logic E_I0_PrevERET;
|
||||
logic E_I0_PrevREFILL;
|
||||
logic E_I0_ExcValidWithoutOF;
|
||||
|
||||
word_t E_I1_A;
|
||||
word_t E_I1_B;
|
||||
@ -225,9 +227,6 @@ module Datapath (
|
||||
word_t M_I0_B;
|
||||
logic M_I0_ALUvalid;
|
||||
logic M_I0_Overflow;
|
||||
logic M_I0_NowExcValid;
|
||||
logic M_I0_PrevExcValid;
|
||||
logic [4:0] M_I0_PrevExcCode;
|
||||
|
||||
logic M_I0_DIV_valid;
|
||||
word_t M_I0_DIVH;
|
||||
@ -319,7 +318,7 @@ module Datapath (
|
||||
assign rstD = D_IA_valid & (D.IA.B & D.IA.BGO | D.IA.JR | D.IA.J) & D_IB_valid & D_readygo;
|
||||
assign rstM = C0_exception.ExcValid;
|
||||
|
||||
assign PF_go = ~D.IA_ExcValid & ~D.IB_ExcValid & ~E.I0.ExcValid & ~E_I1_ExcValidWithoutOF
|
||||
assign PF_go = ~D.IA_ExcValid & ~D.IB_ExcValid & ~E_I0_ExcValidWithoutOF & ~E_I1_ExcValidWithoutOF
|
||||
& (~D_IB_valid | ~D.IA.JR | PF_pcjr[1:0] == 2'b00);
|
||||
assign fetch_i.req = M_exception.ExcValid
|
||||
| PF_go & (~D_IB_valid & ~fetch_i.data_ok | (~D.IA.BJRJ | D_readygo)
|
||||
@ -864,12 +863,14 @@ module Datapath (
|
||||
);
|
||||
|
||||
// E.Exc
|
||||
assign E_I0_NowExcValid = C0_int & E_valid;
|
||||
assign E_I0_NowExcValidWithoutOF = C0_int & E_valid;
|
||||
assign E_I0_NowExcValid = E_I0_NowExcValidWithoutOF | E_I0_Overflow & E.I0.OFA;
|
||||
assign E_I0_ExcValidWithoutOF = E_I0_PrevExcValid | E_I0_NowExcValidWithoutOF;
|
||||
assign E.I0.ExcValid = E_I0_PrevExcValid | E_I0_NowExcValid;
|
||||
assign E.I0.ERET = E_I0_PrevERET & ~C0_int;
|
||||
assign E.I0.REFILL = E_I0_PrevREFILL & ~C0_int;
|
||||
assign E.I0.ExcCode = C0_int ? 5'h0
|
||||
: E_I0_PrevExcCode;
|
||||
: E_I0_PrevExcValid ? E_I0_PrevExcCode : `EXCCODE_OV;
|
||||
|
||||
assign E_I1_NowExcValidWithoutOF = C0_int & E_valid | E.I1.MCtrl.MR & E_I1_STRBERROR;
|
||||
assign E_I1_NowExcValid = E_I1_NowExcValidWithoutOF | E_I1_Overflow & E.I1.OFA;
|
||||
@ -884,7 +885,7 @@ module Datapath (
|
||||
assign E.I1.BadVAddr = E_I1_PrevExcValid ? E.I1.pc : E.I1.ALUOut;
|
||||
|
||||
assign E_I0_go = ~E_I0_NowExcValid & (~E.A | ~E_I1_NowExcValid);
|
||||
assign E_I1_goWithoutOF = ~E_I1_NowExcValidWithoutOF & (E.A | ~E_I0_NowExcValid);
|
||||
assign E_I1_goWithoutOF = ~E_I1_NowExcValidWithoutOF & (E.A | ~E_I0_NowExcValidWithoutOF);
|
||||
assign E_I1_go = ~E_I1_NowExcValid & (E.A | ~E_I0_NowExcValid);
|
||||
|
||||
// E.I0.ALU
|
||||
@ -1065,7 +1066,7 @@ module Datapath (
|
||||
{E.I0.ExcValid, E.I0.ERET, E.I0.REFILL, E.I0.ExcCode, E.I0.CE, E.I0.Delay},
|
||||
M.en,
|
||||
~E_go,
|
||||
{M_I0_PrevExcValid, M.I0.ERET, M.I0.REFILL, M_I0_PrevExcCode, M.I0.CE, M.I0.Delay}
|
||||
{M.I0.ExcValid, M.I0.ERET, M.I0.REFILL, M.I0.ExcCode, M.I0.CE, M.I0.Delay}
|
||||
);
|
||||
ffenrc #(1) M_I0_ExcCtrl_ff (
|
||||
clk,
|
||||
@ -1201,10 +1202,7 @@ module Datapath (
|
||||
dTLBExcValid,
|
||||
{dTLBRefillB, dTLBInvalidB, dTLBModifiedB, dAddressErrorB}
|
||||
);
|
||||
assign M_I0_NowExcValid = M_I0_Overflow & M.I0.OFA;
|
||||
assign M.I0.ExcValid = M_I0_PrevExcValid | M_I0_NowExcValid;
|
||||
assign M.I0.ExcCode = M_I0_PrevExcValid ? M_I0_PrevExcCode
|
||||
: `EXCCODE_OV;
|
||||
|
||||
assign M_I1_NowExcValid = dTLBRefillB | dTLBInvalidB | dTLBModifiedB | dAddressErrorB | M_I1_Trap;
|
||||
assign M.I1.ExcValid = M_I1_PrevExcValid | M_I1_NowExcValid;
|
||||
assign M.I1.REFILL = M_I1_PrevREFILL | dTLBRefillB;
|
||||
@ -1215,8 +1213,8 @@ module Datapath (
|
||||
: dTLBInvalidB ? M.I1.MCtrl.MWR ? `EXCCODE_TLBS : `EXCCODE_TLBL
|
||||
: `EXCCODE_MOD;
|
||||
|
||||
assign M_I0_go = ~M_I0_NowExcValid & (~M.A | ~M_I1_NowExcValid);
|
||||
assign M_I1_go = ~M_I1_NowExcValid & (M.A | ~M_I0_NowExcValid);
|
||||
assign M_I0_go = ~M.A | ~M_I1_NowExcValid;
|
||||
assign M_I1_go = ~M_I1_NowExcValid;
|
||||
|
||||
assign {M_exception, M_exception_REFILL} = {
|
||||
M.I1.ExcValid | M.I0.ExcValid,
|
||||
|
117
src/MMU/TLB.sv
117
src/MMU/TLB.sv
@ -1,6 +1,8 @@
|
||||
`include "defines.svh"
|
||||
`include "TLB.svh"
|
||||
|
||||
`ifdef TLB_ENABLE
|
||||
|
||||
module TLB (
|
||||
input clk,
|
||||
input rst,
|
||||
@ -200,3 +202,118 @@ module TLB (
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
`else
|
||||
|
||||
module TLB (
|
||||
input clk,
|
||||
input rst,
|
||||
|
||||
// CP0
|
||||
input logic [2:0] K0,
|
||||
input logic tlbw, // TLBWI + TLBWR
|
||||
input logic tlbp, // TLBP
|
||||
input logic [2:0] c0_Index, // TLBWR + TLBWI + TLBR
|
||||
|
||||
input EntryHi_t c0_EntryHi, // TLBWI + F/M(ASID)
|
||||
// input PageMask_t c0_PageMask, // TLBWI
|
||||
input EntryLo_t c0_EntryLo1, // TLBWI
|
||||
input EntryLo_t c0_EntryLo0, // TLBWI
|
||||
|
||||
output EntryHi_t EntryHi, // TLBR
|
||||
// output PageMask_t PageMask, // TLBR
|
||||
output EntryLo_t EntryLo1, // TLBR
|
||||
output EntryLo_t EntryLo0, // TLBR
|
||||
output Index_t Index, // TLBP
|
||||
|
||||
// MMU
|
||||
input word_t iVAddr,
|
||||
output word_t iPAddr,
|
||||
output logic iHit, // TLB Refill
|
||||
output logic iCached,
|
||||
output logic iValid, // TLB Invalid
|
||||
output logic iUser, // Privilege
|
||||
|
||||
input word_t dVAddr,
|
||||
output word_t dPAddr,
|
||||
output logic dHit, // TLB Refill
|
||||
output logic dCached,
|
||||
output logic dDirty, // TLB Modified
|
||||
output logic dValid, // TLB Invalid
|
||||
output logic dUser // Privilege
|
||||
);
|
||||
|
||||
word_t fVAddr, fVAddr1;
|
||||
word_t mVAddr, mVAddr1;
|
||||
|
||||
assign fVAddr = iVAddr;
|
||||
// Output
|
||||
ffenr #(32) inst_ff(
|
||||
clk, rst,
|
||||
fVAddr,
|
||||
1'b1,
|
||||
fVAddr1
|
||||
);
|
||||
always_comb begin
|
||||
if (fVAddr1 > 32'hBFFF_FFFF || fVAddr1 <= 32'h7FFF_FFFF) begin
|
||||
// kseg2 + kseg3 + kuseg -> tlb
|
||||
iPAddr = fVAddr1 & 32'h1FFF_FFFF;
|
||||
iHit = 1'b1;
|
||||
iCached = K0[0];
|
||||
iValid = 1'b1;
|
||||
iUser = 1'b1;
|
||||
end else if (fVAddr1 > 32'h9FFF_FFFF) begin
|
||||
// kseg1 uncached
|
||||
iPAddr = fVAddr1 & 32'h1FFF_FFFF;
|
||||
iHit = 1'b1;
|
||||
iCached = 1'b0;
|
||||
iValid = 1'b1;
|
||||
iUser = 1'b0;
|
||||
end else begin
|
||||
// kseg0 -> CP0.K0
|
||||
iPAddr = fVAddr1 & 32'h1FFF_FFFF;
|
||||
iHit = 1'b1;
|
||||
iCached = K0[0];
|
||||
iValid = 1'b1;
|
||||
iUser = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
assign mVAddr = dVAddr;
|
||||
ffenr #(32) data_ff (
|
||||
clk, rst,
|
||||
mVAddr,
|
||||
1'b1,
|
||||
mVAddr1
|
||||
);
|
||||
always_comb begin
|
||||
if (mVAddr1 > 32'hBFFF_FFFF || mVAddr1 <= 32'h7FFF_FFFF) begin
|
||||
// kseg2 + kseg3 + kuseg -> tlb
|
||||
dPAddr = mVAddr1 & 32'h1FFF_FFFF;
|
||||
dHit = 1'b1;
|
||||
dCached = K0[0];
|
||||
dDirty = 1'b1;
|
||||
dValid = 1'b1;
|
||||
dUser = 1'b1;
|
||||
end else if (mVAddr1 > 32'h9FFF_FFFF) begin
|
||||
// kseg1 uncached
|
||||
dPAddr = mVAddr1 & 32'h1FFF_FFFF;
|
||||
dHit = 1'b1;
|
||||
dCached = 1'b0;
|
||||
dDirty = 1'b1;
|
||||
dValid = 1'b1;
|
||||
dUser = 1'b0;
|
||||
end else begin
|
||||
// kseg0 -> CP0.K0
|
||||
dPAddr = mVAddr1 & 32'h1FFF_FFFF;
|
||||
dHit = 1'b1;
|
||||
dCached = K0[0];
|
||||
dDirty = 1'b1;
|
||||
dValid = 1'b1;
|
||||
dUser = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
`endif
|
@ -5,6 +5,8 @@
|
||||
`define Off_TRef 9'h000
|
||||
`define Off_GExc 9'h180
|
||||
|
||||
// `define TLB_ENABLE
|
||||
|
||||
// prio: int
|
||||
// fetch_addr
|
||||
// fetch_tlb_refill
|
||||
|
@ -20,9 +20,9 @@
|
||||
32'b000000??????????0000000000011001 0 0 0 0 1 1 ? ? 0 0 1 0 // MULTU
|
||||
32'b000000??????????0000000000011010 0 0 0 0 1 1 ? ? 0 0 1 0 // DIV
|
||||
32'b000000??????????0000000000011011 0 0 0 0 1 1 ? ? 0 0 1 0 // DIVU
|
||||
32'b000000???????????????00000100000 0 0 0 1 0 0 1 1 0 0 1 1 // ADD
|
||||
32'b000000???????????????00000100000 0 0 0 1 1 1 ? ? 0 0 1 1 // ADD
|
||||
32'b000000???????????????00000100001 0 0 0 0 0 0 1 1 0 0 1 1 // ADDU
|
||||
32'b000000???????????????00000100010 0 0 0 1 0 0 1 1 0 0 1 1 // SUB
|
||||
32'b000000???????????????00000100010 0 0 0 1 1 1 ? ? 0 0 1 1 // SUB
|
||||
32'b000000???????????????00000100011 0 0 0 0 0 0 1 1 0 0 1 1 // SUBU
|
||||
32'b000000???????????????00000100100 0 0 0 0 0 0 1 1 0 0 1 1 // AND
|
||||
32'b000000???????????????00000100101 0 0 0 0 0 0 1 1 0 0 1 1 // OR
|
||||
@ -52,7 +52,7 @@
|
||||
32'b000101?????????????????????????? 0 0 0 0 0 0 0 0 1 1 1 1 // BNE
|
||||
32'b000110?????00000???????????????? 0 0 0 0 0 0 0 0 1 0 1 1 // BLEZ
|
||||
32'b000111?????00000???????????????? 0 0 0 0 0 0 0 0 1 0 1 1 // BGTZ
|
||||
32'b001000?????????????????????????? 0 0 0 1 0 0 1 0 0 0 1 1 // ADDI
|
||||
32'b001000?????????????????????????? 0 0 0 1 1 0 ? 0 0 0 1 1 // ADDI
|
||||
32'b001001?????????????????????????? 0 0 0 0 0 0 1 0 0 0 1 1 // ADDIU
|
||||
32'b001010?????????????????????????? 0 0 0 0 0 0 1 0 0 0 1 1 // SLTI
|
||||
32'b001011?????????????????????????? 0 0 0 0 0 0 1 0 0 0 1 1 // SLTIU
|
||||
|
Loading…
Reference in New Issue
Block a user