From 02f04a2bf39cec4bd74e8ff47ee5aa400364142d Mon Sep 17 00:00:00 2001 From: Paul Pan Date: Wed, 3 Aug 2022 14:26:44 +0800 Subject: [PATCH] Update MU and DCache --- resources/soft/func/inst/n102_memory.S | 321 +++++++++++++++++++++++++ resources/soft/func/start.S | 8 +- sim/Makefile | 2 +- src/Core/Controller.sv | 6 +- src/Core/Datapath.sv | 20 +- src/Core/Gadgets/decoder2.sv | 6 + src/MU/AXIWriter.sv | 2 +- src/MU/DCache.sv | 3 +- src/MU/MU.sv | 62 +++-- src/include/defines.svh | 38 ++- 10 files changed, 424 insertions(+), 44 deletions(-) create mode 100644 resources/soft/func/inst/n102_memory.S diff --git a/resources/soft/func/inst/n102_memory.S b/resources/soft/func/inst/n102_memory.S new file mode 100644 index 0000000..a730f8a --- /dev/null +++ b/resources/soft/func/inst/n102_memory.S @@ -0,0 +1,321 @@ +#include +#include +#include + +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) diff --git a/resources/soft/func/start.S b/resources/soft/func/start.S index 0384199..2725f6d 100644 --- a/resources/soft/func/start.S +++ b/resources/soft/func/start.S @@ -4,7 +4,7 @@ #include -#define TEST_NUM 150 +#define TEST_NUM 152 ##s0, number @@ -420,9 +420,11 @@ inst_test: TEST_UNIT(n98_cache_dcache_test) # 146 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 LI (a0, IO_SIMU_ADDR) diff --git a/sim/Makefile b/sim/Makefile index 6d115db..781f5f8 100644 --- a/sim/Makefile +++ b/sim/Makefile @@ -63,7 +63,7 @@ verilate: func_build: verilate make -C obj_dir -f Vtestbench_top.mk -j -func_coverage: func_build +func_coverage: @rm -rf logs/annotated $(VERILATOR_COVERAGE) $(VERILATOR_COV_FLAGS) diff --git a/src/Core/Controller.sv b/src/Core/Controller.sv index df742f5..57c2913 100644 --- a/src/Core/Controller.sv +++ b/src/Core/Controller.sv @@ -78,20 +78,24 @@ 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 ENABLE_TLB 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]; +`endif 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.index_or_hit = inst[20]; 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.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 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; diff --git a/src/Core/Datapath.sv b/src/Core/Datapath.sv index 0253405..3c4b145 100644 --- a/src/Core/Datapath.sv +++ b/src/Core/Datapath.sv @@ -623,7 +623,9 @@ module Datapath ( 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.MCtrl = D.A ? D.IA.MCtrl1 : D.IB.MCtrl1; +`ifdef ENABLE_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.WCtrl = D.A ? D.IA.WCtrl : D.IB.WCtrl; @@ -811,6 +813,7 @@ module Datapath ( ~D_go | ~D_I1_go, E.I1.MCtrl ); +`ifdef ENABLE_TRAP ffenrc #(3) E_I1_Trap_ff ( clk, rst | rstM, @@ -819,6 +822,7 @@ module Datapath ( ~D_go | ~D_I1_go, E.I1.Trap ); +`endif ffenrc #(5 + 1) E_I1_WCtrl_ff ( clk, rst | rstM, @@ -943,11 +947,11 @@ module Datapath ( E_I1_STRBERROR ); - assign C0.cpu_tlb_tlbp = E.I1.MCtrl.TLBP; - assign mem.req = E.I1.MCtrl.MR & E_I1_goWithoutOF & M.en & ~rstM; - 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.size = {E.I1.MCtrl.SZ[1], E.I1.MCtrl.SZ[0] & ~E.I1.MCtrl.SZ[1]}; + assign C0.cpu_tlb_tlbp = E.I1.MCtrl.TLBP; + assign mem.req = E.I1.MCtrl.MR & E_I1_goWithoutOF & M.en & ~rstM; + 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.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.op = E.I1.MCtrl.CACHE_OP; @@ -1113,6 +1117,7 @@ module Datapath ( ~E_go | ~E_I1_go, M.I1.MCtrl ); +`ifdef ENABLE_TRAP ffenrc #(3) M_I1_Trap_ff ( clk, rst | rstM, @@ -1121,6 +1126,7 @@ module Datapath ( ~E_go | ~E_I1_go, M.I1.Trap ); +`endif ffenrc #(5 + 1) M_I1_WCtrl_ff ( clk, rst | rstM, @@ -1341,11 +1347,15 @@ module Datapath ( ); // M.I1.TRAP +`ifdef ENABLE_TRAP 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 == LT ? M.I1.ALUOut[0] == 1'b1 : M.I1.Trap.TP == GE ? M.I1.ALUOut[0] == 1'b0 : 1'b0); +`else + assign M_I1_Trap = 1'b0; +`endif assign M.en = M_go & W.en; assign M_go = (M.I0.MCtrl.HLS[2:1] != 2'b10 | M_I0_MULT_bvalid) diff --git a/src/Core/Gadgets/decoder2.sv b/src/Core/Gadgets/decoder2.sv index e3646cc..b23241b 100644 --- a/src/Core/Gadgets/decoder2.sv +++ b/src/Core/Gadgets/decoder2.sv @@ -53,20 +53,24 @@ module decoder2 ( 32'b000000???????????????00000100111: ri = 1'b0; // NOR 32'b000000???????????????00000101010: ri = 1'b0; // SLT 32'b000000???????????????00000101011: ri = 1'b0; // SLTU +`ifdef ENABLE_TRAP 32'b000000????????????????????110000: ri = 1'b0; // TGE 32'b000000????????????????????110001: ri = 1'b0; // TGEU 32'b000000????????????????????110010: ri = 1'b0; // TLT 32'b000000????????????????????110011: ri = 1'b0; // TLTU 32'b000000????????????????????110100: ri = 1'b0; // TEQ 32'b000000????????????????????110110: ri = 1'b0; // TNE +`endif 32'b000001?????00000????????????????: ri = 1'b0; // BLTZ 32'b000001?????00001????????????????: ri = 1'b0; // BGEZ +`ifdef ENABLE_TRAP 32'b000001?????01000????????????????: ri = 1'b0; // TGEI 32'b000001?????01001????????????????: ri = 1'b0; // TGEIU 32'b000001?????01010????????????????: ri = 1'b0; // TLTI 32'b000001?????01011????????????????: ri = 1'b0; // TLTIU 32'b000001?????01110????????????????: ri = 1'b0; // TNEI 32'b000001?????01100????????????????: ri = 1'b0; // TEQI +`endif 32'b000001?????10000????????????????: ri = 1'b0; // BLTZAL 32'b000001?????10001????????????????: ri = 1'b0; // BGEZAL 32'b000010??????????????????????????: ri = 1'b0; // J @@ -108,6 +112,7 @@ module decoder2 ( 32'b101010??????????????????????????: ri = 1'b0; // SWL 32'b101011??????????????????????????: ri = 1'b0; // SW 32'b101110??????????????????????????: ri = 1'b0; // SWR +`ifdef ENABLE_CACHEOP 32'b101111?????00000????????????????: ri = 1'b0; // I-Cache Index Invalid 32'b101111?????01000????????????????: ri = 1'b0; // I-Cache Index Store Tag 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?????10001????????????????: ri = 1'b0; // D-Cache Hit 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'b110011??????????????????????????: ri = 1'b0; // PREF (NOP) // 32'b111000??????????????????????????: begin cpu = 1'b1; ce = 2'b0; end // SC (CpU) diff --git a/src/MU/AXIWriter.sv b/src/MU/AXIWriter.sv index e5da022..4743399 100644 --- a/src/MU/AXIWriter.sv +++ b/src/MU/AXIWriter.sv @@ -32,7 +32,7 @@ module AXIWriter #(parameter DATA_LEN = 8) logic [3:0] data_cntr; 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; typedef enum bit [1:0] { DIDLE, DATA } data_state_t; diff --git a/src/MU/DCache.sv b/src/MU/DCache.sv index 7e68089..590d916 100644 --- a/src/MU/DCache.sv +++ b/src/MU/DCache.sv @@ -69,7 +69,8 @@ module DCache ( : 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[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[1].valid == 0 ? 4'b0010 : tag[2].valid == 0 ? 4'b0100 diff --git a/src/MU/MU.sv b/src/MU/MU.sv index 6eefa3f..6613e3e 100644 --- a/src/MU/MU.sv +++ b/src/MU/MU.sv @@ -20,19 +20,26 @@ module MU ( // == CacheOp == // ============= - // NOTE: req and op and addr should be kept until addr_ok logic cop_i_req, cop_d_req; 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_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.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; CacheOp_t stored_cacheop_op; 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 #(`CACHEOP_T_LEN) cacheop_op_store (.*, .d(cacheop.op), .en(cacheop.req & cacheop.addr_ok), .q(stored_cacheop_op)); ffenr #(2) cacheop_req_store ( @@ -44,6 +51,13 @@ module MU ( ); 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 == @@ -94,7 +108,6 @@ module MU ( // =============== logic if_req, if_wait_cache; - // NOTE: TLB Check word_t stored_instfetch_addr; 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)); @@ -122,12 +135,6 @@ module MU ( // == 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] { IFC_LOOKUP, // deal with current request // read if non-cached or not hited @@ -213,8 +220,8 @@ module MU ( end 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 = stored_instfetch_addr[`IC_TAGL-1:`IC_INDEXL]; if (ai_done) begin ifc_nxt_state = IFC_LOOKUP; out_if_valid = 1'b1; @@ -226,10 +233,11 @@ module MU ( // To CPU if_source_select_direct = 0; 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 // 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_data = ai_buffer; 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 #(`XLEN) memaddr_store (.*, .d(memory.addr), .en(in_mem_ready), .q(stored_memory_addr)); + logic mem_store_winfo; logic stored_memory_wr; logic [3:0] stored_memory_wstrb; word_t stored_memory_wdata; - ffen #(1) memwr_store (.*, .d(memory.wr), .en(mem_req), .q(stored_memory_wr)); - ffen #(4) memwstrb_store (.*, .d(memory.wstrb), .en(mem_req), .q(stored_memory_wstrb)); - ffen #(`XLEN) memwdata_store (.*, .d(memory.wdata), .en(mem_req), .q(stored_memory_wdata)); + ffen #(1) memwr_store (.*, .d(memory.wr), .en(mem_store_winfo), .q(stored_memory_wr)); + ffen #(4) memwstrb_store (.*, .d(memory.wstrb), .en(mem_store_winfo), .q(stored_memory_wstrb)); + ffen #(`XLEN) memwdata_store (.*, .d(memory.wdata), .en(mem_store_winfo), .q(stored_memory_wdata)); logic 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_data = stored_memory_wdata; mem_wstrb_direct = 0; + mem_store_winfo = 0; // AXI Data Read amr_call = 0; @@ -467,7 +477,7 @@ module MU ( dcache.ctrl.write_and_hit = 1'b1; 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_wdata_source_data = dcache.hit_row; @@ -476,6 +486,7 @@ module MU ( end end else if (mem_req) begin // Handle Non-Cached or Miss + mem_store_winfo = 1'b1; if (~memory_cached) begin if (~memory.wr) begin // non-cached read @@ -561,6 +572,7 @@ module MU ( end else begin // uncached read in_mem_ready = 1'b1; + dcache.index_for_lookup = memory.addr[`DC_TAGL-1:`DC_INDEXL]; mem_rdata_select_direct = 1'b1; mem_rdata_source_data = amr_buffer; end @@ -598,6 +610,7 @@ module MU ( // to CPU out_mem_valid = 1'b1; in_mem_ready = 1'b1; + dcache.index_for_lookup = memory.addr[`DC_TAGL-1:`DC_INDEXL]; end end @@ -610,8 +623,9 @@ module MU ( dcache.tag = memory_phy_addr[`XLEN-1:`DC_TAGL]; if (~stored_cacheop_op.writeback) begin - mem_nxt_state = MEM_LOOKUP; - cop_d_ok = 1'b1; + mem_nxt_state = MEM_LOOKUP; + cop_d_ok = 1'b1; + mem_wait_cache = 1'b1; dcache.ctrl.cache_index_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; end else begin - mem_nxt_state = MEM_LOOKUP; - cop_d_ok = 1'b1; + mem_nxt_state = MEM_LOOKUP; + cop_d_ok = 1'b1; + mem_wait_cache = 1'b1; end end end @@ -701,8 +716,8 @@ module MU ( ); 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_d = (mem_cur_state == MEM_LOOKUP) & cop_d_req & ~stored_mem_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_CACHE_INVALID | mem_nxt_state == MEM_CACHE_INVALID; // TODO: Cache OP // TLBL: Always @@ -723,7 +738,6 @@ module MU ( // memory assign dVA = choose_cop_d ? cacheop.addr : (memory.req & mem_nxt_state == MEM_LOOKUP ? memory.addr : stored_memory_addr); 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_cached = dCached1; diff --git a/src/include/defines.svh b/src/include/defines.svh index f0a26fc..d141cbd 100644 --- a/src/include/defines.svh +++ b/src/include/defines.svh @@ -1,8 +1,20 @@ `ifndef DEFINES_SVH `define DEFINES_SVH +`define ILA_DEBUG + +`define ENABLE_CACHEOP `define ENABLE_TLB `define ENABLE_CpU +`define ENABLE_TRAP + +`ifdef SIMULATION_VERILATOR + `undef ENABLE_CpU +`endif + +`ifndef ENABLE_CACHEOP + `undef ENABLE_TLB +`endif `define XLEN 32 `define PCRST 32'hBFC00000 @@ -128,15 +140,17 @@ typedef struct packed { } MCtrl0_t; typedef struct packed { - logic MR; // critical - logic MWR; // critical + logic MR; // critical + logic MWR; // critical logic MX; - ALR_t ALR; // critical + ALR_t ALR; // critical logic [1:0] SZ; - logic TLBWI; // critical - logic TLBWR; // critical - logic TLBR; // critical - logic TLBP; // critical +`ifdef ENABLE_TLB + logic TLBWI; // critical + logic TLBWR; // critical + logic TLBR; // critical + logic TLBP; // critical +`endif CacheOp_t CACHE_OP; // critical } MCtrl1_t; @@ -146,7 +160,7 @@ typedef struct packed { } Trap_t; typedef struct packed { - logic RW; // critical + logic RW; // critical } WCtrl_t; typedef struct packed { @@ -176,7 +190,9 @@ typedef struct packed { MCtrl0_t MCtrl0; MCtrl1_t MCtrl1; +`ifdef ENABLE_TRAP Trap_t Trap; +`endif logic [4:0] RD; WCtrl_t WCtrl; @@ -271,7 +287,9 @@ typedef struct packed { ECtrl_t ECtrl; MCtrl1_t MCtrl; +`ifdef ENABLE_TRAP Trap_t Trap; +`endif logic [4:0] RD; WCtrl_t WCtrl; @@ -334,7 +352,9 @@ typedef struct packed { word_t ALUOut; MCtrl1_t MCtrl; +`ifdef ENABLE_TRAP Trap_t Trap; +`endif logic [4:0] RD; WCtrl_t WCtrl; @@ -387,7 +407,9 @@ typedef struct packed { word_t ALUOut; MCtrl1_t MCtrl; +`ifdef ENABLE_TRAP Trap_t Trap; +`endif word_t RDataW; logic [4:0] RD;