summaryrefslogtreecommitdiff
path: root/python/openvino/demo/ip/intel_ai_ip/verilog/dla_lt_funnel.sv
blob: ad75919e8a1becd9e562e81f97be8b10403d5fff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Copyright 2020-2024 Intel Corporation.
//
// This software and the related documents are Intel copyrighted materials,
// and your use of them is governed by the express license under which they
// were provided to you ("License"). Unless the License provides otherwise,
// you may not use, modify, copy, publish, distribute, disclose or transmit
// this software or the related documents without Intel's prior written
// permission.
//
// This software and the related documents are provided as is, with no express
// or implied warranties, other than those that are expressly stated in the
// License.

/**
 * dla_lt_funnel.sv
 *
 * Reduces INPUTS (DDR width) input tokens to OUTPUT (CVEC) output tokens combinationally.
 * Operation:
 *  1. Each input is multiplexed in a 1xOUTPUT multiplexer with enable signal.
 *        The selected output line corresponds with the target output position of the input in the resulting CVEC
 *        line.
 *  2. For each MUX, the elements position i of all MUXes are OR'ed together for each OUTPUT number of MUX ouputs.
 *        At most one input to the token-wise OR operator will be non-zero.
 *  3. Together, the output of the OUTPUT OR-gates have the value of the rearranged inputs.
 *
 * Assumptions:
 *  The user is responsible for ensuring that there are no collisions in the input-output (DDR-CVEC) mapping.
 */

`resetall
`undefineall
`default_nettype none

module dla_lt_funnel #(
  parameter int INPUTS=16, // i.e., DDR tokens
  parameter int OUTPUTS=32, // i.e., CVEC
  parameter int ELEM_WIDTH=16
) (
  input wire [INPUTS-1:0][ELEM_WIDTH-1:0] i_tokens, // input values
  input wire i_valid [INPUTS-1:0], // valid signal corresponding to each input
  input wire [$clog2(OUTPUTS):0] i_select [INPUTS-1:0], // select value in position i represents input i's position in CVEC line
  output logic [OUTPUTS-1:0][ELEM_WIDTH-1:0] o_funnel_out // rearranged and combined output
);
  for (genvar inputs = 0; inputs < INPUTS; inputs++)
  begin: g_mux
    wire [ELEM_WIDTH-1:0] mux_output [OUTPUTS-1:0];
    dla_lt_mux #(.VALUE_WIDTH(ELEM_WIDTH), .NOUTPUT(OUTPUTS)) mux_inst (
      .i_valid(i_valid[inputs]),
      .i_select(i_select[inputs]),
      .i_value(i_tokens[inputs]),
      .o_mux_output(mux_output)
    );
  end

  for (genvar outputs = 0; outputs < OUTPUTS; outputs++)
  begin: g_or
    logic [ELEM_WIDTH-1:0] or_input [INPUTS-1:0];
    for (genvar inputs = 0; inputs < INPUTS; inputs++)
    begin
        assign or_input[inputs] = g_mux[inputs].mux_output[outputs];
    end
    always_comb begin
      for (int i = 0; i < INPUTS; i++) begin
        if (i == 0) begin
          o_funnel_out[outputs] = or_input[0];
        end else begin
          o_funnel_out[outputs] |= or_input[i];
        end
      end
    end
  end
endmodule