Update MU and DCache

This commit is contained in:
Paul Pan 2022-08-03 14:26:44 +08:00
parent db1aa1d615
commit 02f04a2bf3
10 changed files with 424 additions and 44 deletions

View File

@ -0,0 +1,321 @@
#include <asm.h>
#include <regdef.h>
#include <inst_test.h>
LEAF(n102_memory_test)
.set noreorder
addiu s0, s0 ,1
li s2, 0x0
###test inst
## A simple Stream Test
li t0, 0xa00d0000
li t1, 0x800d0000
li a0, 0x08030127
li a1, 0x20220803
sw a1, 0(t1)
cache 21, 0(t1)
sw a1, 4(t1)
cache 21, 4(t1)
sw a1, 8(t1)
cache 21, 8(t1)
sw a1, 12(t1)
cache 21, 12(t1)
sw a1, 16(t1)
cache 21, 16(t1)
sw a1, 20(t1)
cache 21, 20(t1)
sw a1, 24(t1)
cache 21, 24(t1)
sw a1, 28(t1)
cache 21, 28(t1)
sw a1, 32(t1)
cache 21, 32(t1)
sw a1, 36(t1)
cache 21, 36(t1)
lw t2, 0(t0)
bne t2, a1, inst_error
nop
lw t2, 4(t0)
bne t2, a1, inst_error
nop
lw t2, 8(t0)
bne t2, a1, inst_error
nop
lw t2, 12(t0)
bne t2, a1, inst_error
nop
lw t2, 16(t0)
bne t2, a1, inst_error
nop
lw t2, 20(t0)
bne t2, a1, inst_error
nop
lw t2, 24(t0)
bne t2, a1, inst_error
nop
lw t2, 28(t0)
bne t2, a1, inst_error
nop
lw t2, 32(t0)
bne t2, a1, inst_error
nop
lw t2, 36(t0)
bne t2, a1, inst_error
nop
sw a1, 0(t1)
sw a1, 4(t1)
sw a1, 8(t1)
sw a1, 12(t1)
sw a1, 16(t1)
sw a1, 20(t1)
sw a1, 24(t1)
sw a1, 28(t1)
sw a1, 32(t1)
sw a1, 36(t1)
cache 21, 0(t1)
cache 21, 4(t1)
cache 21, 8(t1)
cache 21, 12(t1)
cache 21, 16(t1)
cache 21, 20(t1)
cache 21, 24(t1)
cache 21, 28(t1)
cache 21, 32(t1)
cache 21, 36(t1)
lw t2, 0(t0)
bne t2, a1, inst_error
nop
lw t2, 4(t0)
bne t2, a1, inst_error
nop
lw t2, 8(t0)
bne t2, a1, inst_error
nop
lw t2, 12(t0)
bne t2, a1, inst_error
nop
lw t2, 16(t0)
bne t2, a1, inst_error
nop
lw t2, 20(t0)
bne t2, a1, inst_error
nop
lw t2, 24(t0)
bne t2, a1, inst_error
nop
lw t2, 28(t0)
bne t2, a1, inst_error
nop
lw t2, 32(t0)
bne t2, a1, inst_error
nop
lw t2, 36(t0)
bne t2, a1, inst_error
nop
lw t2, 0(t0)
lw a0, 0(t1)
lw v0, 4(t0)
lw v1, 4(t1)
bne t2, a1, inst_error
nop
bne a0, a1, inst_error
nop
bne v0, a1, inst_error
nop
bne v1, a1, inst_error
nop
lw a0, 0(t1)
lw t2, 0(t0)
lw v1, 4(t1)
lw v0, 4(t0)
bne t2, a1, inst_error
nop
bne a0, a1, inst_error
nop
bne v0, a1, inst_error
nop
bne v1, a1, inst_error
nop
cache 21, 0(t1)
cache 21, 4(t1)
li t3, 0x7f7f7f7f
sw t3, 0(t0)
lw a0, 0(t1)
bne a0, t3, inst_error
nop
##
li t0, 0xa00d0000
li t1, 0xa00d0800
li t2, 0xa00d1000
li t3, 0xa00d1800
li a0, 0x08031104
sw a0, 0(t0)
sw a0, 0(t1)
sw a0, 0(t2)
sw a0, 0(t3) # uncached
cache 9, 0(zero)
li t0, 0x800d0000
li t1, 0x800d0800
li t2, 0x800d1000
li t3, 0x800d1800
lw a1, 0(t0)
bne a1, a0, inst_error
nop
lw a1, 0(t1)
bne a1, a0, inst_error
nop
lw a1, 0(t2)
bne a1, a0, inst_error
nop
lw a1, 0(t3)
bne a1, a0, inst_error
nop # 0x8031104
li a1, 0xBBBBBBBB
sw a1, 0(t1) # t1
li t0, 0xa00d0000
li t1, 0xa00d0800
li t2, 0xa00d1000
li t3, 0xa00d1800
li a0, 0xAAAAAAAA
sw a0, 0(t0)
sw a0, 0(t1)
sw a0, 0(t2)
sw a0, 0(t3) # uncached
cache 1, 0(zero) # t1
li t0, 0x800d0000
li t1, 0x800d0800
li t2, 0x800d1000
li t3, 0x800d1800
li a0, 0xAAAAAAAA
lw a1, 0(t0)
bne a1, a0, inst_error
nop
lw a1, 0(t2)
bne a1, a0, inst_error
nop
lw a1, 0(t3)
bne a1, a0, inst_error
nop
li a0, 0xBBBBBBBB
lw a1, 0(t1)
bne a0, a1, inst_error
nop
##
li t0, 0xa00d0000
li t1, 0xa00d0800
li t2, 0xa00d1000
li t3, 0xa00d1800
li a0, 0xa00d2000
li a1, 0xCCCCCCCC
sw a1, 0(t0)
sw a1, 0(t1)
sw a1, 0(t2)
sw a1, 0(t3)
sw a1, 0(a0)
cache 9, 0(zero)
li t0, 0x800d0000
li t1, 0x800d0800
li t2, 0x800d1000
li t3, 0x800d1800
lw a0, 0(t0)
bne a0, a1, inst_error
nop
lw a0, 0(t1)
bne a0, a1, inst_error
nop
lw a0, 0(t2)
bne a0, a1, inst_error
nop
lw a0, 0(t3)
bne a0, a1, inst_error
nop
li a0, 0xDDDDDDDD
sw a0, 0(t0)
sw a0, 0(t1)
sw a0, 0(t2)
sw a0, 0(t3) #
li a0, 0x800d2000
li a1, 0xCCCCCCCC
lw a0, 0(a0) # (RO)
bne a0, a1, inst_error
nop
li t0, 0xa00d0000
li t1, 0xa00d0800
li t2, 0xa00d1000
li t3, 0xa00d1800 # (C->D)
li a0, 0
lw a1, 0(t0)
xor a0, a0, a1
lw a1, 0(t1)
xor a0, a0, a1
lw a1, 0(t2)
xor a0, a0, a1
lw a1, 0(t3)
xor a0, a0, a1 # a0 = 0xCCCCCCCC ^ 0xCCCCCCCC ^ 0xCCCCCCCC ^ 0xDDDDDDDD
li a1, 0xDDDDDDDD
xor a0, a0, a1
li a1, 0xCCCCCCCC
xor a0, a0, a1
bne a0, zero, inst_error
nop
## Cross Load
li t0, 0xa00d0000
li t1, 0xa00d0800
li t2, 0xa00d1000
li t3, 0xa00d1800
li a1, 0xA5A55A5A
sw a1, 0(t0)
sw a1, 0(t1)
sw a1, 0(t2)
sw a1, 0(t3)
cache 9, 0(zero)
li t0, 0xa00d0000
li t1, 0x800d0800
li t2, 0xa00d1000
li t3, 0x800d1800
lw a0, 0(t0)
lw a1, 0(t1)
lw v0, 0(t2)
lw v1, 0(t3)
###detect exception
bne s2, zero, inst_error
nop
###score ++
addiu s3, s3, 1
###output (s0<<24)|s3
inst_error:
sll t1, s0, 24
or t0, t1, s3
sw t0, 0(s1)
jr ra
nop
END(n102_memory_test)

