diff --git a/Makefile b/Makefile index 9e2203ac1..1b0eae3b1 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ agents = tb/agents/fu_if/fu_if.sv tb/agents/fu_if/fu_if_agent_pkg.sv \ interfaces = include/debug_if.svh include/mem_if.svh tb/agents/fifo_if/fifo_if.sv # this list contains the standalone components src = alu.sv tb/sequences/alu_sequence_pkg.sv tb/env/alu_env_pkg.sv tb/test/alu_lib_pkg.sv tb/alu_tb.sv \ - tb/scoreboard_tb.sv ptw.sv \ + tb/scoreboard_tb.sv ptw.sv tlb.sv \ if_stage.sv compressed_decoder.sv fetch_fifo.sv commit_stage.sv prefetch_buffer.sv \ mmu.sv lsu.sv fifo.sv tb/fifo_tb.sv mem_arbiter.sv \ scoreboard.sv issue_read_operands.sv decoder.sv id_stage.sv util/cluster_clock_gating.sv regfile.sv ex_stage.sv ariane.sv \ diff --git a/ariane.sv b/ariane.sv index 0f8297370..2e59f3ff3 100644 --- a/ariane.sv +++ b/ariane.sv @@ -93,7 +93,7 @@ module ariane priv_lvl_t priv_lvl_i; logic flag_pum_i; logic flag_mxr_i; - logic [19:0] pd_ppn_i; + logic [37:0] pd_ppn_i; logic [0:0] asid_i; logic flush_tlb_i; @@ -184,7 +184,7 @@ module ariane .lsu_valid_o ( lsu_valid_o ), // memory management - .enable_translation_i ( enable_translation_i ), // from CSR + .enable_translation_i ( 1'b0 ), // from CSR .fetch_req_i ( fetch_req_i ), .fetch_gnt_o ( fetch_gnt_o ), .fetch_valid_o ( fetch_valid_o ), diff --git a/btb.sv b/btb.sv deleted file mode 100644 index 771f05aae..000000000 --- a/btb.sv +++ /dev/null @@ -1,106 +0,0 @@ -// Author: Florian Zaruba, ETH Zurich -// Date: 19.04.2017 -// Description: Branch Target Buffer implementation -// -// Copyright (C) 2017 ETH Zurich, University of Bologna -// All rights reserved. -// -// This code is under development and not yet released to the public. -// Until it is released, the code is under the copyright of ETH Zurich and -// the University of Bologna, and may contain confidential and/or unpublished -// work. Any reuse/redistribution is strictly forbidden without written -// permission from ETH Zurich. -// -// Bug fixes and contributions will eventually be released under the -// SolderPad open hardware license in the context of the PULP platform -// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the -// University of Bologna. -// -import ariane_pkg::*; - -module btb #( - parameter int NR_ENTRIES = 64, - parameter int BITS_SATURATION_COUNTER = 2 - ) - ( - input logic clk_i, // Clock - input logic rst_ni, // Asynchronous reset active low - input logic flush_i, // flush the btb - - input logic [63:0] vpc_i, // virtual PC from IF stage - input misspredict misspredict_i, // a miss-predict happened -> update data structure - - output logic is_branch_o, // instruction at vpc_i is a branch - output logic predict_taken_o, // the branch is taken - output logic [63:0] branch_target_address_o // instruction has the following target address -); - // number of bits which are not used for indexing - localparam OFFSET = 2; - - // typedef for all branch target entries - // we may want to try to put a tag field that fills the rest of the PC in-order to mitigate aliasing effects - struct packed { - logic valid; - logic [63:0] target_address; - logic [BITS_SATURATION_COUNTER-1:0] saturation_counter; - } btb_n [NR_ENTRIES-1:0], btb_q [NR_ENTRIES-1:0]; - - logic [$clog2(NR_ENTRIES)-1:0] index, update_pc; - logic [BITS_SATURATION_COUNTER-1:0] saturation_counter; - - // get actual index positions - // we ignore the 0th bit since all instructions are aligned on - // a half word boundary - assign update_pc = misspredict_i.pc[$clog2(NR_ENTRIES) + OFFSET - 1:OFFSET]; - assign index = vpc_i[$clog2(NR_ENTRIES) + OFFSET - 1:OFFSET]; - - // we combinatorially predict the branch and the target address - assign is_branch_o = btb_q[$unsigned(index)].valid; - assign predict_taken_o = btb_q[$unsigned(index)].saturation_counter[BITS_SATURATION_COUNTER-1]; - assign branch_target_address_o = btb_q[$unsigned(index)].target_address; - - // update on a miss-predict - always_comb begin : update_misspredict - btb_n = btb_q; - saturation_counter = btb_q[$unsigned(update_pc)].saturation_counter; - - if (misspredict_i.valid) begin - btb_n[$unsigned(update_pc)].valid = 1'b1; - // update saturation counter - // first check if counter is already saturated in the positive regime e.g.: branch taken - if (saturation_counter == {BITS_SATURATION_COUNTER{1'b1}} && ~misspredict_i.is_taken) begin - // we can safely decrease it - btb_n[$unsigned(update_pc)].saturation_counter = saturation_counter - 1; - // then check if it saturated in the negative regime e.g.: branch not taken - end else if (saturation_counter == {BITS_SATURATION_COUNTER{1'b0}} && misspredict_i.is_taken) begin - // we can safely increase it - btb_n[$unsigned(update_pc)].saturation_counter = saturation_counter + 1; - end else begin // otherwise we are not in any boundaries and can decrease or increase it - if (misspredict_i.is_taken) - btb_n[$unsigned(update_pc)].saturation_counter = saturation_counter + 1; - else - btb_n[$unsigned(update_pc)].saturation_counter = saturation_counter - 1; - end - // the target address is simply updated - btb_n[$unsigned(update_pc)].target_address = misspredict_i.target_address; - end - end - - // sequential process - always_ff @(posedge clk_i or negedge rst_ni) begin - if(~rst_ni) begin - // TODO: think about the reset value - btb_q <= '{default: 0}; - end else begin - // evict all entries - if (flush_i) begin - for (int i = 0; i < NR_ENTRIES; i++) begin - btb_q[i].valid <= 1'b0; - btb_q[i].saturation_counter <= '{default: 0}; - end - end else begin - btb_q <= btb_n; - end - end - end -endmodule \ No newline at end of file diff --git a/ex_stage.sv b/ex_stage.sv index b4a9347ff..1e70f288e 100644 --- a/ex_stage.sv +++ b/ex_stage.sv @@ -55,7 +55,7 @@ module ex_stage #( input priv_lvl_t priv_lvl_i, input logic flag_pum_i, input logic flag_mxr_i, - input logic [19:0] pd_ppn_i, + input logic [37:0] pd_ppn_i, input logic [ASID_WIDTH-1:0] asid_i, input logic flush_tlb_i, mem_if.Slave instr_if, diff --git a/include/ariane_pkg.svh b/include/ariane_pkg.svh index f04ded0a3..9576a758c 100644 --- a/include/ariane_pkg.svh +++ b/include/ariane_pkg.svh @@ -153,6 +153,7 @@ package ariane_pkg; PRIV_LVL_S = 2'b01, PRIV_LVL_U = 2'b00 } priv_lvl_t; + // memory management, pte typedef struct packed { logic[37:0] ppn; @@ -166,6 +167,7 @@ package ariane_pkg; logic r; logic v; } pte_t; + // Bits required for representation of physical address space as 4K pages // (e.g. 27*4K == 39bit address space). localparam PPN4K_WIDTH = 38; diff --git a/lsu.sv b/lsu.sv index 88c850159..b1ff6e584 100644 --- a/lsu.sv +++ b/lsu.sv @@ -21,58 +21,100 @@ import ariane_pkg::*; module lsu #( parameter int ASID_WIDTH = 1 )( - input logic clk_i, - input logic rst_ni, + input logic clk_i, + input logic rst_ni, - input fu_op operator_i, - input logic [63:0] operand_a_i, - input logic [63:0] operand_b_i, - input logic [63:0] imm_i, - output logic lsu_ready_o, // FU is ready e.g. not busy - input logic lsu_valid_i, // Input is valid - input logic lsu_trans_id_i, // transaction id, needed for WB - output logic [4:0] lsu_trans_id_o, // ID of scoreboard entry at which to write back - output logic lsu_valid_o, // transaction id for which the output is the requested one + input fu_op operator_i, + input logic [63:0] operand_a_i, + input logic [63:0] operand_b_i, + input logic [63:0] imm_i, + output logic lsu_ready_o, // FU is ready e.g. not busy + input logic lsu_valid_i, // Input is valid + input logic [TRANS_ID_BITS-1:0] lsu_trans_id_i, // transaction id, needed for WB + output logic [TRANS_ID_BITS-1:0] lsu_trans_id_o, // ID of scoreboard entry at which to write back + output logic lsu_valid_o, // transaction id for which the output is the requested one - input logic enable_translation_i, + input logic enable_translation_i, - input logic fetch_req_i, - output logic fetch_gnt_o, - output logic fetch_valid_o, - output logic fetch_err_o, - input logic [63:0] fetch_vaddr_i, - output logic [31:0] fetch_rdata_o, + input logic fetch_req_i, + output logic fetch_gnt_o, + output logic fetch_valid_o, + output logic fetch_err_o, + input logic [63:0] fetch_vaddr_i, + output logic [31:0] fetch_rdata_o, - input priv_lvl_t priv_lvl_i, - input logic flag_pum_i, - input logic flag_mxr_i, - input logic [19:0] pd_ppn_i, - input logic [ASID_WIDTH-1:0] asid_i, - input logic flush_tlb_i, - mem_if.Slave instr_if, - mem_if.Slave data_if, + input priv_lvl_t priv_lvl_i, + input logic flag_pum_i, + input logic flag_mxr_i, + input logic [37:0] pd_ppn_i, + input logic [ASID_WIDTH-1:0] asid_i, + input logic flush_tlb_i, - output exception lsu_exception_o // to WB, signal exception status LD/ST exception + mem_if.Slave instr_if, + mem_if.Slave data_if, + + output exception lsu_exception_o // to WB, signal exception status LD/ST exception ); + assign lsu_trans_id_o = lsu_trans_id_i; + assign lsu_valid_o = 1'b0; + logic [63:0] vaddr; - // dummy implementation - // instruction interface - assign instr_if.data_req = fetch_req_i; - assign fetch_gnt_o = instr_if.data_gnt; - assign fetch_valid_o = instr_if.data_rvalid; - assign instr_if.address = fetch_vaddr_i; - assign fetch_rdata_o = instr_if.data_rdata; - assign fetch_err_o = 1'b0; - - // ------------------- - // MMU e.g.: TLBs/PTW - // ------------------- - // --------------- // Memory Arbiter // --------------- + logic [2:0][63:0] address_i; + logic [2:0][63:0] data_wdata_i; + logic [2:0] data_req_i; + logic [2:0] data_we_i; + logic [2:0][7:0] data_be_i; + logic [2:0] data_gnt_o; + logic [2:0] data_rvalid_o; + logic [2:0][63:0] data_rdata_o; + + mem_arbiter i_mem_arbiter ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + // to D$ + .address_o ( data_if.address ), + .data_wdata_o ( data_if.data_wdata ), + .data_req_o ( data_if.data_req ), + .data_we_o ( data_if.data_we ), + .data_be_o ( data_if.data_be ), + .data_gnt_i ( data_if.data_gnt ), + .data_rvalid_i( data_if.data_rvalid ), + .data_rdata_i ( data_if.data_rdata ), + + // from PTW, Load logic and store queue + .address_i ( address_i ), + .data_wdata_i ( data_wdata_i ), + .data_req_i ( data_req_i ), + .data_we_i ( data_we_i ), + .data_be_i ( data_be_i ), + .data_gnt_o ( data_gnt_o ), + .data_rvalid_o( data_rvalid_o ), + .data_rdata_o ( data_rdata_o ) + ); + + // ------------------- + // MMU e.g.: TLBs/PTW + // ------------------- + logic lsu_req_i; + logic [63:0] lsu_vaddr_i; + logic lsu_ready_wb_i; + + mmu #( + .INSTR_TLB_ENTRIES ( 16 ), + .DATA_TLB_ENTRIES ( 16 ), + .ASID_WIDTH ( ASID_WIDTH ) + ) i_mmu ( + .lsu_req_i ( lsu_req_i ), + .lsu_vaddr_i ( lsu_vaddr_i ), + .lsu_valid_o ( ), + .* + ); // --------------- // Store Queue diff --git a/mmu.sv b/mmu.sv index c220d33f5..a116d6c78 100644 --- a/mmu.sv +++ b/mmu.sv @@ -38,21 +38,18 @@ module mmu #( input logic [63:0] fetch_vaddr_i, output logic [31:0] fetch_rdata_o, // pass-through because of interfaces // LSU interface + // this is a more minimalistic interface because the actual addressing logic is handled + // in the LSU as we distinguish load and stores, what we do here is simple address translation input logic lsu_req_i, - output logic lsu_gnt_o, - output logic lsu_valid_o, - input logic lsu_we_i, - input logic [7:0] lsu_be_i, - output logic lsu_err_o, input logic [63:0] lsu_vaddr_i, - input logic [63:0] lsu_wdata_i, // pass-through because of interfaces - output logic [63:0] lsu_rdata_o, // pass-through because of interfaces + // if we need to walk the page table we can't grant in the same cycle + output logic lsu_valid_o, // translation is valid // General control signals input priv_lvl_t priv_lvl_i, input logic flag_pum_i, input logic flag_mxr_i, // input logic flag_mprv_i, - input logic [19:0] pd_ppn_i, + input logic [37:0] pd_ppn_i, input logic [ASID_WIDTH-1:0] asid_i, input logic flush_tlb_i, input logic lsu_ready_wb_i, @@ -62,13 +59,168 @@ module mmu #( // Data memory interface mem_if.Slave data_if ); - - // dummy implementation - // instruction interface - assign instr_if.data_req = fetch_req_i; - assign fetch_gnt_o = instr_if.data_gnt; - assign fetch_valid_o = instr_if.data_rvalid; - assign instr_if.address = fetch_vaddr_i; + // assignments necessary to use interfaces here + // only done for the few signals of the instruction interface + logic [63:0] fetch_paddr; + logic fetch_req; + assign instr_if.data_req = fetch_req; + assign instr_if.address = fetch_paddr; assign fetch_rdata_o = instr_if.data_rdata; - assign fetch_err_o = 1'b0; + // instruction error + logic ierr_valid_q, ierr_valid_n; + logic iaccess_err; + logic ptw_active; + logic walking_instr; + logic ptw_error; + + logic flush_i; + logic update_is_2M; + logic update_is_1G; + logic [26:0] update_vpn; + logic [0:0] update_asid; + pte_t update_content; + logic itlb_update; + logic itlb_lu_access; + logic [0:0] lu_asid_i; + logic [63:0] lu_vaddr_i; + pte_t itlb_content; + + logic itlb_is_2M; + logic itlb_is_1G; + logic itlb_lu_hit; + + tlb #( + .TLB_ENTRIES ( INSTR_TLB_ENTRIES ), + .ASID_WIDTH ( ASID_WIDTH ) + ) itlb_i ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .flush_i ( flush_i ), + .update_is_2M_i ( update_is_2M ), + .update_is_1G_i ( update_is_1G ), + .update_vpn_i ( update_vpn ), + .update_asid_i ( update_asid ), + .update_content_i ( update_content ), + .update_tlb_i ( itlb_update_i ), + + .lu_access_i ( itlb_lu_access ), + .lu_asid_i ( lu_asid_i ), + .lu_vaddr_i ( lu_vaddr_i ), + .lu_content_o ( itlb_content ), + .lu_is_2M_o ( itlb_is_2M ), + .lu_is_1G_o ( itlb_is_1G ), + .lu_hit_o ( itlb_lu_hit ) + ); + + ptw #( + .ASID_WIDTH ( ASID_WIDTH ) + ) ptw_i + ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .flush_i ( ), + .ptw_active_o ( ptw_active ), + .walking_instr_o ( walking_instr ), + .ptw_error_o ( ptw_error ), + .enable_translation_i ( enable_translation_i ), + + .address_o ( data_if.address ), + .data_wdata_o ( data_if.data_wdata ), + .data_req_o ( data_if.data_req ), + .data_we_o ( data_if.data_we ), + .data_be_o ( data_if.data_be ), + .data_gnt_i ( data_if.data_gnt ), + .data_rvalid_i ( data_if.data_rvalid ), + .data_rdata_i ( data_if.data_rdata ), + .itlb_update_o ( itlb_update ), + .dtlb_update_o ( ), + .update_content_o ( update_content ), + .update_is_2M_o ( update_is_2M ), + .update_is_1G_o ( update_is_1G ), + .update_vpn_o ( update_vpn ), + .update_asid_o ( update_asid ), + + .itlb_access_i ( itlb_lu_access ), + .itlb_miss_i ( ~itlb_lu_hit ), + .itlb_vaddr_i ( fetch_vaddr_i ), + + .dtlb_access_i ( ), + .dtlb_miss_i ( ), + .dtlb_vaddr_i ( ), + + .* + ); + + +assign iaccess_err = fetch_req_i & ( + ((priv_lvl_i == PRIV_LVL_U) & ~itlb_content.u) + | (flag_pum_i & (priv_lvl_i == PRIV_LVL_S) & itlb_content.u) + ); + + //----------------------- + // Instruction interface + //----------------------- + always_comb begin + // MMU disabled: just pass through + automatic logic fetch_valid = instr_if.data_rvalid; + fetch_req = fetch_req_i; + fetch_paddr = fetch_vaddr_i; + fetch_gnt_o = instr_if.data_gnt; + fetch_err_o = 1'b0; + ierr_valid_n = 1'b0; + + // MMU enabled: address from TLB, request delayed until hit. Error when TLB + // hit and no access right or TLB hit and translated address not valid (e.g. + // AXI decode error), or when PTW performs walk due to itlb miss and raises + // an error. + if (enable_translation_i) begin + fetch_req = 1'b0; + fetch_paddr = {itlb_content.ppn, fetch_vaddr_i[11:0]}; + + if (itlb_is_2M) begin + fetch_paddr[20:12] = fetch_vaddr_i[20:12]; + end + + if (itlb_is_1G) begin + fetch_paddr[29:12] = fetch_vaddr_i[29:12]; + end + + fetch_gnt_o = instr_if.data_gnt; + + // TODO the following two ifs should be mutually exclusive + if (itlb_lu_hit) begin + fetch_req = fetch_req_i; + if (iaccess_err) begin + // Play through an instruction fetch with error signaled with rvalid + fetch_req = 1'b0; + fetch_gnt_o = 1'b1; // immediate grant + //fetch_valid = 1'b0; NOTE: valid from previous fetch: pass through + // NOTE: back-to-back transfers: We only get a request if previous + // transfer is completed, or completes in this cycle) + ierr_valid_n = 1'b1; // valid signaled in next cycle + end + end + if (ptw_active & walking_instr) begin + // On error play through fetch with error signaled with valid + fetch_gnt_o = ptw_error; + ierr_valid_n = ptw_error; // signal valid/error on next cycle + end + end + fetch_err_o = ierr_valid_q; + fetch_valid_o = fetch_valid || ierr_valid_q; + end + + // registers + always_ff @(posedge clk_i or negedge rst_ni) begin + if(~rst_ni) begin + ierr_valid_q <= 1'b0; + end else begin + ierr_valid_q <= ierr_valid_n; + end + end + + //----------------------- + // Data interface + //----------------------- + endmodule \ No newline at end of file diff --git a/ptw.sv b/ptw.sv index bac9ca5a5..10694770c 100644 --- a/ptw.sv +++ b/ptw.sv @@ -21,8 +21,7 @@ import ariane_pkg::*; module ptw #( - parameter int ASID_WIDTH = 1, - parameter int CONTENT_SIZE = 24 // data: ppn + u + g + w + x_only , instr: ppn + u + g + parameter int ASID_WIDTH = 1 ) ( input logic clk_i, // Clock @@ -30,6 +29,9 @@ module ptw #( input logic flush_i, // flush everything, we need to do this because // actually everything we do is speculative at this stage // e.g.: there could be a CSR instruction that changes everything + output logic ptw_active_o, + output logic walking_instr_o, // set when walking for TLB + output logic ptw_error_o, // set when an error occured input logic enable_translation_i, // memory port output logic [63:0] address_o, @@ -43,23 +45,21 @@ module ptw #( // to TLBs, update logic output logic itlb_update_o, output logic dtlb_update_o, - output logic [CONTENT_SIZE-1:0] itlb_update_content_o, - output logic [CONTENT_SIZE-1:0] dtlb_update_content_o, + output pte_t update_content_o, output logic update_is_2M_o, output logic update_is_1G_o, output logic [26:0] update_vpn_o, output logic [ASID_WIDTH-1:0] update_asid_o, + input logic [ASID_WIDTH-1:0] asid_i, // from TLBs // did we miss? input logic itlb_access_i, input logic itlb_miss_i, - input logic [ASID_WIDTH-1:0] itlb_asid_i, input logic [63:0] itlb_vaddr_i, input logic dtlb_access_i, input logic dtlb_miss_i, - input logic [ASID_WIDTH-1:0] dtlb_asid_i, input logic [63:0] dtlb_vaddr_i, // from CSR file input logic [37:0] pd_ppn_i, // ppn from sptbr @@ -77,15 +77,17 @@ module ptw #( PTW_PROPAGATE_ERROR } ptw_state_q, ptw_state_n; - // RV39 defines three levels of page tables + // SV39 defines three levels of page tables enum logic [1:0] { LVL1, LVL2, LVL3 } ptw_lvl_q, ptw_lvl_n; - logic ptw_active; - assign ptw_active = (ptw_state_q != PTW_READY); // is this an instruction page table walk? logic is_instr_ptw_q, is_instr_ptw_n; + + assign ptw_active_o = (ptw_state_q != PTW_READY); + assign walking_instr_o = is_instr_ptw_q; + // register the ASID logic [ASID_WIDTH-1:0] tlb_update_asid_q, tlb_update_asid_n; // register the VPN we need to walk @@ -101,40 +103,7 @@ module ptw #( assign update_vpn_o = tlb_update_vpn_q; assign update_asid_o = tlb_update_asid_q; - struct packed { - // logic r; don't care - // logic w; don't care - // logic x; If page isn't executable it isn't put in the instruction TLB - logic u; - logic g; - logic[PPN4K_WIDTH-1:0] ppn; - } itlb_content; - - struct packed { - // logic r; If page isn't readable it isn't put in the data TLB (unless it - // is executable and the MXR flag is set) - logic x_only; // Because of the MXR flag we need an indication if the page - // is actually not readable, but executable - logic w; - logic u; - logic g; - logic[PPN4K_WIDTH-1:0] ppn; - } dtlb_content; - - always_comb begin - itlb_update_content_o = '{ - u : ptw_pte_i.u, - g : ptw_pte_i.g, - ppn : ptw_pte_i.ppn[37:0] - }; - dtlb_update_content_o = '{ - x_only : ptw_pte_i.x & ~ptw_pte_i.r, - w : ptw_pte_i.w, - u : ptw_pte_i.u, - g : ptw_pte_i.g, - ppn : ptw_pte_i.ppn[37:0] - }; - end + assign update_content_o = ptw_pte_i; //------------------- // Page table walker @@ -162,6 +131,7 @@ module ptw #( always_comb begin : ptw // default assignments data_req_o = 1'b0; + ptw_error_o = 1'b0; itlb_update_o = 1'b0; dtlb_update_o = 1'b0; is_instr_ptw_n = is_instr_ptw_q; @@ -178,14 +148,14 @@ module ptw #( if (enable_translation_i & itlb_access_i & itlb_miss_i & ~dtlb_access_i) begin ptw_pptr_n = {pd_ppn_i, itlb_vaddr_i[38:30]}; is_instr_ptw_n = 1'b0; - tlb_update_asid_n = itlb_asid_i; + tlb_update_asid_n = asid_i; tlb_update_vpn_n = itlb_vaddr_i[38:12]; ptw_state_n = PTW_WAIT_GRANT; // we got a DTLB miss end else if (enable_translation_i & dtlb_access_i & dtlb_miss_i) begin ptw_pptr_n = {pd_ppn_i, dtlb_vaddr_i[38:30]}; is_instr_ptw_n = 1'b0; - tlb_update_asid_n = dtlb_asid_i; + tlb_update_asid_n = asid_i; tlb_update_vpn_n = dtlb_vaddr_i[38:12]; ptw_state_n = PTW_WAIT_GRANT; end @@ -263,6 +233,7 @@ module ptw #( // TODO: propagate error PTW_PROPAGATE_ERROR: begin ptw_state_n = PTW_READY; + ptw_error_o = 1'b1; end default: diff --git a/tlb.sv b/tlb.sv index ba5441bb2..339ed9693 100644 --- a/tlb.sv +++ b/tlb.sv @@ -17,11 +17,11 @@ // (http://www.pulp-platform.org), under the copyright of ETH Zurich and the // University of Bologna. // +import ariane_pkg::*; module tlb #( parameter int TLB_ENTRIES = 4, - parameter int ASID_WIDTH = 1, - parameter int CONTENT_SIZE = 24 // data: ppn + u + g + w + x_only , instr: ppn + u + g + parameter int ASID_WIDTH = 1 ) ( input logic clk_i, // Clock @@ -33,14 +33,14 @@ module tlb #( input logic update_is_1G_i, input logic [26:0] update_vpn_i, input logic [ASID_WIDTH-1:0] update_asid_i, - input logic [CONTENT_SIZE-1:0] update_content_i, + input pte_t update_content_i, input logic update_tlb_i, // Lookup signals input logic lu_access_i, input logic [ASID_WIDTH-1:0] lu_asid_i, input logic [63:0] lu_vaddr_i, - output logic [CONTENT_SIZE-1:0] lu_content_o, + output pte_t lu_content_o, output logic lu_is_2M_o, output logic lu_is_1G_o, output logic lu_hit_o @@ -57,7 +57,7 @@ module tlb #( logic valid; } [TLB_ENTRIES-1:0] tags_q, tags_n; - logic [TLB_ENTRIES-1:0][CONTENT_SIZE-1:0] content_q, content_n; + pte_t [TLB_ENTRIES-1:0] content_q, content_n; logic [8:0] vpn0, vpn1, vpn2; logic [TLB_ENTRIES-1:0] lu_hit; // to replacement logic logic [TLB_ENTRIES-1:0] replace_en; // replace the following entry, set by replacement strategy