-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Copyright 2022 ETH Zurich and University of Bologna. | ||
// Solderpad Hardware License, Version 0.51, see LICENSE for details. | ||
// SPDX-License-Identifier: SHL-0.51 | ||
// | ||
// Author: Matteo Perotti <[email protected]> | ||
// | ||
// Description: Simple memory translation request generator for CVA6's shared MMU | ||
// Generate a request after mmu_req_lat_i cycles from last answer | ||
// Enable with mmu_req_en_i | ||
|
||
module mmu_req_gen ( | ||
input logic clk_i, | ||
input logic rst_ni, | ||
input logic mmu_req_en_i, // Enable the mmu req generator | ||
input logic [5:0] mmu_req_lat_i, // Latency for a new req after last answer (max: 62) | ||
Check warning on line 15 in hw/mmu_req_gen.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/mmu_req_gen.sv#L15
Raw output
|
||
// MMU interface with accelerator | ||
output ariane_pkg::exception_t acc_mmu_misaligned_ex_o, | ||
output logic acc_mmu_req_o, // request address translation | ||
output logic [riscv::VLEN-1:0] acc_mmu_vaddr_o, // virtual address in | ||
output logic acc_mmu_is_store_o, // the translation is requested by a store | ||
Check warning on line 20 in hw/mmu_req_gen.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/mmu_req_gen.sv#L20
Raw output
|
||
input logic acc_mmu_valid_i // translation is valid | ||
); | ||
|
||
// Registers | ||
`include "common_cells/registers.svh" | ||
|
||
logic wait_ans_d, wait_ans_q; | ||
logic acc_mmu_req_d, acc_mmu_req_q; | ||
logic mmu_req_en_q; | ||
logic [5:0] mmu_req_lat_d, mmu_req_lat_q; | ||
logic [5:0] ans2req_cnt_d, ans2req_cnt_q; | ||
logic [5:0] cnt_threshold; | ||
|
||
`FF(wait_ans_q, wait_ans_d, '0, clk_i, rst_ni) | ||
`FF(mmu_req_en_q, mmu_req_en_i, '0, clk_i, rst_ni) | ||
`FF(mmu_req_lat_q, mmu_req_lat_d, '0, clk_i, rst_ni) | ||
`FF(ans2req_cnt_q, ans2req_cnt_d, '0, clk_i, rst_ni) | ||
`FF(acc_mmu_req_q, acc_mmu_req_d, '0, clk_i, rst_ni) | ||
|
||
assign cnt_threshold = mmu_req_lat_q; | ||
assign acc_mmu_req_o = acc_mmu_req_d | acc_mmu_req_q; | ||
|
||
always_comb begin | ||
acc_mmu_misaligned_ex_o = '0; | ||
acc_mmu_vaddr_o = '0; | ||
acc_mmu_is_store_o = '0; | ||
|
||
wait_ans_d = wait_ans_q; | ||
mmu_req_lat_d = mmu_req_lat_q; | ||
ans2req_cnt_d = ans2req_cnt_q; | ||
acc_mmu_req_d = acc_mmu_req_q; | ||
|
||
// Act only if enabled | ||
if (mmu_req_en_q) begin | ||
// If we are not waiting for an answer or if it arrived, count up | ||
if (!wait_ans_q) begin | ||
ans2req_cnt_d += 1; | ||
|
||
// If we have reached the threshold already, make the request and wait for ans | ||
if (ans2req_cnt_q == cnt_threshold) begin | ||
acc_mmu_req_d = 1'b1; | ||
wait_ans_d = 1'b1; | ||
end | ||
end | ||
|
||
// Ans arrived | ||
if (acc_mmu_valid_i) begin | ||
// Reset the req and the counter | ||
ans2req_cnt_d = '0; | ||
acc_mmu_req_d = 1'b0; | ||
// We are not waiting anymore for ans | ||
wait_ans_d = 1'b0; | ||
end | ||
end | ||
end | ||
|
||
endmodule |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
// Copyright 2022 ETH Zurich and University of Bologna. | ||
// Solderpad Hardware License, Version 0.51, see LICENSE for details. | ||
// SPDX-License-Identifier: SHL-0.51 | ||
// | ||
// Author: Vincenzo Maisto <[email protected]> | ||
// | ||
// Description: Simple stub emulating MMU behaviour | ||
|
||
module mmu_stub ( | ||
// Configuration from SoC regfile | ||
input logic ex_en_i, // Exception enable/disable. If disable, the internal status for the exception is reset | ||
Check warning on line 11 in hw/mmu_stub.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/mmu_stub.sv#L11
Raw output
Check warning on line 11 in hw/mmu_stub.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/mmu_stub.sv#L11
Raw output
|
||
input logic [31:0] no_ex_lat_i, // Number of requests to accept before throwing an exception | ||
Check warning on line 12 in hw/mmu_stub.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/mmu_stub.sv#L12
Raw output
Check warning on line 12 in hw/mmu_stub.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/mmu_stub.sv#L12
Raw output
|
||
input logic [31:0] req_rsp_lat_i, // Latency between request and response | ||
Check warning on line 13 in hw/mmu_stub.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/mmu_stub.sv#L13
Raw output
|
||
// Interface | ||
input logic clk_i, | ||
Check warning on line 15 in hw/mmu_stub.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/mmu_stub.sv#L15
Raw output
|
||
input logic rst_ni, | ||
Check warning on line 16 in hw/mmu_stub.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/mmu_stub.sv#L16
Raw output
|
||
input logic en_ld_st_translation_i, // Enable behaviour | ||
Check warning on line 17 in hw/mmu_stub.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/mmu_stub.sv#L17
Raw output
|
||
input ariane_pkg::exception_t misaligned_ex_i, // Ignored | ||
Check warning on line 18 in hw/mmu_stub.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/mmu_stub.sv#L18
Raw output
|
||
input logic req_i, | ||
Check warning on line 19 in hw/mmu_stub.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/mmu_stub.sv#L19
Raw output
|
||
input logic [riscv::VLEN-1:0] vaddr_i, | ||
input logic is_store_i, // Mux exception_o.tval | ||
Check warning on line 21 in hw/mmu_stub.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/mmu_stub.sv#L21
Raw output
|
||
// Cycle 0 | ||
output logic dtlb_hit_o, | ||
Check warning on line 23 in hw/mmu_stub.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/mmu_stub.sv#L23
Raw output
|
||
output logic [riscv::PPNW-1:0] dtlb_ppn_o, // Constant '1 | ||
// Cycle 1 | ||
output logic valid_o, | ||
Check warning on line 26 in hw/mmu_stub.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/mmu_stub.sv#L26
Raw output
|
||
output logic [riscv::PLEN-1:0] paddr_o, // Same as vaddr_i | ||
output ariane_pkg::exception_t exception_o // Valid on trigger_exception_i | ||
Check warning on line 28 in hw/mmu_stub.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/mmu_stub.sv#L28
Raw output
|
||
); | ||
|
||
// Registers | ||
`include "common_cells/registers.svh" | ||
logic [riscv::PLEN-1:0] mock_paddr_d, mock_paddr_q; | ||
logic [riscv::VLEN-1:0] vaddr_d, vaddr_q; | ||
logic is_store_q, is_store_d; | ||
logic lat_cnt_en, lat_cnt_clr; | ||
logic [31:0] lat_cnt_q, lat_cnt_d; | ||
logic [31:0] req_rsp_lat_q, req_rsp_lat_d; | ||
logic [31:0] no_ex_lat_cnt_q, no_ex_lat_cnt_d; | ||
`FF(mock_paddr_q , mock_paddr_d , '0, clk_i, rst_ni) | ||
`FF(vaddr_q , vaddr_d , '0, clk_i, rst_ni) | ||
`FF(is_store_q , is_store_d , '0, clk_i, rst_ni) | ||
`FF(lat_cnt_q , lat_cnt_d , '0, clk_i, rst_ni) | ||
`FF(req_rsp_lat_q , req_rsp_lat_d , '0, clk_i, rst_ni) | ||
`FF(no_ex_lat_cnt_q, no_ex_lat_cnt_d, '0, clk_i, rst_ni) | ||
|
||
// Combinatorial logic | ||
always_comb begin : mmu_stub | ||
// Outputs (defaults) | ||
dtlb_hit_o = '0; | ||
dtlb_ppn_o = '0; // Never used | ||
valid_o = '0; | ||
paddr_o = '0; | ||
exception_o = '0; | ||
|
||
// Latency counter | ||
lat_cnt_en = 1'b0; | ||
lat_cnt_clr = 1'b0; | ||
|
||
// Registers feedback | ||
mock_paddr_d = mock_paddr_q; | ||
vaddr_d = vaddr_q; | ||
is_store_d = is_store_q; | ||
lat_cnt_d = lat_cnt_q; | ||
no_ex_lat_cnt_d = no_ex_lat_cnt_q; | ||
req_rsp_lat_d = req_rsp_lat_i; | ||
|
||
// If translation is enabled | ||
if ( en_ld_st_translation_i ) begin : enable_translation | ||
// Cycle 0 | ||
if ( req_i ) begin : req_valid | ||
// Sample inputs, for next cycle | ||
mock_paddr_d = vaddr_i; // Mock, just pass back the same vaddr | ||
vaddr_d = vaddr_i; | ||
is_store_d = is_store_i; | ||
|
||
// DTBL hit, assume 100% | ||
// NOTE: Ara does not use these | ||
dtlb_hit_o = 1'b1; | ||
dtlb_ppn_o = '1; | ||
|
||
// Count up | ||
lat_cnt_d = lat_cnt_q + 1; | ||
end : req_valid | ||
|
||
// Answer | ||
if (lat_cnt_q == req_rsp_lat_q) begin : valid | ||
// Output to Ara | ||
// Assume Ara consumes this request | ||
valid_o = 1'b1; | ||
paddr_o = mock_paddr_q; | ||
|
||
// Reset the latency counter | ||
lat_cnt_d = '0; | ||
|
||
// Another answer without exception! | ||
no_ex_lat_cnt_d = no_ex_lat_cnt_q + 1; | ||
end : valid | ||
|
||
// Mock exception logic | ||
if (ex_en_i && no_ex_lat_cnt_q == no_ex_lat_i && valid_o) begin : exception | ||
exception_o.valid = 1'b1; | ||
exception_o.cause = ( is_store_q ) ? riscv::STORE_PAGE_FAULT : riscv::LOAD_PAGE_FAULT; | ||
exception_o.tval = {'0, vaddr_q}; | ||
// Reset the ex_lat counter | ||
no_ex_lat_cnt_d = '0; | ||
end : exception | ||
// Reset the ex_lat counter if the exception engine is turned off | ||
if (!ex_en_i) begin | ||
no_ex_lat_cnt_d = '0; | ||
end | ||
end : enable_translation | ||
end : mmu_stub | ||
endmodule : mmu_stub |