17 #ifndef __AXI_T_MANAGER_FROM_FILE__
18 #define __AXI_T_MANAGER_FROM_FILE__
20 #include <nvhls_int.h>
22 #include <ac_reset_signal_is.h>
25 #include <axi/testbench/CSVFileReader.h>
26 #include <nvhls_connections.h>
27 #include <hls_globals.h>
34 #include <boost/assert.hpp>
64 template <
typename axiCfg,
bool enable_
interrupts = false>
class ManagerFromFile :
public sc_module {
66 static const int kDebugLevel = 1;
69 typename axi4_::read::template manager<> if_rd;
70 typename axi4_::write::template manager<> if_wr;
72 sc_in<bool> reset_bar;
77 static const int bytesPerBeat = axi4_::DATA_WIDTH >> 3;
78 static const int bytesPerWord = axi4_::DATA_WIDTH >> 3;
81 std::queue< int > delay_q;
82 std::queue< int > req_q;
83 std::queue< typename axi4_::AddrPayload > raddr_q;
84 std::queue< typename axi4_::AddrPayload > waddr_q;
85 std::queue< typename axi4_::WritePayload > wdata_q;
86 std::queue<typename axi4_::Data> rresp_q;
94 int burst_inflight = 0;
99 ManagerFromFile(sc_module_name name_, std::string filename=
"requests.csv")
100 : sc_module(name_), if_rd(
"if_rd"), if_wr(
"if_wr"), reset_bar(
"reset_bar"), clk(
"clk") {
102 CDCOUT(
"Reading file: " << filename << endl, kDebugLevel);
104 std::vector< std::vector<std::string> > dataList = reader.readCSV();
105 for (
unsigned int i=0; i < dataList.size(); i++) {
106 std::vector<std::string> vec = dataList[i];
107 CMOD_ASSERT_MSG(vec.size() == 5,
"Each request must have five elements");
108 if (!burst_inflight) delay_q.push(atoi(vec[0].c_str()));
110 if (!burst_inflight) {
112 std::stringstream ss;
113 sc_uint<axi4_::ADDR_WIDTH> addr;
116 std::stringstream ss_len;
117 addr_pld.addr =
static_cast<typename axi4_::Addr
>(addr);
118 sc_uint<axi4_::ALEN_WIDTH> len;
119 ss_len << hex << vec[4];
121 if (len)
CMOD_ASSERT_MSG(axiCfg::useBurst,
"A burst transaction was requested but the AXI config does not support bursts");
122 CMOD_ASSERT_MSG(axiCfg::maxBurstSize >= len,
"A burst transaction was requested that is longer than the maximum allowed by the AXI config");
124 addr_pld.len =
static_cast<typename axi4_::BeatNum
>(len);
125 raddr_q.push(addr_pld);
126 burst_inflight = int(len);
130 std::stringstream ss_data;
131 sc_biguint<axi4_::DATA_WIDTH> data;
132 ss_data << hex << vec[3];
134 rresp_q.push(TypeToNVUINT(data));
135 }
else if (vec[1] ==
"W") {
136 if (!burst_inflight) {
138 std::stringstream ss;
139 sc_uint<axi4_::ADDR_WIDTH> addr;
142 std::stringstream ss_len;
143 addr_pld.addr =
static_cast<typename axi4_::Addr
>(addr);
144 sc_uint<axi4_::ALEN_WIDTH> len;
145 ss_len << hex << vec[4];
147 if (len)
CMOD_ASSERT_MSG(axiCfg::useBurst,
"A burst transaction was requested but the AXI config does not support bursts");
148 CMOD_ASSERT_MSG(axiCfg::maxBurstSize >= len,
"A burst transaction was requested that is longer than the maximum allowed by the AXI config");
149 addr_pld.len =
static_cast<typename axi4_::BeatNum
>(len);
150 waddr_q.push(addr_pld);
151 burst_inflight = int(len);
155 std::stringstream ss_data;
156 sc_biguint<axi4_::DATA_WIDTH> data;
157 ss_data << hex << vec[3];
159 wr_data_pld.data = TypeToNVUINT(data);
160 wr_data_pld.wstrb = ~0;
161 if (!burst_inflight) {
162 wr_data_pld.last = 1;
164 wr_data_pld.last = 0;
166 wdata_q.push(wr_data_pld);
167 }
else if (vec[1] ==
"Q") {
168 CMOD_ASSERT_MSG(enable_interrupts,
"Interrupt command read, but interrupts are not enabled");
176 sensitive << clk.pos();
177 async_reset_signal_is(reset_bar,
false);
190 while (!delay_q.empty()) {
191 int delay = delay_q.front();
192 if (delay > 0) wait(delay);
194 if (req_q.front() == 2) {
195 CMOD_ASSERT_MSG(enable_interrupts,
"Interrupt command found, but interrupts are not enabled");
196 CDCOUT(sc_time_stamp() <<
" " << name() <<
" Beginning wait for interrupt"
197 << endl, kDebugLevel);
198 while (interrupt.read() == 0) wait();
199 CDCOUT(sc_time_stamp() <<
" " << name() <<
" Interrupt received"
200 << endl, kDebugLevel);
201 }
else if (req_q.front() == 1) {
202 addr_pld = waddr_q.front();
203 if_wr.aw.Push(addr_pld);
205 CDCOUT(sc_time_stamp() <<
" " << name() <<
" Sent write request:"
206 <<
" addr=[" << addr_pld <<
"]"
207 << endl, kDebugLevel);
209 wr_data_pld = wdata_q.front();
210 if_wr.w.Push(wr_data_pld);
212 CDCOUT(sc_time_stamp() <<
" " << name() <<
" Sent write data:"
213 <<
" data=[" << wr_data_pld <<
"]"
214 << endl, kDebugLevel);
215 }
while (!wr_data_pld.last);
217 }
else if (req_q.front() == 0) {
218 addr_pld = raddr_q.front();
219 if_rd.ar.Push(addr_pld);
221 CDCOUT(sc_time_stamp() <<
" " << name() <<
" Sent read request: "
222 <<
" addr=[" << addr_pld <<
"]"
223 << endl, kDebugLevel);
225 data_pld = if_rd.r.Pop();
226 CDCOUT(sc_time_stamp() <<
" " << name() <<
" Received read response: ["
228 << endl, kDebugLevel);
229 CMOD_ASSERT_MSG(data_pld.data == rresp_q.front(),
"Read response did not match expected value");
231 }
while (!data_pld.last);
A helper class to read CSV files.
The base axi4 class parameterized according a valid config.
An AXI manager that generates traffic according to a file for use in testbenches.
#define CMOD_ASSERT_MSG(X, MSG)
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.
Compute Celing of log2 of a constant.