diff --git a/.gitmodules b/.gitmodules
index 7552cd5068f3335a91eed29dc92a97c2a190a023..df2166d3a8dd621fab4365e9cd0cc8502c410496 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -43,3 +43,6 @@
 [submodule "src/riscv-dbg"]
 	path = src/riscv-dbg
 	url = https://github.com/pulp-platform/riscv-dbg.git
+[submodule "src/rv_plic"]
+	path = src/rv_plic
+	url = https://github.com/pulp-platform/rv_plic.git
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 58653a5ccf52786b18e1f94677b0500c6108832e..1b26d211fc568c50a7c1c91b09e13e5b4829b9ae 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
 - Fix bug in wt_axi_adapter (only appeared when dcache lines were wider than icache lines)
 - Fix potentially long timing path in `axi_lite_interface`
 - Fix VCS elab warning in `load_store_unit`
+- Bump `common_cells` to v1.12.0
+- Provision exponential backoff for AMO SC in L1 D$ miss handler
+- Add lowrisc PLIC
 
 ### 4.1.2
 
diff --git a/Makefile b/Makefile
index 8b560c31668c785a5ac42bbe8faf22000eb36e40..f8dfb2abab704e553b9c05bcf3414211d02aa191 100644
--- a/Makefile
+++ b/Makefile
@@ -58,6 +58,7 @@ ariane_pkg := include/riscv_pkg.sv                          \
 			  include/wt_cache_pkg.sv                       \
 			  src/axi/src/axi_pkg.sv                        \
 			  src/register_interface/src/reg_intf.sv        \
+			  src/register_interface/src/reg_intf_pkg.sv    \
 			  include/axi_intf.sv                           \
 			  tb/ariane_soc_pkg.sv                          \
 			  include/ariane_axi_pkg.sv                     \
