// 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