refactor MU
Co-authored-by: Paul <panyuxuan@hotmail.com> Co-authored-by: cxy004 <cxy004@qq.com>
This commit is contained in:
parent
eb9f835e6b
commit
e569965556
@ -126,6 +126,8 @@ module CP0 (
|
|||||||
count_lo = ~count_lo;
|
count_lo = ~count_lo;
|
||||||
if (count_lo == 1) rf_cp0.Count = rf_cp0.Count + 1;
|
if (count_lo == 1) rf_cp0.Count = rf_cp0.Count + 1;
|
||||||
|
|
||||||
|
rf_cp0.Random.Random = &rf_cp0.Random.Random ? rf_cp0.Wired.Wired
|
||||||
|
: rf_cp0.Random.Random + 1'b1;
|
||||||
if (en) begin
|
if (en) begin
|
||||||
case (addr)
|
case (addr)
|
||||||
// 31: rf_cp0.DESAVE = wdata;
|
// 31: rf_cp0.DESAVE = wdata;
|
||||||
@ -166,7 +168,10 @@ 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.Wired = wdata[2:0];
|
6: begin
|
||||||
|
rf_cp0.Wired.Wired = wdata[2:0];
|
||||||
|
rf_cp0.Random.Random = 3'b111;
|
||||||
|
end
|
||||||
// 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
|
||||||
@ -213,9 +218,6 @@ module CP0 (
|
|||||||
rf_cp0.Index.Index = tlb_Index.Index;
|
rf_cp0.Index.Index = tlb_Index.Index;
|
||||||
end
|
end
|
||||||
|
|
||||||
rf_cp0.Random.Random = &rf_cp0.Random.Random ? rf_cp0.Wired.Wired
|
|
||||||
: rf_cp0.Random.Random + 1'b1;
|
|
||||||
|
|
||||||
if (rf_cp0.Count == rf_cp0.Compare) rf_cp0.Cause.TI = 1;
|
if (rf_cp0.Count == rf_cp0.Compare) rf_cp0.Cause.TI = 1;
|
||||||
|
|
||||||
if (exception.ERET) rf_cp0.Status.EXL = 1'b0;
|
if (exception.ERET) rf_cp0.Status.EXL = 1'b0;
|
||||||
|
@ -9,7 +9,7 @@ module Datapath (
|
|||||||
// MMU
|
// MMU
|
||||||
InstFetch_i.cpu fetch,
|
InstFetch_i.cpu fetch,
|
||||||
Memory_i.cpu mem,
|
Memory_i.cpu mem,
|
||||||
output CacheOp_t cache_op,
|
CacheOp_i.cpu cache_op,
|
||||||
input logic iTLBRefill,
|
input logic iTLBRefill,
|
||||||
input logic iTLBInvalid,
|
input logic iTLBInvalid,
|
||||||
input logic iAddressError,
|
input logic iAddressError,
|
||||||
@ -1133,7 +1133,7 @@ module Datapath (
|
|||||||
assign M.I1.REFILL = M_I1_PrevREFILL | dTLBRefillB;
|
assign M.I1.REFILL = M_I1_PrevREFILL | dTLBRefillB;
|
||||||
assign M.I1.ExcCode = M_I1_PrevExcValid ? M_I1_PrevExcCode
|
assign M.I1.ExcCode = M_I1_PrevExcValid ? M_I1_PrevExcCode
|
||||||
: M_I1_Trap ? `EXCCODE_TR
|
: M_I1_Trap ? `EXCCODE_TR
|
||||||
: dAddressErrorB ? M.I1.MCtrl.MWR ? `EXCCODE_ADES : `EXCCODE_ADES
|
: dAddressErrorB ? M.I1.MCtrl.MWR ? `EXCCODE_ADES : `EXCCODE_ADEL
|
||||||
: dTLBRefillB ? M.I1.MCtrl.MWR ? `EXCCODE_TLBS : `EXCCODE_TLBL
|
: dTLBRefillB ? M.I1.MCtrl.MWR ? `EXCCODE_TLBS : `EXCCODE_TLBL
|
||||||
: dTLBInvalidB ? M.I1.MCtrl.MWR ? `EXCCODE_TLBS : `EXCCODE_TLBL
|
: dTLBInvalidB ? M.I1.MCtrl.MWR ? `EXCCODE_TLBS : `EXCCODE_TLBL
|
||||||
: `EXCCODE_MOD;
|
: `EXCCODE_MOD;
|
||||||
|
44
src/Gadgets/addr_virt_to_phy.sv
Normal file
44
src/Gadgets/addr_virt_to_phy.sv
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
module addr_virt_to_phy (
|
||||||
|
input word_t virt_addr,
|
||||||
|
input logic [19:0] tlb_addr,
|
||||||
|
input logic tlb_hit,
|
||||||
|
input logic tlb_cached,
|
||||||
|
input logic tlb_dirty,
|
||||||
|
input logic tlb_valid,
|
||||||
|
output word_t phy_addr,
|
||||||
|
output logic hit,
|
||||||
|
output logic cached,
|
||||||
|
output logic dirty,
|
||||||
|
output logic valid,
|
||||||
|
output logic privilege
|
||||||
|
);
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
if (virt_addr >= 32'hC000_0000 || virt_addr < 32'h8000_0000) begin
|
||||||
|
// kseg2 + kseg3 + kuseg -> tlb
|
||||||
|
phy_addr = {tlb_addr, virt_addr[11:0]};
|
||||||
|
hit = tlb_hit;
|
||||||
|
cached = tlb_cached;
|
||||||
|
dirty = tlb_dirty;
|
||||||
|
valid = tlb_valid;
|
||||||
|
privilege = virt_addr[31];
|
||||||
|
end else if (virt_addr >= 32'hA000_0000) begin
|
||||||
|
// kseg1 -> uncached
|
||||||
|
phy_addr = virt_addr & 32'h1FFF_FFFF;
|
||||||
|
hit = 1'b1;
|
||||||
|
cached = 1'b0;
|
||||||
|
dirty = 1'b1;
|
||||||
|
valid = 1'b1;
|
||||||
|
privilege = 1'b1;
|
||||||
|
end else begin
|
||||||
|
// kseg0 -> CP0.K0
|
||||||
|
phy_addr = virt_addr & 32'h1FFF_FFFF;
|
||||||
|
hit = 1'b1;
|
||||||
|
cached = K0 == 3'b011;
|
||||||
|
dirty = 1'b1;
|
||||||
|
valid = 1'b1;
|
||||||
|
privilege = 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
@ -6,19 +6,19 @@ module bram #(
|
|||||||
input [$clog2(DATA_DEPTH)-1:0] addra,
|
input [$clog2(DATA_DEPTH)-1:0] addra,
|
||||||
input clka,
|
input clka,
|
||||||
input [DATA_WIDTH-1:0] dina,
|
input [DATA_WIDTH-1:0] dina,
|
||||||
output logic [DATA_WIDTH-1:0] douta,
|
output reg [DATA_WIDTH-1:0] douta,
|
||||||
input wea
|
input wea
|
||||||
);
|
);
|
||||||
|
|
||||||
(* RAM_STYLE="block" *) reg [DATA_WIDTH-1:0] ram [DATA_DEPTH];
|
(* RAM_STYLE="block" *) reg [DATA_WIDTH-1:0] ram [DATA_DEPTH];
|
||||||
|
|
||||||
for(genvar i = 0; i < DATA_DEPTH; i++)
|
for(genvar i = 0; i < DATA_DEPTH; i++)
|
||||||
initial ram[i] = 0;
|
initial ram[i] = 0;
|
||||||
|
|
||||||
always_ff @(posedge clka) begin
|
always_ff @(posedge clka) begin
|
||||||
if(~reset)begin
|
if (~rst) begin
|
||||||
if(wea) ram[addra] <= dina;
|
if(wea) ram[addra] <= dina;
|
||||||
douta <= ~wea ? ram[addra] : dina;
|
douta <= ~wea ? ram[addra] : dina;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
@ -40,14 +40,9 @@ module AXI (
|
|||||||
input wire bvalid,
|
input wire bvalid,
|
||||||
output wire bready,
|
output wire bready,
|
||||||
|
|
||||||
// ICache
|
AXIRead_i.axi inst,
|
||||||
SRAM_RO_AXI_i.slave inst,
|
AXIRead_i.axi rdata,
|
||||||
|
AXIWrite_i.axi wdata
|
||||||
// DCache Read
|
|
||||||
SRAM_RO_AXI_i.slave rdata,
|
|
||||||
|
|
||||||
// DCache Write
|
|
||||||
SRAM_W_AXI_i.slave wdata
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// ==============================
|
// ==============================
|
||||||
|
@ -32,6 +32,7 @@ module DCache (
|
|||||||
|
|
||||||
logic [3:0] hitway;
|
logic [3:0] hitway;
|
||||||
logic [3:0] victim;
|
logic [3:0] victim;
|
||||||
|
DCTagL_t dirt_tag;
|
||||||
logic [3:0] wen;
|
logic [3:0] wen;
|
||||||
|
|
||||||
|
|
||||||
@ -68,7 +69,7 @@ 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 & tag[3].dirty ? 4'b1000
|
: port.ctrl.cache_index_writeback ? 4'b1000
|
||||||
: 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
|
||||||
@ -82,35 +83,33 @@ module DCache (
|
|||||||
: nowLRU[2] == 0 ? 4'b0100
|
: nowLRU[2] == 0 ? 4'b0100
|
||||||
: 4'b1000;
|
: 4'b1000;
|
||||||
|
|
||||||
assign port.dirt_valid = victim & {tag[3].dirty, tag[2].dirty, tag[1].dirty, tag[0].dirty};
|
assign port.dirt = |{victim & {tag[3].dirty, tag[2].dirty, tag[1].dirty, tag[0].dirty}};
|
||||||
assign port.dirt_addr = {
|
assign dirt_tag = (victim[0] ? tag[0].tag : {(32-`DC_TAGL){1'b0}})
|
||||||
(victim[0] ? tag[0].tag : {(32-`DC_TAGL){1'b0}})
|
| (victim[1] ? tag[1].tag : {(32-`DC_TAGL){1'b0}})
|
||||||
| (victim[1] ? tag[1].tag : {(32-`DC_TAGL){1'b0}})
|
| (victim[2] ? tag[2].tag : {(32-`DC_TAGL){1'b0}})
|
||||||
| (victim[2] ? tag[2].tag : {(32-`DC_TAGL){1'b0}})
|
| (victim[3] ? tag[3].tag : {(32-`DC_TAGL){1'b0}});
|
||||||
| (victim[3] ? tag[3].tag : {(32-`DC_TAGL){1'b0}}),
|
assign port.dirt_addr = {dirt_tag, port.index, 4'b0};
|
||||||
port.index, 4'b0
|
|
||||||
};
|
|
||||||
assign port.dirt_row = (victim[0] ? data[0] : `DC_DATA_LENGTH'b0)
|
assign port.dirt_row = (victim[0] ? data[0] : `DC_DATA_LENGTH'b0)
|
||||||
| (victim[1] ? data[1] : `DC_DATA_LENGTH'b0)
|
| (victim[1] ? data[1] : `DC_DATA_LENGTH'b0)
|
||||||
| (victim[2] ? data[2] : `DC_DATA_LENGTH'b0)
|
| (victim[2] ? data[2] : `DC_DATA_LENGTH'b0)
|
||||||
| (victim[3] ? data[3] : `DC_DATA_LENGTH'b0);
|
| (victim[3] ? data[3] : `DC_DATA_LENGTH'b0);
|
||||||
|
|
||||||
assign setLRU_valid = port.ctrl.read_and_hit | port.ctrl.read_but_replace | port.ctrl.write_and_hit | port.ctrl.write_but_replace;
|
assign setLRU_valid = port.ctrl.read_and_hit | port.ctrl.read_but_replace | port.ctrl.write_and_hit | port.ctrl.write_but_replace;
|
||||||
assign setLRU = port.ctrl.read_and_hit ? hitway : 4'b0000
|
assign setLRU = (port.ctrl.read_and_hit ? hitway : 4'b0000)
|
||||||
| port.ctrl.read_but_replace ? victim : 4'b0000
|
| (port.ctrl.read_but_replace ? victim : 4'b0000)
|
||||||
| port.ctrl.write_and_hit ? hitway : 4'b0000
|
| (port.ctrl.write_and_hit ? hitway : 4'b0000)
|
||||||
| port.ctrl.write_but_replace ? victim : 4'b0000;
|
| (port.ctrl.write_but_replace ? victim : 4'b0000);
|
||||||
assign nxtsetLRU = setLRU | nowLRU & {4{~&{nowLRU | setLRU}}};
|
assign nxtsetLRU = setLRU | nowLRU & {4{~&{nowLRU | setLRU}}};
|
||||||
|
|
||||||
assign clrLRU_valid = port.ctrl.cache_index_invalidate | port.ctrl.cache_hit_invalidate | port.ctrl.cache_index_writeback | port.ctrl.cache_hit_writeback;
|
assign clrLRU_valid = port.ctrl.cache_index_invalidate | port.ctrl.cache_hit_invalidate | port.ctrl.cache_index_writeback | port.ctrl.cache_hit_writeback;
|
||||||
assign clrLRU = port.ctrl.cache_index_invalidate ? 4'b1111 : 4'b0000
|
assign clrLRU = (port.ctrl.cache_index_invalidate ? 4'b1111 : 4'b0000)
|
||||||
| port.ctrl.cache_hit_invalidate ? hitway : 4'b0000
|
| (port.ctrl.cache_hit_invalidate ? hitway : 4'b0000)
|
||||||
| port.ctrl.cache_index_writeback ? 4'b1111 : 4'b0000
|
| (port.ctrl.cache_index_writeback ? 4'b1111 : 4'b0000)
|
||||||
| port.ctrl.cache_hit_writeback ? hitway : 4'b0000;
|
| (port.ctrl.cache_hit_writeback ? hitway : 4'b0000);
|
||||||
assign nxtclrLRU = ~clrLRU & nowLRU;
|
assign nxtclrLRU = ~clrLRU & nowLRU;
|
||||||
|
|
||||||
assign nxtLRU = setLRU_valid ? nxtsetLRU : 4'b0000
|
assign nxtLRU = (setLRU_valid ? nxtsetLRU : 4'b0000)
|
||||||
| clrLRU_valid ? nxtclrLRU : 4'b0000;
|
| (clrLRU_valid ? nxtclrLRU : 4'b0000);
|
||||||
|
|
||||||
for (genvar i = 0; i < 128; i++)
|
for (genvar i = 0; i < 128; i++)
|
||||||
initial LRU[i] = 4'b0;
|
initial LRU[i] = 4'b0;
|
||||||
@ -138,13 +137,13 @@ module DCache (
|
|||||||
assign DataRAM3.addr = port.index_for_lookup;
|
assign DataRAM3.addr = port.index_for_lookup;
|
||||||
|
|
||||||
// 写使能
|
// 写使能
|
||||||
assign wen = {4{port.ctrl.read_but_replace}} & victim
|
assign wen = ({4{port.ctrl.read_but_replace}} & victim)
|
||||||
| {4{port.ctrl.write_and_hit}} & hitway
|
| ({4{port.ctrl.write_and_hit}} & hitway)
|
||||||
| {4{port.ctrl.write_but_replace}} & victim
|
| ({4{port.ctrl.write_but_replace}} & victim)
|
||||||
| {4{port.ctrl.cache_index_invalidate}}
|
| ({4{port.ctrl.cache_index_invalidate}} )
|
||||||
| {4{port.ctrl.cache_index_writeback}} & victim
|
| ({4{port.ctrl.cache_index_writeback}} & victim)
|
||||||
| {4{port.ctrl.cache_hit_invalidate}} & hitway
|
| ({4{port.ctrl.cache_hit_invalidate}} & hitway)
|
||||||
| {4{port.ctrl.cache_hit_writeback}} & hitway;
|
| ({4{port.ctrl.cache_hit_writeback}} & hitway);
|
||||||
|
|
||||||
assign {TagRAM3.wen, TagRAM2.wen, TagRAM1.wen, TagRAM0.wen} = wen;
|
assign {TagRAM3.wen, TagRAM2.wen, TagRAM1.wen, TagRAM0.wen} = wen;
|
||||||
assign {DataRAM3.wen, DataRAM2.wen, DataRAM1.wen, DataRAM0.wen} = wen;
|
assign {DataRAM3.wen, DataRAM2.wen, DataRAM1.wen, DataRAM0.wen} = wen;
|
||||||
@ -161,22 +160,22 @@ module DCache (
|
|||||||
assign DataRAM3.wdata = port.update_row;
|
assign DataRAM3.wdata = port.update_row;
|
||||||
|
|
||||||
// bram
|
// bram
|
||||||
bram #(.DATA_WIDTH(32-`DC_TAGL+2), .DATA_DEPTH($pow(2, `DC_TAGL-`DC_INDEXL)))
|
bram #(.DATA_WIDTH(32-`DC_TAGL+2), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
|
||||||
tag_ram0 (.rst(rst), .addra(TagRAM0.addr), .clka(clk), .dina(TagRAM0.wdata), .douta(TagRAM0.rdata), .wea(TagRAM0.wen));
|
tag_ram0 (.rst(rst), .addra(TagRAM0.addr), .clka(clk), .dina(TagRAM0.wdata), .douta(TagRAM0.rdata), .wea(TagRAM0.wen));
|
||||||
bram #(.DATA_WIDTH(32-`DC_TAGL+2), .DATA_DEPTH($pow(2, `DC_TAGL-`DC_INDEXL)))
|
bram #(.DATA_WIDTH(32-`DC_TAGL+2), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
|
||||||
tag_ram1 (.rst(rst), .addra(TagRAM1.addr), .clka(clk), .dina(TagRAM1.wdata), .douta(TagRAM1.rdata), .wea(TagRAM1.wen));
|
tag_ram1 (.rst(rst), .addra(TagRAM1.addr), .clka(clk), .dina(TagRAM1.wdata), .douta(TagRAM1.rdata), .wea(TagRAM1.wen));
|
||||||
bram #(.DATA_WIDTH(32-`DC_TAGL+2), .DATA_DEPTH($pow(2, `DC_TAGL-`DC_INDEXL)))
|
bram #(.DATA_WIDTH(32-`DC_TAGL+2), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
|
||||||
tag_ram2 (.rst(rst), .addra(TagRAM2.addr), .clka(clk), .dina(TagRAM2.wdata), .douta(TagRAM2.rdata), .wea(TagRAM2.wen));
|
tag_ram2 (.rst(rst), .addra(TagRAM2.addr), .clka(clk), .dina(TagRAM2.wdata), .douta(TagRAM2.rdata), .wea(TagRAM2.wen));
|
||||||
bram #(.DATA_WIDTH(32-`DC_TAGL+2), .DATA_DEPTH($pow(2, `DC_TAGL-`DC_INDEXL)))
|
bram #(.DATA_WIDTH(32-`DC_TAGL+2), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
|
||||||
tag_ram3 (.rst(rst), .addra(TagRAM3.addr), .clka(clk), .dina(TagRAM3.wdata), .douta(TagRAM3.rdata), .wea(TagRAM3.wen));
|
tag_ram3 (.rst(rst), .addra(TagRAM3.addr), .clka(clk), .dina(TagRAM3.wdata), .douta(TagRAM3.rdata), .wea(TagRAM3.wen));
|
||||||
|
|
||||||
bram #(.DATA_WIDTH(`DC_DATA_LENGTH), .DATA_DEPTH($pow(2, `DC_TAGL-`DC_INDEXL)))
|
bram #(.DATA_WIDTH(`DC_DATA_LENGTH), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
|
||||||
data_ram0 (.rst(rst), .addra(DataRAM0.addr), .clka(clk), .dina(DataRAM0.wdata), .douta(DataRAM0.rdata), .wea(DataRAM0.wen));
|
data_ram0 (.rst(rst), .addra(DataRAM0.addr), .clka(clk), .dina(DataRAM0.wdata), .douta(DataRAM0.rdata), .wea(DataRAM0.wen));
|
||||||
bram #(.DATA_WIDTH(`DC_DATA_LENGTH), .DATA_DEPTH($pow(2, `DC_TAGL-`DC_INDEXL)))
|
bram #(.DATA_WIDTH(`DC_DATA_LENGTH), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
|
||||||
data_ram1 (.rst(rst), .addra(DataRAM1.addr), .clka(clk), .dina(DataRAM1.wdata), .douta(DataRAM1.rdata), .wea(DataRAM1.wen));
|
data_ram1 (.rst(rst), .addra(DataRAM1.addr), .clka(clk), .dina(DataRAM1.wdata), .douta(DataRAM1.rdata), .wea(DataRAM1.wen));
|
||||||
bram #(.DATA_WIDTH(`DC_DATA_LENGTH), .DATA_DEPTH($pow(2, `DC_TAGL-`DC_INDEXL)))
|
bram #(.DATA_WIDTH(`DC_DATA_LENGTH), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
|
||||||
data_ram2 (.rst(rst), .addra(DataRAM2.addr), .clka(clk), .dina(DataRAM2.wdata), .douta(DataRAM2.rdata), .wea(DataRAM2.wen));
|
data_ram2 (.rst(rst), .addra(DataRAM2.addr), .clka(clk), .dina(DataRAM2.wdata), .douta(DataRAM2.rdata), .wea(DataRAM2.wen));
|
||||||
bram #(.DATA_WIDTH(`DC_DATA_LENGTH), .DATA_DEPTH($pow(2, `DC_TAGL-`DC_INDEXL)))
|
bram #(.DATA_WIDTH(`DC_DATA_LENGTH), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
|
||||||
data_ram3 (.rst(rst), .addra(DataRAM3.addr), .clka(clk), .dina(DataRAM3.wdata), .douta(DataRAM3.rdata), .wea(DataRAM3.wen));
|
data_ram3 (.rst(rst), .addra(DataRAM3.addr), .clka(clk), .dina(DataRAM3.wdata), .douta(DataRAM3.rdata), .wea(DataRAM3.wen));
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -11,7 +11,7 @@ module ICache (
|
|||||||
// ============ Vars ============
|
// ============ Vars ============
|
||||||
// ==============================
|
// ==============================
|
||||||
|
|
||||||
ICTagRAM_t TagRAM0, TagRAM1, TagRAM2, TagRAM3;
|
ICTagRAM_t TagRAM0, TagRAM1, TagRAM2, TagRAM3;
|
||||||
ICDataRAM_t DataRAM0, DataRAM1, DataRAM2, DataRAM3;
|
ICDataRAM_t DataRAM0, DataRAM1, DataRAM2, DataRAM3;
|
||||||
|
|
||||||
(* RAM_STYLE="block" *)
|
(* RAM_STYLE="block" *)
|
||||||
@ -69,17 +69,17 @@ module ICache (
|
|||||||
: 4'b1000;
|
: 4'b1000;
|
||||||
|
|
||||||
assign setLRU_valid = port.ctrl.read_and_hit | port.ctrl.read_but_replace;
|
assign setLRU_valid = port.ctrl.read_and_hit | port.ctrl.read_but_replace;
|
||||||
assign setLRU = port.ctrl.read_and_hit ? hitway : 4'b0000
|
assign setLRU = (port.ctrl.read_and_hit ? hitway : 4'b0000)
|
||||||
| port.ctrl.read_but_replace ? victim : 4'b0000;
|
| (port.ctrl.read_but_replace ? victim : 4'b0000);
|
||||||
assign nxtsetLRU = setLRU | nowLRU & {4{~&{nowLRU | setLRU}}};
|
assign nxtsetLRU = setLRU | nowLRU & {4{~&{nowLRU | setLRU}}};
|
||||||
|
|
||||||
assign clrLRU_valid = port.ctrl.cache_index_invalidate | port.ctrl.cache_hit_invalidate;
|
assign clrLRU_valid = port.ctrl.cache_index_invalidate | port.ctrl.cache_hit_invalidate;
|
||||||
assign clrLRU = port.ctrl.cache_index_invalidate ? 4'b1111 : 4'b0000
|
assign clrLRU = (port.ctrl.cache_index_invalidate ? 4'b1111 : 4'b0000)
|
||||||
| port.ctrl.cache_hit_invalidate ? hitway : 4'b0000;
|
| (port.ctrl.cache_hit_invalidate ? hitway : 4'b0000);
|
||||||
assign nxtclrLRU = ~clrLRU & nowLRU;
|
assign nxtclrLRU = ~clrLRU & nowLRU;
|
||||||
|
|
||||||
assign nxtLRU = setLRU_valid ? nxtsetLRU : 4'b0000
|
assign nxtLRU = (setLRU_valid ? nxtsetLRU : 4'b0000)
|
||||||
| clrLRU_valid ? nxtclrLRU : 4'b0000;
|
| (clrLRU_valid ? nxtclrLRU : 4'b0000);
|
||||||
|
|
||||||
for (genvar i = 0; i < 64; i++)
|
for (genvar i = 0; i < 64; i++)
|
||||||
initial LRU[i] = 4'b0;
|
initial LRU[i] = 4'b0;
|
||||||
@ -106,9 +106,9 @@ module ICache (
|
|||||||
assign DataRAM2.addr = port.index_for_lookup;
|
assign DataRAM2.addr = port.index_for_lookup;
|
||||||
assign DataRAM3.addr = port.index_for_lookup;
|
assign DataRAM3.addr = port.index_for_lookup;
|
||||||
// 写使能
|
// 写使能
|
||||||
assign wen = {4{port.ctrl.read_but_replace}} & victim
|
assign wen = ({4{port.ctrl.read_but_replace}} & victim)
|
||||||
| {4{port.ctrl.cache_index_invalidate}}
|
| ({4{port.ctrl.cache_index_invalidate}} )
|
||||||
| {4{port.ctrl.cache_hit_invalidate}} & hitway;
|
| ({4{port.ctrl.cache_hit_invalidate}} & hitway);
|
||||||
|
|
||||||
assign {TagRAM3.wen, TagRAM2.wen, TagRAM1.wen, TagRAM0.wen} = wen;
|
assign {TagRAM3.wen, TagRAM2.wen, TagRAM1.wen, TagRAM0.wen} = wen;
|
||||||
assign {DataRAM3.wen, DataRAM2.wen, DataRAM1.wen, DataRAM0.wen} = wen;
|
assign {DataRAM3.wen, DataRAM2.wen, DataRAM1.wen, DataRAM0.wen} = wen;
|
||||||
@ -122,22 +122,22 @@ module ICache (
|
|||||||
assign DataRAM2.wdata = port.update_row;
|
assign DataRAM2.wdata = port.update_row;
|
||||||
assign DataRAM3.wdata = port.update_row;
|
assign DataRAM3.wdata = port.update_row;
|
||||||
|
|
||||||
bram #(.DATA_WIDTH(32-`IC_TAGL+1), .DATA_DEPTH($pow(2, `IC_TAGL-`IC_INDEXL)))
|
bram #(.DATA_WIDTH(32-`IC_TAGL+1), .DATA_DEPTH(2 ** (`IC_TAGL-`IC_INDEXL)))
|
||||||
tag_ram0 (.rst(rst), .addra(TagRAM0.addr), .clka(clk), .dina(TagRAM0.wdata), .douta(TagRAM0.rdata), .wea(TagRAM0.wen));
|
tag_ram0 (.rst(rst), .addra(TagRAM0.addr), .clka(clk), .dina(TagRAM0.wdata), .douta(TagRAM0.rdata), .wea(TagRAM0.wen));
|
||||||
bram #(.DATA_WIDTH(32-`IC_TAGL+1), .DATA_DEPTH($pow(2, `IC_TAGL-`IC_INDEXL)))
|
bram #(.DATA_WIDTH(32-`IC_TAGL+1), .DATA_DEPTH(2 ** (`IC_TAGL-`IC_INDEXL)))
|
||||||
tag_ram1 (.rst(rst), .addra(TagRAM1.addr), .clka(clk), .dina(TagRAM1.wdata), .douta(TagRAM1.rdata), .wea(TagRAM1.wen));
|
tag_ram1 (.rst(rst), .addra(TagRAM1.addr), .clka(clk), .dina(TagRAM1.wdata), .douta(TagRAM1.rdata), .wea(TagRAM1.wen));
|
||||||
bram #(.DATA_WIDTH(32-`IC_TAGL+1), .DATA_DEPTH($pow(2, `IC_TAGL-`IC_INDEXL)))
|
bram #(.DATA_WIDTH(32-`IC_TAGL+1), .DATA_DEPTH(2 ** (`IC_TAGL-`IC_INDEXL)))
|
||||||
tag_ram2 (.rst(rst), .addra(TagRAM2.addr), .clka(clk), .dina(TagRAM2.wdata), .douta(TagRAM2.rdata), .wea(TagRAM2.wen));
|
tag_ram2 (.rst(rst), .addra(TagRAM2.addr), .clka(clk), .dina(TagRAM2.wdata), .douta(TagRAM2.rdata), .wea(TagRAM2.wen));
|
||||||
bram #(.DATA_WIDTH(32-`IC_TAGL+1), .DATA_DEPTH($pow(2, `IC_TAGL-`IC_INDEXL)))
|
bram #(.DATA_WIDTH(32-`IC_TAGL+1), .DATA_DEPTH(2 ** (`IC_TAGL-`IC_INDEXL)))
|
||||||
tag_ram3 (.rst(rst), .addra(TagRAM3.addr), .clka(clk), .dina(TagRAM3.wdata), .douta(TagRAM3.rdata), .wea(TagRAM3.wen));
|
tag_ram3 (.rst(rst), .addra(TagRAM3.addr), .clka(clk), .dina(TagRAM3.wdata), .douta(TagRAM3.rdata), .wea(TagRAM3.wen));
|
||||||
|
|
||||||
bram #(.DATA_WIDTH(`IC_DATA_LENGTH), .DATA_DEPTH($pow(2, `IC_TAGL-`IC_INDEXL)))
|
bram #(.DATA_WIDTH(`IC_DATA_LENGTH), .DATA_DEPTH(2 ** (`IC_TAGL-`IC_INDEXL)))
|
||||||
data_ram0 (.rst(rst), .addra(DataRAM0.addr), .clka(clk), .dina(DataRAM0.wdata), .douta(DataRAM0.rdata), .wea(DataRAM0.wen));
|
data_ram0 (.rst(rst), .addra(DataRAM0.addr), .clka(clk), .dina(DataRAM0.wdata), .douta(DataRAM0.rdata), .wea(DataRAM0.wen));
|
||||||
bram #(.DATA_WIDTH(`IC_DATA_LENGTH), .DATA_DEPTH($pow(2, `IC_TAGL-`IC_INDEXL)))
|
bram #(.DATA_WIDTH(`IC_DATA_LENGTH), .DATA_DEPTH(2 ** (`IC_TAGL-`IC_INDEXL)))
|
||||||
data_ram1 (.rst(rst), .addra(DataRAM1.addr), .clka(clk), .dina(DataRAM1.wdata), .douta(DataRAM1.rdata), .wea(DataRAM1.wen));
|
data_ram1 (.rst(rst), .addra(DataRAM1.addr), .clka(clk), .dina(DataRAM1.wdata), .douta(DataRAM1.rdata), .wea(DataRAM1.wen));
|
||||||
bram #(.DATA_WIDTH(`IC_DATA_LENGTH), .DATA_DEPTH($pow(2, `IC_TAGL-`IC_INDEXL)))
|
bram #(.DATA_WIDTH(`IC_DATA_LENGTH), .DATA_DEPTH(2 ** (`IC_TAGL-`IC_INDEXL)))
|
||||||
data_ram2 (.rst(rst), .addra(DataRAM2.addr), .clka(clk), .dina(DataRAM2.wdata), .douta(DataRAM2.rdata), .wea(DataRAM2.wen));
|
data_ram2 (.rst(rst), .addra(DataRAM2.addr), .clka(clk), .dina(DataRAM2.wdata), .douta(DataRAM2.rdata), .wea(DataRAM2.wen));
|
||||||
bram #(.DATA_WIDTH(`IC_DATA_LENGTH), .DATA_DEPTH($pow(2, `IC_TAGL-`IC_INDEXL)))
|
bram #(.DATA_WIDTH(`IC_DATA_LENGTH), .DATA_DEPTH(2 ** (`IC_TAGL-`IC_INDEXL)))
|
||||||
data_ram3 (.rst(rst), .addra(DataRAM3.addr), .clka(clk), .dina(DataRAM3.wdata), .douta(DataRAM3.rdata), .wea(DataRAM3.wen));
|
data_ram3 (.rst(rst), .addra(DataRAM3.addr), .clka(clk), .dina(DataRAM3.wdata), .douta(DataRAM3.rdata), .wea(DataRAM3.wen));
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
175
src/MU/MU.sv
175
src/MU/MU.sv
@ -2,42 +2,18 @@
|
|||||||
`include "Cache.svh"
|
`include "Cache.svh"
|
||||||
`include "TLB.svh"
|
`include "TLB.svh"
|
||||||
|
|
||||||
module MMU (
|
module MU (
|
||||||
input clk,
|
input clk,
|
||||||
input rst,
|
input rst,
|
||||||
ICache_i.mmu ic,
|
ICache_i.mu icache,
|
||||||
DCache_i.mmu dc,
|
DCache_i.mu dcache,
|
||||||
InstFetch_i.mu inst,
|
InstFetch_i.mu instfetch,
|
||||||
Memory_i.mu data,
|
Memory_i.mu memory,
|
||||||
input CacheOp_t cacheOp,
|
CacheOp_i.mu cacheop,
|
||||||
AXI_read_i.mu inst_axi,
|
AXIRead_i.mu axiread_inst,
|
||||||
AXI_read_i.mu rdata_axi,
|
AXIRead_i.mu axiread_data,
|
||||||
AXI_write_i.mu wdata_axi,
|
AXIWrite_i.mu axiwrite_data,
|
||||||
// CP0
|
CP0_i.mu cp0
|
||||||
input logic [2:0] K0,
|
|
||||||
input logic in_kernel,
|
|
||||||
input logic tlbwi, // TLBWI -> Write TLB
|
|
||||||
input logic tlbwr, // TLBWR -> Write TLB
|
|
||||||
input logic tlbp, // TLBP -> Write CP0 Index
|
|
||||||
input Random_t c0_Random, // TLBWR
|
|
||||||
input Index_t c0_Index, // TLBWI + TLBR
|
|
||||||
input EntryHi_t c0_EntryHi, // TLBWI + F/M(ASID)
|
|
||||||
// input PageMask_t c0_PageMask, // TLBWI
|
|
||||||
input EntryLo_t c0_EntryLo1, // TLBWI
|
|
||||||
input EntryLo_t c0_EntryLo0, // TLBWI
|
|
||||||
output EntryHi_t EntryHi, // TLBR
|
|
||||||
// output PageMask_t PageMask, // TLBR
|
|
||||||
output EntryLo_t EntryLo1, // TLBR
|
|
||||||
output EntryLo_t EntryLo0, // TLBR
|
|
||||||
output Index_t Index, // TLBP
|
|
||||||
// Exceptions
|
|
||||||
output logic iTLBRefill,
|
|
||||||
output logic iTLBInvalid,
|
|
||||||
output logic iAddressError,
|
|
||||||
output logic dTLBRefill,
|
|
||||||
output logic dTLBInvalid,
|
|
||||||
output logic dTLBModified,
|
|
||||||
output logic dAddressError
|
|
||||||
);
|
);
|
||||||
// ======================
|
// ======================
|
||||||
// ======== Defs ========
|
// ======== Defs ========
|
||||||
@ -132,9 +108,9 @@ module MMU (
|
|||||||
end
|
end
|
||||||
I_WD2: begin
|
I_WD2: begin
|
||||||
if (inst_axi.rvalid) begin
|
if (inst_axi.rvalid) begin
|
||||||
inst.data_ok = 1;
|
|
||||||
if (iCached2) iNextState = I_WD3;
|
if (iCached2) iNextState = I_WD3;
|
||||||
else begin
|
else begin
|
||||||
|
inst.data_ok = 1;
|
||||||
iEn = 1;
|
iEn = 1;
|
||||||
iNextState = I_IDLE;
|
iNextState = I_IDLE;
|
||||||
end
|
end
|
||||||
@ -156,7 +132,10 @@ module MMU (
|
|||||||
if (inst_axi.rvalid) iNextState = I_WD8;
|
if (inst_axi.rvalid) iNextState = I_WD8;
|
||||||
end
|
end
|
||||||
I_WD8: begin
|
I_WD8: begin
|
||||||
if (inst_axi.rvalid) iNextState = I_REFILL;
|
if (inst_axi.rvalid) begin
|
||||||
|
iNextState = I_REFILL;
|
||||||
|
inst.data_ok = 1;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
I_REFILL: begin
|
I_REFILL: begin
|
||||||
iEn = 1;
|
iEn = 1;
|
||||||
@ -235,12 +214,12 @@ module MMU (
|
|||||||
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;
|
||||||
mux5 #(64) inst_rdata_mux (
|
mux5 #(64) inst_rdata_mux (
|
||||||
ic.row[63:0],
|
ic.row[ 63: 0],
|
||||||
ic.row[127:64],
|
ic.row[127: 64],
|
||||||
ic.row[191:128],
|
ic.row[191:128],
|
||||||
ic.row[255:192],
|
ic.row[255:192],
|
||||||
{inst_axi.rdata, iD1},
|
{iState == I_WD2 ? inst_axi.rdata : iD2, iD1},
|
||||||
{iState == I_WD2, iPA1[4:3]},
|
{iState != I_IDLE, iPA1[4:3]},
|
||||||
{inst.rdata1, inst.rdata0}
|
{inst.rdata1, inst.rdata0}
|
||||||
);
|
);
|
||||||
assign ic.req = iEn;
|
assign ic.req = iEn;
|
||||||
@ -341,10 +320,10 @@ module MMU (
|
|||||||
if (rdata_axi.addr_ok) begin
|
if (rdata_axi.addr_ok) begin
|
||||||
if (~rdata_axi.rvalid) drNextState = DR_WD1;
|
if (~rdata_axi.rvalid) drNextState = DR_WD1;
|
||||||
else begin
|
else begin
|
||||||
|
data.data_ok = 1;
|
||||||
if (dCached2) drNextState = DR_WD2;
|
if (dCached2) drNextState = DR_WD2;
|
||||||
else begin
|
else begin
|
||||||
dEn = 1;
|
dEn = 1;
|
||||||
data.data_ok = 1;
|
|
||||||
drNextState = DR_IDLE;
|
drNextState = DR_IDLE;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -352,9 +331,9 @@ module MMU (
|
|||||||
end
|
end
|
||||||
DR_WD1: begin
|
DR_WD1: begin
|
||||||
if (rdata_axi.rvalid) begin
|
if (rdata_axi.rvalid) begin
|
||||||
if (~dwr1) data.data_ok = 1;
|
|
||||||
if (dCached2) drNextState = DR_WD2;
|
if (dCached2) drNextState = DR_WD2;
|
||||||
else begin
|
else begin
|
||||||
|
data.data_ok = 1;
|
||||||
dEn = 1;
|
dEn = 1;
|
||||||
drNextState = DR_IDLE;
|
drNextState = DR_IDLE;
|
||||||
end
|
end
|
||||||
@ -367,7 +346,10 @@ module MMU (
|
|||||||
if (rdata_axi.rvalid) drNextState = DR_WD4;
|
if (rdata_axi.rvalid) drNextState = DR_WD4;
|
||||||
end
|
end
|
||||||
DR_WD4: begin
|
DR_WD4: begin
|
||||||
if (rdata_axi.rvalid) drNextState = DR_REFILL;
|
if (rdata_axi.rvalid) begin
|
||||||
|
drNextState = DR_REFILL;
|
||||||
|
data.data_ok = 1;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
DR_REFILL: begin
|
DR_REFILL: begin
|
||||||
if (wdata_ok) begin
|
if (wdata_ok) begin
|
||||||
@ -416,8 +398,8 @@ module MMU (
|
|||||||
dc.row[ 63:32],
|
dc.row[ 63:32],
|
||||||
dc.row[ 95:64],
|
dc.row[ 95:64],
|
||||||
dc.row[127:96],
|
dc.row[127:96],
|
||||||
rdata_axi.rdata,
|
drState == DR_WD4 ? drD1 : rdata_axi.rdata,
|
||||||
{rdata_axi.rvalid, dPA1[3:2]},
|
{drState != DR_IDLE, dPA1[3:2]},
|
||||||
data.rdata
|
data.rdata
|
||||||
);
|
);
|
||||||
assign dc.req = dEn;
|
assign dc.req = dEn;
|
||||||
@ -588,14 +570,19 @@ module MMU (
|
|||||||
assign dc.wvalid = dEn2 ? data.wr : dwr1;
|
assign dc.wvalid = dEn2 ? data.wr : dwr1;
|
||||||
assign dc.wdata = dEn2 ? data.wdata : dWdata1;
|
assign dc.wdata = dEn2 ? data.wdata : dWdata1;
|
||||||
assign dc.wstrb = dEn2 ? data.wstrb : dWstrb1;
|
assign dc.wstrb = dEn2 ? data.wstrb : dWstrb1;
|
||||||
// ==============================
|
|
||||||
// ========== VA -> PA ==========
|
// =====================================
|
||||||
// ==============================
|
// ======= virt addr -> phy addr =======
|
||||||
|
// =====================================
|
||||||
|
|
||||||
|
// turns stored addr to its phy addr
|
||||||
|
|
||||||
|
`ifdef ENABLE_TLB
|
||||||
|
|
||||||
logic tlbw;
|
logic tlbw;
|
||||||
logic [2:0] c0_Index_u;
|
logic [2:0] c0_Index_u;
|
||||||
assign tlbw = tlbwi | tlbwr;
|
assign tlbw = tlbwi | tlbwr;
|
||||||
assign c0_Index_u = tlbwr ? c0_Random[2:0] : c0_Index[2:0];
|
assign c0_Index_u = tlbwr ? c0_Random[2:0] : c0_Index[2:0];
|
||||||
`ifdef ENABLE_TLB
|
|
||||||
TLB TLB (
|
TLB TLB (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
@ -626,8 +613,94 @@ module MMU (
|
|||||||
.dValid (dMValid1),
|
.dValid (dMValid1),
|
||||||
.dUser (dUser1)
|
.dUser (dUser1)
|
||||||
);
|
);
|
||||||
|
|
||||||
`else
|
`else
|
||||||
|
|
||||||
|
addr_virt_to_phy instfetch_addr_convert(
|
||||||
|
.virt_addr (stored_instfetch_addr),
|
||||||
|
.tlb_addr (stored_instfetch_addr[31:12]),
|
||||||
|
.tlb_hit (1'b1),
|
||||||
|
.tlb_cached(1'b0),
|
||||||
|
.tlb_dirty (1'b1),
|
||||||
|
.tlb_valid (1'b1),
|
||||||
|
.phy_addr (instfetch_phy_addr),
|
||||||
|
.hit (instfetch_hit),
|
||||||
|
.cached (instfetch_cached),
|
||||||
|
.dirty (),
|
||||||
|
.valid (instfetch_valid),
|
||||||
|
.privilege (instfetch_privilege)
|
||||||
|
);
|
||||||
|
addr_virt_to_phy memory_addr_convert(
|
||||||
|
.virt_addr (stored_memory_addr),
|
||||||
|
.tlb_addr (stored_memory_addr[31:12]),
|
||||||
|
.tlb_hit (1'b1),
|
||||||
|
.tlb_cached(1'b0),
|
||||||
|
.tlb_dirty (1'b1),
|
||||||
|
.tlb_valid (1'b1),
|
||||||
|
.phy_addr (memory_phy_addr),
|
||||||
|
.hit (memory_hit),
|
||||||
|
.cached (memory_cached),
|
||||||
|
.dirty (memory_dirty),
|
||||||
|
.valid (memory_valid),
|
||||||
|
.privilege (memory_privilege)
|
||||||
|
);
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
// =====================================
|
||||||
|
// == 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
|
||||||
|
// cache
|
||||||
|
IFC_READ, // wait for AXI read
|
||||||
|
// refill if cached
|
||||||
|
IFC_CACHE_INVALID // cache_index_invalid, cache_hit_invalid
|
||||||
|
} IFC_state_t;
|
||||||
|
|
||||||
|
IFC_state_t IFC_cur_state;
|
||||||
|
IFC_state_t IFC_next_state;
|
||||||
|
|
||||||
|
always_ff @(posedge clk) begin
|
||||||
|
if (rst) IFC_cur_state <= IFC_LOOKUP;
|
||||||
|
else IFC_cur_state <= IFC_next_state;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
IFC_next_state = IFC_cur_state;
|
||||||
|
|
||||||
|
instfetch_allow_next_req = 1'b0;
|
||||||
|
|
||||||
|
// AXI action
|
||||||
|
// ?????
|
||||||
|
|
||||||
|
case (IFC_cur_state)
|
||||||
|
instfetch.addr_ok = 1'b0;
|
||||||
|
instfetch.data_ok = 1'b0;
|
||||||
|
instfetch.rdata0 = 32'h0;
|
||||||
|
instfetch.rdata1 = 32'h0;
|
||||||
|
|
||||||
|
// cacheop.addr_ok
|
||||||
|
|
||||||
|
icache.ctrl = 4'b0;
|
||||||
|
icache.index_for_lookup = stored.addr;
|
||||||
|
icache.index = ?????;
|
||||||
|
icache.tag = ?????;
|
||||||
|
icache.update_row = ?????;
|
||||||
|
|
||||||
|
IFC_LOOKUP: begin
|
||||||
|
if (stored.cacheop.icache_op) begin
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -164,6 +164,20 @@ module TLB (
|
|||||||
iUser = 1'b0;
|
iUser = 1'b0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
addr_virt_to_phy instfetch_addr_convert(
|
||||||
|
.virt_addr (fVAddr1),
|
||||||
|
.tlb_addr (fPAddr1),
|
||||||
|
.tlb_hit (fHit1),
|
||||||
|
.tlb_cached (fCached1),
|
||||||
|
.tlb_dirty (fDirty1),
|
||||||
|
.tlb_valid (fValid1),
|
||||||
|
.phy_addr (iPAddr),
|
||||||
|
.hit (iHit),
|
||||||
|
.cached (iCached),
|
||||||
|
.dirty (iDirty),
|
||||||
|
.valid (iValid),
|
||||||
|
.privilege (iUser) // not
|
||||||
|
);
|
||||||
|
|
||||||
ffenr #(56) data_ff (
|
ffenr #(56) data_ff (
|
||||||
clk, rst,
|
clk, rst,
|
||||||
@ -171,32 +185,19 @@ module TLB (
|
|||||||
1'b1,
|
1'b1,
|
||||||
{mVAddr1, mPAddr1, mHit1, mCached1, mValid1, mDirty1}
|
{mVAddr1, mPAddr1, mHit1, mCached1, mValid1, mDirty1}
|
||||||
);
|
);
|
||||||
always_comb begin
|
addr_virt_to_phy memory_addr_convert(
|
||||||
if (mVAddr1 > 32'hBFFF_FFFF || mVAddr1 <= 32'h7FFF_FFFF) begin
|
.virt_addr (mVAddr1),
|
||||||
// kseg2 + kseg3 + kuseg -> tlb
|
.tlb_addr (mPAddr1),
|
||||||
dPAddr = {mPAddr1, mVAddr1[11:0]};
|
.tlb_hit (mHit1),
|
||||||
dHit = mHit1;
|
.tlb_cached (mCached1),
|
||||||
dCached = mCached1;
|
.tlb_dirty (mDirty1),
|
||||||
dDirty = mDirty1;
|
.tlb_valid (mValid1),
|
||||||
dValid = mValid1;
|
.phy_addr (dPAddr),
|
||||||
dUser = ~mVAddr1[31];
|
.hit (dHit),
|
||||||
end else if (mVAddr1 > 32'h9FFF_FFFF) begin
|
.cached (dCached),
|
||||||
// kseg1 uncached
|
.dirty (dDirty),
|
||||||
dPAddr = mVAddr1 & 32'h1FFF_FFFF;
|
.valid (dValid),
|
||||||
dHit = 1'b1;
|
.privilege (dUser) // not
|
||||||
dCached = 1'b0;
|
);
|
||||||
dDirty = 1'b1;
|
|
||||||
dValid = 1'b1;
|
|
||||||
dUser = 1'b0;
|
|
||||||
end else begin
|
|
||||||
// kseg0 -> CP0.K0
|
|
||||||
dPAddr = mVAddr1 & 32'h1FFF_FFFF;
|
|
||||||
dHit = 1'b1;
|
|
||||||
dCached = K0[0];
|
|
||||||
dDirty = 1'b1;
|
|
||||||
dValid = 1'b1;
|
|
||||||
dUser = 1'b0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -1,6 +1,43 @@
|
|||||||
`include "defines.svh"
|
`include "defines.svh"
|
||||||
`include "Cache.svh"
|
`include "Cache.svh"
|
||||||
|
|
||||||
|
interface InstFetch_i;
|
||||||
|
logic req;
|
||||||
|
word_t addr;
|
||||||
|
logic addr_ok;
|
||||||
|
logic data_ok;
|
||||||
|
word_t rdata0;
|
||||||
|
word_t rdata1;
|
||||||
|
|
||||||
|
modport cpu(output req, addr, input addr_ok, data_ok, rdata0, rdata1);
|
||||||
|
modport mu (input req, addr, output addr_ok, data_ok, rdata0, rdata1);
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
interface Memory_i;
|
||||||
|
logic req;
|
||||||
|
logic wr;
|
||||||
|
word_t addr;
|
||||||
|
logic [1:0] size;
|
||||||
|
logic [3:0] wstrb;
|
||||||
|
word_t wdata;
|
||||||
|
logic addr_ok;
|
||||||
|
logic data_ok;
|
||||||
|
word_t rdata;
|
||||||
|
|
||||||
|
modport cpu(output req, wr, addr, size, wstrb, wdata, input addr_ok, data_ok, rdata);
|
||||||
|
modport mu (input req, wr, addr, size, wstrb, wdata, output addr_ok, data_ok, rdata);
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
interface CacheOp_i;
|
||||||
|
logic req;
|
||||||
|
word_t addr;
|
||||||
|
logic addr_ok;
|
||||||
|
CacheOp_t op;
|
||||||
|
|
||||||
|
modport cpu(output req, addr, op, input addr_ok);
|
||||||
|
modport mu (input req, addr, op, output addr_ok);
|
||||||
|
endinterface
|
||||||
|
|
||||||
interface ICache_i;
|
interface ICache_i;
|
||||||
ICacheCtrl_t ctrl;
|
ICacheCtrl_t ctrl;
|
||||||
ICIndexL_t index_for_lookup;
|
ICIndexL_t index_for_lookup;
|
||||||
@ -25,9 +62,9 @@ interface ICache_i;
|
|||||||
endinterface
|
endinterface
|
||||||
|
|
||||||
interface DCache_i;
|
interface DCache_i;
|
||||||
ICacheCtrl_t ctrl;
|
DCacheCtrl_t ctrl;
|
||||||
DCIndexL_t index_for_lookup;
|
DCIndexL_t index_for_lookup;
|
||||||
ICIndexL_t index;
|
DCIndexL_t index;
|
||||||
DCTagL_t tag;
|
DCTagL_t tag;
|
||||||
logic hit;
|
logic hit;
|
||||||
DCData_t hit_row;
|
DCData_t hit_row;
|
||||||
@ -52,34 +89,7 @@ interface DCache_i;
|
|||||||
);
|
);
|
||||||
endinterface
|
endinterface
|
||||||
|
|
||||||
interface InstFetch_i;
|
interface AXIRead_i;
|
||||||
logic req;
|
|
||||||
word_t addr;
|
|
||||||
logic addr_ok;
|
|
||||||
logic data_ok;
|
|
||||||
word_t rdata0;
|
|
||||||
word_t rdata1;
|
|
||||||
|
|
||||||
modport cpu(output req, addr, input addr_ok, data_ok, rdata0, rdata1);
|
|
||||||
modport mu(input req, addr, output addr_ok, data_ok, rdata0, rdata1);
|
|
||||||
endinterface
|
|
||||||
|
|
||||||
interface Memory_i;
|
|
||||||
logic req;
|
|
||||||
logic wr;
|
|
||||||
word_t addr;
|
|
||||||
logic [1:0] size;
|
|
||||||
logic [3:0] wstrb;
|
|
||||||
word_t wdata;
|
|
||||||
logic addr_ok;
|
|
||||||
logic data_ok;
|
|
||||||
word_t rdata;
|
|
||||||
|
|
||||||
modport cpu(output req, wr, addr, size, wstrb, wdata, input addr_ok, data_ok, rdata);
|
|
||||||
modport mu(input req, wr, addr, size, wstrb, wdata, output addr_ok, data_ok, rdata);
|
|
||||||
endinterface
|
|
||||||
|
|
||||||
interface AXI_read_i;
|
|
||||||
logic req;
|
logic req;
|
||||||
word_t addr;
|
word_t addr;
|
||||||
logic [3:0] len;
|
logic [3:0] len;
|
||||||
@ -93,7 +103,7 @@ interface AXI_read_i;
|
|||||||
modport mu (output req, addr, len, size, input addr_ok, data_ok, rdata, rvalid);
|
modport mu (output req, addr, len, size, input addr_ok, data_ok, rdata, rvalid);
|
||||||
endinterface
|
endinterface
|
||||||
|
|
||||||
interface AXI_write_i;
|
interface AXIWrite_i;
|
||||||
logic req;
|
logic req;
|
||||||
word_t addr;
|
word_t addr;
|
||||||
logic [3:0] len;
|
logic [3:0] len;
|
||||||
@ -109,3 +119,86 @@ interface AXI_write_i;
|
|||||||
modport axi(input req, addr, len, size, wstrb, wdata, wvalid, wlast, output addr_ok, data_ok, wready);
|
modport axi(input req, addr, len, size, wstrb, wdata, wvalid, wlast, output addr_ok, data_ok, wready);
|
||||||
modport mu (output req, addr, len, size, wstrb, wdata, wvalid, wlast, input addr_ok, data_ok, wready);
|
modport mu (output req, addr, len, size, wstrb, wdata, wvalid, wlast, input addr_ok, data_ok, wready);
|
||||||
endinterface
|
endinterface
|
||||||
|
|
||||||
|
interface CP0_i;
|
||||||
|
logic [2:0] cp0_K0;
|
||||||
|
logic cp0_in_kernel;
|
||||||
|
logic cpu_tlbwi;
|
||||||
|
logic cpu_tlbwr;
|
||||||
|
logic cpu_tlbp;
|
||||||
|
Random_t cp0_Random; // TLBWR
|
||||||
|
EntryHi_t cp0_EntryHi; // TLBWI + F/M(ASID)
|
||||||
|
PageMask_t cp0_PageMask; // TLBWI
|
||||||
|
EntryLo_t cp0_EntryLo1; // TLBWI
|
||||||
|
EntryLo_t cp0_EntryLo0; // TLBWI
|
||||||
|
Index_t cp0_Index; // TLBWI + TLBR
|
||||||
|
EntryHi_t tlb_EntryHi;
|
||||||
|
PageMask_t tlb_PageMask;
|
||||||
|
EntryLo_t tlb_EntryLo1;
|
||||||
|
EntryLo_t tlb_EntryLo0;
|
||||||
|
Index_t tlb_Index; // TLBP
|
||||||
|
logic tlb_iTLBRefill;
|
||||||
|
logic tlb_iTLBInvalid;
|
||||||
|
logic tlb_iAddressError;
|
||||||
|
logic tlb_dTLBRefill;
|
||||||
|
logic tlb_dTLBInvalid;
|
||||||
|
logic tlb_dTLBModified;
|
||||||
|
logic tlb_dAddressError;
|
||||||
|
|
||||||
|
modport mu(
|
||||||
|
input cp0_K0,
|
||||||
|
input cp0_in_kernel,
|
||||||
|
input cpu_tlbwi,
|
||||||
|
input cpu_tlbwr,
|
||||||
|
input cpu_tlbp,
|
||||||
|
input cp0_Random,
|
||||||
|
input cp0_Index,
|
||||||
|
input cp0_EntryHi,
|
||||||
|
input cp0_PageMask,
|
||||||
|
input cp0_EntryLo1,
|
||||||
|
input cp0_EntryLo0,
|
||||||
|
output tlb_EntryHi,
|
||||||
|
output tlb_PageMask,
|
||||||
|
output tlb_EntryLo1,
|
||||||
|
output tlb_EntryLo0,
|
||||||
|
output tlb_Index,
|
||||||
|
output tlb_iTLBRefill,
|
||||||
|
output tlb_iTLBInvalid,
|
||||||
|
output tlb_iAddressError,
|
||||||
|
output tlb_dTLBRefill,
|
||||||
|
output tlb_dTLBInvalid,
|
||||||
|
output tlb_dTLBModified,
|
||||||
|
output tlb_dAddressError
|
||||||
|
);
|
||||||
|
modport cp0(
|
||||||
|
output cp0_K0,
|
||||||
|
output cp0_in_kernel,
|
||||||
|
output cpu_tlbwi,
|
||||||
|
output cpu_tlbwr,
|
||||||
|
output cpu_tlbp,
|
||||||
|
output cp0_Random,
|
||||||
|
output cp0_Index,
|
||||||
|
output cp0_EntryHi,
|
||||||
|
output cp0_PageMask,
|
||||||
|
output cp0_EntryLo1,
|
||||||
|
output cp0_EntryLo0,
|
||||||
|
input tlb_EntryHi,
|
||||||
|
input tlb_PageMask,
|
||||||
|
input tlb_EntryLo1,
|
||||||
|
input tlb_EntryLo0,
|
||||||
|
input tlb_Index
|
||||||
|
);
|
||||||
|
modport cpu(
|
||||||
|
output cpu_tlbwi,
|
||||||
|
output cpu_tlbwr,
|
||||||
|
output cpu_tlbp,
|
||||||
|
input tlb_iTLBRefill,
|
||||||
|
input tlb_iTLBInvalid,
|
||||||
|
input tlb_iAddressError,
|
||||||
|
input tlb_dTLBRefill,
|
||||||
|
input tlb_dTLBInvalid,
|
||||||
|
input tlb_dTLBModified,
|
||||||
|
input tlb_dAddressError
|
||||||
|
);
|
||||||
|
|
||||||
|
endinterface
|
@ -84,14 +84,12 @@ typedef enum logic [1:0] {
|
|||||||
URIGHT = 2'b10
|
URIGHT = 2'b10
|
||||||
} ALR_t;
|
} ALR_t;
|
||||||
|
|
||||||
typedef enum logic [2:0] {
|
typedef struct packed {
|
||||||
CNOP = 3'b000,
|
logic icache_op;
|
||||||
IC_L = 3'b001, // I-Cache Lookup
|
logic dcache_op;
|
||||||
IC_I = 3'b011, // I-Cache Index
|
logic index_or_hit; // 0 for index
|
||||||
DC_LB = 3'b100, // D-Cache Lookup writeBack
|
// 1 for hit
|
||||||
DC_LO = 3'b101, // D-Cache Lookup writeOnly
|
logic writeback;
|
||||||
DC_IB = 3'b110, // D-Cache Index writeBack
|
|
||||||
DC_IO = 3'b111 // D-Cache Index writeOnly
|
|
||||||
} CacheOp_t;
|
} CacheOp_t;
|
||||||
|
|
||||||
typedef enum logic [1:0] {
|
typedef enum logic [1:0] {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
`include "defines.svh"
|
`include "defines.svh"
|
||||||
|
|
||||||
`include "CP0.svh"
|
`include "CP0.svh"
|
||||||
`include "DCache.svhCache.svh"
|
`include "Cache.svh"
|
||||||
|
|
||||||
module mycpu_top (
|
module mycpu_top (
|
||||||
input wire [5:0] ext_int, //high active
|
input wire [5:0] ext_int, //high active
|
||||||
@ -64,17 +64,17 @@ module mycpu_top (
|
|||||||
output wire debug_wb_pc_A
|
output wire debug_wb_pc_A
|
||||||
);
|
);
|
||||||
|
|
||||||
AXI_read_i inst_axi;
|
AXIRead_i inst_axi();
|
||||||
AXI_read_i rdata_axi;
|
AXIRead_i rdata_axi();
|
||||||
AXI_write_i wdata_axi;
|
AXIWrite_i wdata_axi();
|
||||||
|
|
||||||
ICache_i icache;
|
ICache_i icache();
|
||||||
DCache_i dcache;
|
DCache_i dcache();
|
||||||
|
|
||||||
InstFetch_i inst;
|
InstFetch_i inst();
|
||||||
Memory_i data;
|
Memory_i data();
|
||||||
|
|
||||||
CacheOp_t cache_op;
|
CacheOp_i cache_op();
|
||||||
|
|
||||||
logic C0_int;
|
logic C0_int;
|
||||||
logic [4:0] C0_addr;
|
logic [4:0] C0_addr;
|
||||||
@ -168,7 +168,7 @@ module mycpu_top (
|
|||||||
.dc (dcache.mu),
|
.dc (dcache.mu),
|
||||||
.inst (inst.mu),
|
.inst (inst.mu),
|
||||||
.data (data.mu),
|
.data (data.mu),
|
||||||
.cacheOp (cache_op),
|
.cacheOp (cache_op.mu),
|
||||||
.inst_axi (inst_axi.mu),
|
.inst_axi (inst_axi.mu),
|
||||||
.rdata_axi (rdata_axi.mu),
|
.rdata_axi (rdata_axi.mu),
|
||||||
.wdata_axi (wdata_axi.mu),
|
.wdata_axi (wdata_axi.mu),
|
||||||
@ -243,9 +243,9 @@ module mycpu_top (
|
|||||||
Datapath datapath (
|
Datapath datapath (
|
||||||
.clk (aclk),
|
.clk (aclk),
|
||||||
.rst (~aresetn),
|
.rst (~aresetn),
|
||||||
.fetch_i (inst.cpu),
|
.fetch (inst.cpu),
|
||||||
.mem_i (data.cpu),
|
.mem (data.cpu),
|
||||||
.cache_op(cache_op),
|
.cache_op(cache_op.cpu),
|
||||||
|
|
||||||
.iTLBRefill (iTLBRefill),
|
.iTLBRefill (iTLBRefill),
|
||||||
.iTLBInvalid (iTLBInvalid),
|
.iTLBInvalid (iTLBInvalid),
|
||||||
|
Loading…
Reference in New Issue
Block a user