MatchLib
All Classes Namespaces Files Functions Modules Pages
AxiSubordinateToReadyValid.h
1/*
2 * Copyright (c) 2017-2024, 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 __AXISUBORDINATETOREADYVALID_H__
18#define __AXISUBORDINATETOREADYVALID_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/AxiSubordinateToReadyValid/testbench/RVSink.h>
27#include "Arbiter.h"
28
54template <typename axiCfg, typename rvCfg>
55class AxiSubordinateToReadyValid : 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 subordinate<> if_axi_rd;
62 typename axi4_::write::template subordinate<> 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:
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
A generalized implementation of generic n-way roundrobin arbiter.
Definition Arbiter.h:61
An AXI subordinate that converts AXI requests into a simplified format.
The base axi4 class parameterized according a valid config.
Definition axi4.h:64
#define CDCOUT(x, y)
Definition hls_globals.h:73
#define NVUINTW(width)
Definition nvhls_types.h:35
nvhls_t< W >::nvuint_t get_slc(type X, const unsigned int i)
Function that returns slice of bits.
Definition nvhls_int.h:437
A struct composed of the signals associated with AXI read and write requests.
Definition axi4.h:114
A struct composed of the signals associated with an AXI read response.
Definition axi4.h:157
A struct composed of the signals associated with an AXI write response.
Definition axi4.h:190
A struct composed of the signals associated with AXI write data.
Definition axi4.h:215