View File

@ -4,7 +4,7 @@
#include <utils.h> #include <utils.h>
#define TEST_NUM 150 #define TEST_NUM 152
##s0, number ##s0, number
@ -420,9 +420,11 @@ inst_test:
TEST_UNIT(n98_cache_dcache_test) # 146 TEST_UNIT(n98_cache_dcache_test) # 146
TEST_UNIT_ONLY_CACHE(n99_cache_icache_test) TEST_UNIT_ONLY_CACHE(n99_cache_icache_test)
TEST_UNIT_CACHE(n100_movz_movn_test) TEST_UNIT_CACHE(n100_movz_movn_test) # 148 149
TEST_UNIT(n101_trap_test) TEST_UNIT(n101_trap_test) # 150
TEST_UNIT_CACHE(n102_memory_test) # 151 152
###check io access ###check io access
LI (a0, IO_SIMU_ADDR) LI (a0, IO_SIMU_ADDR)

View File

@ -63,7 +63,7 @@ verilate:
func_build: verilate func_build: verilate
make -C obj_dir -f Vtestbench_top.mk -j make -C obj_dir -f Vtestbench_top.mk -j
func_coverage: func_build func_coverage:
@rm -rf logs/annotated @rm -rf logs/annotated
$(VERILATOR_COVERAGE) $(VERILATOR_COV_FLAGS) $(VERILATOR_COVERAGE) $(VERILATOR_COV_FLAGS)

View File

