Skip to content

Commit

Permalink
Add support for SV32 MMU (openhwgroup#701)
Browse files Browse the repository at this point in the history
Signed-off-by: Florian Zaruba <[email protected]>
Co-authored-by: sjthales <[email protected]>
  • Loading branch information
zarubaf and sjthales authored Aug 5, 2021
1 parent 1eb23f8 commit 9717239
Show file tree
Hide file tree
Showing 15 changed files with 1,288 additions and 56 deletions.
9 changes: 6 additions & 3 deletions Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,12 @@ sources:
- src/compressed_decoder.sv
- src/axi_shim.sv
- src/ex_stage.sv
- src/mmu.sv
- src/ptw.sv
- src/mult.sv
- src/mmu_sv39/mmu.sv
- src/mmu_sv39/ptw.sv
- src/mmu_sv39/mult.sv
- src/mmu_sv32/cva6_mmu_sv32.sv
- src/mmu_sv32/cva6_ptw_sv32.sv
- src/mmu_sv32/cva6_mult_sv32.sv
- src/load_unit.sv
- src/issue_read_operands.sv
- src/pmp/src/pmp_entry.sv
Expand Down
3 changes: 2 additions & 1 deletion Flist.ariane
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ src/issue_read_operands.sv
src/issue_stage.sv
src/load_unit.sv
src/load_store_unit.sv
src/mmu.sv
src/mmu_sv39/mmu.sv
src/mmu_sv32/cva6_mmu_sv32.sv
src/mult.sv
src/multiplier.sv
src/serdiv.sv
Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ src := $(filter-out src/ariane_regfile.sv, $(wildcard src/*.sv)) \
$(wildcard src/axi_riscv_atomics/src/*.sv) \
$(wildcard src/axi_mem_if/src/*.sv) \
$(wildcard src/pmp/src/*.sv) \
$(wildcard src/mmu_sv32/*.sv) \
$(wildcard src/mmu_sv39/*.sv) \
src/rv_plic/rtl/rv_plic_target.sv \
src/rv_plic/rtl/rv_plic_gateway.sv \
src/rv_plic/rtl/plic_regmap.sv \
Expand Down
9 changes: 6 additions & 3 deletions ariane.core
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,20 @@ filesets:
- src/lsu_arbiter.sv
- src/lsu.sv
- src/miss_handler.sv
- src/mmu.sv
- src/mmu_sv39/mmu.sv
- src/mmu_sv32/cva6_mmu_sv32.sv
- src/mult.sv
- src/nbdcache.sv
- src/pcgen_stage.sv
- src/perf_counters.sv
- src/ptw.sv
- src/mmu_sv39/ptw.sv
- src/mmu_sv32/cva6_ptw_sv32.sv
- src/regfile_ff.sv
- src/scoreboard.sv
- src/store_buffer.sv
- src/store_unit.sv
- src/tlb.sv
- src/mmu_sv39/tlb.sv
- src/mmu_sv32/cva6_tlb_sv32.sv
file_type : systemVerilogSource
depend :
- pulp-platform.org::axi_mem_if
Expand Down
15 changes: 14 additions & 1 deletion include/ariane_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,11 @@ package ariane_pkg;
// we want jump accordingly e.g.: +4, +2
} scoreboard_entry_t;

// ---------------
// MMU instanciation
// ---------------
localparam bit MMU_PRESENT = 1'b1; // MMU is present

// --------------------
// Atomics
// --------------------
Expand All @@ -635,7 +640,7 @@ package ariane_pkg;
logic valid; // valid flag
logic is_2M; //
logic is_1G; //
logic [26:0] vpn;
logic [27-1:0] vpn; // VPN (39bits) = 27bits + 12bits offset
logic [ASID_WIDTH-1:0] asid;
riscv::pte_t content;
} tlb_update_t;
Expand All @@ -644,6 +649,14 @@ package ariane_pkg;
// (e.g. 27*4K == 39bit address space).
localparam PPN4K_WIDTH = 38;

typedef struct packed {
logic valid; // valid flag
logic is_4M; //
logic [20-1:0] vpn; //VPN (32bits) = 20bits + 12bits offset
logic [9-1:0] asid; //ASID length = 9 for Sv32 mmu
riscv::pte_sv32_t content;
} tlb_update_sv32_t;

typedef enum logic [1:0] {
FE_NONE,
FE_INSTR_ACCESS_FAULT,
Expand Down
29 changes: 26 additions & 3 deletions include/riscv_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ package riscv;
// Warning: When using STD_CACHE, configuration must be PLEN=56 and VLEN=64
// Warning: VLEN must be superior or equal to PLEN
localparam VLEN = (XLEN == 32) ? 32 : 64; // virtual address length
localparam PLEN = (XLEN == 32) ? 32 : 56; // physical address length
localparam PLEN = (XLEN == 32) ? 34 : 56; // physical address length

localparam IS_XLEN32 = (XLEN == 32) ? 1'b1 : 1'b0;
localparam IS_XLEN64 = (XLEN == 32) ? 1'b0 : 1'b1;
Expand Down Expand Up @@ -267,10 +267,10 @@ package riscv;
// ----------------------
// Virtual Memory
// ----------------------
// memory management, pte
// memory management, pte for sv39
typedef struct packed {
logic [9:0] reserved;
logic [PLEN-12-1:0] ppn;
logic [44-1:0] ppn; // PPN length for
logic [1:0] rsw;
logic d;
logic a;
Expand All @@ -282,6 +282,20 @@ package riscv;
logic v;
} pte_t;

// memory management, pte for sv32
typedef struct packed {
logic [22-1:0] ppn; // PPN length for
logic [1:0] rsw;
logic d;
logic a;
logic g;
logic u;
logic x;
logic w;
logic r;
logic v;
} pte_sv32_t;

// ----------------------
// Exception Cause Codes
// ----------------------
Expand Down Expand Up @@ -637,10 +651,19 @@ package riscv;
return {csr, 5'h0, 3'h2, dest, 7'h73};
endfunction

function automatic logic [31:0] branch(logic [4:0] src2, logic [4:0] src1, logic [2:0] funct3, logic [11:0] offset);
// OpCode Branch
return {offset[11], offset[9:4], src2, src1, funct3, offset[3:0], offset[10], 7'b11_000_11};
endfunction

function automatic logic [31:0] ebreak ();
return 32'h00100073;
endfunction

function automatic logic [31:0] wfi ();
return 32'h10500073;
endfunction

function automatic logic [31:0] nop ();
return 32'h00000013;
endfunction
Expand Down
1 change: 1 addition & 0 deletions src/csr_regfile.sv
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,7 @@ module csr_regfile import ariane_pkg::*; #(
`endif
dcsr_q <= '0;
dcsr_q.prv <= riscv::PRIV_LVL_M;
dcsr_q.xdebugver <= 4'h4;
dpc_q <= '0;
dscratch0_q <= {riscv::XLEN{1'b0}};
dscratch1_q <= {riscv::XLEN{1'b0}};
Expand Down
118 changes: 91 additions & 27 deletions src/load_store_unit.sv
Original file line number Diff line number Diff line change
Expand Up @@ -130,34 +130,98 @@ module load_store_unit import ariane_pkg::*; #(
// -------------------
// MMU e.g.: TLBs/PTW
// -------------------
mmu #(
.INSTR_TLB_ENTRIES ( 16 ),
.DATA_TLB_ENTRIES ( 16 ),
.ASID_WIDTH ( ASID_WIDTH ),
.ArianeCfg ( ArianeCfg )
) i_mmu (
if (MMU_PRESENT && (riscv::XLEN == 64)) begin : gen_mmu_sv39
mmu #(
.INSTR_TLB_ENTRIES ( 16 ),
.DATA_TLB_ENTRIES ( 16 ),
.ASID_WIDTH ( ASID_WIDTH ),
.ArianeCfg ( ArianeCfg )
) i_cva6_mmu (
// misaligned bypass
.misaligned_ex_i ( misaligned_exception ),
.lsu_is_store_i ( st_translation_req ),
.lsu_req_i ( translation_req ),
.lsu_vaddr_i ( mmu_vaddr ),
.lsu_valid_o ( translation_valid ),
.lsu_paddr_o ( mmu_paddr ),
.lsu_exception_o ( mmu_exception ),
.lsu_dtlb_hit_o ( dtlb_hit ), // send in the same cycle as the request
.lsu_dtlb_ppn_o ( dtlb_ppn ), // send in the same cycle as the request
// connecting PTW to D$ IF
.req_port_i ( dcache_req_ports_i [0] ),
.req_port_o ( dcache_req_ports_o [0] ),
// icache address translation requests
.icache_areq_i ( icache_areq_i ),
.asid_to_be_flushed_i,
.vaddr_to_be_flushed_i,
.icache_areq_o ( icache_areq_o ),
.pmpcfg_i,
.pmpaddr_i,
.*
);
.misaligned_ex_i ( misaligned_exception ),
.lsu_is_store_i ( st_translation_req ),
.lsu_req_i ( translation_req ),
.lsu_vaddr_i ( mmu_vaddr ),
.lsu_valid_o ( translation_valid ),
.lsu_paddr_o ( mmu_paddr ),
.lsu_exception_o ( mmu_exception ),
.lsu_dtlb_hit_o ( dtlb_hit ), // send in the same cycle as the request
.lsu_dtlb_ppn_o ( dtlb_ppn ), // send in the same cycle as the request
// connecting PTW to D$ IF
.req_port_i ( dcache_req_ports_i [0] ),
.req_port_o ( dcache_req_ports_o [0] ),
// icache address translation requests
.icache_areq_i ( icache_areq_i ),
.asid_to_be_flushed_i,
.vaddr_to_be_flushed_i,
.icache_areq_o ( icache_areq_o ),
.pmpcfg_i,
.pmpaddr_i,
.*
);
end else if (MMU_PRESENT && (riscv::XLEN == 32)) begin : gen_mmu_sv32
cva6_mmu_sv32 #(
.INSTR_TLB_ENTRIES ( 16 ),
.DATA_TLB_ENTRIES ( 16 ),
.ASID_WIDTH ( ASID_WIDTH ),
.ArianeCfg ( ArianeCfg )
) i_cva6_mmu (
// misaligned bypass
.misaligned_ex_i ( misaligned_exception ),
.lsu_is_store_i ( st_translation_req ),
.lsu_req_i ( translation_req ),
.lsu_vaddr_i ( mmu_vaddr ),
.lsu_valid_o ( translation_valid ),
.lsu_paddr_o ( mmu_paddr ),
.lsu_exception_o ( mmu_exception ),
.lsu_dtlb_hit_o ( dtlb_hit ), // send in the same cycle as the request
.lsu_dtlb_ppn_o ( dtlb_ppn ), // send in the same cycle as the request
// connecting PTW to D$ IF
.req_port_i ( dcache_req_ports_i [0] ),
.req_port_o ( dcache_req_ports_o [0] ),
// icache address translation requests
.icache_areq_i ( icache_areq_i ),
.asid_to_be_flushed_i,
.vaddr_to_be_flushed_i,
.icache_areq_o ( icache_areq_o ),
.pmpcfg_i,
.pmpaddr_i,
.*
);
end else begin : gen_no_mmu
assign icache_areq_o.fetch_valid = icache_areq_i.fetch_req;
assign icache_areq_o.fetch_paddr = icache_areq_i.fetch_vaddr[riscv::PLEN-1:0];
assign icache_areq_o.fetch_exception = '0;

assign dcache_req_ports_o[0].address_index = '0;
assign dcache_req_ports_o[0].address_tag = '0;
assign dcache_req_ports_o[0].data_wdata = 64'b0;
assign dcache_req_ports_o[0].data_req = 1'b0;
assign dcache_req_ports_o[0].data_be = 8'hFF;
assign dcache_req_ports_o[0].data_size = 2'b11;
assign dcache_req_ports_o[0].data_we = 1'b0;
assign dcache_req_ports_o[0].kill_req = '0;
assign dcache_req_ports_o[0].tag_valid = 1'b0;

assign itlb_miss_o = 1'b0;
assign dtlb_miss_o = 1'b0;
assign dtlb_ppn = mmu_vaddr[riscv::PLEN-1:12];
assign dtlb_hit = 1'b1;

assign mmu_exception = '0;

always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
mmu_paddr <= '0;
translation_valid <= '0;
end else begin
mmu_paddr <= mmu_vaddr[riscv::PLEN-1:0];
translation_valid <= translation_req;
end
end
end


logic store_buffer_empty;
// ------------------
// Store Unit
Expand Down
Loading

0 comments on commit 9717239

Please sign in to comment.