64 unsigned int function_id,
vertex op_v,
66 const std::vector<ModuleGenerator::parameter>& _p,
67 const std::vector<ModuleGenerator::parameter>& ,
68 const std::vector<ModuleGenerator::parameter>& ,
69 const std::vector<ModuleGenerator::parameter>& )
71 const auto retval_size = [&]() {
73 const auto FB = HLSMgr->CGetFunctionBehavior(function_id);
74 const auto TM = HLSMgr->get_tree_manager();
75 const auto call_stmt =
77 THROW_ASSERT(call_stmt && call_stmt->get_kind() == gimple_call_K,
"Expected gimple call statement.");
78 const auto gc = GetPointerS<const gimple_call>(call_stmt);
79 THROW_ASSERT(gc->args.size() >= 2,
"Expected at least two arguments for the builtin wait call.");
80 const auto called_addr = gc->args.at(0);
81 const auto called_hasreturn = gc->args.at(1);
99 out <<
"reg [0:0] index;\n\n";
101 else if(_p.size() > 3
U)
103 out <<
"reg [" <<
ceil_log2(_p.size() - 2
U) <<
"-1:0] index;\n\n";
107 out <<
"wire [BITSIZE_Mout_addr_ram-1:0] paramAddressRead;\n\n";
109 out <<
"reg [31:0] step;\n" 110 <<
"reg [31:0] next_step;\n" 111 <<
"reg done_port;\n" 112 <<
"reg Sout_DataRdy;\n" 113 <<
"reg Mout_oe_ram;\n" 114 <<
"reg Mout_we_ram;\n" 115 <<
"reg [BITSIZE_Mout_addr_ram-1:0] Mout_addr_ram;\n" 116 <<
"reg [BITSIZE_Mout_Wdata_ram-1:0] Mout_Wdata_ram;\n" 117 <<
"reg [BITSIZE_Mout_data_ram_size-1:0] Mout_data_ram_size;\n" 118 <<
"reg active_request;\n" 119 <<
"reg active_request_next;\n\n";
122 out <<
"reg [" << retval_size <<
"-1:0] readValue 1INIT_ZERO_VALUE;\n" 123 <<
"reg [" << retval_size <<
"-1:0] next_readValue;\n\n";
128 out <<
"reg [BITSIZE_Mout_addr_ram-1:0] paramAddress [" << (_p.size() - 2
U) <<
"-1:0];\n\n";
131 const auto n_iterations = retval_size ? (_p.size() + 3
U) : _p.size();
133 out <<
"parameter [31:0] ";
134 for(
auto idx = 0
U; idx <= n_iterations; ++idx)
136 if(idx != n_iterations)
138 out <<
"S_" << idx <<
" = 32'd" << idx <<
",\n";
142 out <<
"S_" << idx <<
" = 32'd" << idx <<
";\n";
150 <<
" $readmemb(MEMORY_INIT_file, paramAddress, 0, " << (_p.size() - 2
U) <<
"-1);\n" 156 out <<
"assign paramAddressRead = paramAddress[index];\n";
158 out <<
"assign Sout_Rdata_ram = Sin_Rdata_ram;\n";
160 out <<
"always @ (posedge clock 1RESET_EDGE)\n" 161 <<
" if (1RESET_VALUE)\n" 163 <<
" active_request <= 0;\n" 167 <<
" active_request <= active_request_next;\n" 171 out <<
"always @ (posedge clock 1RESET_EDGE)\n" 172 <<
" if (1RESET_VALUE)\n" 178 if(retval_size == 1
U)
180 out <<
" readValue <= {1'b0};\n";
184 out <<
" readValue <= {" << retval_size <<
" {1'b0}};\n";
186 out <<
" end else begin\n" 187 <<
" step <= next_step;\n" 188 <<
" readValue <= next_readValue;\n" 193 out <<
" end else begin\n" 194 <<
" step <= next_step;\n" 200 out <<
"always @(*)\n" 203 <<
" if (step == S_0) begin\n" 211 for(idx = 1
U; idx <= _p.size() - 3
U; ++idx)
213 out <<
" else if (step == S_" << idx <<
") begin\n" 214 <<
" index = " << idx - 1
U <<
";\n" 221 out <<
" else if (step == S_" << idx <<
") begin\n" 222 <<
" index = " << idx - 1
U <<
";\n" 231 if(_p.size() > 2
U && retval_size)
233 out <<
" else if (step == S_" << idx <<
") begin\n" 234 <<
" index = " << idx - 4
U <<
";\n" 243 out <<
"always @(*)\n" 245 <<
" Sout_DataRdy = Sin_DataRdy;\n" 246 <<
" done_port = 1'b0;\n" 247 <<
" next_step = S_0;\n" 248 << (retval_size ?
" next_readValue = readValue;\n" :
"") <<
" Mout_we_ram = Min_we_ram;\n" 249 <<
" Mout_Wdata_ram = Min_Wdata_ram;\n" 250 <<
" Mout_oe_ram = Min_oe_ram;\n" 251 <<
" Mout_addr_ram = Min_addr_ram;\n" 252 <<
" Mout_data_ram_size = Min_data_ram_size;\n" 253 <<
" active_request_next = 0;\n" 254 <<
" if (step == S_0) begin\n" 255 <<
" if (start_port == 1'b1) begin\n" 256 <<
" active_request_next = 1;\n";
259 out <<
" next_step = in2[0] ? S_2 : S_1;\n";
263 out <<
" next_step = S_1;\n";
265 out <<
" end else begin\n" 266 <<
" next_step = S_0;\n" 273 for(idx = 1
U; idx <= _p.size() - 3
U; ++idx)
275 if(idx != _p.size() - 3
U)
277 out <<
" else if (step == S_" << idx <<
") begin\n" 278 <<
" Mout_we_ram = active_request;\n" 279 <<
" Mout_addr_ram = (in1 + paramAddressRead) & {BITSIZE_Mout_addr_ram{active_request}};\n" 280 <<
" Mout_Wdata_ram = " << _p[idx + 1].name <<
" & {BITSIZE_Mout_Wdata_ram{active_request}};\n" 281 <<
" Mout_data_ram_size = " << _p[idx + 1].type_size
282 <<
" & {BITSIZE_Mout_data_ram_size{active_request}};\n" 283 <<
" if (M_DataRdy == 1'b1) begin\n" 284 <<
" next_step = S_" << idx + 1
U <<
";\n" 285 <<
" active_request_next = 1;\n" 286 <<
" end else begin\n" 287 <<
" next_step = S_" << idx <<
";\n" 293 out <<
" else if (step == S_" << idx <<
") begin\n" 294 <<
" Mout_we_ram = active_request;\n" 295 <<
" Mout_addr_ram = (in1 + paramAddressRead) & {BITSIZE_Mout_addr_ram{active_request}};\n" 296 <<
" Mout_Wdata_ram = " << _p[idx + 1].name <<
" & {BITSIZE_Mout_Wdata_ram{active_request}};\n" 297 <<
" Mout_data_ram_size = " << _p[idx + 1].type_size
298 <<
" & {BITSIZE_Mout_data_ram_size{active_request}};\n" 299 <<
" if (M_DataRdy == 1'b1) begin\n" 300 <<
" next_step = in2[0] ? S_" << idx + 2
U <<
" : S_" << idx + 1
U <<
";\n" 301 <<
" active_request_next = 1;\n" 302 <<
" end else begin\n" 303 <<
" next_step = S_" << idx <<
";\n" 311 out <<
" else if (step == S_" << idx <<
") begin\n" 312 <<
" Mout_we_ram = active_request;\n" 313 <<
" Mout_addr_ram = (in1 + paramAddressRead) & {BITSIZE_Mout_addr_ram{active_request}};\n" 314 <<
" Mout_Wdata_ram = " << _p[idx + 1].name <<
" & {BITSIZE_Mout_Wdata_ram{active_request}};\n" 315 <<
" Mout_data_ram_size = " << _p[idx + 1].type_size
316 <<
" & {BITSIZE_Mout_data_ram_size{active_request}};\n" 317 <<
" if (M_DataRdy == 1'b1) begin\n" 318 <<
" next_step = S_" << idx + 1
U <<
";\n" 319 <<
" active_request_next = 1;\n" 320 <<
" end else begin\n" 321 <<
" next_step = S_" << idx <<
";\n" 327 out <<
" else if (step == S_" << idx <<
") begin\n" 328 <<
" Mout_we_ram = active_request;\n" 329 <<
" Mout_addr_ram = in1 & {BITSIZE_Mout_addr_ram{active_request}};\n" 330 <<
" Mout_Wdata_ram = unlock_address & {BITSIZE_Mout_Wdata_ram{active_request}};\n" 331 <<
" Mout_data_ram_size = BITSIZE_Mout_Wdata_ram & {BITSIZE_Mout_data_ram_size{active_request}};\n" 332 <<
" if (M_DataRdy == 1'b1) begin\n" 333 <<
" next_step = S_" << idx + 1
U <<
";\n" 334 <<
" active_request_next = 1;\n" 335 <<
" end else begin\n" 336 <<
" next_step = S_" << idx <<
";\n" 341 out <<
" else if (step == S_" << idx <<
") begin\n" 342 <<
" if (S_we_ram == 1 && S_addr_ram == unlock_address) begin\n" 343 <<
" Sout_DataRdy = 1'b1;\n" 344 <<
" next_step = in2[0] ? S_" << (retval_size ? idx + 1
U : 0
U) <<
" : S_0;\n" 345 <<
" active_request_next = 1;\n" 346 <<
" done_port = in2[0] ? 1'b0 : 1'b1;\n" 347 <<
" end else begin\n" 348 <<
" next_step = S_" << idx <<
";\n" 353 if(_p.size() > 2
U && retval_size)
355 out <<
" else if (step == S_" << idx <<
") begin\n" 356 <<
" Mout_oe_ram = active_request;\n" 357 <<
" Mout_addr_ram = (in1 + paramAddressRead) & {BITSIZE_Mout_addr_ram{active_request}};\n" 358 <<
" Mout_data_ram_size = " << retval_size <<
" & {BITSIZE_Mout_data_ram_size{active_request}};\n" 359 <<
" if (M_DataRdy == 1'b1) begin\n" 360 <<
" next_step = S_" << idx + 1
U <<
";\n" 361 <<
" active_request_next = 1;\n" 362 <<
" next_readValue = M_Rdata_ram;\n" 363 <<
" end else begin\n" 364 <<
" next_step = S_" << idx <<
";\n" 369 out <<
" else if (step == S_" << idx <<
") begin\n" 370 <<
" Mout_we_ram = active_request;\n" 371 <<
" Mout_addr_ram = " << _p[_p.size() - 1
U].name <<
" & {BITSIZE_Mout_addr_ram{active_request}};\n" 372 <<
" Mout_Wdata_ram = readValue & {BITSIZE_Mout_Wdata_ram{active_request}};\n" 373 <<
" Mout_data_ram_size = " << retval_size <<
" & {BITSIZE_Mout_data_ram_size{active_request}};\n" 374 <<
" if (M_DataRdy == 1'b1) begin\n" 375 <<
" next_step = S_0;\n" 376 <<
" active_request_next = 1;\n" 377 <<
" done_port = 1'b1;\n" 378 <<
" end else begin\n" 379 <<
" 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...
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
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.
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.
static tree_nodeConstRef CGetPointedType(const tree_nodeConstRef &pointer)
Return the pointed type of a pointer object.
BuiltinWaitCallModuleGenerator(const HLS_managerRef &HLSMgr)
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 ...