Test Passed? maybe

1. fix timing loop
2. fix multi driven
3. fix CACHE I-Cache Index logic
4. fix testcase
This commit is contained in:
Paul Pan 2021-09-04 16:31:25 +08:00
parent fa0c8ece07
commit e08ded2242
8 changed files with 128 additions and 77 deletions

View File

@ -8,22 +8,49 @@ LEAF(n99_cache_icache_test)
li s2, 0x0 li s2, 0x0
###test inst ###test inst
.n99_1_prepare:
addi a1, zero, 0
.n99_1: .n99_1:
addi a0, zero, 0
.n99_1_replace:
nop # will be replaced with "addi a0, a0, 1" -> 20840001
bne a0, a1, inst_error
nop
bne a1, zero, .n99_2_prepare # jump out 2nd
nop
addi a1, a1, 1
.n99_1_work:
la v0, .n99_1_replace la v0, .n99_1_replace
li v1, 0x20840001 li v1, 0x20840001
li t0, 0x20000000
subu v0, v0, t0 # v0 <- 9fcxxxxx
sw v1, 0(v0) sw v1, 0(v0)
cache 21, 0(v0) # D-Cache Hit WriteBack Invalid cache 21, 0(v0) # D-Cache Hit WriteBack Invalid
cache 16, 0(v0) # I-Cache Hit Invalid cache 16, 0(v0) # I-Cache Hit Invalid
addi a0, zero, 0 # TODO: clear Datapath on CACHE
addi a1, zero, 1 # using enough nop to stop prefetch
.n99_1_replace: nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop
nop # line will be replaced with "addi a0, a0, 1" -> 20840001 nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop
bne a0, a1, inst_error j .n99_1
nop nop
.n99_2_prepare:
addi a1, zero, 0
.n99_2: .n99_2:
addi a0, zero, 0
.n99_2_replace:
nop # will be replaced with "addi a0, a0, 1" -> 20840001
bne a0, a1, inst_error
nop
bne a1, zero, .n99_3_prepare # jump out 2nd
nop
addi a1, a1, 1
.n99_2_work:
la v0, .n99_2_replace la v0, .n99_2_replace
li v1, 0x20840001 li v1, 0x20840001
li t0, 0x20000000
subu v0, v0, t0
sw v1, 0(v0) sw v1, 0(v0)
cache 21, 0(v0) # D-Cache Hit WriteBack Invalid cache 21, 0(v0) # D-Cache Hit WriteBack Invalid
addi t0, zero, 0 addi t0, zero, 0
@ -31,21 +58,35 @@ LEAF(n99_cache_icache_test)
.n99_2_loop: .n99_2_loop:
beq t0, t1, .n99_2_check beq t0, t1, .n99_2_check
nop nop
add v0, t0, zero cache 0, 0(t0) # I-Cache Index Invalid
cache 0, 0(v0) # I-Cache Index Invalid
addi t0, t0, 1 addi t0, t0, 1
j .n99_2_loop j .n99_2_loop
nop
.n99_2_check: .n99_2_check:
addi a0, zero, 0 # TODO: clear Datapath on CACHE
addi a1, zero, 1 # using enough nop to stop prefetch
.n99_2_replace: nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop
nop # line will be replaced with "addi a0, a0, 1" -> 20840001 nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop
bne a0, a1, inst_error j .n99_2
nop nop
.n99_3_prepare:
addi a1, zero, 0
.n99_3: .n99_3:
addi a0, zero, 0
.n99_3_replace:
nop # will be replaced with "addi a0, a0, 1" -> 20840001
bne a0, a1, inst_error
nop
bne a1, zero, .n99_success # jump out 2nd
nop
addi a1, a1, 1
.n99_3_work:
la v0, .n99_3_replace la v0, .n99_3_replace
li v1, 0x20840001 li v1, 0x20840001
li t0, 0x20000000
subu v0, v0, t0
sw v1, 0(v0) sw v1, 0(v0)
cache 21, 0(v0) # D-Cache Hit WriteBack Invalid cache 21, 0(v0) # D-Cache Hit WriteBack Invalid
addi t0, zero, 0 addi t0, zero, 0
@ -53,16 +94,19 @@ LEAF(n99_cache_icache_test)
.n99_3_loop: .n99_3_loop:
beq t0, t1, .n99_3_check beq t0, t1, .n99_3_check
nop nop
add v0, t0, zero cache 0, 0(t0) # I-Cache Index Invalid
cache 8, 0(v0) # I-Cache Index Store Tag
addi t0, t0, 1 addi t0, t0, 1
j .n99_3_loop j .n99_3_loop
nop
.n99_3_check: .n99_3_check:
addi a0, zero, 0 # TODO: clear Datapath on CACHE
addi a1, zero, 1 # using enough nop to stop prefetch
.n99_3_replace: nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop
nop # line will be replaced with "addi a0, a0, 1" -> 20840001 nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop
bne a0, a1, inst_error j .n99_3
nop
.n99_success:
nop nop
###detect exception ###detect exception

