TLB updates

This commit is contained in:
Eric Matthews 2020-08-15 11:02:55 -07:00
parent b150f3a627
commit ffcc2ef7c6
4 changed files with 36 additions and 48 deletions

View file

@ -80,6 +80,7 @@ module gc_unit(
output logic gc_fetch_flush,
output logic gc_fetch_pc_override,
output logic gc_supress_writeback,
output logic gc_tlb_flush,
output logic [31:0] gc_fetch_pc,
@ -204,6 +205,7 @@ module gc_unit(
gc_issue_hold <= issue.new_request || second_cycle_flush || processing_csr || (next_state inside {PRE_CLEAR_STATE, INIT_CLEAR_STATE, TLB_CLEAR_STATE, IQ_DRAIN}) || potential_branch_exception;
gc_supress_writeback <= next_state inside {PRE_CLEAR_STATE, INIT_CLEAR_STATE, TLB_CLEAR_STATE} ? 1 : 0;
gc_init_clear <= (next_state == INIT_CLEAR_STATE);
gc_tlb_flush <= next_state inside {INIT_CLEAR_STATE, TLB_CLEAR_STATE};
end
////////////////////////////////////////////////////

View file

@ -148,12 +148,12 @@ interface mmu_interface;
//From CSR
logic [21:0] ppn;
logic mxr; //Make eXecutable Readable
logic pum; //Protect User Memory
logic sum; //permit Supervisor User Memory access
logic [1:0] privilege;
modport mmu (input virtual_address, new_request, execute, rnw, ppn, mxr, pum, privilege, output write_entry, new_phys_addr);
modport mmu (input virtual_address, new_request, execute, rnw, ppn, mxr, sum, privilege, output write_entry, new_phys_addr);
modport tlb (input write_entry, new_phys_addr, output new_request, virtual_address, execute, rnw);
modport csr (output ppn, mxr, pum, privilege);
modport csr (output ppn, mxr, sum, privilege);
endinterface
@ -166,12 +166,8 @@ interface tlb_interface;
logic complete;
logic [31:0] physical_address;
logic flush;
logic flush_complete;
modport tlb (input virtual_address, new_request, flush, rnw, execute, output complete, physical_address, flush_complete);
modport tlb (input virtual_address, new_request, rnw, execute, output complete, physical_address);
modport mem (output new_request, virtual_address, rnw, execute, input complete, physical_address);
modport fence (output flush, input flush_complete);
endinterface

View file

@ -127,6 +127,7 @@ module taiga (
logic gc_fetch_flush;
logic gc_fetch_pc_override;
logic gc_supress_writeback;
logic gc_tlb_flush;
logic [31:0] gc_fetch_pc;
logic[31:0] csr_rd;
@ -289,6 +290,7 @@ module taiga (
.clk (clk),
.rst (rst),
.tlb_on (tlb_on),
.gc_tlb_flush (gc_tlb_flush),
.asid (asid),
.tlb (itlb),
.mmu (immu)
@ -445,6 +447,7 @@ module taiga (
.clk (clk),
.rst (rst),
.tlb_on (tlb_on),
.gc_tlb_flush (gc_tlb_flush),
.asid (asid),
.tlb (dtlb),
.mmu (dmmu)
@ -496,6 +499,7 @@ module taiga (
.gc_fetch_flush (gc_fetch_flush),
.gc_fetch_pc_override (gc_fetch_pc_override),
.gc_supress_writeback (gc_supress_writeback),
.gc_tlb_flush (gc_tlb_flush),
.gc_fetch_pc (gc_fetch_pc),
.csr_rd (csr_rd),
.csr_id (csr_id),

View file

@ -31,11 +31,12 @@ module tlb_lut_ram #(
input logic clk,
input logic rst,
input logic tlb_on,
input gc_tlb_flush,
input logic [ASIDLEN-1:0] asid,
mmu_interface.tlb mmu,
tlb_interface.tlb tlb
);
//////////////////////////////////////////
localparam TLB_TAG_W = 32-12-$clog2(DEPTH);
typedef struct packed {
@ -44,36 +45,39 @@ module tlb_lut_ram #(
logic [19:0] phys_addr;
} tlb_entry_t;
logic [$clog2(DEPTH)-1:0] tlb_read_addr;
logic [$clog2(DEPTH)-1:0] tlb_write_addr;
logic [$clog2(DEPTH)-1:0] tlb_addr;
logic [TLB_TAG_W-1:0] virtual_tag;
tlb_entry_t ram [DEPTH-1:0][WAYS-1:0];
logic [DEPTH-1:0] valid [WAYS-1:0];
logic [WAYS-1:0] tag_hit;
logic hit;
logic [WAYS-1:0] replacement_way;
logic [$bits(tlb_entry_t)-1:0] ram_data [WAYS-1:0][1];
tlb_entry_t ram_entry [WAYS-1:0];
tlb_entry_t new_entry;
logic flush_in_progress;
logic [$clog2(DEPTH)-1:0] flush_addr;
logic hit;
logic [WAYS-1:0] tlb_write;
////////////////////////////////////////////////////
//Implementation
//LUTRAM-based
//Reset is performed sequentially, coordinated by the gc unit
assign virtual_tag = tlb.virtual_address[31:32-TLB_TAG_W];
assign tlb_read_addr = tlb.virtual_address[$clog2(DEPTH)+11:12];
always_ff @ (posedge clk) begin
if (~flush_in_progress)
flush_addr <= 0;
else
flush_addr <= flush_addr + 1;
end
assign tlb_write_addr = tlb.flush ? flush_addr : tlb_read_addr;
assign tlb_write = tlb.flush ? {WAYS{flush_in_progress}} : (replacement_way & {WAYS{mmu.write_entry}});
assign tlb_addr = tlb.virtual_address[12 +: $clog2(DEPTH)];
assign tlb_write = {WAYS{gc_tlb_flush}} | replacement_way;
assign new_entry.valid = ~tlb.flush;
assign new_entry.valid = ~gc_tlb_flush;
assign new_entry.tag = virtual_tag;
assign new_entry.phys_addr = mmu.new_phys_addr;
@ -81,9 +85,14 @@ module tlb_lut_ram #(
generate
for (i=0; i<WAYS; i=i+1) begin : lut_rams
lut_ram #(.WIDTH($bits(tlb_entry_t)), .DEPTH(DEPTH), .READ_PORTS(1))
ram_block (.clk(clk),
.waddr(tlb_write_addr), .ram_write(tlb_write[i]), .new_ram_data(new_entry),
.raddr({tlb_read_addr}), .ram_data_out(ram_data[i]));
ram_block (
.clk(clk),
.waddr(tlb_addr),
.ram_write(tlb_write[i]),
.new_ram_data(new_entry),
.raddr({tlb_addr}),
.ram_data_out(ram_data[i])
);
assign ram_entry[i] = ram_data[i][0];
end
endgenerate
@ -95,30 +104,7 @@ module tlb_lut_ram #(
.one_hot (replacement_way)
);
always_ff @ (posedge clk) begin
if (rst)
flush_in_progress <= 0;
else if (tlb.flush_complete)
flush_in_progress <= 0;
else if (tlb.flush)
flush_in_progress <= 1;
end
always_ff @ (posedge clk) begin
if (rst)
flush_addr <= 0;
else if (flush_in_progress)
flush_addr <= flush_addr + 1;
end
always_ff @ (posedge clk) begin
if (rst)
tlb.flush_complete <= 0;
else
tlb.flush_complete <= (flush_addr == (DEPTH-1));
end
assign virtual_tag = tlb.virtual_address[31:32-TLB_TAG_W];
always_comb begin
for (int i=0; i<WAYS; i=i+1) begin