// Copyright © 2019-2023 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. `include "VX_platform.vh" `TRACING_OFF module VX_reduce #( parameter DATAW_IN = 1, parameter DATAW_OUT = DATAW_IN, parameter N = 1, parameter `STRING OP = "+" ) ( input wire [N-1:0][DATAW_IN-1:0] data_in, output wire [DATAW_OUT-1:0] data_out ); if (N == 1) begin assign data_out = DATAW_OUT'(data_in[0]); end else begin localparam int N_A = N / 2; localparam int N_B = N - N_A; wire [N_A-1:0][DATAW_IN-1:0] in_A; wire [N_B-1:0][DATAW_IN-1:0] in_B; wire [DATAW_OUT-1:0] out_A, out_B; for (genvar i = 0; i < N_A; i++) begin assign in_A[i] = data_in[i]; end for (genvar i = 0; i < N_B; i++) begin assign in_B[i] = data_in[N_A + i]; end VX_reduce #( .DATAW_IN (DATAW_IN), .DATAW_OUT (DATAW_OUT), .N (N_A), .OP (OP) ) reduce_A ( .data_in (in_A), .data_out (out_A) ); VX_reduce #( .DATAW_IN (DATAW_IN), .DATAW_OUT (DATAW_OUT), .N (N_B), .OP (OP) ) reduce_B ( .data_in (in_B), .data_out (out_B) ); if (OP == "+") assign data_out = out_A + out_B; else if (OP == "^") assign data_out = out_A ^ out_B; else if (OP == "&") assign data_out = out_A & out_B; else if (OP == "|") assign data_out = out_A | out_B; else `ERROR(("invalid parameter")); end endmodule `TRACING_ON