View File

@ -299,6 +299,26 @@ inst_test:
nop ##### nop #####
kseg0_kseg1: kseg0_kseg1:
jal n98_cache_dcache_test
nop
jal wait_1s
nop
la t1, n99_kseg1_kseg0
li t2, 0x20000000
subu t9, t1, t2
jr t9
nop
n99_kseg1_kseg0:
jal n99_cache_icache_test
nop
jal wait_1s
nop
la t9, n99_kseg0_kseg1
jr t9
nop
n99_kseg0_kseg1:
jal n2_addu_test #addu jal n2_addu_test #addu
nop nop
jal wait_1s jal wait_1s
@ -683,25 +703,6 @@ kseg0_kseg1:
nop nop
jal wait_1s jal wait_1s
nop nop
jal n98_cache_dcache_test
nop
jal wait_1s
nop
la t1, n99_kseg1_kseg0
li t2, 0x20000000
subu t9, t1, t2
jr t9
nop
n99_kseg1_kseg0:
jal n99_cache_icache_test
nop
jal wait_1s
nop
la t9, n99_kseg0_kseg1
jr t9
nop
n99_kseg0_kseg1:
###check io access ###check io access
LI (a0, IO_SIMU_ADDR) LI (a0, IO_SIMU_ADDR)

View File

