62 const std::vector<ModuleGenerator::parameter>& ,
63 const std::vector<ModuleGenerator::parameter>& ,
64 const std::vector<ModuleGenerator::parameter>& ,
65 const std::vector<ModuleGenerator::parameter>& )
73 const auto port_prefix = mod_cir->
get_id().substr(
sizeof(
"if_") - 1
U, std::string::npos);
74 std::string np_library = mod_cir->
get_id() +
" index";
75 std::string internal_port_assign;
76 const auto add_port_parametric_wire = [&](
const std::string& name,
port_o::port_direction dir,
unsigned port_size) {
77 const auto port_name = port_prefix +
"_" + name;
80 GetPointerS<port_o>(port_obj)->set_is_memory(
true);
83 np_library +=
" " + port_name;
88 out <<
"[BITSIZE_" << port_name <<
"-1:0] ";
93 internal_port_assign +=
"assign " + name +
"=" + port_name +
";\n";
97 internal_port_assign +=
"assign " + port_name +
"=" + name +
";\n";
101 const auto add_port_parametric_reg = [&](
const std::string& name,
port_o::port_direction dir,
unsigned port_size) {
102 const auto port_name = port_prefix +
"_" + name;
105 GetPointerS<port_o>(port_obj)->set_is_memory(
true);
108 np_library +=
" " + port_name;
113 out <<
"[BITSIZE_" << port_name <<
"-1:0] ";
115 out << name <<
";\n";
116 if(dir == port_o::IN)
118 internal_port_assign +=
"assign " + name +
"=" + port_name +
";\n";
122 internal_port_assign +=
"assign " + port_name +
"=" + name +
";\n";
126 add_port_parametric_reg(
"awready", port_o::OUT, 0
U);
127 add_port_parametric_reg(
"wready", port_o::OUT, 0
U);
128 add_port_parametric_reg(
"bid", port_o::OUT, 1
U);
129 add_port_parametric_reg(
"bresp", port_o::OUT, 2
U);
130 add_port_parametric_reg(
"buser", port_o::OUT, 1
U);
131 add_port_parametric_reg(
"bvalid", port_o::OUT, 0
U);
132 add_port_parametric_reg(
"arready", port_o::OUT, 0
U);
133 add_port_parametric_reg(
"rid", port_o::OUT, 1
U);
134 add_port_parametric_reg(
"rdata", port_o::OUT, 1
U);
135 add_port_parametric_reg(
"rresp", port_o::OUT, 2
U);
136 add_port_parametric_reg(
"rlast", port_o::OUT, 0
U);
137 add_port_parametric_reg(
"ruser", port_o::OUT, 1
U);
138 add_port_parametric_reg(
"rvalid", port_o::OUT, 0
U);
140 add_port_parametric_reg(
"awid", port_o::IN, 1
U);
141 add_port_parametric_reg(
"awaddr", port_o::IN, 1
U);
142 add_port_parametric_reg(
"awlen", port_o::IN, 1
U);
143 add_port_parametric_reg(
"awsize", port_o::IN, 1
U);
144 add_port_parametric_reg(
"awburst", port_o::IN, 2
U);
145 add_port_parametric_reg(
"awlock", port_o::IN, 1
U);
146 add_port_parametric_reg(
"awcache", port_o::IN, 1
U);
147 add_port_parametric_reg(
"awprot", port_o::IN, 1
U);
148 add_port_parametric_reg(
"awqos", port_o::IN, 1
U);
149 add_port_parametric_reg(
"awregion", port_o::IN, 1
U);
150 add_port_parametric_reg(
"awuser", port_o::IN, 1
U);
151 add_port_parametric_reg(
"awvalid", port_o::IN, 0
U);
153 add_port_parametric_reg(
"wdata", port_o::IN, 1
U);
154 add_port_parametric_reg(
"wstrb", port_o::IN, 1
U);
155 add_port_parametric_reg(
"wlast", port_o::IN, 0
U);
156 add_port_parametric_reg(
"wuser", port_o::IN, 1
U);
157 add_port_parametric_reg(
"wvalid", port_o::IN, 0
U);
159 add_port_parametric_wire(
"bready", port_o::IN, 0
U);
161 add_port_parametric_reg(
"arid", port_o::IN, 1
U);
162 add_port_parametric_reg(
"araddr", port_o::IN, 1
U);
163 add_port_parametric_reg(
"arlen", port_o::IN, 1
U);
164 add_port_parametric_reg(
"arsize", port_o::IN, 1
U);
165 add_port_parametric_reg(
"arburst", port_o::IN, 2
U);
166 add_port_parametric_reg(
"arlock", port_o::IN, 1
U);
167 add_port_parametric_reg(
"arcache", port_o::IN, 1
U);
168 add_port_parametric_reg(
"arprot", port_o::IN, 1
U);
169 add_port_parametric_reg(
"arqos", port_o::IN, 1
U);
170 add_port_parametric_reg(
"arregion", port_o::IN, 1
U);
171 add_port_parametric_reg(
"aruser", port_o::IN, 1
U);
172 add_port_parametric_reg(
"arvalid", port_o::IN, 0
U);
173 add_port_parametric_wire(
"rready", port_o::IN, 0
U);
177 if(HLSMgr->get_parameter()->getOption<
unsigned int>(OPT_mem_delay_write) == 1)
180 "Warning: AXI does not support mem-delay-write==1, as it requires at least a cycle of latency -> " 181 "mem-delay-write changed to 2.\n");
183 out << internal_port_assign <<
"\n" 184 <<
"localparam WRITE_DELAY=" 185 <<
std::max(1
U, (HLSMgr->get_parameter()->getOption<
unsigned int>(OPT_mem_delay_write) - 1)) <<
",\n" 186 <<
" READ_DELAY=" << (HLSMgr->get_parameter()->getOption<
unsigned int>(OPT_mem_delay_read) - 1) <<
",\n" 187 <<
" QUEUE_SIZE=" << HLSMgr->get_parameter()->getOption<
unsigned int>(OPT_tb_queue_size) <<
",\n" 188 <<
" BITSIZE_data=BITSIZE_" << port_prefix <<
"_rdata,\n" 189 <<
" BITSIZE_counter=32,\n" 190 <<
" BITSIZE_burst=BITSIZE_" << port_prefix <<
"_arburst,\n" 191 <<
" BITSIZE_len=BITSIZE_" << port_prefix <<
"_arlen,\n" 192 <<
" BITSIZE_delay=32,\n" 193 <<
" BITSIZE_size=BITSIZE_" << port_prefix <<
"_arsize,\n" 194 <<
" BITSIZE_addr=BITSIZE_" << port_prefix <<
"_araddr,\n" 195 <<
" BITSIZE_wstrb=BITSIZE_" << port_prefix <<
"_wstrb,\n" 196 <<
" BITSIZE_id=BITSIZE_" << port_prefix <<
"_arid,\n" 197 <<
" OFFSET_delay=0,\n" 198 <<
" OFFSET_counter=OFFSET_delay+BITSIZE_delay,\n" 199 <<
" OFFSET_burst=OFFSET_counter+BITSIZE_counter,\n" 200 <<
" OFFSET_len=OFFSET_burst+BITSIZE_burst,\n" 201 <<
" OFFSET_size=OFFSET_len+BITSIZE_len,\n" 202 <<
" OFFSET_addr=OFFSET_size+BITSIZE_size,\n" 203 <<
" OFFSET_id=OFFSET_addr+BITSIZE_addr,\n" 204 <<
" OFFSET_data=OFFSET_id+BITSIZE_id,\n" 205 <<
" OFFSET_wstrb=OFFSET_data+BITSIZE_data,\n" 207 "BITSIZE_aritem=BITSIZE_id+BITSIZE_addr+BITSIZE_size+BITSIZE_len+BITSIZE_burst+BITSIZE_counter+BITSIZE_delay," 210 "BITSIZE_awitem=BITSIZE_wstrb+BITSIZE_data+BITSIZE_id+BITSIZE_addr+BITSIZE_size+BITSIZE_len+" 211 "BITSIZE_burst+BITSIZE_counter+BITSIZE_delay;" 214 reg [QUEUE_SIZE*BITSIZE_aritem-1:0] arqueue; 215 reg [QUEUE_SIZE*BITSIZE_aritem-1:0] next_arqueue; 216 reg [QUEUE_SIZE*BITSIZE_awitem-1:0] awqueue; 217 reg [QUEUE_SIZE*BITSIZE_awitem-1:0] next_awqueue; 218 reg [31:0] test_addr; 219 reg [31:0] test_wstrb; 220 reg [31:0] test_data; 221 reg [31:0] test_addr_read; 222 integer arqueue_size, next_arqueue_size; 223 integer awqueue_size, next_awqueue_size; 225 reg [BITSIZE_id-1:0] awid_reg; 226 reg [BITSIZE_addr-1:0] awaddr_reg; 227 reg [BITSIZE_size-1:0] awsize_reg; 228 reg [BITSIZE_len-1:0] awlen_reg; 229 reg [BITSIZE_burst-1:0] awburst_reg; 230 reg [BITSIZE_counter-1:0] counter_reg, counter_next; 232 reg wlast_reg, wlast_next; 234 if_utils #(index, BITSIZE_data) m_utils(); 241 next_arqueue_size = 0; 245 next_awqueue_size = 0; 266 // Combinatorial logic for read transactions 269 automatic integer unsigned i; 270 next_arqueue = arqueue; 271 next_arqueue_size = arqueue_size; 272 if(arvalid && arready) // Valid and ready -> accept new transaction 274 next_arqueue[arqueue_size*BITSIZE_aritem +:BITSIZE_aritem] = {arid, araddr, arsize, arlen, arburst, {BITSIZE_counter{1'b0}}, ({BITSIZE_delay{1'b0}} + READ_DELAY)}; // size of parameter is implementation dependent 275 next_arqueue_size = arqueue_size + 1; 277 for(i = 0; i < QUEUE_SIZE; i = i + 1) 279 if(arqueue[i*BITSIZE_aritem+OFFSET_delay+:BITSIZE_delay] > 1) 281 next_arqueue[i*BITSIZE_aritem+OFFSET_delay+:BITSIZE_delay] = arqueue[i*BITSIZE_aritem+OFFSET_delay+:BITSIZE_delay] - 1; 284 if(next_arqueue_size > 0 && next_arqueue[OFFSET_counter+:BITSIZE_counter] >= (next_arqueue[OFFSET_len+:BITSIZE_len] + 1) && rready && rvalid) 286 for(i = 1; i < QUEUE_SIZE; i = i + 1) 288 next_arqueue[(i-1)*BITSIZE_aritem+:BITSIZE_aritem] = next_arqueue[i*BITSIZE_aritem+:BITSIZE_aritem]; 290 next_arqueue_size = next_arqueue_size - 1; 292 if(next_arqueue_size > 0 && (next_arqueue[OFFSET_delay+:BITSIZE_delay] == 1) && (next_arqueue[OFFSET_counter+:BITSIZE_counter] < (next_arqueue[OFFSET_len+:BITSIZE_len] + 1))) 294 next_arqueue[OFFSET_counter+:BITSIZE_counter] = next_arqueue[OFFSET_counter+:BITSIZE_counter] + 1; 298 // Combinatorial logic for write transactions 302 automatic reg [BITSIZE_counter-1:0] counter; 303 next_awqueue = awqueue; 304 next_awqueue_size = awqueue_size; 305 wlast_next = wlast_reg; 306 if(awvalid && awready && wready && wvalid) // Valid and ready -> accept new transaction and save data 308 next_awqueue[awqueue_size*BITSIZE_awitem+:BITSIZE_awitem] = {wstrb, wdata, awid, awaddr, awsize, awlen, awburst, {BITSIZE_counter{1'b0}}, ({BITSIZE_delay{1'b0}} + WRITE_DELAY)}; 309 next_awqueue_size = awqueue_size + 1; 311 else if(awvalid && awready && wlast_reg) 317 awburst_reg = awburst; 321 else if(wready && wvalid) 323 next_awqueue[awqueue_size*BITSIZE_awitem+:BITSIZE_awitem] = {wstrb, wdata, awid_reg, awaddr_reg, awsize_reg, awlen_reg, awburst_reg, counter_reg, ({BITSIZE_delay{1'b0}} + WRITE_DELAY)}; 324 next_awqueue_size = awqueue_size + 1; 325 counter_next = counter_reg + 1; 327 for(i = 0; i < QUEUE_SIZE; i = i + 1) 329 if(awqueue[i*BITSIZE_awitem+OFFSET_delay+:BITSIZE_delay] > 1) 331 next_awqueue[i*BITSIZE_awitem+OFFSET_delay+:BITSIZE_delay] = awqueue[i*BITSIZE_awitem+OFFSET_delay+:BITSIZE_delay] - 1; 334 if(write_done && next_awqueue_size > 0 && ((next_awqueue[OFFSET_counter+:BITSIZE_counter] == next_awqueue[OFFSET_len+:BITSIZE_len] && bready) || next_awqueue[OFFSET_counter+:BITSIZE_counter] < next_awqueue[OFFSET_len+:BITSIZE_len])) 336 for(i = 1; i < QUEUE_SIZE; i = i + 1) 338 next_awqueue[(i-1)*BITSIZE_awitem+:BITSIZE_awitem] = next_awqueue[i*BITSIZE_awitem+:BITSIZE_awitem]; 340 next_awqueue_size = next_awqueue_size - 1; 344 always@(posedge clock) 356 arready <= (next_arqueue_size - (next_arqueue_size > 0 && next_arqueue[OFFSET_counter+:BITSIZE_counter] >= next_arqueue[OFFSET_len+:BITSIZE_len]) < QUEUE_SIZE); //Ready if next_queue_size - rlast < QUEUE_SIZE 357 awready <= (wlast_next || wlast) && (next_awqueue_size - (next_awqueue_size > 0 && next_awqueue[OFFSET_delay+:BITSIZE_delay] == 1 && next_awqueue[OFFSET_counter+:BITSIZE_counter] == next_awqueue[OFFSET_len+:BITSIZE_len]) < QUEUE_SIZE); // ready if next_queue_size - bvalid < QUEUE_SIZE 358 wready <= (next_awqueue_size - (next_awqueue_size > 0 && next_awqueue[OFFSET_delay+:BITSIZE_delay] == 1 && next_awqueue[OFFSET_counter+:BITSIZE_counter] == next_awqueue[OFFSET_len+:BITSIZE_len]) < QUEUE_SIZE); 359 wlast_reg <= wlast_next || wlast; 360 counter_reg <= counter_next; 364 always@(posedge clock) 373 rvalid <= (next_arqueue_size > 0 && next_arqueue[OFFSET_delay+:BITSIZE_delay] == 1); // if at posedge_clock delay is 1 I have to perfrom the operation in this cycle 374 bvalid <= (next_awqueue_size > 0 && next_awqueue[OFFSET_delay+:BITSIZE_delay] == 1 && next_awqueue[OFFSET_counter+:BITSIZE_counter] == (next_awqueue[OFFSET_len+:BITSIZE_len])); // if at posedge_clock delay is 1 I have to perfrom the last operation in this cycle 378 always@(posedge clock) 389 arqueue <= next_arqueue; 390 arqueue_size <= next_arqueue_size; 391 awqueue <= next_awqueue; 392 awqueue_size <= next_awqueue_size; 396 // Sequential logic for read transactions 397 always@(posedge clock) 399 automatic ptr_t currAddr; 400 automatic ptr_t endAddr; 403 if(next_arqueue_size > 0 && next_arqueue[OFFSET_delay+:BITSIZE_delay] == 1) 405 if(next_arqueue[OFFSET_burst+:BITSIZE_burst] == 2'b00) 407 currAddr = next_arqueue[OFFSET_addr+:BITSIZE_addr]; 409 else if(next_arqueue[OFFSET_burst+:BITSIZE_burst] == 2'b01) 411 currAddr = next_arqueue[OFFSET_addr+:BITSIZE_addr] + (next_arqueue[OFFSET_counter+:BITSIZE_counter] - 1) * (1 << next_arqueue[OFFSET_size+:BITSIZE_size]); 415 $display("Unsupported burst type: %0d", next_arqueue[OFFSET_burst+:BITSIZE_burst]); 418 test_addr_read <= currAddr; 419 rid <= next_arqueue[OFFSET_id+:BITSIZE_id]; 420 rdata <= m_utils.read_a(currAddr); 421 if(next_arqueue[OFFSET_counter+:BITSIZE_counter] >= (next_arqueue[OFFSET_len+:BITSIZE_len] + 1)) 428 // Sequential logic for write transactions 429 always@(posedge clock) 431 automatic ptr_t currAddr; 432 automatic ptr_t endAddr; 437 if(next_awqueue_size > 0 && next_awqueue[OFFSET_delay+:BITSIZE_delay] == 1) // Performs the first write of the queue 439 if(next_awqueue[OFFSET_burst+:BITSIZE_burst] == 2'b00) 441 currAddr = next_awqueue[OFFSET_addr+:BITSIZE_addr]; 443 else if(next_awqueue[OFFSET_burst+:BITSIZE_burst] == 2'b01) 445 currAddr = next_awqueue[OFFSET_addr+:BITSIZE_addr] + next_awqueue[OFFSET_counter+:BITSIZE_counter] * (1 << next_awqueue[OFFSET_size+:BITSIZE_size]); 449 $display("Unsupported burst type: %0d", next_arqueue[OFFSET_burst+:BITSIZE_burst]); 452 test_wstrb <= next_awqueue[OFFSET_wstrb+:BITSIZE_wstrb]; 453 test_addr <= currAddr; 454 test_data <= next_awqueue[OFFSET_data+:BITSIZE_data]; 455 bid <= next_awqueue[OFFSET_id+:BITSIZE_id]; 457 m_utils.write_strobe(next_awqueue[OFFSET_data+:BITSIZE_data], next_awqueue[OFFSET_wstrb+:BITSIZE_wstrb], currAddr); Data structure representing the entire HLS information.
refcount< structural_type_descriptor > structural_type_descriptorRef
RefCount type definition of the structural_type_descriptor class structure.
#define OUTPUT_LEVEL_NONE
no output print is performed.
Structure representing the most relevant information about the type of a structural object...
const std::string & get_id() const
Return the identifier associated with the structural_object.
mathematical utility function not provided by standard libraries
TestbenchAXIMModuleGenerator(const HLS_managerRef &HLSMgr)
port_direction
Enumerative type describing the direction of a port.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
static void add_NP_functionality(structural_objectRef cir, NP_functionality::NP_functionaly_type dt, std::string functionality_description)
Add a not-parsed functionality.
This class writes different HDL based descriptions (VHDL, Verilog, SystemC) starting from a structura...
static structural_objectRef add_port(const std::string &id, port_o::port_direction pdir, structural_objectRef owner, structural_type_descriptorRef type_descr, unsigned int treenode=0)
Create a new port.
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
This file collects some utility functions.
void InternalExec(std::ostream &out, structural_objectRef mod, unsigned int function_id, vertex op_v, const HDLWriter_Language language, const std::vector< ModuleGenerator::parameter > &_p, const std::vector< ModuleGenerator::parameter > &_ports_in, const std::vector< ModuleGenerator::parameter > &_ports_out, const std::vector< ModuleGenerator::parameter > &_ports_inout) final
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
this class is used to manage the command-line or XML options.
Class implementation of the structural_manager.
#define PRINT_OUT_MEX(profLevel, curprofLevel, mex)
A brief description of the C++ Header File.