diff --git a/core/gc_unit.sv b/core/gc_unit.sv index c81dcfb..f904b2c 100644 --- a/core/gc_unit.sv +++ b/core/gc_unit.sv @@ -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 //////////////////////////////////////////////////// diff --git a/core/interfaces.sv b/core/interfaces.sv index b8ede81..27fa095 100755 --- a/core/interfaces.sv +++ b/core/interfaces.sv @@ -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 diff --git a/core/taiga.sv b/core/taiga.sv index 9a18f96..9f34cce 100755 --- a/core/taiga.sv +++ b/core/taiga.sv @@ -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), diff --git a/core/tlb_lut_ram.sv b/core/tlb_lut_ram.sv index 0d6f8fa..297b441 100755 --- a/core/tlb_lut_ram.sv +++ b/core/tlb_lut_ram.sv @@ -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