summaryrefslogtreecommitdiff
path: root/python/openvino/demo/ip/intel_ai_ip/verilog/dla_demux.sv
blob: 8191462fad2101e555f89c23a92de5a436e164b6 (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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// 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.

// Description of functionality:
// This module acts as a simple demux to steer data to either one of two outputs
// the module receives config data, which is the select signal, and based on the value
// of the sel signal, the module steers input data to either first or second output
// This module could be generalized in the future to have 1 to many (instead of 1:2)

`resetall
`undefineall
`default_nettype none
`include "dla_acl_parameter_assert.svh"

module dla_demux import dla_common_pkg::*, dla_demux_pkg::*; #(
  // DLA (input data) side parameters
  parameter   int CONFIG_WIDTH                  = 32,
  parameter   int DATA_WIDTH                    = 32
) (
  input  wire                                 clk_dla,
  input  wire                                 i_aresetn,

  // config input
  input  wire  [CONFIG_WIDTH-1:0]             i_config_data,
  input  wire                                 i_config_valid,
  output logic                                o_config_ready,

  // Input Data
  output logic                                o_ready,            // backpressure to upstream
  input  wire                                 i_valid,            // valid from upstream
  input  wire [DATA_WIDTH-1:0]                i_data,             // input data from xbar
  input  wire                                 i_transmitter_done, //upstream done

  // Output 1 Data (select = 0)
  input  wire                                i_1_ready,      // backpressure from downstream 1
  output wire                                o_1_valid,      // valid to downstream 1

  // Output 2 Data (select = 1)
  input  wire                                i_2_ready,      // backpressure from downstream 2
  output wire                                o_2_valid,      // valid to downstream 2

  // Output Data
  output logic [DATA_WIDTH-1:0]              o_data          // Output data
);

// Handle Config data
    logic   [CONFIG_WIDTH-1:0] config_offset;
    logic                      config_done;
    demux_sel_config_t         cfg;
    logic                      select;     // select signal

    localparam int NUM_CONFIG_OFFSETS = divCeil($bits(cfg), CONFIG_WIDTH);

    // For now, ensure size of config is exact multiple of CONFIG_WIDTH
    `DLA_ACL_PARAMETER_ASSERT($bits(cfg) == NUM_CONFIG_OFFSETS * CONFIG_WIDTH);

    //reset parameterization
    localparam int RESET_USE_SYNCHRONIZER = 1;
    localparam int RESET_PIPE_DEPTH       = 3;
    localparam int RESET_NUM_COPIES       = 1;

    logic [RESET_NUM_COPIES-1:0] sclrn;

    /////////////////////////////
    //  Reset Synchronization  //
    /////////////////////////////

    dla_reset_handler_simple #(
        .USE_SYNCHRONIZER   (RESET_USE_SYNCHRONIZER),
        .PIPE_DEPTH         (RESET_PIPE_DEPTH),
        .NUM_COPIES         (RESET_NUM_COPIES)
    ) dla_demux_synchronizer (
        .clk                (clk_dla),
        .i_resetn           (i_aresetn),
        .o_sclrn            (sclrn)
    );

    assign select = cfg.select[0];
    assign o_config_ready = ~config_done;

    always_ff @(posedge clk_dla) begin
        // config state machine
        if (i_config_valid & o_config_ready) begin
            // update progress in accepting NUM_CONFIG_OFFSETS transactions
            if (config_offset == NUM_CONFIG_OFFSETS-1) begin
                config_offset    <= '0;
                config_done <= 1'b1;
            end
            else begin
                config_offset  <= config_offset + 1'b1;
            end
            cfg <= (i_config_data[CONFIG_WIDTH-1:0] << ($bits(cfg) - CONFIG_WIDTH)) | (cfg >> CONFIG_WIDTH);
        end else begin
            // Back to configure state
            if (i_transmitter_done) begin
                config_done <= 0;
            end
        end
        // resetn
        if (~sclrn[0]) begin
            config_done <= 1'b0;
            config_offset <= '0;
            cfg.select <= '0;
        end
    end
// steer input data
    logic i_ready_comb, intermediate_out_valid;
    assign i_ready_comb = config_done ? (select ? i_2_ready : i_1_ready) : 1'b0;
    assign o_1_valid = config_done ? (select ? 1'b0 : intermediate_out_valid) : 1'b0;
    assign o_2_valid = config_done ? (select ? intermediate_out_valid : 1'b0) : 1'b0;

    dla_st_pipeline_stage #(
      .DATA_WIDTH  (DATA_WIDTH   )
    ) inp_pipe_inst (
      .clock       (clk_dla               ),
      .i_resetn    (sclrn[0]              ),
      .o_ready     (o_ready               ),
      .i_valid     (i_valid               ),
      .i_data      (i_data                ),
      .i_ready     (i_ready_comb          ),
      .o_valid     (intermediate_out_valid),
      .o_data      (o_data                )
    );

endmodule