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