diff --git a/Bender.yml b/Bender.yml new file mode 100644 index 0000000..ae90c42 --- /dev/null +++ b/Bender.yml @@ -0,0 +1,82 @@ +# Copyright © 2023 Manuel Rodríguez & Zero-Day Labs, Lda. +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + +# Licensed under the Solderpad Hardware License v 2.1 (the “License”); +# you may not use this file except in compliance with the License, +# or, at your option, the Apache License version 2.0. +# You may obtain a copy of the License at https://solderpad.org/licenses/SHL-2.1/. +# Unless required by applicable law or agreed to in writing, +# any work distributed under the License is distributed on an “AS IS” BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and limitations under the License. +# +# Author: Manuel Rodríguez +# Date: 02/03/2024 +# Acknowledges: SSRC - Technology Innovation Institute (TII) +# +# Description: RISC-V IOMMU Bender package descriptor. + +package: + name: riscv-iommu + authors: + - "Manuel Rodríguez " + +dependencies: + common_cells: { git: "https://github.com/pulp-platform/common_cells.git", version: 1.30.0 } + axi: { git: "https://github.com/pulp-platform/axi.git", version: 0.39.2 } + register_interface: { git: "git@github.com:AlSaqr-platform/register_interface.git", version: 0.4.3 } + +export_include_dirs: + - include + +sources: + # Source files grouped in levels. Files in level 0 have no dependencies on files in this + # package. Files in level 1 only depend on files in level 0, files in level 2 on files in + # levels 1 and 0, etc. Files within a level are ordered alphabetically. + # Level 0 + - vendor/fifo_v2.sv + - vendor/fifo.sv + - vendor/axi_single_slice.sv + - vendor/axi_r_buffer.sv + - vendor/axi_aw_buffer.sv + - vendor/axi_w_buffer.sv + - vendor/axi_b_buffer.sv + - vendor/axi_ar_buffer.sv + - vendor/axi2apb_64_32.sv + - vendor/apb2reg.sv + - packages/rv_iommu/rv_iommu_field_pkg.sv + - packages/rv_iommu/rv_iommu_pkg.sv + - packages/rv_iommu/rv_iommu_reg_pkg.sv + - rtl/ext_interfaces/rv_iommu_axi4_bc.sv + - rtl/ext_interfaces/rv_iommu_ds_if.sv + - rtl/ext_interfaces/rv_iommu_prog_if.sv + # Level 1 + - rtl/software_interface/regmap/rv_iommu_field_arb.sv + - rtl/software_interface/rv_iommu_cq_handler.sv + - rtl/software_interface/rv_iommu_fq_handler.sv + - rtl/software_interface/rv_iommu_hpm.sv + - rtl/software_interface/rv_iommu_msi_ig.sv + - rtl/software_interface/rv_iommu_wsi_ig.sv + - rtl/translation_logic/rv_iommu_ddtc.sv + - rtl/translation_logic/rv_iommu_iotlb_sv39x4.sv + - rtl/translation_logic/rv_iommu_mrif_handler.sv + - rtl/translation_logic/rv_iommu_mrifc.sv + - rtl/translation_logic/rv_iommu_msiptw.sv + - rtl/translation_logic/rv_iommu_pdtc.sv + - rtl/translation_logic/cdw/rv_iommu_cdw.sv + - rtl/translation_logic/cdw/rv_iommu_cdw_pc.sv + - rtl/translation_logic/ptw/rv_iommu_ptw_sv39x4.sv + - rtl/translation_logic/ptw/rv_iommu_ptw_sv39x4_pc.sv + # Level 2 + - rtl/software_interface/regmap/rv_iommu_field.sv + - rtl/translation_logic/wrapper/rv_iommu_tw_sv39x4.sv + - rtl/translation_logic/wrapper/rv_iommu_tw_sv39x4_pc.sv + # Level 3 + - rtl/software_interface/regmap/rv_iommu_regmap.sv + - rtl/translation_logic/wrapper/rv_iommu_translation_wrapper.sv + # Level 4 + - rtl/software_interface/wrapper/rv_iommu_sw_if_wrapper.sv + # Level 5 + - rtl/riscv_iommu.sv + + diff --git a/rtl/ext_interfaces/rv_iommu_prog_if.sv b/rtl/ext_interfaces/rv_iommu_prog_if.sv index 5f616fe..56808e1 100644 --- a/rtl/ext_interfaces/rv_iommu_prog_if.sv +++ b/rtl/ext_interfaces/rv_iommu_prog_if.sv @@ -142,7 +142,9 @@ module rv_iommu_prog_if #( ); // APB to REG IF - apb_to_reg i_apb_to_reg ( + apb2reg #( + .AddrWidth(56) + ) i_apb_to_reg ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), .penable_i ( penable ), @@ -160,4 +162,4 @@ module rv_iommu_prog_if #( `REG_BUS_ASSIGN_TO_REQ(regmap_req_o, iommu_reg_bus) `REG_BUS_ASSIGN_FROM_RSP(iommu_reg_bus, regmap_resp_i) -endmodule \ No newline at end of file +endmodule diff --git a/rtl/riscv_iommu.sv b/rtl/riscv_iommu.sv index 0524cbe..795f540 100644 --- a/rtl/riscv_iommu.sv +++ b/rtl/riscv_iommu.sv @@ -733,11 +733,10 @@ module riscv_iommu #( .ar_chan_t ( ar_chan_t ), .r_chan_t ( r_chan_t ), // AXI request/response - .req_t ( axi_req_t ), - .resp_t ( axi_rsp_t ), + .axi_req_t ( axi_req_t ), + .axi_resp_t ( axi_rsp_t ), .NoMstPorts ( 3 ), // MRIF supports adds ignoring mechanism .AxiLookBits ( ID_WIDTH ), // Assuming same value as AXI ID width - .FallThrough ( 1'b0 ), .SpillAw ( 1'b0 ), .SpillW ( 1'b0 ), .SpillB ( 1'b0 ), @@ -774,11 +773,10 @@ module riscv_iommu #( .ar_chan_t ( ar_chan_t ), .r_chan_t ( r_chan_t ), // AXI request/response - .req_t ( axi_req_t ), - .resp_t ( axi_rsp_t ), + .axi_req_t ( axi_req_t ), + .axi_resp_t ( axi_rsp_t ), .NoMstPorts ( 2 ), // MRIF supports adds ignoring mechanism .AxiLookBits ( ID_WIDTH ), // Assuming same value as AXI ID width - .FallThrough ( 1'b0 ), .SpillAw ( 1'b0 ), .SpillW ( 1'b0 ), .SpillB ( 1'b0 ), @@ -801,8 +799,8 @@ module riscv_iommu #( // IOMMU Error Slave axi_err_slv #( .AxiIdWidth (ID_WIDTH ), - .req_t (axi_req_t ), - .resp_t (axi_rsp_t ), + .axi_req_t (axi_req_t ), + .axi_resp_t (axi_rsp_t ), .Resp (axi_pkg::RESP_SLVERR ), // error generated by this slave .RespWidth (DATA_WIDTH ), // data response width, gets zero extended or truncated to r.data. .RespData (64'hCA11AB1EBADCAB1E ), // hexvalue for data return value @@ -978,4 +976,4 @@ module riscv_iommu #( `endif //pragma translate_on -endmodule \ No newline at end of file +endmodule diff --git a/rtl/software_interface/regmap/rv_iommu_regmap.sv b/rtl/software_interface/regmap/rv_iommu_regmap.sv index 1ed3922..48d5996 100644 --- a/rtl/software_interface/regmap/rv_iommu_regmap.sv +++ b/rtl/software_interface/regmap/rv_iommu_regmap.sv @@ -18,6 +18,8 @@ // Defines data structures and other register-related data. // This module was developed using LowRISC `reggen` tool. +`include "assertions.svh" + module rv_iommu_regmap #( parameter int DATA_WIDTH = 32, diff --git a/rtl/software_interface/rv_iommu_cq_handler.sv b/rtl/software_interface/rv_iommu_cq_handler.sv index 4de696d..d9dd927 100644 --- a/rtl/software_interface/rv_iommu_cq_handler.sv +++ b/rtl/software_interface/rv_iommu_cq_handler.sv @@ -149,7 +149,7 @@ module rv_iommu_cq_handler #( mem_req_o.aw.addr = {{riscv::XLEN-riscv::PLEN{1'b0}}, cq_pptr_q}; mem_req_o.aw.len = 8'b0; mem_req_o.aw.size = 3'b010; - mem_req_o.aw.burst = axi_pkg::BURST_FIXED; + mem_req_o.aw.burst = axi_pkg::BURST_INCR; mem_req_o.aw.lock = '0; mem_req_o.aw.cache = '0; mem_req_o.aw.prot = '0; diff --git a/rtl/software_interface/rv_iommu_fq_handler.sv b/rtl/software_interface/rv_iommu_fq_handler.sv index 2fb054b..cecda30 100644 --- a/rtl/software_interface/rv_iommu_fq_handler.sv +++ b/rtl/software_interface/rv_iommu_fq_handler.sv @@ -221,7 +221,7 @@ module rv_iommu_fq_handler #( mem_req_o.ar.addr = '0; // IOMMU never reads from FQ mem_req_o.ar.len = '0; mem_req_o.ar.size = 3'b011; - mem_req_o.ar.burst = axi_pkg::BURST_FIXED; + mem_req_o.ar.burst = axi_pkg::BURST_INCR; mem_req_o.ar.lock = '0; mem_req_o.ar.cache = '0; mem_req_o.ar.prot = '0; @@ -425,4 +425,4 @@ module rv_iommu_fq_handler #( end end -endmodule \ No newline at end of file +endmodule diff --git a/rtl/software_interface/rv_iommu_msi_ig.sv b/rtl/software_interface/rv_iommu_msi_ig.sv index f5def4f..28557bc 100644 --- a/rtl/software_interface/rv_iommu_msi_ig.sv +++ b/rtl/software_interface/rv_iommu_msi_ig.sv @@ -104,7 +104,7 @@ module rv_iommu_msi_ig #( mem_req_o.aw.addr = {{riscv::XLEN-riscv::PLEN{1'b0}}, msi_addr_x_i[intv_q], 2'b0}; mem_req_o.aw.len = 8'd0; // MSI writes only 32 bits mem_req_o.aw.size = 3'b010; // 4-bytes beat - mem_req_o.aw.burst = axi_pkg::BURST_FIXED; + mem_req_o.aw.burst = axi_pkg::BURST_INCR; mem_req_o.aw.lock = '0; mem_req_o.aw.cache = '0; mem_req_o.aw.prot = '0; @@ -131,7 +131,7 @@ module rv_iommu_msi_ig #( mem_req_o.ar.addr = '0; // we never read here mem_req_o.ar.len = '0; mem_req_o.ar.size = 3'b011; - mem_req_o.ar.burst = axi_pkg::BURST_FIXED; + mem_req_o.ar.burst = axi_pkg::BURST_INCR; mem_req_o.ar.lock = '0; mem_req_o.ar.cache = '0; mem_req_o.ar.prot = '0; @@ -204,10 +204,9 @@ module rv_iommu_msi_ig #( // Write MSI to the corresponding address WRITE: begin - case (wr_state_q) // Send request to AW Channel - AW_REQ: begin + if (wr_state_q == AW_REQ) begin mem_req_o.aw_valid = 1'b1; if (mem_resp_i.aw_ready) begin @@ -215,8 +214,8 @@ module rv_iommu_msi_ig #( end end + else if (wr_state_q == W_DATA) begin // Send data through W channel - W_DATA: begin mem_req_o.w_valid = 1'b1; mem_req_o.w.last = 1'b1; @@ -226,9 +225,9 @@ module rv_iommu_msi_ig #( end // Check response code - B_RESP: begin - if (mem_resp_i.b_valid) begin - + else if (wr_state_q == B_RESP) begin + if (mem_resp_i.b_valid) begin + mem_req_o.b_ready = 1'b1; state_n = IDLE; wr_state_n = AW_REQ; @@ -241,9 +240,8 @@ module rv_iommu_msi_ig #( end end end - - default: state_n = IDLE; - endcase + else + state_n = IDLE; end // We may receive an AXI or access error when writing @@ -276,4 +274,4 @@ module rv_iommu_msi_ig #( end end -endmodule \ No newline at end of file +endmodule diff --git a/rtl/translation_logic/ptw/rv_iommu_ptw_sv39x4.sv b/rtl/translation_logic/ptw/rv_iommu_ptw_sv39x4.sv index bc8d8b6..2e9ec23 100644 --- a/rtl/translation_logic/ptw/rv_iommu_ptw_sv39x4.sv +++ b/rtl/translation_logic/ptw/rv_iommu_ptw_sv39x4.sv @@ -259,7 +259,7 @@ module rv_iommu_ptw_sv39x4 #( mem_req_o.aw.addr = '0; // Physical address to access mem_req_o.aw.len = 8'b0; // 1 beat per burst only mem_req_o.aw.size = 3'b011; // 64 bits (8 bytes) per beat - mem_req_o.aw.burst = axi_pkg::BURST_FIXED; // Fixed start address + mem_req_o.aw.burst = axi_pkg::BURST_INCR; // Fixed start address mem_req_o.aw.lock = '0; mem_req_o.aw.cache = '0; mem_req_o.aw.prot = '0; @@ -286,7 +286,7 @@ module rv_iommu_ptw_sv39x4 #( mem_req_o.ar.addr = {{riscv::XLEN-riscv::PLEN{1'b0}}, ptw_pptr_q}; // Physical address to access mem_req_o.ar.len = 8'b0; // 1 beat per burst only mem_req_o.ar.size = 3'b011; // 64 bits (8 bytes) per beat - mem_req_o.ar.burst = axi_pkg::BURST_FIXED; // Fixed start address + mem_req_o.ar.burst = axi_pkg::BURST_INCR; // Fixed start address mem_req_o.ar.lock = '0; mem_req_o.ar.cache = '0; mem_req_o.ar.prot = '0; diff --git a/rtl/translation_logic/ptw/rv_iommu_ptw_sv39x4_pc.sv b/rtl/translation_logic/ptw/rv_iommu_ptw_sv39x4_pc.sv index 3377fe7..d903454 100644 --- a/rtl/translation_logic/ptw/rv_iommu_ptw_sv39x4_pc.sv +++ b/rtl/translation_logic/ptw/rv_iommu_ptw_sv39x4_pc.sv @@ -269,7 +269,7 @@ module rv_iommu_ptw_sv39x4_pc #( mem_req_o.aw.addr = '0; // Physical address to access mem_req_o.aw.len = 8'b0; // 1 beat per burst only mem_req_o.aw.size = 3'b011; // 64 bits (8 bytes) per beat - mem_req_o.aw.burst = axi_pkg::BURST_FIXED; // Fixed start address + mem_req_o.aw.burst = axi_pkg::BURST_INCR; // Fixed start address mem_req_o.aw.lock = '0; mem_req_o.aw.cache = '0; mem_req_o.aw.prot = '0; @@ -296,7 +296,7 @@ module rv_iommu_ptw_sv39x4_pc #( mem_req_o.ar.addr = {{riscv::XLEN-riscv::PLEN{1'b0}}, ptw_pptr_q}; // Physical address to access mem_req_o.ar.len = 8'b0; // 1 beat per burst only mem_req_o.ar.size = 3'b011; // 64 bits (8 bytes) per beat - mem_req_o.ar.burst = axi_pkg::BURST_FIXED; // Fixed start address + mem_req_o.ar.burst = axi_pkg::BURST_INCR; // Fixed start address mem_req_o.ar.lock = '0; mem_req_o.ar.cache = '0; mem_req_o.ar.prot = '0; diff --git a/rtl/translation_logic/rv_iommu_msiptw.sv b/rtl/translation_logic/rv_iommu_msiptw.sv index 952678c..b7dd0c4 100644 --- a/rtl/translation_logic/rv_iommu_msiptw.sv +++ b/rtl/translation_logic/rv_iommu_msiptw.sv @@ -399,19 +399,20 @@ module rv_iommu_msiptw #( end : flat_seq //# MSI-MRIF - generate + // States + typedef enum logic[1:0] { + MRIF_PTE, // 00 + NOTICE_PTE, // 01 + MRIF_ERROR // 10 + } state_mrif_t; + + state_mrif_t mrif_state_q, mrif_state_n; + + generate // MRIF support enabled if (MSITrans == rv_iommu::MSI_FLAT_MRIF) begin : gen_mrif_support - // States - typedef enum logic[1:0] { - MRIF_PTE, // 00 - NOTICE_PTE, // 01 - MRIF_ERROR // 10 - } state_mrif_t; - state_mrif_t mrif_state_q, mrif_state_n; - // Read ports rv_iommu::msi_pte_mrif_t msi_pte_mrif; rv_iommu::msi_pte_notice_t msi_pte_notice; @@ -565,4 +566,4 @@ module rv_iommu_msiptw #( end : gen_mrif_support_disabled endgenerate -endmodule \ No newline at end of file +endmodule diff --git a/vendor/apb_to_reg.sv b/vendor/apb2reg.sv similarity index 66% rename from vendor/apb_to_reg.sv rename to vendor/apb2reg.sv index 8d39117..e90f614 100644 --- a/vendor/apb_to_reg.sv +++ b/vendor/apb2reg.sv @@ -10,18 +10,21 @@ // // Florian Zaruba -module apb_to_reg ( - input logic clk_i, - input logic rst_ni, +module apb2reg #( + parameter int unsigned DataWidth = 32, + parameter int unsigned AddrWidth = 64 +) ( + input logic clk_i, + input logic rst_ni, - input logic penable_i, - input logic pwrite_i, - input logic [63:0] paddr_i, - input logic psel_i, - input logic [31:0] pwdata_i, - output logic [31:0] prdata_o, - output logic pready_o, - output logic pslverr_o, + input logic penable_i, + input logic pwrite_i, + input logic [AddrWidth-1:0] paddr_i, + input logic psel_i, + input logic [DataWidth-1:0] pwdata_i, + output logic [DataWidth-1:0] prdata_o, + output logic pready_o, + output logic pslverr_o, REG_BUS.out reg_o );