summaryrefslogtreecommitdiff
path: root/python/openvino/demo/ip/intel_ai_ip/verilog/dla_streamer_fsm.sv
blob: 9286e3930885d54e2e83266ef366c9bfbff9d225 (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
136
// Copyright 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_streamer_fsm.sv
 *
 *  This module implements a state machine to produce the correct AXI-s o_tready signal for CoreDLA
 *  input streaming. The goal is to make sure that the o_ready signal goes low as soon as the last
 *  input transmission for the current frame is received, and does not go high again until the next
 *  move instruction is configured in the input feeder.
 *
 *  To accomplish this, this module implements the FSM as shown below:
 *
 * ~i_dla_ready | ~i_stream_en
 *     ┌────┐
 *     │    │
 *     │    │                  ┌───────┐ ~i_tvalid
 *   ┌─┴────▼┌─────┐           │       ├────┐        ┌─────────────────────────────────────────────────────────────┐
 *   │       │     └──────────►│  S1   │    │        │                                                             │
 *   │  S0   |   i_dla_ready   │       │◄───┘        │  S0: IDLE ("Wait for input feeder to become ready")         │
 *   │       │   & i_stream_en ├──┬────┘             │      o_stream_ready = 0                                     │
 *   └───────┘                 │  │                  │                                                             │
 *       ▲                     │  │                  │  S1: STREAM_FIRST ("Accept first input")                    │
 *       │     i_lt_done_frame │  │i_tvalid          │      o_stream_ready = 1                                     │
 *       │              ┌──────┘  │                  │                                                             │
 *       │              │         │                  │  S1: STREAMING ("Accept AXI-s inputs")                      │
 *       │              │     ┌───▼───┐              │      o_stream_ready = 1                                     │
 *       │~i_dla_ready  │     │       ├────┐         │                                                             │
 *       │              │     │   S2  │    │         │  S2: WAIT_FOR_NEXT_FRAME ("Downstream is digesting inputs") │
 *       │   ┌──────────┘     │       │◄───┘         │      o_stream_ready = 0                                     │
 *       │   ▼                └───┬───┘              └─────────────────────────────────────────────────────────────┘
 *     ┌─┴─────┐                  │
 *     │       │                  │i_lt_done_frame
 *     │   S3  ├──────────────────┘
 *     │       │
 *     └─────┬─┘
 *       ▲   │
 *       │   │
 *       └───┘
 *        i_dla_ready
 *
 *
 *  Note: This FSM assumes that the i_dla_ready signal from the input feeder goes low between every input frame.
 */

`resetall
`undefineall
`default_nettype none

module dla_streamer_fsm (
  input wire clk_dla,
  input wire clk_axi,
  input wire i_resetn_axi,
  input wire i_resetn_async,
  input wire i_dla_ready,
  input wire i_lt_ready,
  input wire i_streaming_enable,
  input wire i_lt_done_frame,
  input wire i_tvalid,
  output logic o_stream_ready,
  output logic o_reading_first_word // Used to start the 'active jobs' CSR counter
);
enum { // 2-state ints
  IDLE_BIT,
  STREAM_FIRST_BIT,
  STREAMING_BIT,
  WAIT_FOR_NEXT_FRAME_BIT
} index;
enum logic [index.num()-1:0] { // 1-hot encodings
  IDLE = 1 << IDLE_BIT,
  STREAM_FIRST = 1 << STREAM_FIRST_BIT,
  STREAMING = 1 << STREAMING_BIT,
  WAIT_FOR_NEXT_FRAME = 1 << WAIT_FOR_NEXT_FRAME_BIT,
  XXX = 'x
} state, next;
logic axi_dla_ready;
// move the ready signal from input feeder into AXI domain.
dla_clock_cross_full_sync cc_dla_ready (
  .clk_src(clk_dla),
  .i_src_async_resetn(1'b1),
  .i_src_data(i_dla_ready),
  .o_src_data(), // in streamer, sort out resets and pass in the appropriate resets.
  .clk_dst(clk_axi),
  .i_dst_async_resetn(1'b1),
  .o_dst_data(axi_dla_ready)
);
always_comb begin : fsm_combinational
  next = XXX;
  unique case (1'b1)
    state[IDLE_BIT]:
      if (i_lt_ready & i_streaming_enable)
        next = STREAM_FIRST;
      else
        next = IDLE;
    state[STREAM_FIRST_BIT]:
      if (i_tvalid & i_streaming_enable)
        next = STREAMING;
      else
        next = STREAM_FIRST;
    state[STREAMING_BIT]:
      if (i_lt_done_frame)
        next = WAIT_FOR_NEXT_FRAME;
      else
        next = STREAMING;
    state[WAIT_FOR_NEXT_FRAME_BIT]:
      next = IDLE;
    default:
      next = XXX;
  endcase
end

always_ff @( posedge clk_axi ) begin : fsm_state_logic
  state <= next;
  o_reading_first_word <= 0;
  if (state[STREAM_FIRST_BIT] & next != STREAM_FIRST) begin
    o_reading_first_word <= 1;
  end

  if (~i_resetn_axi) begin
    state <= IDLE;
  end
end

assign o_stream_ready = state[STREAMING_BIT] | (state[STREAM_FIRST_BIT] & i_streaming_enable);

endmodule