@@ -112,10 +113,13 @@ src :=  $(filter-out src/ariane_regfile.sv, $(wildcard src/*.sv))              \
         $(wildcard src/clint/*.sv)                                             \
         $(wildcard fpga/src/axi2apb/src/*.sv)                                  \
         $(wildcard fpga/src/axi_slice/src/*.sv)                                \
-        $(wildcard src/plic/*.sv)                                              \
         $(wildcard src/axi_node/src/*.sv)                                      \
         $(wildcard src/axi_riscv_atomics/src/*.sv)                             \
         $(wildcard src/axi_mem_if/src/*.sv)                                    \
+        src/rv_plic/rtl/rv_plic_target.sv                                      \
+        src/rv_plic/rtl/rv_plic_gateway.sv                                     \
+        src/rv_plic/rtl/plic_regmap.sv                                         \
+        src/rv_plic/rtl/plic_top.sv                                            \
         src/riscv-dbg/src/dmi_cdc.sv                                           \
         src/riscv-dbg/src/dmi_jtag.sv                                          \
         src/riscv-dbg/src/dmi_jtag_tap.sv                                      \
diff --git a/fpga/src/ariane_peripherals_xilinx.sv b/fpga/src/ariane_peripherals_xilinx.sv
index 09932b8e751918bebaba73ffef92f9cddf098283..18c25c6cdce382102bae0d7ad26909991674b7c0 100644
--- a/fpga/src/ariane_peripherals_xilinx.sv
+++ b/fpga/src/ariane_peripherals_xilinx.sv
@@ -156,17 +156,31 @@ module ariane_peripherals #(
         .reg_o     ( reg_bus      )
     );
 
-    plic #(
-        .ID_BITWIDTH        ( ariane_soc::PLICIdWidth       ),
-        .PARAMETER_BITWIDTH ( ariane_soc::ParameterBitwidth ),
-        .NUM_TARGETS        ( ariane_soc::NumTargets        ),
-        .NUM_SOURCES        ( ariane_soc::NumSources        )
+    reg_intf::reg_intf_resp_d32 plic_resp;
+    reg_intf::reg_intf_req_a32_d32 plic_req;
+
+    assign plic_req.addr  = reg_bus.addr;
+    assign plic_req.write = reg_bus.write;
+    assign plic_req.wdata = reg_bus.wdata;
+    assign plic_req.wstrb = reg_bus.wstrb;
+    assign plic_req.valid = reg_bus.valid;
+
+    assign reg_bus.rdata = plic_resp.rdata;
+    assign reg_bus.error = plic_resp.error;
+    assign reg_bus.ready = plic_resp.ready;
+
+    plic_top #(
+      .N_SOURCE    ( ariane_soc::NumSources  ),
+      .N_TARGET    ( ariane_soc::NumTargets  ),
+      .MAX_PRIO    ( ariane_soc::MaxPriority )
     ) i_plic (
-        .clk_i              ( clk_i                  ),
-        .rst_ni             ( rst_ni                 ),
-        .irq_sources_i      ( irq_sources            ),
-        .eip_targets_o      ( irq_o                  ),
-        .external_bus_io    ( reg_bus                )
+      .clk_i,
+      .rst_ni,
+      .req_i         ( plic_req    ),
+      .resp_o        ( plic_resp   ),
+      .le_i          ( '0          ), // 0:level 1:edge
+      .irq_sources_i ( irq_sources ),
+      .eip_targets_o ( irq_o       )
     );
 
     // ---------------
diff --git a/src/plic/plic.sv b/src/plic/plic.sv
deleted file mode 100644
index 5e694f65ce0bbfb2f7ab260cc787a78ec7e20dd0..0000000000000000000000000000000000000000
--- a/src/plic/plic.sv
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2018 ETH Zurich and University of Bologna.
-// Copyright and related rights are licensed under the Solderpad Hardware
-// License, Version 0.51 (the "License"); you may not use this file except in
-// compliance with the License.  You may obtain a copy of the License at
-// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-// or agreed to in writing, software, hardware and materials distributed under
-// this 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.
-//
-//-------------------------------------------------------------------------------
-//-- Title      : PLIC Core
-//-- File       : plic_core.sv
-//-- Author     : Gian Marti      <gimarti.student.ethz.ch>
-//-- Author     : Thomas Kramer   <tkramer.student.ethz.ch>
-//-- Author     : Thomas E. Benz  <tbenz.student.ethz.ch>
-//-- Company    : Integrated Systems Laboratory, ETH Zurich
-//-- Created    : 2018-03-31
-//-- Last update: 2018-03-31
-//-- Platform   : ModelSim (simulation), Synopsys (synthesis)
-//-- Standard   : SystemVerilog IEEE 1800-2012
-//-------------------------------------------------------------------------------
-//-- Description: PLIC Top-level
-//-------------------------------------------------------------------------------
-//-- Revisions  :
-//-- Date        Version  Author  Description
-//-- 2018-03-31  2.0      tbenz   Created header
-//-------------------------------------------------------------------------------
-
-module plic #(
-    parameter int ADDR_WIDTH         = 32,   // can be either 32 or 64 bits (don't use 64bit at the moment as this causes memory map issues)
-    parameter int DATA_WIDTH         = 32,   // can be either 32 or 64 bits (don't use 64bit at the moment as this causes memory map issues)
-    parameter int ID_BITWIDTH        = -1,   // width of the gateway identifiers
-    parameter int PARAMETER_BITWIDTH = -1,   // width of the internal parameter e.g. priorities
-    parameter int NUM_TARGETS        = -1,   // number of target slices
-    parameter int NUM_SOURCES        = -1    // number of sources = number of gateways
-) (
-    input  logic                   clk_i,
-    input  logic                   rst_ni,
-    input  logic [NUM_SOURCES-1:0] irq_sources_i,
-    output logic [NUM_TARGETS-1:0] eip_targets_o,
-    REG_BUS.in                     external_bus_io
-);
-    // declare all local variables
-    // gateway arrays always go from NUM_SOURCES to 1 because gateway ids start at 1
-    logic                          gateway_irq_pendings    [NUM_SOURCES];               //for pending irqs of the gateways
-    logic                          gateway_claimed         [NUM_SOURCES];               //if a gateway is claimed, it masks its irq
-    logic                          gateway_completed       [NUM_SOURCES];               //if a gateway is completed, it is reenabled
-    logic [ID_BITWIDTH-1:0       ] gateway_ids             [NUM_SOURCES];               //ids of gateways
-    logic [PARAMETER_BITWIDTH-1:0] gateway_priorities      [NUM_SOURCES];               //priorities of gateways
-
-    logic                          irq_enableds            [NUM_SOURCES][NUM_TARGETS];
-    logic [PARAMETER_BITWIDTH-1:0] target_thresholds       [NUM_TARGETS];
-    logic [ID_BITWIDTH-1:0       ] identifier_of_largest_priority_per_target [NUM_TARGETS];
-
-    logic                          target_irq_claims       [NUM_TARGETS];
-    logic                          target_irq_completes    [NUM_TARGETS];
-    logic [ID_BITWIDTH-1:0       ] target_irq_completes_id [NUM_TARGETS];
-
-    //instantiate and connect gateways
-    for (genvar counter = 0; counter < NUM_SOURCES; counter++) begin : gen_plic_gateway
-        plic_gateway plic_gateway_instance (
-            .clk_i         ( clk_i                         ),
-            .rst_ni        ( rst_ni                        ),
-            .irq_source_i  ( irq_sources_i       [counter] ),
-            .claim_i       ( gateway_claimed     [counter] ),
-            .completed_i   ( gateway_completed   [counter] ),
-            .irq_pending_o ( gateway_irq_pendings[counter] )
-        );
-    end
-
-    // assign ids to gateways
-    for (genvar counter = 1; counter <= NUM_SOURCES; counter++) begin
-        assign gateway_ids[counter-1] = counter;
-
-    end
-
-    // instantiate and connect target slices
-    for (genvar counter = 0; counter < NUM_TARGETS; counter++) begin : gen_plic_target_slice
-
-        logic irq_enableds_slice[NUM_SOURCES];
-        for (genvar inner_counter = 0; inner_counter < NUM_SOURCES; inner_counter++) begin
-            assign irq_enableds_slice[inner_counter] = irq_enableds[inner_counter][counter];
-        end
-
-        plic_target_slice #(
-            .PRIORITY_BITWIDTH ( PARAMETER_BITWIDTH ),
-            .ID_BITWIDTH       ( ID_BITWIDTH        ),
-            .NUM_GATEWAYS      ( NUM_SOURCES        )
-        ) plic_target_slice_instance (
-            .interrupt_pending_i     ( gateway_irq_pendings                               ),
-            .interrupt_priority_i    ( gateway_priorities                                 ),
-            .interrupt_id_i          ( gateway_ids                                        ),
-            .interrupt_enable_i      ( irq_enableds_slice                                 ),
-            .threshold_i             ( target_thresholds[counter]                         ),
-            .ext_interrupt_present_o ( eip_targets_o[counter]                             ),
-            .identifier_of_largest_o ( identifier_of_largest_priority_per_target[counter] )
-        );
-    end
-
-    //instantiate and connect plic_interface
-    plic_interface #(
-        .ADDR_WIDTH         ( ADDR_WIDTH         ),
-        .DATA_WIDTH         ( DATA_WIDTH         ),
-        .ID_BITWIDTH        ( ID_BITWIDTH        ),
-        .PARAMETER_BITWIDTH ( PARAMETER_BITWIDTH ),
-        .NUM_TARGETS        ( NUM_TARGETS        ),
-        .NUM_GATEWAYS       ( NUM_SOURCES        )
-    ) plic_interface_instance (
-        .clk_i,
-        .rst_ni,
-        .id_of_largest_priority_i   ( identifier_of_largest_priority_per_target ),
-        .pending_array_i            ( gateway_irq_pendings                      ),
-        .thresholds_o               ( target_thresholds                         ),
-        .gateway_priorities_o       ( gateway_priorities                        ),
-        .irq_enables_o              ( irq_enableds                              ),
-        .target_irq_claims_o        ( target_irq_claims                         ),
-        .target_irq_completes_o     ( target_irq_completes                      ),
-        .target_irq_completes_id_o  ( target_irq_completes_id                   ),
-        .external_bus_io            ( external_bus_io                           )
-    );
-
-    //instantiate and connect claim_complete_tracker
-    plic_claim_complete_tracker #(
-        .NUM_TARGETS  ( NUM_TARGETS ),
-        .NUM_GATEWAYS ( NUM_SOURCES ),
-        .ID_BITWIDTH  ( ID_BITWIDTH )
-    ) plic_claim_complete_tracker_instance (
-        .clk_i                                     ( clk_i                                     ),
-        .rst_ni                                    ( rst_ni                                    ),
-        .identifier_of_largest_priority_per_target ( identifier_of_largest_priority_per_target ),
-        .target_irq_claims_i                       ( target_irq_claims                         ),
-        .target_irq_completes_i                    ( target_irq_completes                      ),
-        .target_irq_completes_identifier_i         ( target_irq_completes_id                   ),
-        .gateway_irq_claims_o                      ( gateway_claimed                           ),
-        .gateway_irq_completes_o                   ( gateway_completed                         )
-    );
-
-    //pragma translate_off
-    `ifndef VERILATOR
-    initial begin
-        assert((ADDR_WIDTH == 32) | (ADDR_WIDTH == 64)) else $error("Address width has to bei either 32 or 64 bit");
-        assert((DATA_WIDTH == 32) | (DATA_WIDTH == 64)) else $error("Data width has to bei either 32 or 64 bit");
-        assert(ID_BITWIDTH > 0       )                  else $error("ID_BITWIDTH has to be larger than 1");
-        assert(ID_BITWIDTH < 10      )                  else $error("ID_BITWIDTH has to be smaller than 10");
-        assert(PARAMETER_BITWIDTH > 0)                  else $error("PARAMETER_BITWIDTH has to be larger than 1");
-        assert(PARAMETER_BITWIDTH < 8)                  else $error("PARAMETER_BITWIDTH has to be smaller than 8");
-        assert(NUM_SOURCES > 0       )                  else $error("Num od Gateways has to be larger than 1");
-        assert(NUM_SOURCES < 512     )                  else $error("Num of Gateways has to be smaller than 512");
-        assert(NUM_TARGETS > 0       )                  else $error("Num Target slices has to be larger than 1");
-        assert(NUM_TARGETS < 15872   )                  else $error("Num target slices has to be smaller than 15872");
-    end
-    `endif
-    //pragma translate_on
-endmodule
diff --git a/src/plic/plic_claim_complete_tracker.sv b/src/plic/plic_claim_complete_tracker.sv
deleted file mode 100644
index f7ab51d1d116000c20bde67c17a8a11e5f07586f..0000000000000000000000000000000000000000
--- a/src/plic/plic_claim_complete_tracker.sv
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2018 ETH Zurich and University of Bologna.
-// Copyright and related rights are licensed under the Solderpad Hardware
-// License, Version 0.51 (the "License"); you may not use this file except in
-// compliance with the License.  You may obtain a copy of the License at
-// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-// or agreed to in writing, software, hardware and materials distributed under
-// this 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.
-//
-//-------------------------------------------------------------------------------
-//-- Title      : Claim - Complete - Tracker
-//-------------------------------------------------------------------------------
-//-- File       : plic_claim_complete_tracker.sv
-//-- Author     : Gian Marti      <gimarti.student.ethz.ch>
-//-- Author     : Thomas Kramer   <tkramer.student.ethz.ch>
-//-- Author     : Thomas E. Benz  <tbenz.student.ethz.ch>
-//-- Company    : Integrated Systems Laboratory, ETH Zurich
-//-- Created    : 2018-03-31
-//-- Last update: 2018-03-31
-//-- Platform   : ModelSim (simulation), Synopsys (synthesis)
-//-- Standard   : SystemVerilog IEEE 1800-2012
-//-------------------------------------------------------------------------------
-//-- Description: Implements the control logic of the plic
-//-------------------------------------------------------------------------------
-//-- Revisions  :
-//-- Date        Version  Author  Description
-//-- 2018-03-31  2.0      tbenz   Created header
-//-------------------------------------------------------------------------------
-
-//FSM that receives interrupt claims and interrupt completes from targets
-//and generates the fitting inerrupt claims and interrupt completes for sources
-module plic_claim_complete_tracker #(
-    parameter int NUM_TARGETS  =  1,
-    parameter int NUM_GATEWAYS =  1,
-    parameter int ID_BITWIDTH  =  4
-)(
-    input  logic                   clk_i,   // Clock
-    input  logic                   rst_ni,  // Asynchronous reset active low
-
-    input  logic [ID_BITWIDTH-1:0] identifier_of_largest_priority_per_target[NUM_TARGETS],
-    input  logic                   target_irq_claims_i   [NUM_TARGETS],
-    input  logic                   target_irq_completes_i[NUM_TARGETS],
-    input  logic [ID_BITWIDTH-1:0] target_irq_completes_identifier_i[NUM_TARGETS],
-
-    output logic                   gateway_irq_claims_o   [NUM_GATEWAYS],
-    output logic                   gateway_irq_completes_o[NUM_GATEWAYS]
-
-);
-
-    // claimed_gateways_q[target] is 0 if the target has not claimed the irq of any gateway
-    // and the is the identifier of the claimed gateway otherwise
-    logic [ID_BITWIDTH-1:0] claimed_gateways_q[NUM_TARGETS];
-
-    // the +1 is because counting starts from 1 and goes to NUM_GATEWAYS+1
-    logic                   claim_array         [NUM_GATEWAYS+1][NUM_TARGETS];
-    logic                   save_claims_array_q [NUM_GATEWAYS+1][NUM_TARGETS];
-    logic                   complete_array      [NUM_GATEWAYS+1][NUM_TARGETS];
-
-    // for handling claims
-    for (genvar counter = 0; counter < NUM_TARGETS; counter++) begin
-        always_ff @(posedge clk_i or negedge rst_ni) begin : proc_target
-
-            if (~rst_ni) begin
-                claimed_gateways_q[counter]         <= '0;
-
-                for (integer i = 0; i <= NUM_GATEWAYS; i++) begin
-                    claim_array[i][counter]         <= '0;
-                    save_claims_array_q[i][counter] <= '0;
-                end
-
-            end else begin
-                // per default, all claims and completes are zero
-                for (integer i = 0; i <= NUM_GATEWAYS; i++) begin
-                    claim_array[i][counter]    <= 0;
-                    complete_array[i][counter] <= 0;
-                end
-
-                // if a claim is issued, forward it to gateway with highest priority for the claiming target
-                if (target_irq_claims_i[counter]) begin
-                    claim_array[identifier_of_largest_priority_per_target[counter]][counter]         <= 1;
-                    // save claim for later when the complete-notification arrives
-                    save_claims_array_q[identifier_of_largest_priority_per_target[counter]][counter] <= 1;
-
-                end else begin
-                    // if a complete is issued, check if that gateway has previously been claimed by
-                    // this target and forward the
-                    // complete message to that gateway. if no claim has previously been issued, the
-                    // complete message is ignored
-                    if (target_irq_completes_i[counter] && (save_claims_array_q[target_irq_completes_identifier_i[counter]][counter] > 0)) begin
-                        complete_array[target_irq_completes_identifier_i[counter]][counter]      <= 1;
-                        save_claims_array_q[target_irq_completes_identifier_i[counter]][counter] <= 0;
-                    end
-                end
-            end
-        end
-    end
-
-
-    // the outputs for an id are the ORs of all targets for that id
-    always_comb begin : proc_result_computation
-        for (integer gateway = 1; gateway <= NUM_GATEWAYS; gateway++) begin
-            automatic logic is_claimed   = '0;
-            automatic logic is_completed = '0;
-
-            for (integer target = 0; target < NUM_TARGETS; target++) begin
-                is_claimed   = is_claimed   | claim_array   [gateway][target];
-                is_completed = is_completed | complete_array[gateway][target];
-            end
-
-            if (is_claimed) begin
-                gateway_irq_claims_o   [gateway-1] = 1;
-            end else begin
-                gateway_irq_claims_o   [gateway-1] = 0;
-            end
-
-            if (is_completed) begin
-                gateway_irq_completes_o[gateway-1] = 1;
-            end else begin
-                gateway_irq_completes_o[gateway-1] = 0;
-            end
-        end
-    end
-
-endmodule //plic_claim_complete_tracker
diff --git a/src/plic/plic_comparator.sv b/src/plic/plic_comparator.sv
deleted file mode 100644
index 49b5f2f57cd6606ea788779046cf2ec2a3c91df8..0000000000000000000000000000000000000000
--- a/src/plic/plic_comparator.sv
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2018 ETH Zurich and University of Bologna.
-// Copyright and related rights are licensed under the Solderpad Hardware
-// License, Version 0.51 (the "License"); you may not use this file except in
-// compliance with the License.  You may obtain a copy of the License at
-// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-// or agreed to in writing, software, hardware and materials distributed under
-// this 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.
-//
-//-------------------------------------------------------------------------------
-//-- Title      : Comperator
-//-- File       : plic_comperator.sv
-//-- Author     : Gian Marti      <gimarti.student.ethz.ch>
-//-- Author     : Thomas Kramer   <tkramer.student.ethz.ch>
-//-- Author     : Thomas E. Benz  <tbenz.student.ethz.ch>
-//-- Company    : Integrated Systems Laboratory, ETH Zurich
-//-- Created    : 2018-03-31
-//-- Last update: 2018-03-31
-//-- Platform   : ModelSim (simulation), Synopsys (synthesis)
-//-- Standard   : SystemVerilog IEEE 1800-2012
-//-------------------------------------------------------------------------------
-//-- Description: Comparator
-//-------------------------------------------------------------------------------
-//-- Revisions  :
-//-- Date        Version  Author  Description
-//-- 2018-03-31  2.0      tbenz   Created header
-//-------------------------------------------------------------------------------
-
-// find larger operand (value and identifier)
-// chooses the left operand on equality
-module plic_comparator #(
-    parameter int ID_BITWIDTH       = -1,
-    parameter int PRIORITY_BITWIDTH = -1
-)(
-    input  logic [PRIORITY_BITWIDTH-1:0]  left_priority_i,
-    input  logic [PRIORITY_BITWIDTH-1:0]  right_priority_i,
-    input  logic [ID_BITWIDTH-1:0      ]  left_identifier_i,
-    input  logic [ID_BITWIDTH-1:0      ]  right_identifier_i,
-    output logic [PRIORITY_BITWIDTH-1:0]  larger_priority_o,
-    output logic[ ID_BITWIDTH-1:0      ]  identifier_of_larger_o
-);
-
-    always_comb begin : proc_compare
-        if (left_priority_i >= right_priority_i) begin
-            larger_priority_o      = left_priority_i;
-            identifier_of_larger_o = left_identifier_i;
-        end else begin
-            larger_priority_o      = right_priority_i;
-            identifier_of_larger_o = right_identifier_i;
-        end
-    end
-
-    //pragma translate_off
-    `ifndef VERILATOR
-    initial begin
-        assert(ID_BITWIDTH       > 0)   else $error("ID_BITWIDTH has to be larger than 0");
-        assert(PRIORITY_BITWIDTH > 0)   else $error("PRIORITY_BITWIDTH has to be larger than 0");
-    end
-    `endif
-    //pragma translate_on
-
-endmodule
diff --git a/src/plic/plic_find_max.sv b/src/plic/plic_find_max.sv
deleted file mode 100644
index 2d206877403edeb8090117b3623bec9462352f83..0000000000000000000000000000000000000000
--- a/src/plic/plic_find_max.sv
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2018 ETH Zurich and University of Bologna.
-// Copyright and related rights are licensed under the Solderpad Hardware
-// License, Version 0.51 (the "License"); you may not use this file except in
-// compliance with the License.  You may obtain a copy of the License at
-// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-// or agreed to in writing, software, hardware and materials distributed under
-// this 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.
-//
-//-------------------------------------------------------------------------------
-//-- Title      : Find Maximun
-//-- File       : plic_find_max.sv
-//-- Author     : Gian Marti      <gimarti.student.ethz.ch>
-//-- Author     : Thomas Kramer   <tkramer.student.ethz.ch>
-//-- Author     : Thomas E. Benz  <tbenz.student.ethz.ch>
-//-- Company    : Integrated Systems Laboratory, ETH Zurich
-//-- Created    : 2018-03-31
-//-- Last update: 2018-03-31
-//-- Platform   : ModelSim (simulation), Synopsys (synthesis)
-//-- Standard   : SystemVerilog IEEE 1800-2012
-//-------------------------------------------------------------------------------
-//-- Description: Find the element with the largest priority
-//-------------------------------------------------------------------------------
-//-- Revisions  :
-//-- Date        Version  Author  Description
-//-- 2018-03-31  2.0      tbenz   Created header
-//-------------------------------------------------------------------------------
-
-module plic_find_max #(
-    parameter int NUM_OPERANDS      = 2,
-    parameter int ID_BITWIDTH       = 4,
-    parameter int PRIORITY_BITWIDTH = 3
-)(
-    input  logic [PRIORITY_BITWIDTH-1:0] priorities_i  [NUM_OPERANDS],
-    input  logic [ID_BITWIDTH-1:0      ] identifiers_i [NUM_OPERANDS],
-    output logic [PRIORITY_BITWIDTH-1:0] largest_priority_o,
-    output logic [ID_BITWIDTH-1:0      ] identifier_of_largest_o
-);
-
-    localparam int max_stage            = ($clog2(NUM_OPERANDS)-1);
-    localparam int num_operands_aligned = 2**(max_stage+1);
-
-    logic [PRIORITY_BITWIDTH-1:0] priority_stages   [max_stage + 2][num_operands_aligned];
-    logic [ID_BITWIDTH-1:0      ] identifier_stages [max_stage + 2][num_operands_aligned];
-
-
-    always_comb begin : proc_zero_padding
-        for (integer operand = 0; operand < num_operands_aligned; operand++) begin
-            if(operand < NUM_OPERANDS) begin
-                priority_stages  [0][operand] = priorities_i  [operand];
-                identifier_stages[0][operand] = identifiers_i [operand];
-            end else begin
-                priority_stages  [0][operand] = '0;
-                identifier_stages[0][operand] = '0;
-            end
-        end
-    end
-
-    for (genvar comparator_stage = max_stage; comparator_stage >= 0 ; comparator_stage--) begin
-        for (genvar stage_index  = 0; stage_index < 2**comparator_stage; stage_index++)   begin
-            plic_comparator #(
-                .ID_BITWIDTH        (ID_BITWIDTH       ),
-                .PRIORITY_BITWIDTH  (PRIORITY_BITWIDTH )
-            ) comp_instance(
-                .left_priority_i        ( priority_stages  [max_stage - comparator_stage][2*stage_index]     ),
-                .right_priority_i       ( priority_stages  [max_stage - comparator_stage][2*stage_index + 1] ),
-                .left_identifier_i      ( identifier_stages[max_stage - comparator_stage][2*stage_index]     ),
-                .right_identifier_i     ( identifier_stages[max_stage - comparator_stage][2*stage_index + 1] ),
-                .larger_priority_o      ( priority_stages  [max_stage - (comparator_stage-1)][stage_index]   ),
-                .identifier_of_larger_o ( identifier_stages[max_stage - (comparator_stage-1)][stage_index]   )
-            );
-        end
-    end
-
-    assign largest_priority_o      = priority_stages  [max_stage+1][0];
-    assign identifier_of_largest_o = identifier_stages[max_stage+1][0];
-endmodule
diff --git a/src/plic/plic_gateway.sv b/src/plic/plic_gateway.sv
deleted file mode 100644
index 137e5af785d392143ea3eea5d565167e3223675c..0000000000000000000000000000000000000000
--- a/src/plic/plic_gateway.sv
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2018 ETH Zurich and University of Bologna.
-// Copyright and related rights are licensed under the Solderpad Hardware
-// License, Version 0.51 (the "License"); you may not use this file except in
-// compliance with the License.  You may obtain a copy of the License at
-// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-// or agreed to in writing, software, hardware and materials distributed under
-// this 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.
-//
-//-------------------------------------------------------------------------------
-//-- Title      : Interrupt Gateway
-//-- File       : plic_gateway.sv
-//-- Author     : Gian Marti      <gimarti.student.ethz.ch>
-//-- Author     : Thomas Kramer   <tkramer.student.ethz.ch>
-//-- Author     : Thomas E. Benz  <tbenz.student.ethz.ch>
-//-- Company    : Integrated Systems Laboratory, ETH Zurich
-//-- Created    : 2018-03-31
-//-- Last update: 2018-03-31
-//-- Platform   : ModelSim (simulation), Synopsys (synthesis)
-//-- Standard   : SystemVerilog IEEE 1800-2012
-//-------------------------------------------------------------------------------
-//-- Description: Implementation of the Irq Gateway
-//-------------------------------------------------------------------------------
-//-- Revisions  :
-//-- Date        Version  Author  Description
-//-- 2018-03-31  2.0      tbenz   Created header
-//-------------------------------------------------------------------------------
-
-// the gateway does enable or disable itself depending on the signals claim_i, completed_i
-// the gateway knows neither its gateway_id nor its priority
-module plic_gateway (
-    input  logic       clk_i,
-    input  logic       rst_ni,
-    input  logic       irq_source_i,
-    input  logic       claim_i,
-    input  logic       completed_i,
-    output logic       irq_pending_o
-);
-    logic irq_pending_q;        // is 1 when an interrupt appears until the interrupt is claimed
-    logic wait_completion_q;    // is 1 when an interrupt appears until the interrupt is completed
-                                // also determines if the gateway is disabled, i.e. if interrupts are masked
-    logic irq_trigger;
-
-    assign irq_trigger = (~wait_completion_q | completed_i) & irq_source_i;
-
-    always_ff @(posedge clk_i or negedge rst_ni) begin : proc_update_ff
-        if (~rst_ni) begin
-            irq_pending_q     <= 1'b0;
-            wait_completion_q <= 1'b0;
-        end else begin
-            //pragma translate_off
-            `ifndef VERILATOR
-            assert (~(claim_i & (~wait_completion_q & irq_source_i)));
-            assert (~(completed_i & (~wait_completion_q & irq_source_i)));
-            `endif
-            //pragma translate_on
-
-            //interrupts not masked and interrupt received -> output to 1
-            if (irq_trigger) begin
-                irq_pending_q <= 1;
-            //interrupt claimed -> output to 0
-            end else if (claim_i) begin
-                irq_pending_q <= 0;
-            end
-
-            //interrupts not masked and interrupt received -> interrupts masked from know on
-            if (irq_trigger) begin
-                wait_completion_q <= 1;
-            //interrupt completed -> demask interrupts
-            end else if (completed_i) begin
-                wait_completion_q <= 0;
-            end
-        end
-    end
-
-    // Make sure there is 0 cycles delay from claim_i to irq_pending_o.
-    assign irq_pending_o = (irq_pending_q | irq_trigger) & ~claim_i;
-
-endmodule
diff --git a/src/plic/plic_interface.sv b/src/plic/plic_interface.sv
deleted file mode 100644
index 8293cc857a3a7715681babd8096b60313b3a37f6..0000000000000000000000000000000000000000
--- a/src/plic/plic_interface.sv
+++ /dev/null
@@ -1,304 +0,0 @@
-// Copyright 2018 ETH Zurich and University of Bologna.
-// Copyright and related rights are licensed under the Solderpad Hardware
-// License, Version 0.51 (the "License"); you may not use this file except in
-// compliance with the License.  You may obtain a copy of the License at
-// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-// or agreed to in writing, software, hardware and materials distributed under
-// this 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.
-//
-//-------------------------------------------------------------------------------
-//-- Title      : Register Interface
-//-- File       : plic_target_slice.sv
-//-- Author     : Gian Marti      <gimarti.student.ethz.ch>
-//-- Author     : Thomas Kramer   <tkramer.student.ethz.ch>
-//-- Author     : Thomas E. Benz  <tbenz.student.ethz.ch>
-//-- Company    : Integrated Systems Laboratory, ETH Zurich
-//-- Created    : 2018-03-31
-//-- Last update: 2018-03-31
-//-- Platform   : ModelSim (simulation), Synopsys (synthesis)
-//-- Standard   : SystemVerilog IEEE 1800-2012
-//-------------------------------------------------------------------------------
-//-- Description: Implementation of the plic's register interface
-//-------------------------------------------------------------------------------
-//-- Revisions  :
-//-- Date        Version  Author  Description
-//-- 2018-03-31  2.0      tbenz   Created header
-//-------------------------------------------------------------------------------
-
-module plic_interface #(
-    parameter int ADDR_WIDTH         = 32,   // width of external address bus
-    parameter int DATA_WIDTH         = 32,   // width of external data bus
-    parameter int ID_BITWIDTH        = 10,   // width of the gateway indecies
-    parameter int PARAMETER_BITWIDTH =  3,   // width of the internal parameter e.g. priorities
-    parameter int NUM_TARGETS        =  1,   // number of target slices
-    parameter int NUM_GATEWAYS       =  1    // number of gateways
-)(
-    input  logic                         clk_i,                                     // the clock signal
-    input  logic                         rst_ni,                                    // asynchronous reset active low
-    input  logic[ID_BITWIDTH-1:0]        id_of_largest_priority_i[NUM_TARGETS],     // input array id of largest priority
-    input  logic                         pending_array_i[NUM_GATEWAYS],             // array with the interrupt pending , idx0 is gateway 1
-    output reg [PARAMETER_BITWIDTH-1:0]  thresholds_o[NUM_TARGETS],                 // save internally the thresholds, communicate values over this port to the core
-    output reg [PARAMETER_BITWIDTH-1:0]  gateway_priorities_o[NUM_GATEWAYS],        // save internally the the priorities, communicate values
-    output logic                         irq_enables_o[NUM_GATEWAYS][NUM_TARGETS],  // communicate enable bits over this port
-    output logic                         target_irq_claims_o[NUM_TARGETS],          // claim signals
-    output logic                         target_irq_completes_o[NUM_TARGETS],       // complete signals
-    output logic[ID_BITWIDTH-1:0]        target_irq_completes_id_o[NUM_TARGETS],    // the id of the gateway to be completed
-    REG_BUS.in                           external_bus_io                            // the bus
-);
-
-    //define ennumerated types
-    enum logic [2:0] {INV, PRI, IPA, IEB, THR, CCP} funct;   // the address mapping will primarily check what
-                                                             // function should be performed
-                                                             // INV: invalid, PRI: priorities, IPA: interrupt pending
-                                                             // IEB: interrupt enable, THR: threshold and claim/complete
-                                                             // CCP: claim/clear pulses
-
-        //calculate some parameter needed later
-    localparam int num_gateway_bundles = (NUM_GATEWAYS-1) / DATA_WIDTH + 1;       // how many bundles we have to consider
-    localparam int bpw                 = DATA_WIDTH / 8;                          // how many bytes a data word consist of
-    //internal signals
-    logic [ADDR_WIDTH-12-1:0     ]  page_address;       // the upper part of the address
-    logic [11:0                  ]  page_offset;        // the lowest 12 bit describes the page offset
-    logic [11-$clog2(bpw):0      ]  page_word_offset;   // the word address of each page offset
-    logic [$clog2(bpw)-1:0       ]  word_offset;        // the byte in the word
-
-    logic [DATA_WIDTH/8-1:0      ]  write_active;       // 0 if inactive, else what byte ahs to be written
-    logic                           read_active;        // 0 if inactive, 1 when reading the word
-    //bundle definitions
-    logic [DATA_WIDTH-1:0        ]  irq_pending_bundle[num_gateway_bundles];
-
-    //registers
-    logic [PARAMETER_BITWIDTH-1:0]  thresholds_d[NUM_TARGETS];
-    logic [PARAMETER_BITWIDTH-1:0]  thresholds_q[NUM_TARGETS];
-
-    logic [PARAMETER_BITWIDTH-1:0]  priorities_d[NUM_GATEWAYS];
-    logic [PARAMETER_BITWIDTH-1:0]  priorities_q[NUM_GATEWAYS];
-
-    logic [ID_BITWIDTH-1:0       ]  id_of_largest_priority_d[NUM_TARGETS];
-    logic [ID_BITWIDTH-1:0       ]  id_of_largest_priority_q[NUM_TARGETS];
-
-    logic [DATA_WIDTH/bpw-1:0    ]  ena_bundles_d[num_gateway_bundles][NUM_TARGETS][DATA_WIDTH/8];
-    logic [DATA_WIDTH/bpw-1:0    ]  ena_bundles_q[num_gateway_bundles][NUM_TARGETS][DATA_WIDTH/8];
-
-    // assignments
-    assign id_of_largest_priority_d = id_of_largest_priority_i;
-
-    // assign addresses
-    assign page_address      = external_bus_io.addr[ADDR_WIDTH-1:12];
-    assign page_offset       = external_bus_io.addr[11:0           ];
-    assign page_word_offset  = external_bus_io.addr[11:$clog2(bpw) ];
-    assign word_offset       = external_bus_io.addr[$clog2(bpw)-1:0];
-
-    assign write_active      = (external_bus_io.valid &  external_bus_io.write) ? external_bus_io.wstrb : '0;
-    assign read_active       = external_bus_io.valid  & !external_bus_io.write;
-
-    // bundle signals
-    for (genvar bundle = 0; bundle < num_gateway_bundles; bundle++) begin
-        for (genvar ip_bit = 0; ip_bit < DATA_WIDTH; ip_bit++) begin
-            if (bundle * DATA_WIDTH + ip_bit < NUM_GATEWAYS) begin
-                assign irq_pending_bundle[bundle][ip_bit] = pending_array_i[bundle * DATA_WIDTH + ip_bit];
-            end else begin
-                assign irq_pending_bundle[bundle][ip_bit] = '0;
-            end
-        end
-    end
-
-    for (genvar bundle = 0; bundle < num_gateway_bundles; bundle++) begin
-        for (genvar target = 0; target < NUM_TARGETS; target++) begin
-            for (genvar byte_in_word = 0; byte_in_word < DATA_WIDTH/8; byte_in_word++) begin
-                for (genvar enable_bit = 0; enable_bit < 8; enable_bit++) begin
-                    assign irq_enables_o[bundle * DATA_WIDTH + enable_bit + byte_in_word * 8][target] =
-                                                            ena_bundles_q[bundle][target][byte_in_word][enable_bit];
-                end
-            end
-        end
-    end
-
-    // determine the function to be performed
-    always_comb begin : proc_address_map
-        // default values
-        funct = INV;
-        // only aligned access is allowed:
-        if (word_offset == '0) begin
-            // we have now an word alligned access -> check out page offset to determine
-            // what type of access this is.
-            if (page_address[13:0] == 0) begin // we access the gateway priority bits
-                // the page_word_offset tells us now which gateway we consider
-                // in order to grant or deny access, we have to check if the gateway
-                // in question really exist.
-                // Gateway 0 does not exist, so return an error
-                if (page_word_offset <= NUM_GATEWAYS && page_word_offset > 0) begin //the gateway in question exists
-                    // set the current operation to be an access to the priority registers
-                    funct = PRI;
-                end
-            // we now access the IP Bits, read only
-            end else if (page_address[13:0] == 1) begin
-                // the page_word_offset tells us now, which word we have to consider,
-                // the word, which includes the IP bit in question should be returned
-                if (page_word_offset<num_gateway_bundles) begin
-                    funct = IPA;
-                end
-            // access of the enable bits for each target
-            end else if (page_address[13:9] == 0) begin
-                // the bottom part page_word_offset now tells us which gateway bundle we have to consider
-                // part of the page_address and the upper part of the page_word_offset give us the target nr.
-                if (page_offset[6:$clog2(bpw)] < num_gateway_bundles) begin
-                    if (({page_address[8:0], page_offset[11:7]} - 64) < NUM_TARGETS) begin
-                        funct = IEB;
-                    end
-                end
-            // priority / claim / complete
-            end else begin
-                // page address - 0h20 gives the target number
-                if (page_address[13:0] - 'h200 < NUM_TARGETS) begin
-                    // check lowest bit of the page_word_offset to get the exact function
-                    if (page_word_offset == 0) begin
-                        funct = THR;
-                    end else if (page_word_offset == 1) begin
-                        funct = CCP;
-                    end
-                end
-            end
-        end
-    end
-
-    always_comb begin : proc_read_write
-        // defalt values
-        external_bus_io.rdata = 0;
-        external_bus_io.error = 0;
-        external_bus_io.ready = 0;
-
-        for (integer target = 0; target<NUM_TARGETS; target++) begin
-            target_irq_claims_o      [target] = '0;
-            target_irq_completes_o   [target] = '0;
-            target_irq_completes_id_o[target] = '0;
-        end
-
-        //just keep the values untouched as default
-        priorities_d  = priorities_q;
-        ena_bundles_d = ena_bundles_q;
-        thresholds_d  = thresholds_q;
-
-        case (funct)
-            PRI: begin
-                // read case
-                if (read_active != 0) begin
-                    external_bus_io.rdata = priorities_q[page_word_offset-1];
-                    external_bus_io.ready = 1;
-                // write case
-                end else if (write_active[0] == 1) begin
-                    priorities_d[page_word_offset-1] = external_bus_io.wdata[PARAMETER_BITWIDTH-1:0];
-                    external_bus_io.ready = 1;
-                end
-            end
-
-            IPA: begin
-                // read case
-                if (read_active != 0) begin
-                    external_bus_io.rdata = irq_pending_bundle[page_word_offset];
-                    external_bus_io.ready = 1;
-                // write case
-                end else if (write_active != 0) begin
-                    external_bus_io.error = 1;  //not allowed
-                end
-            end
-
-            IEB: begin
-                // read case
-                if (read_active != 0) begin
-                    for (integer byte_in_word = 0; byte_in_word < DATA_WIDTH/8; byte_in_word++) begin
-                        external_bus_io.rdata[8*(byte_in_word) +: 8] =  ena_bundles_q[page_offset[6:$clog2(bpw)]][({page_address[8:0], page_offset[11:7]} - 64)][byte_in_word];
-                    end
-                    external_bus_io.ready = 1;
-                // write case
-                end else if(write_active != 0) begin
-                    for (integer byte_in_word=0; byte_in_word<DATA_WIDTH/8; byte_in_word++) begin
-                        if(write_active[byte_in_word]) begin
-                            ena_bundles_d[page_offset[6:$clog2(bpw)]][({page_address[8:0], page_offset[11:7]} - 64)][byte_in_word] = external_bus_io.wdata[8*(byte_in_word) +: 8];
-                        end
-                    end
-                    external_bus_io.ready = 1;
-                end
-            end
-
-            THR: begin
-                // read case
-                if (read_active != 0) begin
-                    external_bus_io.rdata[PARAMETER_BITWIDTH-1:0] = thresholds_q[(page_address[13:0] - 'h200)];
-                    external_bus_io.ready = 1;
-                // write case
-                end else if (write_active != 0) begin
-                    thresholds_d[(page_address[13:0] - 'h200)] = external_bus_io.wdata[PARAMETER_BITWIDTH-1:0];
-                    external_bus_io.ready = 1;
-                end
-            end
-
-            CCP: begin
-                // read case
-                if (read_active != 0) begin
-                    target_irq_claims_o[(page_address[13:0] - 'h200)] = 1;
-                    external_bus_io.rdata[ID_BITWIDTH-1:0] = id_of_largest_priority_q[(page_address[13:0] - 'h200)];
-                    external_bus_io.ready = 1;
-                // write case
-                end else if (write_active != 0) begin
-                    target_irq_completes_o[(page_address[13:0] - 'h200)] = 1;
-                    target_irq_completes_id_o[(page_address[13:0] - 'h200)] = external_bus_io.wdata[ID_BITWIDTH-1:0];
-                    external_bus_io.ready = 1;
-                end
-            end
-
-            default : begin
-                //per default: error
-                external_bus_io.error = 1;
-                external_bus_io.ready = 1;
-            end
-        endcase // funct
-    end
-
-    // store data in flip flops
-    always_ff @(posedge clk_i or negedge rst_ni) begin : proc_update_ff
-        if (~rst_ni) begin // set all registers to 0
-            for (integer gateway = 0; gateway < NUM_GATEWAYS; gateway++)
-                priorities_q[gateway] <= 0;
-
-            for (integer bundle = 0; bundle < num_gateway_bundles; bundle++)
-                for (integer target = 0; target < NUM_TARGETS; target++)
-                    for (integer byte_in_word = 0; byte_in_word < DATA_WIDTH/8; byte_in_word++)
-                        ena_bundles_q[bundle][target][byte_in_word] <= 0;
-
-            for (integer target = 0; target < NUM_TARGETS; target++) begin
-                thresholds_q[target]             <= 0;
-                id_of_largest_priority_q[target] <= 0;
-            end
-        end else begin
-            priorities_q             <= priorities_d;
-            ena_bundles_q            <= ena_bundles_d;
-            thresholds_q             <= thresholds_d;
-            id_of_largest_priority_q <= id_of_largest_priority_d;
-        end
-    end
-
-    //assign outputs
-    assign thresholds_o         = thresholds_q;
-    assign gateway_priorities_o = priorities_q;
-
-    // pragma translate_off
-    `ifndef VERILATOR
-    initial begin
-        assert ((ADDR_WIDTH==32) | (ADDR_WIDTH==64)) else $error("Address width has to bei either 32 or 64 bit");
-        assert ((DATA_WIDTH==32) | (DATA_WIDTH==64)) else $error("Data width has to bei either 32 or 64 bit");
-        assert (ID_BITWIDTH>0)                       else $error("ID_BITWIDTH has to be larger than 1");
-        assert (ID_BITWIDTH<10)                      else $error("ID_BITWIDTH has to be smaller than 10");
-        assert (PARAMETER_BITWIDTH>0)                else $error("PARAMETER_BITWIDTH has to be larger than 1");
-        assert (PARAMETER_BITWIDTH<8)                else $error("PARAMETER_BITWIDTH has to be smaller than 8");
-        assert (NUM_GATEWAYS>0)                      else $error("Num od Gateways has to be larger than 1");
-        assert (NUM_GATEWAYS<512)                    else $error("Num of Gateways has to be smaller than 512");
-        assert (NUM_TARGETS>0)                       else $error("Num Target slices has to be larger than 1");
-        assert (NUM_TARGETS<15872)                   else $error("Num target slices has to be smaller than 15872");
-    end
-    `endif
-    // pragma translate_on
-
-endmodule
diff --git a/src/plic/plic_target_slice.sv b/src/plic/plic_target_slice.sv
deleted file mode 100644
index aba21521954ef4e3c600973de6054e620ee45e69..0000000000000000000000000000000000000000
--- a/src/plic/plic_target_slice.sv
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2018 ETH Zurich and University of Bologna.
-// Copyright and related rights are licensed under the Solderpad Hardware
-// License, Version 0.51 (the "License"); you may not use this file except in
-// compliance with the License.  You may obtain a copy of the License at
-// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-// or agreed to in writing, software, hardware and materials distributed under
-// this 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.
-//
-//-------------------------------------------------------------------------------
-//-- Title      : Target Slice
-//-- File       : plic_target_slice.sv
-//-- Author     : Gian Marti      <gimarti.student.ethz.ch>
-//-- Author     : Thomas Kramer   <tkramer.student.ethz.ch>
-//-- Author     : Thomas E. Benz  <tbenz.student.ethz.ch>
-//-- Company    : Integrated Systems Laboratory, ETH Zurich
-//-- Created    : 2018-03-31
-//-- Last update: 2018-03-31
-//-- Platform   : ModelSim (simulation), Synopsys (synthesis)
-//-- Standard   : SystemVerilog IEEE 1800-2012
-//-------------------------------------------------------------------------------
-//-- Description: Target Slice
-//-------------------------------------------------------------------------------
-//-- Revisions  :
-//-- Date        Version  Author  Description
-//-- 2018-03-31  2.0      tbenz   Created header
-//-------------------------------------------------------------------------------
-
-// Note: The gateways are expected to be ordered by their IDs (ascending).
-// This resolves priority ties by choosing the gateway with the lower ID.
-module plic_target_slice #(
-    parameter int PRIORITY_BITWIDTH = 8,
-    parameter int ID_BITWIDTH       = 8,
-    parameter int NUM_GATEWAYS      = 1
-)(
-    // Input signals from gateways.
-    input  logic                          interrupt_pending_i [NUM_GATEWAYS],
-    input  logic [PRIORITY_BITWIDTH-1:0]  interrupt_priority_i[NUM_GATEWAYS],
-    input  logic [ID_BITWIDTH-1:0      ]  interrupt_id_i      [NUM_GATEWAYS],
-    input  logic                          interrupt_enable_i  [NUM_GATEWAYS],
-    input  logic [PRIORITY_BITWIDTH-1:0]  threshold_i,
-    output logic                          ext_interrupt_present_o,
-    output logic [ID_BITWIDTH-1:0      ]  identifier_of_largest_o
-);
-
-    logic[PRIORITY_BITWIDTH:0]  interrupt_priority_masked[NUM_GATEWAYS];
-
-
-    // Signals that represent the selected interrupt source.
-    logic[PRIORITY_BITWIDTH:0] best_priority;
-    logic[ID_BITWIDTH-1:0    ] best_id;
-
-    // Create a tree to find the best interrupt source.
-    plic_find_max #(
-        .NUM_OPERANDS             ( NUM_GATEWAYS              ),
-        .ID_BITWIDTH              ( ID_BITWIDTH               ),
-        .PRIORITY_BITWIDTH        ( PRIORITY_BITWIDTH + 1     )
-    ) find_max_instance (
-        .priorities_i             ( interrupt_priority_masked ),
-        .identifiers_i            ( interrupt_id_i            ),
-        // Outputs
-        .largest_priority_o       ( best_priority             ),
-        .identifier_of_largest_o  ( best_id                   )
-    );
-
-    // Compare the priority of the best interrupt source to the threshold.
-    always_comb begin : proc_compare_threshold
-        if ((best_priority - 1 > threshold_i) && (best_priority != '0)) begin
-            ext_interrupt_present_o = 1;
-            identifier_of_largest_o = best_id;
-        end else begin
-            if ((best_priority - 1 <= threshold_i) && (best_priority != '0)) begin
-                ext_interrupt_present_o = 0;
-                identifier_of_largest_o = best_id;
-            end else begin
-                ext_interrupt_present_o = 0;
-                identifier_of_largest_o = 0;
-            end
-        end
-    end
-
-    always_comb begin : proc_mask_gateway_outputs
-        for (int i = 0; i < NUM_GATEWAYS; i++) begin
-             if (interrupt_enable_i[i] && interrupt_pending_i[i]) begin
-                interrupt_priority_masked[i] = interrupt_priority_i[i] + 1;      //priority shift +1
-             end else begin
-                interrupt_priority_masked[i] = '0;
-             end
-        end
-    end
-endmodule
diff --git a/src/register_interface b/src/register_interface
index d10dce04b7211da044d31baaa06c7044c84083d9..d8aeccc65fdbbb30ef9dd28e065c2947a2396eab 160000
--- a/src/register_interface
+++ b/src/register_interface
@@ -1 +1 @@
-Subproject commit d10dce04b7211da044d31baaa06c7044c84083d9
+Subproject commit d8aeccc65fdbbb30ef9dd28e065c2947a2396eab
diff --git a/src/rv_plic b/src/rv_plic
new file mode 160000
index 0000000000000000000000000000000000000000..6046cfa518237c06031e65030f250bb29555e913
--- /dev/null
+++ b/src/rv_plic
@@ -0,0 +1 @@
+Subproject commit 6046cfa518237c06031e65030f250bb29555e913
diff --git a/tb/ariane_peripherals.sv b/tb/ariane_peripherals.sv
index ce488c0beb6222c92ab55a25e4c13838fe9473e3..84f20db2c4e4dc1e3d162a0fe93732b66d018a36 100644
--- a/tb/ariane_peripherals.sv
+++ b/tb/ariane_peripherals.sv
@@ -148,17 +148,31 @@ module ariane_peripherals #(
         .reg_o     ( reg_bus      )
     );
 
-    plic #(
-        .ID_BITWIDTH        ( ariane_soc::PLICIdWidth       ),
-        .PARAMETER_BITWIDTH ( ariane_soc::ParameterBitwidth ),
-        .NUM_TARGETS        ( ariane_soc::NumTargets        ),
-        .NUM_SOURCES        ( ariane_soc::NumSources        )
+    reg_intf::reg_intf_resp_d32 plic_resp;
+    reg_intf::reg_intf_req_a32_d32 plic_req;
+
+    assign plic_req.addr  = reg_bus.addr;
+    assign plic_req.write = reg_bus.write;
+    assign plic_req.wdata = reg_bus.wdata;
+    assign plic_req.wstrb = reg_bus.wstrb;
+    assign plic_req.valid = reg_bus.valid;
+
+    assign reg_bus.rdata = plic_resp.rdata;
+    assign reg_bus.error = plic_resp.error;
+    assign reg_bus.ready = plic_resp.ready;
+
+    plic_top #(
+      .N_SOURCE    ( ariane_soc::NumSources  ),
+      .N_TARGET    ( ariane_soc::NumTargets  ),
+      .MAX_PRIO    ( ariane_soc::MaxPriority )
     ) i_plic (
-        .clk_i              ( clk_i                  ),
-        .rst_ni             ( rst_ni                 ),
-        .irq_sources_i      ( irq_sources            ),
-        .eip_targets_o      ( irq_o                  ),
-        .external_bus_io    ( reg_bus                )
+      .clk_i,
+      .rst_ni,
+      .req_i         ( plic_req    ),
+      .resp_o        ( plic_resp   ),
+      .le_i          ( '0          ), // 0:level 1:edge
+      .irq_sources_i ( irq_sources ),
+      .eip_targets_o ( irq_o       )
     );
 
     // ---------------
diff --git a/tb/ariane_soc_pkg.sv b/tb/ariane_soc_pkg.sv
index 36463832691968bc6a9d203c5c1298cee684fd60..316b9866de0eb150e111f73413bf580dc2fd5dff 100644
--- a/tb/ariane_soc_pkg.sv
+++ b/tb/ariane_soc_pkg.sv
@@ -12,11 +12,11 @@
 // Description: Contains SoC information as constants
 package ariane_soc;
     // M-Mode Hart, S-Mode Hart
-    localparam NumTargets = 2;
-    // Uart, SPI, Ethernet
-    localparam NumSources = 3;
-    localparam PLICIdWidth = 3;
-    localparam ParameterBitwidth = PLICIdWidth;
+    localparam int unsigned NumTargets = 2;
+    // Uart, SPI, Ethernet, reserved
+    localparam int unsigned NumSources = 30;
+    localparam int unsigned MaxPriority = 7;
+
     localparam NrSlaves = 2; // actually masters, but slaves on the crossbar
 
     // 4 is recommended by AXI standard, so lets stick to it, do not change