66 unsigned int function_id,
vertex op_v,
68 const std::vector<ModuleGenerator::parameter>& _p,
69 const std::vector<ModuleGenerator::parameter>& ,
70 const std::vector<ModuleGenerator::parameter>& ,
71 const std::vector<ModuleGenerator::parameter>& )
73 const auto retval_size = [&]() {
75 const auto FB = HLSMgr->CGetFunctionBehavior(function_id);
76 const auto TM = HLSMgr->get_tree_manager();
77 const auto call_stmt =
79 THROW_ASSERT(call_stmt && call_stmt->get_kind() == gimple_call_K,
"Expected gimple call statement.");
80 const auto gc = GetPointerS<const gimple_call>(call_stmt);
81 THROW_ASSERT(gc->args.size() >= 2,
"Expected at least two arguments for the builtin wait call.");
82 const auto called_addr = gc->args.at(0);
83 const auto called_hasreturn = gc->args.at(1);
101 out <<
"reg [0:0] index;\n\n";
103 else if(_p.size() > 3
U)
105 out <<
"reg [" <<
ceil_log2(_p.size() - 2
U) <<
"-1:0] index;\n\n";
110 out <<
"wire [BITSIZE_Mout_addr_ram-1:0] paramAddressRead;\n\n";
113 out <<
"reg [31:0] step;\n" 114 <<
"reg [31:0] next_step;\n" 115 <<
"reg done_port;\n" 116 <<
"reg [PORTSIZE_Sout_DataRdy-1:0] Sout_DataRdy;\n" 117 <<
"reg [PORTSIZE_Mout_oe_ram-1:0] Mout_oe_ram;\n" 118 <<
"reg [PORTSIZE_Mout_we_ram-1:0] Mout_we_ram;\n" 119 <<
"reg [PORTSIZE_Mout_addr_ram*BITSIZE_Mout_addr_ram-1:0] Mout_addr_ram;\n" 120 <<
"reg [PORTSIZE_Mout_Wdata_ram*BITSIZE_Mout_Wdata_ram-1:0] Mout_Wdata_ram;\n" 121 <<
"reg [PORTSIZE_Mout_data_ram_size*BITSIZE_Mout_data_ram_size-1:0] Mout_data_ram_size;\n" 122 <<
"reg active_request;\n" 123 <<
"reg active_request_next;\n\n";
127 out <<
"reg [" << retval_size <<
"-1:0] readValue 1INIT_ZERO_VALUE;\n" 128 <<
"reg [" << retval_size <<
"-1:0] next_readValue;\n\n";
133 out <<
"reg [BITSIZE_Mout_addr_ram-1:0] paramAddress [" << (_p.size() - 2
U) <<
"-1:0];\n\n";
136 out <<
"function [PORTSIZE_S_addr_ram-1:0] check_condition;\n" 137 <<
" input [PORTSIZE_S_addr_ram*BITSIZE_S_addr_ram-1:0] m;\n" 140 <<
" for(i1 = 0; i1 < PORTSIZE_S_addr_ram; i1 = i1 + 1)\n" 142 <<
" check_condition[i1] = m[i1*BITSIZE_S_addr_ram +:BITSIZE_S_addr_ram] == unlock_address;\n" 147 out <<
"wire [PORTSIZE_S_addr_ram-1:0] internal;\n";
149 out <<
"parameter [31:0] ";
150 const auto n_iterations = retval_size ? (_p.size() + 3
U) : _p.size();
151 for(
auto idx = 0
U; idx <= n_iterations; ++idx)
153 if(idx != n_iterations)
155 out <<
"S_" << idx <<
" = 32'd" << idx <<
",\n";
159 out <<
"S_" << idx <<
" = 32'd" << idx <<
";\n";
167 <<
" $readmemb(MEMORY_INIT_file, paramAddress, 0, " << (_p.size() - 2
U) <<
"-1);\n" 173 out <<
"assign paramAddressRead = paramAddress[index];\n";
175 out <<
"assign Sout_Rdata_ram = Sin_Rdata_ram;\n" 176 <<
"assign internal = check_condition(S_addr_ram);\n";
179 out <<
"always @ (posedge clock 1RESET_EDGE)\n" 180 <<
" if (1RESET_VALUE)\n" 186 if(retval_size == 1
U)
188 out <<
" readValue <= {1'b0};\n";
192 out <<
" readValue <= {" << retval_size <<
" {1'b0}};\n";
194 out <<
" end else begin\n" 195 <<
" step <= next_step;\n" 196 <<
" readValue <= next_readValue;\n" 201 out <<
" end else begin\n" 202 <<
" step <= next_step;\n" 208 out <<
"always @(*)\n" 211 <<
" if (step == S_0) begin\n" 219 for(idx = 1
U; idx <= (_p.size() - 3
U); ++idx)
221 out <<
" else if (step == S_" << idx <<
") begin\n" 222 <<
" index = " << (idx - 1
U) <<
";\n" 228 out <<
" else if (step == S_" << idx <<
") begin\n" 229 <<
" index = " << (idx - 1
U) <<
";\n" 238 if(_p.size() > 2
U && retval_size)
240 out <<
" else if (step == S_" << idx <<
") begin\n" 241 <<
" index = " << (idx - 4
U) <<
";\n" 250 out <<
"always @ (posedge clock 1RESET_EDGE)\n" 251 <<
" if (1RESET_VALUE)\n" 253 <<
" active_request <= 0;\n" 257 <<
" active_request <= active_request_next;\n" 260 out <<
"always @(*)\n" 262 <<
" Sout_DataRdy = Sin_DataRdy;\n" 263 <<
" done_port = 1'b0;\n" 264 <<
" next_step = S_0;\n" 265 << (retval_size ?
" next_readValue = readValue;\n" :
"") <<
" Mout_we_ram = Min_we_ram;\n" 266 <<
" Mout_Wdata_ram = Min_Wdata_ram;\n" 267 <<
" Mout_oe_ram = Min_oe_ram;\n" 268 <<
" Mout_addr_ram = Min_addr_ram;\n" 269 <<
" Mout_data_ram_size = Min_data_ram_size;\n" 270 <<
" active_request_next = 0;\n";
272 out <<
" if (step == S_0) begin\n" 273 <<
" if (start_port == 1'b1) begin\n" 274 <<
" active_request_next = 1;\n";
277 out <<
" next_step = in2[0] ? S_2 : S_1;\n";
281 out <<
" next_step = S_1;\n";
283 out <<
" end else begin\n" 284 <<
" next_step = S_0;\n" 290 for(idx = 1
U; idx <= (_p.size() - 3
U); ++idx)
292 if(idx != (_p.size() - 3
U))
294 out <<
" else if (step == S_" << idx <<
") begin\n" 295 <<
" Mout_we_ram[0] = active_request;\n" 296 <<
" Mout_addr_ram[BITSIZE_Mout_addr_ram-1:0] = (in1 + paramAddressRead) & " 297 "{BITSIZE_Mout_addr_ram{active_request}};\n" 298 <<
" Mout_Wdata_ram[BITSIZE_Mout_Wdata_ram-1:0] = " << _p[idx + 1].name
299 <<
" & {BITSIZE_Mout_Wdata_ram{active_request}};\n" 300 <<
" Mout_data_ram_size[BITSIZE_Mout_data_ram_size-1:0] = " << _p[idx + 1].type_size
301 <<
" & {BITSIZE_Mout_data_ram_size{active_request}};\n" 302 <<
" if (M_DataRdy[0] == 1'b1) begin\n" 303 <<
" next_step = S_" << (idx + 1
U) <<
";\n" 304 <<
" active_request_next = 1;\n" 305 <<
" end else begin\n" 306 <<
" next_step = S_" << idx <<
";\n" 312 out <<
" else if (step == S_" << idx <<
") begin\n" 313 <<
" Mout_we_ram[0] = active_request;\n" 314 <<
" Mout_addr_ram[BITSIZE_Mout_addr_ram-1:0] = (in1 + paramAddressRead) & " 315 "{BITSIZE_Mout_addr_ram{active_request}};\n" 316 <<
" Mout_Wdata_ram[BITSIZE_Mout_Wdata_ram-1:0] = " << _p[idx + 1].name
317 <<
" & {BITSIZE_Mout_Wdata_ram{active_request}};\n" 318 <<
" Mout_data_ram_size[BITSIZE_Mout_data_ram_size-1:0] = " << _p[idx + 1].type_size
319 <<
" & {BITSIZE_Mout_data_ram_size{active_request}};\n" 320 <<
" if (M_DataRdy[0] == 1'b1) begin\n" 321 <<
" next_step = in2[0] ? S_" << (idx + 2
U) <<
" : S_" << (idx + 1
U) <<
";\n" 322 <<
" active_request_next = 1;\n" 323 <<
" end else begin\n" 324 <<
" next_step = S_" << idx <<
";\n" 332 out <<
" else if (step == S_" << idx <<
") begin\n" 333 <<
" Mout_we_ram[0] = active_request;\n" 334 <<
" Mout_addr_ram[BITSIZE_Mout_addr_ram-1:0] = (in1 + paramAddressRead) & " 335 "{BITSIZE_Mout_addr_ram{active_request}};\n" 336 <<
" Mout_Wdata_ram[BITSIZE_Mout_Wdata_ram-1:0] = " << _p[idx + 1].name
337 <<
" & {BITSIZE_Mout_Wdata_ram{active_request}};\n" 338 <<
" Mout_data_ram_size[BITSIZE_Mout_data_ram_size-1:0] = " << _p[idx + 1].type_size
339 <<
" & {BITSIZE_Mout_data_ram_size{active_request}};\n" 340 <<
" if (M_DataRdy[0] == 1'b1) begin\n" 341 <<
" next_step = S_" << (idx + 1
U) <<
";\n" 342 <<
" active_request_next = 1;\n" 343 <<
" end else begin\n" 344 <<
" next_step = S_" << idx <<
";\n" 350 out <<
" else if (step == S_" << idx <<
") begin\n" 351 <<
" Mout_we_ram[0] = active_request;\n" 352 <<
" Mout_addr_ram[BITSIZE_Mout_addr_ram-1:0] = in1 & {BITSIZE_Mout_addr_ram{active_request}};\n" 353 <<
" Mout_Wdata_ram[BITSIZE_Mout_Wdata_ram-1:0] = unlock_address & " 354 "{BITSIZE_Mout_Wdata_ram{active_request}};\n" 355 <<
" Mout_data_ram_size[BITSIZE_Mout_data_ram_size-1:0] = BITSIZE_Mout_Wdata_ram & " 356 "{BITSIZE_Mout_data_ram_size{active_request}};\n" 357 <<
" if (M_DataRdy[0] == 1'b1) begin\n" 358 <<
" next_step = S_" << (idx + 1
U) <<
";\n" 359 <<
" active_request_next = 1;\n" 360 <<
" end else begin\n" 361 <<
" next_step = S_" << idx <<
";\n" 366 out <<
" else if (step == S_" << idx <<
") begin\n" 367 <<
" if (|(S_we_ram & internal)) begin\n" 368 <<
" Sout_DataRdy = (S_we_ram & internal) | Sin_DataRdy;\n" 369 <<
" next_step = in2[0] ? S_" << (retval_size ? (idx + 1
U) : 0
U) <<
" : S_0;\n" 370 <<
" active_request_next = 1;\n" 371 <<
" done_port = in2[0] ? 1'b0 : 1'b1;\n" 372 <<
" end else begin\n" 373 <<
" next_step = S_" << idx <<
";\n" 378 if(_p.size() > 2
U && retval_size)
380 out <<
" else if (step == S_" << idx <<
") begin\n" 381 <<
" Mout_oe_ram[0] = active_request;\n" 382 <<
" Mout_addr_ram[BITSIZE_Mout_addr_ram-1:0] = (in1 + paramAddressRead) & " 383 "{BITSIZE_Mout_addr_ram{active_request}};\n" 384 <<
" Mout_data_ram_size[BITSIZE_Mout_data_ram_size-1:0] = " << retval_size
385 <<
" & {BITSIZE_Mout_data_ram_size{active_request}};\n" 386 <<
" if (M_DataRdy[0] == 1'b1) begin\n" 387 <<
" next_step = S_" << (idx + 1
U) <<
";\n" 388 <<
" active_request_next = 1;\n" 389 <<
" next_readValue = M_Rdata_ram;\n" 390 <<
" end else begin\n" 391 <<
" next_step = S_" << idx <<
";\n" 396 out <<
" else if (step == S_" << idx <<
") begin\n" 397 <<
" Mout_we_ram[0] = active_request;\n" 398 <<
" Mout_addr_ram[BITSIZE_Mout_addr_ram-1:0] = " << _p[_p.size() - 1
U].name
399 <<
" & {BITSIZE_Mout_addr_ram{active_request}};\n" 400 <<
" Mout_Wdata_ram[BITSIZE_Mout_Wdata_ram-1:0] = readValue & {BITSIZE_Mout_Wdata_ram{active_request}};\n" 401 <<
" Mout_data_ram_size[BITSIZE_Mout_data_ram_size-1:0] = " << retval_size
402 <<
" & {BITSIZE_Mout_data_ram_size{active_request}};\n" 403 <<
" if (M_DataRdy[0] == 1'b1) begin\n" 404 <<
" next_step = S_0;\n" 405 <<
" active_request_next = 1;\n" 406 <<
" done_port = 1'b1;\n" 407 <<
" end else begin\n" 408 <<
" next_step = S_" << idx <<
";\n" Data structure representing the entire HLS information.
Definition of the class representing a generic C application.
mathematical utility function not provided by standard libraries
T ceil_log2(T x)
Return the smallest n such that 2**n >= X.
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object.
This class writes different HDL based descriptions (VHDL, Verilog, SystemC) starting from a structura...
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
#define GET_CONST_NODE(t)
This file collects some utility functions.
This class describes all classes used to represent a structural object.
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
Class specification of the tree_reindex support class.
Data structures used in operations graph.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
static tree_nodeConstRef CGetType(const tree_nodeConstRef &node)
Return the treenode of the type of node.
BuiltinWaitCallNModuleGenerator(const HLS_managerRef &HLSMgr)
static tree_nodeConstRef CGetPointedType(const tree_nodeConstRef &pointer)
Return the pointed type of a pointer object.
static integer_cst_t GetConstValue(const tree_nodeConstRef &tn, bool is_signed=true)
Get value from integer constant.
static tree_nodeConstRef GetFunctionReturnType(const tree_nodeConstRef &function, bool void_as_null=true)
Return the return type of a function.
Class specification of the manager of the tree structures extracted from the raw file.
A brief description of the C++ Header File.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...