@ -78,20 +78,24 @@ module Controller (
assign ctrl.MCtrl1.MX = ~inst[28]; 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.ALR = ALR_t'({inst[28] & inst[27] & ~inst[26], ~inst[28] & inst[27] & ~inst[26]});
assign ctrl.MCtrl1.SZ = inst[27:26]; assign ctrl.MCtrl1.SZ = inst[27:26];
`ifdef ENABLE_TLB
assign ctrl.MCtrl1.TLBR = ~inst[31] & inst[30] & ~inst[29] & inst[25] & ~inst[3] & ~inst[1]; 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.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.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]; assign ctrl.MCtrl1.TLBP = ~inst[31] & inst[30] & ~inst[4] & inst[3];
`endif
assign ctrl.MCtrl1.CACHE_OP.icache_op = inst[31] & inst[29] & inst[28] & inst[26] & ~inst[16]; assign ctrl.MCtrl1.CACHE_OP.icache_op = inst[31] & inst[29] & inst[28] & inst[26] & ~inst[16];
assign ctrl.MCtrl1.CACHE_OP.dcache_op = inst[31] & inst[29] & inst[28] & inst[26] & inst[16]; assign ctrl.MCtrl1.CACHE_OP.dcache_op = inst[31] & inst[29] & inst[28] & inst[26] & inst[16];
assign ctrl.MCtrl1.CACHE_OP.index_or_hit = inst[20]; assign ctrl.MCtrl1.CACHE_OP.index_or_hit = inst[20];
assign ctrl.MCtrl1.CACHE_OP.writeback = ~inst[20] & ~inst[19] & inst[16] | inst[18]; assign ctrl.MCtrl1.CACHE_OP.writeback = ~inst[20] & ~inst[19] & inst[16] | inst[18];
`ifdef ENABLE_TRAP
assign ctrl.Trap.TEN = ~inst[29] & (~inst[26] & ~inst[30] & ~inst[31] & ~inst[28] & ~inst[27] & inst[4] & inst[5] | inst[26] & ~inst[31] & ~inst[28] & ~inst[27] & inst[19]); assign ctrl.Trap.TEN = ~inst[29] & (~inst[26] & ~inst[30] & ~inst[31] & ~inst[28] & ~inst[27] & inst[4] & inst[5] | inst[26] & ~inst[31] & ~inst[28] & ~inst[27] & inst[19]);
assign ctrl.Trap.TP = TrapOp_t'({~inst[26] & inst[2] | inst[26] & inst[18], ~inst[26] & inst[1] | inst[26] & inst[17]}); assign ctrl.Trap.TP = TrapOp_t'({~inst[26] & inst[2] | inst[26] & inst[18], ~inst[26] & inst[1] | inst[26] & inst[17]});
`endif
logic mov, rw, eqz; logic mov, rw, eqz;
assign mov = ~inst[31] & ~inst[30] & ~inst[29] & ~inst[28] & ~inst[27] & ~inst[26] & ~inst[5] & ~inst[4] & inst[3] & ~inst[2] & inst[1]; assign mov = ~inst[31] & ~inst[30] & ~inst[29] & ~inst[28] & ~inst[27] & ~inst[26] & ~inst[5] & ~inst[4] & inst[3] & ~inst[2] & inst[1];
assign rw = ~inst[30] & (~inst[26] & (~inst[27] & (~inst[31] & (~inst[28] & (~inst[4] & (~inst[3] | ~inst[2] & (inst[0] | inst[1])) | inst[4] & ~inst[5] & ~inst[3] & ~inst[0]) | inst[29]) | inst[31] & ~inst[29]) | inst[27] & (~inst[31] & inst[29] | inst[31] & ~inst[29])) | inst[26] & (~inst[29] & (~inst[27] & ~inst[28] & inst[20] | inst[27] & ~inst[28] | inst[31]) | inst[29] & ~inst[31])) | inst[30] & ~inst[31] & ~inst[3] & (~inst[29] & ~inst[25] & ~inst[23] | inst[29] & inst[1]); assign rw = ~inst[30] & (~inst[26] & (~inst[27] & (~inst[31] & (~inst[28] & (~inst[4] & (~inst[3] | ~inst[2] & (inst[0] | inst[1])) | inst[4] & ~inst[5] & ~inst[3] & ~inst[0]) | inst[29]) | inst[31] & ~inst[29]) | inst[27] & (~inst[31] & inst[29] | inst[31] & ~inst[29])) | inst[26] & (~inst[29] & (~inst[27] & ~inst[28] & inst[20] | inst[27] & ~inst[28] | inst[31]) | inst[29] & ~inst[31])) | inst[30] & ~inst[31] & ~inst[3] & (~inst[29] & ~inst[25] & ~inst[23] | inst[29] & inst[1]);
assign eqz = rt == 32'h0; assign eqz = rt == 32'h0;

View File

@ -623,7 +623,9 @@ module Datapath (
assign D.I1.sa = D.A ? D.IA_sa : D.IB_sa; assign D.I1.sa = D.A ? D.IA_sa : D.IB_sa;
assign D.I1.ECtrl = D.A ? D.IA.ECtrl : D.IB.ECtrl; assign D.I1.ECtrl = D.A ? D.IA.ECtrl : D.IB.ECtrl;
assign D.I1.MCtrl = D.A ? D.IA.MCtrl1 : D.IB.MCtrl1; assign D.I1.MCtrl = D.A ? D.IA.MCtrl1 : D.IB.MCtrl1;
`ifdef ENABLE_TRAP
assign D.I1.Trap = D.A ? D.IA.Trap : D.IB.Trap; assign D.I1.Trap = D.A ? D.IA.Trap : D.IB.Trap;
`endif
assign D.I1.RD = D.A ? D.IA.RD : D.IB.RD; assign D.I1.RD = D.A ? D.IA.RD : D.IB.RD;
assign D.I1.WCtrl = D.A ? D.IA.WCtrl : D.IB.WCtrl; assign D.I1.WCtrl = D.A ? D.IA.WCtrl : D.IB.WCtrl;
@ -811,6 +813,7 @@ module Datapath (
~D_go | ~D_I1_go, ~D_go | ~D_I1_go,
E.I1.MCtrl E.I1.MCtrl
); );
`ifdef ENABLE_TRAP
ffenrc #(3) E_I1_Trap_ff ( ffenrc #(3) E_I1_Trap_ff (
clk, clk,
rst | rstM, rst | rstM,
@ -819,6 +822,7 @@ module Datapath (
~D_go | ~D_I1_go, ~D_go | ~D_I1_go,
E.I1.Trap E.I1.Trap
); );
`endif
ffenrc #(5 + 1) E_I1_WCtrl_ff ( ffenrc #(5 + 1) E_I1_WCtrl_ff (
clk, clk,
rst | rstM, rst | rstM,
@ -943,11 +947,11 @@ module Datapath (
E_I1_STRBERROR E_I1_STRBERROR
); );
assign C0.cpu_tlb_tlbp = E.I1.MCtrl.TLBP; assign C0.cpu_tlb_tlbp = E.I1.MCtrl.TLBP;
assign mem.req = E.I1.MCtrl.MR & E_I1_goWithoutOF & M.en & ~rstM; assign mem.req = E.I1.MCtrl.MR & E_I1_goWithoutOF & M.en & ~rstM;
assign E_I1_ADDR = E_I1_ForwardS + E.I1.imm; assign E_I1_ADDR = E_I1_ForwardS + E.I1.imm;
assign mem.addr = |E.I1.MCtrl.ALR ? {E_I1_ADDR[31:2], 2'b0} : E_I1_ADDR; assign mem.addr = |E.I1.MCtrl.ALR ? {E_I1_ADDR[31:2], 2'b0} : E_I1_ADDR;
assign mem.size = {E.I1.MCtrl.SZ[1], E.I1.MCtrl.SZ[0] & ~E.I1.MCtrl.SZ[1]}; assign mem.size = {E.I1.MCtrl.SZ[1], E.I1.MCtrl.SZ[0] & ~E.I1.MCtrl.SZ[1]};
assign cache_op.req = cache_op.op.icache_op | cache_op.op.dcache_op; assign cache_op.req = cache_op.op.icache_op | cache_op.op.dcache_op;
assign cache_op.op = E.I1.MCtrl.CACHE_OP; assign cache_op.op = E.I1.MCtrl.CACHE_OP;
@ -1113,6 +1117,7 @@ module Datapath (
~E_go | ~E_I1_go, ~E_go | ~E_I1_go,
M.I1.MCtrl M.I1.MCtrl
); );
`ifdef ENABLE_TRAP
ffenrc #(3) M_I1_Trap_ff ( ffenrc #(3) M_I1_Trap_ff (
clk, clk,
rst | rstM, rst | rstM,
@ -1121,6 +1126,7 @@ module Datapath (
~E_go | ~E_I1_go, ~E_go | ~E_I1_go,
M.I1.Trap M.I1.Trap
); );
`endif
ffenrc #(5 + 1) M_I1_WCtrl_ff ( ffenrc #(5 + 1) M_I1_WCtrl_ff (
clk, clk,
rst | rstM, rst | rstM,
@ -1341,11 +1347,15 @@ module Datapath (
); );
// M.I1.TRAP // M.I1.TRAP
`ifdef ENABLE_TRAP
assign M_I1_Trap = M.I1.Trap.TEN & ( M.I1.Trap.TP == NE ? M.I1.ALUOut != 32'b0 assign M_I1_Trap = M.I1.Trap.TEN & ( M.I1.Trap.TP == NE ? M.I1.ALUOut != 32'b0
: M.I1.Trap.TP == EQ ? M.I1.ALUOut == 32'b0 : M.I1.Trap.TP == EQ ? M.I1.ALUOut == 32'b0
: M.I1.Trap.TP == LT ? M.I1.ALUOut[0] == 1'b1 : M.I1.Trap.TP == LT ? M.I1.ALUOut[0] == 1'b1
: M.I1.Trap.TP == GE ? M.I1.ALUOut[0] == 1'b0 : M.I1.Trap.TP == GE ? M.I1.ALUOut[0] == 1'b0
: 1'b0); : 1'b0);
`else
assign M_I1_Trap = 1'b0;
`endif
assign M.en = M_go & W.en; assign M.en = M_go & W.en;
assign M_go = (M.I0.MCtrl.HLS[2:1] != 2'b10 | M_I0_MULT_bvalid) assign M_go = (M.I0.MCtrl.HLS[2:1] != 2'b10 | M_I0_MULT_bvalid)

View File

@ -53,20 +53,24 @@ module decoder2 (
32'b000000???????????????00000100111: ri = 1'b0; // NOR 32'b000000???????????????00000100111: ri = 1'b0; // NOR
32'b000000???????????????00000101010: ri = 1'b0; // SLT 32'b000000???????????????00000101010: ri = 1'b0; // SLT
32'b000000???????????????00000101011: ri = 1'b0; // SLTU 32'b000000???????????????00000101011: ri = 1'b0; // SLTU
`ifdef ENABLE_TRAP
32'b000000????????????????????110000: ri = 1'b0; // TGE 32'b000000????????????????????110000: ri = 1'b0; // TGE
32'b000000????????????????????110001: ri = 1'b0; // TGEU 32'b000000????????????????????110001: ri = 1'b0; // TGEU
32'b000000????????????????????110010: ri = 1'b0; // TLT 32'b000000????????????????????110010: ri = 1'b0; // TLT
32'b000000????????????????????110011: ri = 1'b0; // TLTU 32'b000000????????????????????110011: ri = 1'b0; // TLTU
32'b000000????????????????????110100: ri = 1'b0; // TEQ 32'b000000????????????????????110100: ri = 1'b0; // TEQ
32'b000000????????????????????110110: ri = 1'b0; // TNE 32'b000000????????????????????110110: ri = 1'b0; // TNE
`endif
32'b000001?????00000????????????????: ri = 1'b0; // BLTZ 32'b000001?????00000????????????????: ri = 1'b0; // BLTZ
32'b000001?????00001????????????????: ri = 1'b0; // BGEZ 32'b000001?????00001????????????????: ri = 1'b0; // BGEZ
`ifdef ENABLE_TRAP
32'b000001?????01000????????????????: ri = 1'b0; // TGEI 32'b000001?????01000????????????????: ri = 1'b0; // TGEI
32'b000001?????01001????????????????: ri = 1'b0; // TGEIU 32'b000001?????01001????????????????: ri = 1'b0; // TGEIU
32'b000001?????01010????????????????: ri = 1'b0; // TLTI 32'b000001?????01010????????????????: ri = 1'b0; // TLTI
32'b000001?????01011????????????????: ri = 1'b0; // TLTIU 32'b000001?????01011????????????????: ri = 1'b0; // TLTIU
32'b000001?????01110????????????????: ri = 1'b0; // TNEI 32'b000001?????01110????????????????: ri = 1'b0; // TNEI
32'b000001?????01100????????????????: ri = 1'b0; // TEQI 32'b000001?????01100????????????????: ri = 1'b0; // TEQI
`endif
32'b000001?????10000????????????????: ri = 1'b0; // BLTZAL 32'b000001?????10000????????????????: ri = 1'b0; // BLTZAL
32'b000001?????10001????????????????: ri = 1'b0; // BGEZAL 32'b000001?????10001????????????????: ri = 1'b0; // BGEZAL
32'b000010??????????????????????????: ri = 1'b0; // J 32'b000010??????????????????????????: ri = 1'b0; // J
@ -108,6 +112,7 @@ module decoder2 (
32'b101010??????????????????????????: ri = 1'b0; // SWL 32'b101010??????????????????????????: ri = 1'b0; // SWL
32'b101011??????????????????????????: ri = 1'b0; // SW 32'b101011??????????????????????????: ri = 1'b0; // SW
32'b101110??????????????????????????: ri = 1'b0; // SWR 32'b101110??????????????????????????: ri = 1'b0; // SWR
`ifdef ENABLE_CACHEOP
32'b101111?????00000????????????????: ri = 1'b0; // I-Cache Index Invalid 32'b101111?????00000????????????????: ri = 1'b0; // I-Cache Index Invalid
32'b101111?????01000????????????????: ri = 1'b0; // I-Cache Index Store Tag 32'b101111?????01000????????????????: ri = 1'b0; // I-Cache Index Store Tag
32'b101111?????10000????????????????: ri = 1'b0; // I-Cache Hit Invalid 32'b101111?????10000????????????????: ri = 1'b0; // I-Cache Hit Invalid
@ -115,6 +120,7 @@ module decoder2 (
32'b101111?????01001????????????????: ri = 1'b0; // D-Cache Index Store Tag 32'b101111?????01001????????????????: ri = 1'b0; // D-Cache Index Store Tag
32'b101111?????10001????????????????: ri = 1'b0; // D-Cache Hit Invalid 32'b101111?????10001????????????????: ri = 1'b0; // D-Cache Hit Invalid
32'b101111?????10101????????????????: ri = 1'b0; // D-Cache Hit Writeback Invalid 32'b101111?????10101????????????????: ri = 1'b0; // D-Cache Hit Writeback Invalid
`endif
// 32'b110000??????????????????????????: begin cpu = 1'b1; ce = 2'b0; end // LL (CpU) // 32'b110000??????????????????????????: begin cpu = 1'b1; ce = 2'b0; end // LL (CpU)
32'b110011??????????????????????????: ri = 1'b0; // PREF (NOP) 32'b110011??????????????????????????: ri = 1'b0; // PREF (NOP)
// 32'b111000??????????????????????????: begin cpu = 1'b1; ce = 2'b0; end // SC (CpU) // 32'b111000??????????????????????????: begin cpu = 1'b1; ce = 2'b0; end // SC (CpU)

View File

@ -32,7 +32,7 @@ module AXIWriter #(parameter DATA_LEN = 8)
logic [3:0] data_cntr; logic [3:0] data_cntr;
logic [DATA_LEN-1:0] data_select; logic [DATA_LEN-1:0] data_select;
ffen #(4) cntr_ff (.*, .d((call ? 4'b0 : data_cntr) + 4'b0001) , .en(shift | call), .q(data_cntr)); ffen #(4) cntr_ff (.*, .d((call ? 4'b0 : data_cntr) + (shift ? 4'b0001 : 4'b0)) , .en(shift | call), .q(data_cntr));
assign data_select = call ? data : stored_data; assign data_select = call ? data : stored_data;
typedef enum bit [1:0] { DIDLE, DATA } data_state_t; typedef enum bit [1:0] { DIDLE, DATA } data_state_t;

View File

@ -69,7 +69,8 @@ module DCache (
: port.ctrl.cache_index_writeback & tag[0].dirty ? 4'b0001 : port.ctrl.cache_index_writeback & tag[0].dirty ? 4'b0001
: port.ctrl.cache_index_writeback & tag[1].dirty ? 4'b0010 : port.ctrl.cache_index_writeback & tag[1].dirty ? 4'b0010
: port.ctrl.cache_index_writeback & tag[2].dirty ? 4'b0100 : port.ctrl.cache_index_writeback & tag[2].dirty ? 4'b0100
: port.ctrl.cache_index_writeback ? 4'b1000 : port.ctrl.cache_index_writeback & tag[3].dirty ? 4'b1000
: port.ctrl.cache_index_writeback ? 4'b1111 // NOTE: <----
: tag[0].valid == 0 ? 4'b0001 : tag[0].valid == 0 ? 4'b0001
: tag[1].valid == 0 ? 4'b0010 : tag[1].valid == 0 ? 4'b0010
: tag[2].valid == 0 ? 4'b0100 : tag[2].valid == 0 ? 4'b0100

View File

@ -20,19 +20,26 @@ module MU (
// == CacheOp == // == CacheOp ==
// ============= // =============
// NOTE: req and op and addr should be kept until addr_ok
logic cop_i_req, cop_d_req; logic cop_i_req, cop_d_req;
logic cacheop_handling; logic cacheop_handling;
assign cop_i_req = cacheop.req & cacheop.op.icache_op & ~cacheop_handling;
assign cop_d_req = cacheop.req & cacheop.op.dcache_op & ~cacheop_handling;
logic cop_i_ok, cop_d_ok; logic cop_i_ok, cop_d_ok;
logic cop_i_addr_ok, cop_d_addr_ok; logic cop_i_addr_ok, cop_d_addr_ok;
`ifdef ENABLE_CACHEOP
assign cop_i_req = cacheop.req & cacheop.op.icache_op & ~cacheop_handling;
assign cop_d_req = cacheop.req & cacheop.op.dcache_op & ~cacheop_handling;
assign cacheop.addr_ok = (~cop_i_req | cop_i_addr_ok) & (~cop_d_req | cop_d_addr_ok) & ~cacheop_handling; assign cacheop.addr_ok = (~cop_i_req | cop_i_addr_ok) & (~cop_d_req | cop_d_addr_ok) & ~cacheop_handling;
assign cacheop.data_ok = cop_i_ok | cop_d_ok; assign cacheop.data_ok = cop_i_ok | cop_d_ok;
`else
assign cop_i_req = 0;
assign cop_d_req = 0;
assign cacheop.addr_ok = 1;
assign cacheop.data_ok = 1;
`endif
logic stored_icacheop_req, stored_dcacheop_req; logic stored_icacheop_req, stored_dcacheop_req;
CacheOp_t stored_cacheop_op; CacheOp_t stored_cacheop_op;
word_t stored_cacheop_addr; word_t stored_cacheop_addr;
`ifdef ENABLE_CACHEOP
ffen #(`XLEN) cacheop_addr_store (.*, .d(cacheop.addr), .en(cacheop.req & cacheop.addr_ok), .q(stored_cacheop_addr)); ffen #(`XLEN) cacheop_addr_store (.*, .d(cacheop.addr), .en(cacheop.req & cacheop.addr_ok), .q(stored_cacheop_addr));
ffen #(`CACHEOP_T_LEN) cacheop_op_store (.*, .d(cacheop.op), .en(cacheop.req & cacheop.addr_ok), .q(stored_cacheop_op)); ffen #(`CACHEOP_T_LEN) cacheop_op_store (.*, .d(cacheop.op), .en(cacheop.req & cacheop.addr_ok), .q(stored_cacheop_op));
ffenr #(2) cacheop_req_store ( ffenr #(2) cacheop_req_store (
@ -44,6 +51,13 @@ module MU (
); );
assign cacheop_handling = stored_icacheop_req | stored_dcacheop_req; assign cacheop_handling = stored_icacheop_req | stored_dcacheop_req;
`else
assign stored_icacheop_req = 0;
assign stored_dcacheop_req = 0;
assign stored_cacheop_op = 0;
assign stored_cacheop_addr = 0;
assign cacheop_handling = 0;
`endif
// ========================= // =========================
// == InstFetch Functions == // == InstFetch Functions ==
@ -94,7 +108,6 @@ module MU (
// =============== // ===============
logic if_req, if_wait_cache; logic if_req, if_wait_cache;
// NOTE: TLB Check
word_t stored_instfetch_addr; word_t stored_instfetch_addr;
ffenr #(1) ifreq_store (.*, .d(instfetch.req), .en(in_if_ready), .q(if_req), .rst(rst | if_wait_cache)); ffenr #(1) ifreq_store (.*, .d(instfetch.req), .en(in_if_ready), .q(if_req), .rst(rst | if_wait_cache));
ffen #(`XLEN) ifaddr_store (.*, .d(instfetch.addr), .en(in_if_ready), .q(stored_instfetch_addr)); ffen #(`XLEN) ifaddr_store (.*, .d(instfetch.addr), .en(in_if_ready), .q(stored_instfetch_addr));
@ -122,12 +135,6 @@ module MU (
// == InstFetch Control State Machine == // == InstFetch Control State Machine ==
// ===================================== // =====================================
// cache ctrl:
// read_and_hit : lookup(0) and hit(1)
// read_but_replace : lookup(0) but miss(1), replace(2)
// cache_index_invalid : lookup(0) and invalid(2) all 4 rows
// cache_hit_invalid : lookup(0) and invalid(2) the hited(1) row
typedef enum bit [1:0] { typedef enum bit [1:0] {
IFC_LOOKUP, // deal with current request IFC_LOOKUP, // deal with current request
// read if non-cached or not hited // read if non-cached or not hited
@ -213,8 +220,8 @@ module MU (
end end
IFC_READ: begin IFC_READ: begin
icache.index = stored_instfetch_addr[`IC_TAGL-1:`IC_INDEXL];
icache.index_for_lookup = stored_instfetch_addr[`IC_TAGL-1:`IC_INDEXL]; icache.index_for_lookup = stored_instfetch_addr[`IC_TAGL-1:`IC_INDEXL];
icache.index = stored_instfetch_addr[`IC_TAGL-1:`IC_INDEXL];
if (ai_done) begin if (ai_done) begin
ifc_nxt_state = IFC_LOOKUP; ifc_nxt_state = IFC_LOOKUP;
out_if_valid = 1'b1; out_if_valid = 1'b1;
@ -226,10 +233,11 @@ module MU (
// To CPU // To CPU
if_source_select_direct = 0; if_source_select_direct = 0;
if_source_data = ai_buffer; if_source_data = ai_buffer;
if_wait_cache = 1; // Cache require one more cycle // NOTE: <<< if_wait_cache = 1; // Cache require one more cycle
end else begin end else begin
// un-cached: return to CPU and receive next req // un-cached: return to CPU and receive next req
in_if_ready = 1'b1; // NOTE: <<< in_if_ready = 1'b1;
icache.index_for_lookup = instfetch.addr[`IC_TAGL-1:`IC_INDEXL];
if_source_select_direct = 1'b1; if_source_select_direct = 1'b1;
if_source_data = ai_buffer; if_source_data = ai_buffer;
end end
@ -343,12 +351,13 @@ module MU (
ffen #(3) memsize_store (.*, .d({1'b0, memory.size}), .en(in_mem_ready), .q(stored_memory_size)); ffen #(3) memsize_store (.*, .d({1'b0, memory.size}), .en(in_mem_ready), .q(stored_memory_size));
ffen #(`XLEN) memaddr_store (.*, .d(memory.addr), .en(in_mem_ready), .q(stored_memory_addr)); ffen #(`XLEN) memaddr_store (.*, .d(memory.addr), .en(in_mem_ready), .q(stored_memory_addr));
logic mem_store_winfo;
logic stored_memory_wr; logic stored_memory_wr;
logic [3:0] stored_memory_wstrb; logic [3:0] stored_memory_wstrb;
word_t stored_memory_wdata; word_t stored_memory_wdata;
ffen #(1) memwr_store (.*, .d(memory.wr), .en(mem_req), .q(stored_memory_wr)); ffen #(1) memwr_store (.*, .d(memory.wr), .en(mem_store_winfo), .q(stored_memory_wr));
ffen #(4) memwstrb_store (.*, .d(memory.wstrb), .en(mem_req), .q(stored_memory_wstrb)); ffen #(4) memwstrb_store (.*, .d(memory.wstrb), .en(mem_store_winfo), .q(stored_memory_wstrb));
ffen #(`XLEN) memwdata_store (.*, .d(memory.wdata), .en(mem_req), .q(stored_memory_wdata)); ffen #(`XLEN) memwdata_store (.*, .d(memory.wdata), .en(mem_store_winfo), .q(stored_memory_wdata));
logic stored_mem_handshake; logic stored_mem_handshake;
ffenr #(1) mem_handshake_store (.*, .d(in_mem_valid), .en(in_mem_ready), .q(stored_mem_handshake)); ffenr #(1) mem_handshake_store (.*, .d(in_mem_valid), .en(in_mem_ready), .q(stored_mem_handshake));
@ -412,6 +421,7 @@ module MU (
mem_wdata_source_data = dcache.hit_row; mem_wdata_source_data = dcache.hit_row;
mem_wdata_data = stored_memory_wdata; mem_wdata_data = stored_memory_wdata;
mem_wstrb_direct = 0; mem_wstrb_direct = 0;
mem_store_winfo = 0;
// AXI Data Read // AXI Data Read
amr_call = 0; amr_call = 0;
@ -467,7 +477,7 @@ module MU (
dcache.ctrl.write_and_hit = 1'b1; dcache.ctrl.write_and_hit = 1'b1;
dcache.index_for_lookup = stored_memory_addr[`DC_TAGL-1:`DC_INDEXL]; dcache.index_for_lookup = stored_memory_addr[`DC_TAGL-1:`DC_INDEXL];
dcache.index = dcache.index_for_lookup; // stored_memory_addr[`DC_TAGL-1:`DC_INDEXL]; dcache.index = stored_memory_addr[`DC_TAGL-1:`DC_INDEXL];
mem_wstrb_direct = 1'b1; // wstrb is provided in stage M mem_wstrb_direct = 1'b1; // wstrb is provided in stage M
mem_wdata_source_data = dcache.hit_row; mem_wdata_source_data = dcache.hit_row;
@ -476,6 +486,7 @@ module MU (
end end
end else if (mem_req) begin end else if (mem_req) begin
// Handle Non-Cached or Miss // Handle Non-Cached or Miss
mem_store_winfo = 1'b1;
if (~memory_cached) begin if (~memory_cached) begin
if (~memory.wr) begin if (~memory.wr) begin
// non-cached read // non-cached read
@ -561,6 +572,7 @@ module MU (
end else begin end else begin
// uncached read // uncached read
in_mem_ready = 1'b1; in_mem_ready = 1'b1;
dcache.index_for_lookup = memory.addr[`DC_TAGL-1:`DC_INDEXL];
mem_rdata_select_direct = 1'b1; mem_rdata_select_direct = 1'b1;
mem_rdata_source_data = amr_buffer; mem_rdata_source_data = amr_buffer;
end end
@ -598,6 +610,7 @@ module MU (
// to CPU // to CPU
out_mem_valid = 1'b1; out_mem_valid = 1'b1;
in_mem_ready = 1'b1; in_mem_ready = 1'b1;
dcache.index_for_lookup = memory.addr[`DC_TAGL-1:`DC_INDEXL];
end end
end end
@ -610,8 +623,9 @@ module MU (
dcache.tag = memory_phy_addr[`XLEN-1:`DC_TAGL]; dcache.tag = memory_phy_addr[`XLEN-1:`DC_TAGL];
if (~stored_cacheop_op.writeback) begin if (~stored_cacheop_op.writeback) begin
mem_nxt_state = MEM_LOOKUP; mem_nxt_state = MEM_LOOKUP;
cop_d_ok = 1'b1; cop_d_ok = 1'b1;
mem_wait_cache = 1'b1;
dcache.ctrl.cache_index_invalidate = ~stored_cacheop_op.index_or_hit; dcache.ctrl.cache_index_invalidate = ~stored_cacheop_op.index_or_hit;
dcache.ctrl.cache_hit_invalidate = stored_cacheop_op.index_or_hit; dcache.ctrl.cache_hit_invalidate = stored_cacheop_op.index_or_hit;
@ -632,8 +646,9 @@ module MU (
amw_data = dcache.dirt_row; amw_data = dcache.dirt_row;
end else begin end else begin
mem_nxt_state = MEM_LOOKUP; mem_nxt_state = MEM_LOOKUP;
cop_d_ok = 1'b1; cop_d_ok = 1'b1;
mem_wait_cache = 1'b1;
end end
end end
end end
@ -701,8 +716,8 @@ module MU (
); );
logic choose_cop_i, choose_cop_d; logic choose_cop_i, choose_cop_d;
assign choose_cop_i = (ifc_cur_state == IFC_LOOKUP) & cop_i_req & ~stored_if_handshake; assign choose_cop_i = ifc_cur_state == IFC_CACHE_INVALID | ifc_nxt_state == IFC_CACHE_INVALID;
assign choose_cop_d = (mem_cur_state == MEM_LOOKUP) & cop_d_req & ~stored_mem_handshake; assign choose_cop_d = mem_cur_state == MEM_CACHE_INVALID | mem_nxt_state == MEM_CACHE_INVALID;
// TODO: Cache OP // TODO: Cache OP
// TLBL: Always // TLBL: Always
@ -723,7 +738,6 @@ module MU (
// memory // memory
assign dVA = choose_cop_d ? cacheop.addr : (memory.req & mem_nxt_state == MEM_LOOKUP ? memory.addr : stored_memory_addr); assign dVA = choose_cop_d ? cacheop.addr : (memory.req & mem_nxt_state == MEM_LOOKUP ? memory.addr : stored_memory_addr);
assign memory_phy_addr = dPA1; assign memory_phy_addr = dPA1;
// TODO: should memory.wr be stored?
assign memory_valid = dHit1 & dMValid1 & (cp0.cp0_in_kernel | dUser1) & (~memory.wr | dDirty1); assign memory_valid = dHit1 & dMValid1 & (cp0.cp0_in_kernel | dUser1) & (~memory.wr | dDirty1);
assign memory_cached = dCached1; assign memory_cached = dCached1;

View File

@ -1,8 +1,20 @@
`ifndef DEFINES_SVH `ifndef DEFINES_SVH
`define DEFINES_SVH `define DEFINES_SVH
`define ILA_DEBUG
`define ENABLE_CACHEOP
`define ENABLE_TLB `define ENABLE_TLB
`define ENABLE_CpU `define ENABLE_CpU
`define ENABLE_TRAP
`ifdef SIMULATION_VERILATOR
`undef ENABLE_CpU
`endif
`ifndef ENABLE_CACHEOP
`undef ENABLE_TLB
`endif
`define XLEN 32 `define XLEN 32
`define PCRST 32'hBFC00000 `define PCRST 32'hBFC00000
@ -128,15 +140,17 @@ typedef struct packed {
} MCtrl0_t; } MCtrl0_t;
typedef struct packed { typedef struct packed {
logic MR; // critical logic MR; // critical
logic MWR; // critical logic MWR; // critical
logic MX; logic MX;
ALR_t ALR; // critical ALR_t ALR; // critical
logic [1:0] SZ; logic [1:0] SZ;
logic TLBWI; // critical `ifdef ENABLE_TLB
logic TLBWR; // critical logic TLBWI; // critical
logic TLBR; // critical logic TLBWR; // critical
logic TLBP; // critical logic TLBR; // critical
logic TLBP; // critical
`endif
CacheOp_t CACHE_OP; // critical CacheOp_t CACHE_OP; // critical
} MCtrl1_t; } MCtrl1_t;
@ -146,7 +160,7 @@ typedef struct packed {
} Trap_t; } Trap_t;
typedef struct packed { typedef struct packed {
logic RW; // critical logic RW; // critical
} WCtrl_t; } WCtrl_t;
typedef struct packed { typedef struct packed {
@ -176,7 +190,9 @@ typedef struct packed {
MCtrl0_t MCtrl0; MCtrl0_t MCtrl0;
MCtrl1_t MCtrl1; MCtrl1_t MCtrl1;
`ifdef ENABLE_TRAP
Trap_t Trap; Trap_t Trap;
`endif
logic [4:0] RD; logic [4:0] RD;
WCtrl_t WCtrl; WCtrl_t WCtrl;
@ -271,7 +287,9 @@ typedef struct packed {
ECtrl_t ECtrl; ECtrl_t ECtrl;
MCtrl1_t MCtrl; MCtrl1_t MCtrl;
`ifdef ENABLE_TRAP
Trap_t Trap; Trap_t Trap;
`endif
logic [4:0] RD; logic [4:0] RD;
WCtrl_t WCtrl; WCtrl_t WCtrl;
@ -334,7 +352,9 @@ typedef struct packed {
word_t ALUOut; word_t ALUOut;
MCtrl1_t MCtrl; MCtrl1_t MCtrl;
`ifdef ENABLE_TRAP
Trap_t Trap; Trap_t Trap;
`endif
logic [4:0] RD; logic [4:0] RD;
WCtrl_t WCtrl; WCtrl_t WCtrl;
@ -387,7 +407,9 @@ typedef struct packed {
word_t ALUOut; word_t ALUOut;
MCtrl1_t MCtrl; MCtrl1_t MCtrl;
`ifdef ENABLE_TRAP
Trap_t Trap; Trap_t Trap;
`endif
word_t RDataW; word_t RDataW;
logic [4:0] RD; logic [4:0] RD;