@ -115,7 +115,7 @@ module CP0 (
rf_cp0.EntryLo0.V = 1'b0; rf_cp0.EntryLo0.V = 1'b0;
rf_cp0.EntryLo0.G = 1'b0; rf_cp0.EntryLo0.G = 1'b0;
rf_cp0.Index.P = 1'b0; rf_cp0.Index.P = 1'b0;
rf_cp0.Index.Index = 2'b0; rf_cp0.Index.Index = 3'b0;
rf_cp0.Random.Random = 3'b111; rf_cp0.Random.Random = 3'b111;
rf_cp0.EBase.EBase = 18'b0; rf_cp0.EBase.EBase = 18'b0;
@ -166,7 +166,7 @@ module CP0 (
9: rf_cp0.Count = wdata; 9: rf_cp0.Count = wdata;
8: rf_cp0.BadVAddr = wdata; 8: rf_cp0.BadVAddr = wdata;
// 7: rf_cp0.HWREna = wdata; // 7: rf_cp0.HWREna = wdata;
6: rf_cp0.Wired = wdata[2:0]; 6: rf_cp0.Wired = {29'b0, wdata[2:0]};
// 5: rf_cp0.PageMask.Mask = wdata[24:13]; // 5: rf_cp0.PageMask.Mask = wdata[24:13];
// 4: rf_cp0.Context = wdata; // 4: rf_cp0.Context = wdata;
3: begin 3: begin

View File

@ -241,10 +241,10 @@ module DCache (
assign DataRAM2.wen = (bwe1 & wen[2]) | (bwe2 & wen2[2]); assign DataRAM2.wen = (bwe1 & wen[2]) | (bwe2 & wen2[2]);
assign DataRAM3.wen = (bwe1 & wen[3]) | (bwe2 & wen2[3]); assign DataRAM3.wen = (bwe1 & wen[3]) | (bwe2 & wen2[3]);
// 写数据 // 写数据
assign TagRAM0.wdata = port.clear ? `DC_TAG_LENGTH'b0 : {port.tag1, port.wvalid, 1'b1}; assign TagRAM0.wdata = {port.tag1, port.wvalid, ~port.clear};
assign TagRAM1.wdata = port.clear ? `DC_TAG_LENGTH'b0 : {port.tag1, port.wvalid, 1'b1}; assign TagRAM1.wdata = {port.tag1, port.wvalid, ~port.clear};
assign TagRAM2.wdata = port.clear ? `DC_TAG_LENGTH'b0 : {port.tag1, port.wvalid, 1'b1}; assign TagRAM2.wdata = {port.tag1, port.wvalid, ~port.clear};
assign TagRAM3.wdata = port.clear ? `DC_TAG_LENGTH'b0 : {port.tag1, port.wvalid, 1'b1}; assign TagRAM3.wdata = {port.tag1, port.wvalid, ~port.clear};
assign DataRAM0.wdata = state == LOOKUP ? wdata1[0] : wdata2[0]; assign DataRAM0.wdata = state == LOOKUP ? wdata1[0] : wdata2[0];
assign DataRAM1.wdata = state == LOOKUP ? wdata1[1] : wdata2[1]; assign DataRAM1.wdata = state == LOOKUP ? wdata1[1] : wdata2[1];

View File

@ -176,23 +176,23 @@ module ICache (
assign DataRAM2.addr = baddr; assign DataRAM2.addr = baddr;
assign DataRAM3.addr = baddr; assign DataRAM3.addr = baddr;
// 写使能 // 写使能
assign TagRAM0.wen = bwe & wen2[0]; assign TagRAM0.wen = bwe & wen2[0] | port.clear & wen[0];
assign TagRAM1.wen = bwe & wen2[1]; assign TagRAM1.wen = bwe & wen2[1] | port.clear & wen[1];
assign TagRAM2.wen = bwe & wen2[2]; assign TagRAM2.wen = bwe & wen2[2] | port.clear & wen[2];
assign TagRAM3.wen = bwe & wen2[3]; assign TagRAM3.wen = bwe & wen2[3] | port.clear & wen[3];
assign DataRAM0.wen = bwe & wen2[0]; assign DataRAM0.wen = bwe & wen2[0] | port.clear & wen[0];
assign DataRAM1.wen = bwe & wen2[1]; assign DataRAM1.wen = bwe & wen2[1] | port.clear & wen[1];
assign DataRAM2.wen = bwe & wen2[2]; assign DataRAM2.wen = bwe & wen2[2] | port.clear & wen[2];
assign DataRAM3.wen = bwe & wen2[3]; assign DataRAM3.wen = bwe & wen2[3] | port.clear & wen[3];
// 写数据 // 写数据
assign TagRAM0.wdata = {port.tag1, 1'b1}; assign TagRAM0.wdata = {port.tag1, ~port.clear};
assign TagRAM1.wdata = {port.tag1, 1'b1}; assign TagRAM1.wdata = {port.tag1, ~port.clear};
assign TagRAM2.wdata = {port.tag1, 1'b1}; assign TagRAM2.wdata = {port.tag1, ~port.clear};
assign TagRAM3.wdata = {port.tag1, 1'b1}; assign TagRAM3.wdata = {port.tag1, ~port.clear};
assign DataRAM0.wdata = port.clear ? `IC_TAG_LENGTH'b0 : port.rdata; assign DataRAM0.wdata = port.rdata;
assign DataRAM1.wdata = port.clear ? `IC_TAG_LENGTH'b0 : port.rdata; assign DataRAM1.wdata = port.rdata;
assign DataRAM2.wdata = port.clear ? `IC_TAG_LENGTH'b0 : port.rdata; assign DataRAM2.wdata = port.rdata;
assign DataRAM3.wdata = port.clear ? `IC_TAG_LENGTH'b0 : port.rdata; assign DataRAM3.wdata = port.rdata;
ICTag_bram tag_ram0 ( ICTag_bram tag_ram0 (
.addra(TagRAM0.addr), .addra(TagRAM0.addr),

View File

@ -1,6 +1,8 @@
`include "defines.svh" `include "defines.svh"
`include "sram.svh" `include "sram.svh"
`include "CP0.svh" `include "CP0.svh"
`include "ICache.svh"
`include "DCache.svh"
module Datapath ( module Datapath (
input clk, input clk,

View File

@ -97,6 +97,10 @@ module MMU (
word_t iD1, iD2, iD3, iD4, iD5, iD6, iD7; word_t iD1, iD2, iD3, iD4, iD5, iD6, iD7;
logic diReq;
CacheOp_t cacheOp1, cacheOp2;
word_t dVA1;
// ================================ // ================================
// ======== iState Machine ======== // ======== iState Machine ========
// ================================ // ================================
@ -183,7 +187,7 @@ module MMU (
/* /*
* I-Cache Cache指令实现备注: * I-Cache Cache指令实现备注:
* I_CACHE iEn == 0 * I_CACHE iEn == 0
* I_CACHE iEn = 1 * I_CACHE iEn = 0
* Exceptions * Exceptions
* TLB iNextState == I_CACHE时发送 * TLB iNextState == I_CACHE时发送
* I-Cache iNextState == I_CACHE时发送 * I-Cache iNextState == I_CACHE时发送
@ -192,8 +196,9 @@ module MMU (
* drState * drState
*/ */
if (~iTLBRefill & ~iTLBInvalid & iCached1 & (ic.hit | cacheOp1[1])) ic.clear = 1; if (~iTLBRefill & ~iTLBInvalid & (iCached1 & ic.hit | cacheOp1[1])) ic.clear = 1;
iEn = 1; iEn = 0;
iEn2 = 1;
iNextState = I_IDLE; iNextState = I_IDLE;
end end
endcase endcase
@ -219,7 +224,7 @@ module MMU (
// ========== iFunction ========== // ========== iFunction ==========
// =============================== // ===============================
assign iVA = iNextState == I_CACHE ? data.addr : inst.addr; assign iVA = iNextState == I_CACHE ? dVA1 : inst.addr;
assign iValid1 = iReq1 & iHit1 & iMValid1 & (in_kernel | iUser1); assign iValid1 = iReq1 & iHit1 & iMValid1 & (in_kernel | iUser1);
assign inst.addr_ok = iEn; assign inst.addr_ok = iEn;
@ -234,12 +239,11 @@ module MMU (
); );
// I-Cache req on inst query or cache instruction // I-Cache req on inst query or cache instruction
assign ic.req = iEn | iNextState == I_CACHE; assign ic.req = iEn & iState != I_CACHE | iNextState == I_CACHE;
assign ic.valid = iValid1 & iCached1; assign ic.valid = iValid1 & iCached1;
assign ic.index = iVA[`IC_TAGL-1:`IC_INDEXL]; assign ic.index = iVA[`IC_TAGL-1:`IC_INDEXL];
assign ic.tag1 = iEn2 ? iPA1[31:`IC_TAGL] : iPA2[31:`IC_TAGL]; assign ic.tag1 = iEn2 ? iPA1[31:`IC_TAGL] : iPA2[31:`IC_TAGL];
assign ic.rvalid = inst_axi.rvalid & inst_axi.data_ok; assign ic.rvalid = inst_axi.rvalid & inst_axi.data_ok;
assign ic.clear = iState == I_CACHE & ~cacheOp1[2] & iCached1 & (ic.hit | cacheOp1[1]);
mux4 #(256) ic_rdata_mux ( mux4 #(256) ic_rdata_mux (
{inst_axi.rdata, iD7, iD6, iD5, iD4, iD3, iD2, iD1}, {inst_axi.rdata, iD7, iD6, iD5, iD4, iD3, iD2, iD1},
@ -254,8 +258,8 @@ module MMU (
assign inst_axi.len = (iEn2 ? iCached1 : iCached2) ? 4'b0111 : 4'b0001; assign inst_axi.len = (iEn2 ? iCached1 : iCached2) ? 4'b0111 : 4'b0001;
assign inst_axi.size = 3'b010; assign inst_axi.size = 3'b010;
assign iTLBRefill = (iState == I_IDLE & iReq1 | iState == I_CACHE & ~cacheOp[1]) & ~iHit1; assign iTLBRefill = (iState == I_IDLE & iReq1 | iState == I_CACHE & ~cacheOp1[1]) & ~iHit1;
assign iTLBInvalid = (iState == I_IDLE & iReq1 | iState == I_CACHE & ~cacheOp[1]) & ~iMValid1; assign iTLBInvalid = (iState == I_IDLE & iReq1 | iState == I_CACHE & ~cacheOp1[1]) & ~iMValid1;
assign iAddressError = (iState == I_IDLE) & iReq1 & ~in_kernel & ~iUser1; assign iAddressError = (iState == I_IDLE) & iReq1 & ~in_kernel & ~iUser1;
// ====================== // ======================
@ -265,7 +269,7 @@ module MMU (
word_t dVA; word_t dVA;
logic dEn; logic dEn;
logic dReq1, dcReq1, diReq; logic dReq1, dcReq1;
logic dHit1; logic dHit1;
logic dCached1, dCached2; logic dCached1, dCached2;
logic dDirty1; logic dDirty1;
@ -275,8 +279,6 @@ module MMU (
word_t dPA1, dPA2; word_t dPA1, dPA2;
logic [1:0] dSize1; logic [1:0] dSize1;
CacheOp_t cacheOp1, cacheOp2;
logic dEn2; logic dEn2;
logic dwr1; logic dwr1;
logic [3:0] dWstrb1; logic [3:0] dWstrb1;
@ -294,6 +296,7 @@ module MMU (
ffenr #(1) dvalid_ff (clk, rst, data.req, dEn, dReq1); ffenr #(1) dvalid_ff (clk, rst, data.req, dEn, dReq1);
ffen #(2) dsize_ff (clk, data.size, dEn, dSize1); ffen #(2) dsize_ff (clk, data.size, dEn, dSize1);
ffen #(32) dVA1_ff (clk, data.addr, dEn, dVA1);
ffen #(32) dPA_ff (clk, dPA1, dEn2, dPA2); ffen #(32) dPA_ff (clk, dPA1, dEn2, dPA2);
ffen #(1) dCached_ff (clk, dCached1, dEn2, dCached2); ffen #(1) dCached_ff (clk, dCached1, dEn2, dCached2);
ffen #(1) dwr_ff (clk, data.wr, dEn2, dwr1); ffen #(1) dwr_ff (clk, data.wr, dEn2, dwr1);
@ -322,8 +325,8 @@ module MMU (
rdata_axi.req = 0; rdata_axi.req = 0;
case (drState) case (drState)
DR_IDLE: begin DR_IDLE: begin
if (~dValid1) dEn = 1; if (diReq) drNextState = DR_CACHE;
else if (~dcReq1) drNextState = DR_CACHE; else if (~dValid1) dEn = 1;
else begin else begin
dEn2 = 1; dEn2 = 1;
if (data.wr) data.data_ok = 1; if (data.wr) data.data_ok = 1;
@ -407,9 +410,8 @@ module MMU (
*/ */
assign dVA = data.addr; assign dVA = data.addr;
assign diReq = dEn ? data.req & ~cacheOp[2] & |cacheOp[1:0] assign diReq = dReq1 & ~cacheOp1[2] & |cacheOp1[1:0];
: dReq1 & ~cacheOp1[2] & |cacheOp1[1:0]; assign dcReq1 = dReq1 & (cacheOp1 == CNOP | cacheOp1[2]); // exclude I-Cache clear
assign dcReq1 = dReq1 & (cacheOp1 == CNOP | cacheOp[2]); // exclude I-Cache clear
assign dValid1 = dReq1 & dHit1 & dMValid1 & (~data.wr | dDirty1) & (in_kernel | dUser1); assign dValid1 = dReq1 & dHit1 & dMValid1 & (~data.wr | dDirty1) & (in_kernel | dUser1);
assign dTLBRefill = drState == DR_IDLE & dcReq1 & (cacheOp1 == CNOP | ~cacheOp1[1]) & ~dHit1; assign dTLBRefill = drState == DR_IDLE & dcReq1 & (cacheOp1 == CNOP | ~cacheOp1[1]) & ~dHit1;
@ -457,6 +459,8 @@ module MMU (
// do not request when handling CACHE instruction on I-Cache // do not request when handling CACHE instruction on I-Cache
assign dc.req = dEn & (cacheOp[2] | ~|cacheOp[1:0]); assign dc.req = dEn & (cacheOp[2] | ~|cacheOp[1:0]);
// TODO: 在实现 CACHE 指令的 D-Cache Index 功能时应替换成下面注释的内容
// assign dc.valid = dValid1 & (dCached1 & (~cacheOp1[2] | dc.hit) | cacheOp1[1]);
assign dc.valid = dValid1 & dCached1 & (~cacheOp1[2] | cacheOp1[1] | dc.hit); assign dc.valid = dValid1 & dCached1 & (~cacheOp1[2] | cacheOp1[1] | dc.hit);
assign dc.index = dVA[`DC_TAGL-1:`DC_INDEXL]; assign dc.index = dVA[`DC_TAGL-1:`DC_INDEXL];
assign dc.tag1 = dEn2 ? dPA1[31:`DC_TAGL] : dPA2[31:`DC_TAGL]; assign dc.tag1 = dEn2 ? dPA1[31:`DC_TAGL] : dPA2[31:`DC_TAGL];

View File

@ -6,7 +6,7 @@
// IC for I-Cache // IC for I-Cache
`define IC_TAGL 11 `define IC_TAGL 11
`define IC_INDEXL 5 `define IC_INDEXL 5
`define IC_TAG_LENGTH (32-`IC_TAGL+1) // Tag + Valid `define IC_TAG_LENGTH 22 // Tag + Valid
`define IC_DATA_LENGTH 256 // 32Bytes `define IC_DATA_LENGTH 256 // 32Bytes
typedef logic [`IC_DATA_LENGTH-1:0] ICData_t; typedef logic [`IC_DATA_LENGTH-1:0] ICData_t;