17 #ifndef __AXISUBORDINATETOREADYVALID_H__
18 #define __AXISUBORDINATETOREADYVALID_H__
22 #include <hls_globals.h>
24 #include <mem_array.h>
26 #include <axi/AxiSubordinateToReadyValid/testbench/RVSink.h>
54 template <
typename axiCfg,
typename rvCfg>
57 static const int kDebugLevel = 5;
61 typename axi4_::read::template subordinate<> if_axi_rd;
62 typename axi4_::write::template subordinate<> if_axi_wr;
64 sc_in<bool> reset_bar;
68 rvDataW = rvCfg::dataWidth,
69 rvAddrW = rvCfg::addrWidth,
70 rvWstrbW = rvCfg::wstrbWidth,
73 typedef typename RVSink<rvCfg>::Read Read;
74 typedef typename RVSink<rvCfg>::Write Write;
75 typedef typename RVSink<rvCfg>::Addr rvAddr;
77 Connections::In<Read> if_rv_rd;
78 Connections::Out<Write> if_rv_wr;
82 : if_axi_rd(
"if_axi_rd"),
83 if_axi_wr(
"if_axi_wr"),
84 reset_bar(
"reset_bar"),
87 if_rv_wr(
"if_rv_wr") {
89 sensitive << clk.pos();
90 async_reset_signal_is(reset_bar,
false);
107 static const int bytesPerBeat = rvDataW >> 3;
113 NVUINTW(axi4_::ADDR_WIDTH) read_addr;
114 NVUINTW(axi4_::ALEN_WIDTH) axiRdLen;
117 bool read_arb_req = 0;
118 bool write_arb_req = 0;
123 bool read_inFlight = 0;
124 bool arb_needs_update = 1;
126 #pragma hls_pipeline_init_interval 1
127 #pragma pipeline_stall_mode flush
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;
138 if (if_axi_rd.ar.PopNB(axi_rd_req)) {
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;
144 axi_rd_resp.resp = axi4_::Enc::XRESP::OKAY;
145 axi_rd_resp.id = axi_rd_req.id;
149 if (!write_arb_req) {
150 if (if_axi_wr.aw.PopNB(axi_wr_req_addr)) {
152 NVUINTW(rvAddrW) addr_temp_cast(
static_cast< sc_uint<rvAddrW>
>(axi_wr_req_addr.addr));
153 write_addr = addr_temp_cast;
157 if (select_mask == 1) {
158 if (!read_inFlight) {
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);
167 if (if_rv_rd.PopNB(rv_rd)) {
168 axi_rd_resp.data = rv_rd.data;
170 axi_rd_resp.last = 1;
172 arb_needs_update = 1;
174 axi_rd_resp.last = 0;
176 read_addr += bytesPerBeat;
178 if_axi_rd.r.Push(axi_rd_resp);
179 CDCOUT(sc_time_stamp() <<
" " << name() <<
" RV read response:"
181 << endl, kDebugLevel);
185 }
else if (select_mask == 2) {
186 if (if_axi_wr.w.PopNB(axi_wr_req_data)) {
187 rv_wr.addr = write_addr;
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) {
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);
208 write_addr += bytesPerBeat;
A generalized implementation of generic n-way roundrobin arbiter.
An AXI subordinate that converts AXI requests into a simplified format.
The base axi4 class parameterized according a valid config.
NVUINTW(Wrapped< T >::width) TypeToNVUINT(T in)
Convert Type to NVUINT.
A struct composed of the signals associated with AXI read and write requests.
A struct composed of the signals associated with an AXI read response.
A struct composed of the signals associated with an AXI write response.
A struct composed of the signals associated with AXI write data.