Merge remote-tracking branch 'origin/next' into 2alu
This commit is contained in:
commit
0183c129bf
321
resources/soft/func/inst/n102_memory.S
Normal file
321
resources/soft/func/inst/n102_memory.S
Normal 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)
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include <utils.h>
|
||||
|
||||
#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)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -79,19 +79,23 @@ 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[31] & ~inst[29] & ~inst[28] & ~inst[27] & (~inst[30] & ~inst[26] & inst[5] & inst[4] | inst[26] & 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.WCtrl.RW = ctrl.RD != 5'b00000 & (~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]));
|
||||
`endif
|
||||
|
||||
endmodule
|
||||
|
@ -648,7 +648,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;
|
||||
|
||||
@ -836,6 +838,7 @@ module Datapath (
|
||||
~D_go | ~D_I1_go,
|
||||
E.I1.MCtrl
|
||||
);
|
||||
`ifdef ENABLE_TRAP
|
||||
ffenrc #(3) E_I1_Trap_ff (
|
||||
clk,
|
||||
rst | rstM,
|
||||
@ -844,6 +847,7 @@ module Datapath (
|
||||
~D_go | ~D_I1_go,
|
||||
E.I1.Trap
|
||||
);
|
||||
`endif
|
||||
ffenrc #(5 + 1) E_I1_WCtrl_ff (
|
||||
clk,
|
||||
rst | rstM,
|
||||
@ -1160,6 +1164,7 @@ module Datapath (
|
||||
~E_go | ~E_I1_go,
|
||||
M.I1.MCtrl
|
||||
);
|
||||
`ifdef ENABLE_TRAP
|
||||
ffenrc #(3) M_I1_Trap_ff (
|
||||
clk,
|
||||
rst | rstM,
|
||||
@ -1168,6 +1173,7 @@ module Datapath (
|
||||
~E_go | ~E_I1_go,
|
||||
M.I1.Trap
|
||||
);
|
||||
`endif
|
||||
ffenrc #(5 + 1) M_I1_WCtrl_ff (
|
||||
clk,
|
||||
rst | rstM,
|
||||
@ -1418,11 +1424,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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
54
src/MU/MU.sv
54
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
|
||||
@ -612,6 +625,7 @@ module MU (
|
||||
if (~stored_cacheop_op.writeback) begin
|
||||
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;
|
||||
@ -634,6 +648,7 @@ module MU (
|
||||
end else begin
|
||||
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;
|
||||
|
||||
|
@ -1,8 +1,20 @@
|
||||
`ifndef DEFINES_SVH
|
||||
`define DEFINES_SVH
|
||||
|
||||
`define ILA_DEBUG
|
||||
|
||||
`define ENABLE_CACHEOP
|
||||
`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 PCRST 32'hBFC00000
|
||||
@ -133,10 +145,12 @@ typedef struct packed {
|
||||
logic MX;
|
||||
ALR_t ALR; // critical
|
||||
logic [1:0] SZ;
|
||||
`ifdef ENABLE_TLB
|
||||
logic TLBWI; // critical
|
||||
logic TLBWR; // critical
|
||||
logic TLBR; // critical
|
||||
logic TLBP; // critical
|
||||
`endif
|
||||
CacheOp_t CACHE_OP; // critical
|
||||
} MCtrl1_t;
|
||||
|
||||
@ -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;
|
||||
@ -272,7 +288,9 @@ typedef struct packed {
|
||||
ECtrl_t ECtrl;
|
||||
|
||||
MCtrl1_t MCtrl;
|
||||
`ifdef ENABLE_TRAP
|
||||
Trap_t Trap;
|
||||
`endif
|
||||
|
||||
logic [4:0] RD;
|
||||
WCtrl_t WCtrl;
|
||||
@ -336,7 +354,9 @@ typedef struct packed {
|
||||
word_t ALUOut;
|
||||
|
||||
MCtrl1_t MCtrl;
|
||||
`ifdef ENABLE_TRAP
|
||||
Trap_t Trap;
|
||||
`endif
|
||||
|
||||
logic [4:0] RD;
|
||||
WCtrl_t WCtrl;
|
||||
@ -397,7 +417,9 @@ typedef struct packed {
|
||||
word_t ALUOut;
|
||||
|
||||
MCtrl1_t MCtrl;
|
||||
`ifdef ENABLE_TRAP
|
||||
Trap_t Trap;
|
||||
`endif
|
||||
word_t RDataW;
|
||||
|
||||
logic [4:0] RD;
|
||||
|
Loading…
Reference in New Issue
Block a user