MatchLib
AxiSlaveToReadyValid.h
1 /*
2  * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License")
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef __AXISLAVETOREADYVALID_H__
18 #define __AXISLAVETOREADYVALID_H__
19 
20 #include <systemc.h>
21 #include <ac_int.h>
22 #include <hls_globals.h>
23 #include <axi/axi4.h>
24 #include <mem_array.h>
25 #include <fifo.h>
26 #include <axi/AxiSlaveToReadyValid/testbench/RVSink.h>
27 #include "Arbiter.h"
28 
54 template <typename axiCfg, typename rvCfg>
55 class AxiSlaveToReadyValid : public sc_module {
56  public:
57  static const int kDebugLevel = 5;
58 
59  typedef typename axi::axi4<axiCfg> axi4_;
60 
61  typename axi4_::read::template slave<> if_axi_rd;
62  typename axi4_::write::template slave<> if_axi_wr;
63 
64  sc_in<bool> reset_bar;
65  sc_in<bool> clk;
66 
67  enum {
68  rvDataW = rvCfg::dataWidth,
69  rvAddrW = rvCfg::addrWidth,
70  rvWstrbW = rvCfg::wstrbWidth,
71  };
72 
73  typedef typename RVSink<rvCfg>::Read Read;
74  typedef typename RVSink<rvCfg>::Write Write;
75  typedef typename RVSink<rvCfg>::Addr rvAddr;
76 
77  Connections::In<Read> if_rv_rd;
78  Connections::Out<Write> if_rv_wr;
79 
80  public:
81  SC_CTOR(AxiSlaveToReadyValid)
82  : if_axi_rd("if_axi_rd"),
83  if_axi_wr("if_axi_wr"),
84  reset_bar("reset_bar"),
85  clk("clk"),
86  if_rv_rd("if_rv_rd"),
87  if_rv_wr("if_rv_wr") {
88  SC_THREAD(run);
89  sensitive << clk.pos();
90  async_reset_signal_is(reset_bar, false);
91  }
92 
93  protected:
94  void run() {
95  if_axi_rd.reset();
96  if_axi_wr.reset();
97 
98  if_rv_rd.Reset();
99  if_rv_wr.Reset();
100 
101  typename axi4_::AddrPayload axi_rd_req;
102  typename axi4_::ReadPayload axi_rd_resp;
103  typename axi4_::AddrPayload axi_wr_req_addr;
104  typename axi4_::WritePayload axi_wr_req_data;
105  typename axi4_::WRespPayload axi_wr_resp;
106 
107  static const int bytesPerBeat = rvDataW >> 3;
108 
109  Write rv_wr;
110  Read rv_rd;
111  rvAddr addr_temp;
112 
113  NVUINTW(axi4_::ADDR_WIDTH) read_addr;
114  NVUINTW(axi4_::ALEN_WIDTH) axiRdLen;
115  NVUINTW(rvAddrW) write_addr;
116 
117  bool read_arb_req = 0;
118  bool write_arb_req = 0;
119  NVUINTW(2) valid_mask = 0;
120  NVUINTW(2) select_mask = 0;
121  Arbiter<2> arb;
122 
123  bool read_inFlight = 0;
124  bool arb_needs_update = 1;
125 
126  #pragma hls_pipeline_init_interval 1
127  #pragma pipeline_stall_mode flush
128  while (1) {
129  wait();
130 
131  valid_mask = write_arb_req << 1 | read_arb_req;
132  if (arb_needs_update) {
133  select_mask = arb.pick(valid_mask);
134  if (select_mask != 0) arb_needs_update = 0;
135  }
136 
137  if (!read_arb_req) {
138  if (if_axi_rd.ar.PopNB(axi_rd_req)) {
139  read_arb_req = 1;
140  NVUINTW(axi4_::ADDR_WIDTH) addr_temp_cast(static_cast<sc_uint<axi4_::ADDR_WIDTH> >(axi_rd_req.addr));
141  NVUINTW(axi4_::ALEN_WIDTH) len_temp(static_cast< sc_uint<axi4_::ALEN_WIDTH> >(axi_rd_req.len));
142  read_addr = addr_temp_cast;
143  axiRdLen = len_temp;
144  axi_rd_resp.resp = axi4_::Enc::XRESP::OKAY;
145  axi_rd_resp.id = axi_rd_req.id;
146  }
147  }
148 
149  if (!write_arb_req) {
150  if (if_axi_wr.aw.PopNB(axi_wr_req_addr)) {
151  write_arb_req = 1;
152  NVUINTW(rvAddrW) addr_temp_cast(static_cast< sc_uint<rvAddrW> >(axi_wr_req_addr.addr));
153  write_addr = addr_temp_cast;
154  }
155  }
156 
157  if (select_mask == 1) {
158  if (!read_inFlight) {
159  rv_wr.rw = 0;
160  rv_wr.addr = nvhls::get_slc<rvAddrW>(read_addr,0);
161  if_rv_wr.Push(rv_wr);
162  CDCOUT(sc_time_stamp() << " " << name() << " RV read:"
163  << " addr=" << hex << rv_wr.addr.to_int64()
164  << endl, kDebugLevel);
165  read_inFlight = 1;
166  } else {
167  if (if_rv_rd.PopNB(rv_rd)) {
168  axi_rd_resp.data = rv_rd.data;
169  if (axiRdLen == 0) {
170  axi_rd_resp.last = 1;
171  read_arb_req = 0;
172  arb_needs_update = 1;
173  } else {
174  axi_rd_resp.last = 0;
175  axiRdLen--;
176  read_addr += bytesPerBeat;
177  }
178  if_axi_rd.r.Push(axi_rd_resp);
179  CDCOUT(sc_time_stamp() << " " << name() << " RV read response:"
180  << axi_rd_resp
181  << endl, kDebugLevel);
182  read_inFlight = 0;
183  }
184  }
185  } else if (select_mask == 2) {
186  if (if_axi_wr.w.PopNB(axi_wr_req_data)) {
187  rv_wr.addr = write_addr;
188  rv_wr.rw = 1;
189  NVUINTW(axi4_::WSTRB_WIDTH) wstrb_temp_cast(static_cast<sc_uint<axi4_::WSTRB_WIDTH> >(axi_wr_req_data.wstrb));
190  rv_wr.wstrb = wstrb_temp_cast;
191  NVUINTW(axi4_::DATA_WIDTH) data_temp_cast(static_cast<typename axi4_::Data>(axi_wr_req_data.data));
192  rv_wr.data = data_temp_cast;
193  if_rv_wr.Push(rv_wr);
194  CDCOUT(sc_time_stamp() << " " << name() << " RV write:"
195  << " data=" << hex << rv_wr.data
196  << " addr=" << hex << rv_wr.addr.to_uint64()
197  << " strb=" << hex << rv_wr.wstrb.to_uint64()
198  << endl, kDebugLevel);
199  if (axi_wr_req_data.last == 1) {
200  write_arb_req = 0;
201  arb_needs_update = 1;
202  if (axiCfg::useWriteResponses) {
203  axi_wr_resp.resp = axi4_::Enc::XRESP::OKAY;
204  axi_wr_resp.id = axi_wr_req_addr.id;
205  if_axi_wr.bwrite(axi_wr_resp);
206  }
207  } else {
208  write_addr += bytesPerBeat;
209  }
210  }
211  }
212  }
213  }
214 };
215 
216 #endif
An AXI slave that converts AXI requests into a simplified format.
A struct composed of the signals associated with an AXI write response.
Definition: axi4.h:236
NVUINTW(Wrapped< T >::width) TypeToNVUINT(T in)
Convert Type to NVUINT.
Definition: TypeToBits.h:115
A struct composed of the signals associated with AXI write data.
Definition: axi4.h:279
A struct composed of the signals associated with AXI read and write requests.
Definition: axi4.h:108
A struct composed of the signals associated with an AXI read response.
Definition: axi4.h:180
#define CDCOUT(x, y)
Definition: hls_globals.h:73
The base axi4 class parameterized according a valid config.
Definition: axi4.h:58
A generalized implementation of generic n-way roundrobin arbiter.
Definition: Arbiter.h:61