PandA-2024.02
top_entity.cpp
Go to the documentation of this file.
1 /*
2  *
3  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
4  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
5  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
6  * _/ _/ _/ _/ _/ _/ _/ _/ _/
7  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
8  *
9  * ***********************************************
10  * PandA Project
11  * URL: http://panda.dei.polimi.it
12  * Politecnico di Milano - DEIB
13  * System Architectures Group
14  * ***********************************************
15  * Copyright (C) 2004-2024 Politecnico di Milano
16  *
17  * This file is part of the PandA framework.
18  *
19  * The PandA framework is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
41 #include "top_entity.hpp"
42 #include "BambuParameter.hpp"
43 #include "behavioral_helper.hpp"
44 #include "call_graph_manager.hpp"
45 #include "commandport_obj.hpp"
46 #include "conn_binding.hpp"
47 #include "copyrights_strings.hpp"
48 #include "custom_map.hpp"
49 #include "custom_set.hpp"
50 #include "dbgPrintHelper.hpp"
51 #include "exceptions.hpp"
52 #include "fu_binding.hpp"
53 #include "function_behavior.hpp"
54 #include "functions.hpp"
55 #include "generic_obj.hpp"
56 #include "hls.hpp"
57 #include "hls_device.hpp"
58 #include "hls_manager.hpp"
59 #include "memory.hpp"
60 #include "schedule.hpp"
61 #include "string_manipulation.hpp" // for GET_CLASS
62 #include "structural_manager.hpp"
63 #include "structural_objects.hpp"
64 #include "technology_manager.hpp"
65 #include "technology_node.hpp"
66 #include <list>
67 #include <string>
68 #include <tuple>
69 
70 top_entity::top_entity(const ParameterConstRef _parameters, const HLS_managerRef _HLSMgr, unsigned int _funId,
71  const DesignFlowManagerConstRef _design_flow_manager, const HLSFlowStep_Type _hls_flow_step_type)
72  : HLSFunctionStep(_parameters, _HLSMgr, _funId, _design_flow_manager, _hls_flow_step_type)
73 {
74  debug_level = parameters->get_class_debug_level(GET_CLASS(*this));
75 }
76 
77 top_entity::~top_entity() = default;
78 
81 {
83  switch(relationship_type)
84  {
86  {
87  ret.insert(std::make_tuple(parameters->getOption<HLSFlowStep_Type>(OPT_datapath_architecture),
89  if(HLSMgr->get_HLS(funId))
90  {
91  ret.insert(std::make_tuple(HLSMgr->get_HLS(funId)->controller_type, HLSFlowStepSpecializationConstRef(),
93  }
94  break;
95  }
97  {
98  break;
99  }
101  {
102  break;
103  }
104  default:
105  THROW_UNREACHABLE("");
106  }
107  return ret;
108 }
109 
111 {
113  const auto FB = HLSMgr->CGetFunctionBehavior(funId);
114  const auto BH = FB->CGetBehavioralHelper();
115  const auto function_name = BH->get_function_name();
116  const auto top_functions = HLSMgr->CGetCallGraphManager()->GetRootFunctions();
117  const auto is_top = top_functions.find(BH->get_function_index()) != top_functions.end();
118  const auto module_name = is_top ? "_" + function_name : function_name;
119 
122  THROW_ASSERT(HLS->datapath, "Datapath not created");
123  THROW_ASSERT(HLS->controller, "Controller not created");
124 
125  // reference to hls top circuit
127  SM = HLS->top;
128  const auto& Datapath = HLS->datapath;
129  const auto& Controller = HLS->controller;
130 
132  PRINT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, "Top circuit creation");
133 
135  const structural_type_descriptorRef module_type(new structural_type_descriptor(module_name));
137  SM->set_top_info(module_name, module_type);
138  const auto circuit = SM->get_circ();
139  THROW_ASSERT(circuit, "Top circuit is missing");
140  // Now the top circuit is created, just as an empty box. <circuit> is a reference to the structural object that
141  // will contain all the circuit components
142 
143  circuit->set_black_box(false);
144 
146  GetPointerS<module>(circuit)->set_description("Top component for " + function_name);
147  GetPointerS<module>(circuit)->set_copyright(GENERATED_COPYRIGHT);
148  GetPointerS<module>(circuit)->set_authors("Component automatically generated by bambu");
149  GetPointerS<module>(circuit)->set_license(GENERATED_LICENSE);
150 
151  const auto datapath_circuit = Datapath->get_circ();
152  THROW_ASSERT(datapath_circuit, "Missing datapath circuit");
153  const auto controller_circuit = Controller->get_circ();
154  THROW_ASSERT(controller_circuit, "Missing controller circuit");
155 
156  PRINT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, "Creating datapath object");
158  PRINT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, "Adding datapath");
159  datapath_circuit->set_owner(circuit);
160  GetPointerS<module>(circuit)->add_internal_object(datapath_circuit);
161 
162  PRINT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, "Creating controller object");
164  PRINT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, "Adding controller");
165  controller_circuit->set_owner(circuit);
166  GetPointerS<module>(circuit)->add_internal_object(controller_circuit);
167 
169  const structural_type_descriptorRef bool_type(new structural_type_descriptor("bool", 0));
170 
171  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "\tStart adding clock signal...");
173  const auto clock_obj = SM->add_port(CLOCK_PORT_NAME, port_o::IN, circuit, bool_type);
174  GetPointerS<port_o>(clock_obj)->set_is_clock(true);
176  const auto datapath_clock = datapath_circuit->find_member(CLOCK_PORT_NAME, port_o_K, datapath_circuit);
177  SM->add_connection(datapath_clock, clock_obj);
178  const auto controller_clock = controller_circuit->find_member(CLOCK_PORT_NAME, port_o_K, controller_circuit);
179  SM->add_connection(controller_clock, clock_obj);
180  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "\tClock signal added!");
181 
182  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "\tAdding reset signal...");
184  const auto reset_obj = SM->add_port(RESET_PORT_NAME, port_o::IN, circuit, bool_type);
186  const auto datapath_reset = datapath_circuit->find_member(RESET_PORT_NAME, port_o_K, datapath_circuit);
187  SM->add_connection(datapath_reset, reset_obj);
189  const auto controller_reset = controller_circuit->find_member(RESET_PORT_NAME, port_o_K, controller_circuit);
190  SM->add_connection(controller_reset, reset_obj);
191  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "\tReset signal added!");
192 
193  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "\tAdding start signal...");
195  const auto start_obj = SM->add_port(START_PORT_NAME, port_o::IN, circuit, bool_type);
196  const auto controller_start = controller_circuit->find_member(START_PORT_NAME, port_o_K, controller_circuit);
198  const auto datapath_start = datapath_circuit->find_member(START_PORT_NAME, port_o_K, datapath_circuit);
199  structural_objectRef sync_datapath_controller;
200  if(datapath_start)
201  {
202  SM->add_connection(start_obj, datapath_start);
203  sync_datapath_controller = SM->add_sign("done2start", circuit, bool_type);
204  structural_objectRef datapath_done = datapath_circuit->find_member(DONE_PORT_NAME, port_o_K, datapath_circuit);
205  SM->add_connection(datapath_done, sync_datapath_controller);
206  }
207  else
208  {
209  SM->add_connection(start_obj, controller_start);
210  }
211  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "\tStart signal added!");
212 
213  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "\tStart adding Done signal...");
215  const auto done_obj = SM->add_port(DONE_PORT_NAME, port_o::OUT, circuit, bool_type);
216  THROW_ASSERT(done_obj, "Done port not added in the top component");
217  const auto controller_done = controller_circuit->find_member(DONE_PORT_NAME, port_o_K, controller_circuit);
218  THROW_ASSERT(controller_done, "Done signal not found in the controller");
219  if(datapath_start)
220  {
221  SM->add_connection(sync_datapath_controller, controller_start);
222  }
223  structural_objectRef done_signal_out;
224  if(HLS->registered_done_port && (parameters->getOption<HLSFlowStep_Type>(OPT_controller_architecture) ==
226  parameters->getOption<HLSFlowStep_Type>(OPT_controller_architecture) ==
228  parameters->getOption<HLSFlowStep_Type>(OPT_controller_architecture) ==
230  {
231  const auto TM = HLS->HLS_D->get_technology_manager();
232  const auto reset_type = parameters->getOption<std::string>(OPT_reset_type);
233  const auto delay_unit = reset_type == "sync" ? flipflop_SR : flipflop_AR;
234  const auto delay_gate =
235  SM->add_module_from_technology_library("done_delayed_REG", delay_unit, LIBRARY_STD, circuit, TM);
236  const auto port_ck = delay_gate->find_member(CLOCK_PORT_NAME, port_o_K, delay_gate);
237  if(port_ck)
238  {
239  SM->add_connection(clock_obj, port_ck);
240  }
241  const auto port_rst = delay_gate->find_member(RESET_PORT_NAME, port_o_K, delay_gate);
242  if(port_rst)
243  {
244  SM->add_connection(reset_obj, port_rst);
245  }
246 
247  const auto done_signal_in = SM->add_sign("done_delayed_REG_signal_in", circuit,
248  GetPointerS<module>(delay_gate)->get_in_port(2)->get_typeRef());
249  SM->add_connection(GetPointerS<module>(delay_gate)->get_in_port(2), done_signal_in);
250  SM->add_connection(controller_done, done_signal_in);
251  done_signal_out = SM->add_sign("done_delayed_REG_signal_out", circuit,
252  GetPointerS<module>(delay_gate)->get_out_port(0)->get_typeRef());
253  SM->add_connection(GetPointerS<module>(delay_gate)->get_out_port(0), done_signal_out);
254  SM->add_connection(done_obj, done_signal_out);
255  }
256  else
257  {
259  {
260  done_signal_out = SM->add_sign("done_signal_out", circuit, bool_type);
261  SM->add_connection(controller_done, done_signal_out);
262  SM->add_connection(done_signal_out, done_obj);
263  }
264  else
265  {
266  SM->add_connection(controller_done, done_obj);
267  }
268  }
269  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "\tDone signal added!");
270 
273  {
274  const auto controller_flow_start = datapath_circuit->find_member(START_PORT_NAME_CFC, port_o_K, datapath_circuit);
275  THROW_ASSERT(controller_flow_start, "controller flow start signal not found in the datapath");
276  if(datapath_start)
277  {
278  SM->add_connection(sync_datapath_controller, controller_flow_start);
279  }
280  else
281  {
282  SM->add_connection(start_obj, controller_flow_start);
283  }
284  THROW_ASSERT(done_signal_out, "expected done signal");
285  const auto controller_flow_done = datapath_circuit->find_member(DONE_PORT_NAME_CFC, port_o_K, datapath_circuit);
286  THROW_ASSERT(controller_flow_done, "controller flow done signal not found in the datapath");
287  SM->add_connection(done_signal_out, controller_flow_done);
288  const auto controller_flow_present_state =
289  datapath_circuit->find_member(PRESENT_STATE_PORT_NAME, port_o_K, datapath_circuit);
290  THROW_ASSERT(controller_flow_present_state, "controller flow present state signal not found in the datapath");
291  const auto controller_present_state = Controller->add_port(
292  PRESENT_STATE_PORT_NAME, port_o::OUT, controller_circuit, controller_flow_present_state->get_typeRef());
293  const auto p_signal =
294  SM->add_sign(PRESENT_STATE_PORT_NAME "_sig1", circuit, controller_flow_present_state->get_typeRef());
295  SM->add_connection(controller_present_state, p_signal);
296  SM->add_connection(p_signal, controller_flow_present_state);
297  const auto controller_flow_next_state =
298  datapath_circuit->find_member(NEXT_STATE_PORT_NAME, port_o_K, datapath_circuit);
299  THROW_ASSERT(controller_flow_next_state, "controller flow next state signal not found in the datapath");
300  const auto controller_next_state = Controller->add_port(NEXT_STATE_PORT_NAME, port_o::OUT, controller_circuit,
301  controller_flow_next_state->get_typeRef());
302  const auto n_signal =
303  SM->add_sign(NEXT_STATE_PORT_NAME "_sig1", circuit, controller_flow_next_state->get_typeRef());
304  SM->add_connection(controller_next_state, n_signal);
305  SM->add_connection(n_signal, controller_flow_next_state);
306  }
307 
309 
310  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "\tAdding input/output ports...");
311  add_ports(circuit, clock_obj, reset_obj);
312  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "\tInput/output ports added!");
313 
314  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "\tAdding command ports...");
315  add_command_signals(circuit);
316  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "\tCommand ports added!");
317 
318  if(!is_top || (parameters->isOption(OPT_expose_globals) && parameters->getOption<bool>(OPT_expose_globals)))
319  {
321  }
322 
323  PRINT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, "Circuit created without errors!");
325 }
326 
327 void top_entity::add_input_register(structural_objectRef port_in, const std::string& port_prefix,
328  structural_objectRef circuit, structural_objectRef clock_port,
329  structural_objectRef reset_port, structural_objectRef e_port)
330 {
331  const auto TM = HLS->HLS_D->get_technology_manager();
332  const auto register_library = TM->get_library(register_STD);
333  structural_objectRef r_signal;
334  const auto reg_mod =
335  SM->add_module_from_technology_library(port_prefix + "_REG", register_STD, register_library, circuit, TM);
336  GetPointerS<module>(reg_mod)->get_in_port(2)->type_resize(GET_TYPE_SIZE(port_in));
337  GetPointerS<module>(reg_mod)->get_out_port(0)->type_resize(GET_TYPE_SIZE(port_in));
338 
339  const auto port_ck = reg_mod->find_member(CLOCK_PORT_NAME, port_o_K, reg_mod);
340  SM->add_connection(clock_port, port_ck);
341 
342  const auto port_rs = reg_mod->find_member(RESET_PORT_NAME, port_o_K, reg_mod);
343  SM->add_connection(reset_port, port_rs);
344 
345  r_signal = SM->add_sign(port_prefix + "_SIGI1", circuit, port_in->get_typeRef());
346  SM->add_connection(e_port, r_signal);
347  SM->add_connection(GetPointerS<module>(reg_mod)->get_in_port(2), r_signal);
348 
349  r_signal =
350  SM->add_sign(port_prefix + "_SIGI2", circuit, GetPointerS<module>(reg_mod)->get_out_port(0)->get_typeRef());
351  SM->add_connection(GetPointerS<module>(reg_mod)->get_out_port(0), r_signal);
352  SM->add_connection(port_in, r_signal);
353 }
354 
356  structural_objectRef reset_port)
357 {
359  const auto FB = HLSMgr->CGetFunctionBehavior(funId);
360  const auto BH = FB->CGetBehavioralHelper();
361  bool has_registered_inputs = HLS->registered_inputs;
362 
363  const auto Datapath = HLS->datapath->get_circ();
364  const auto function_parameters = BH->get_parameters();
365  const auto conn = HLS->Rconn;
366  const auto curr_address_bitsize = HLSMgr->get_address_bitsize();
367  for(const auto& function_parameter : function_parameters)
368  {
369  const auto prefix = "in_port_";
370  const auto in_obj = Datapath->find_member(prefix + BH->PrintVariable(function_parameter), port_o_K,
371  Datapath); // port get by name in order to do not use conn_binding
372  THROW_ASSERT(in_obj, "in_obj is not a port");
374  if(HLSMgr->Rmem->has_base_address(function_parameter) &&
375  !HLSMgr->Rmem->has_parameter_base_address(function_parameter, HLS->functionId) &&
376  !HLSMgr->Rmem->is_parm_decl_stored(function_parameter))
377  {
378  port_type = structural_type_descriptorRef(new structural_type_descriptor("bool", curr_address_bitsize));
379  }
380  else
381  {
382  port_type = structural_type_descriptorRef(new structural_type_descriptor(function_parameter, BH));
383  }
384  structural_objectRef top_obj;
385  if(in_obj->get_kind() == port_vector_o_K)
386  {
387  THROW_ERROR("Should never be reached, in_obj is not a port vector");
388  top_obj = SM->add_port_vector(FB->CGetBehavioralHelper()->PrintVariable(function_parameter), port_o::IN,
389  GetPointerS<port_o>(in_obj)->get_ports_size(), circuit, port_type);
390  }
391  else
392  {
393  top_obj = SM->add_port(FB->CGetBehavioralHelper()->PrintVariable(function_parameter), port_o::IN, circuit,
394  port_type);
395  }
396  const auto is_pipelined = HLSMgr->CGetFunctionBehavior(funId)->is_simple_pipeline();
397  if(has_registered_inputs && !is_pipelined)
398  {
399  const auto port_prefix = GetPointerS<port_o>(in_obj)->get_id();
400  if(in_obj->get_kind() == port_vector_o_K)
401  {
402  for(auto p = 0U; p < GetPointerS<port_o>(in_obj)->get_ports_size(); ++p)
403  {
404  add_input_register(GetPointerS<port_o>(in_obj)->get_port(p),
405  port_prefix + GetPointerS<port_o>(in_obj)->get_port(p)->get_id(), circuit, clock_port,
406  reset_port, GetPointerS<port_o>(top_obj)->get_port(p));
407  }
408  }
409  else
410  {
411  add_input_register(in_obj, port_prefix, circuit, clock_port, reset_port, top_obj);
412  }
413  }
414  else
415  {
416  SM->add_connection(in_obj, top_obj);
417  }
418  }
419  const auto return_type_index = BH->GetFunctionReturnType(BH->get_function_index());
420  if(return_type_index)
421  {
422  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Return type index is " + STR(return_type_index));
424  structural_objectRef ret_obj;
425  if(conn)
426  {
427  const auto return_port = conn->get_port(return_type_index, conn_binding::OUT);
428  ret_obj = return_port->get_structural_obj();
429  port_type = ret_obj->get_typeRef();
430  }
431  else
432  {
433  ret_obj = Datapath->find_member(RETURN_PORT_NAME, port_o_K,
434  Datapath); // port get by name in order to do not use conn_binding
435  THROW_ASSERT(ret_obj, "in_obj is not a port");
436  if(HLSMgr->Rmem->has_base_address(return_type_index) &&
437  !HLSMgr->Rmem->has_parameter_base_address(return_type_index, HLS->functionId) &&
438  !HLSMgr->Rmem->is_parm_decl_stored(return_type_index))
439  {
440  port_type = structural_type_descriptorRef(new structural_type_descriptor("bool", curr_address_bitsize));
441  }
442  else
443  {
444  port_type = structural_type_descriptorRef(new structural_type_descriptor(return_type_index, BH));
445  }
446  }
447  structural_objectRef top_obj;
448  if(ret_obj->get_kind() == port_vector_o_K)
449  {
450  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Adding vector return port");
451  top_obj = SM->add_port_vector(RETURN_PORT_NAME, port_o::OUT, GetPointer<port_o>(ret_obj)->get_ports_size(),
452  circuit, port_type);
453  }
454  else
455  {
456  THROW_ASSERT(ret_obj->get_kind() == port_o_K, ret_obj->get_kind_text());
457  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Adding return port");
458  top_obj = SM->add_port(RETURN_PORT_NAME, port_o::OUT, circuit, port_type);
459  }
460  SM->add_connection(ret_obj, top_obj);
461  }
462 
463  const auto top_functions = HLSMgr->CGetCallGraphManager()->GetRootFunctions();
464  const auto is_top = top_functions.count(BH->get_function_index());
465  bool master_port = true; // Datapath->find_member("M_DataRdy", port_o_K, Datapath);
469  std::map<unsigned long long, structural_objectRef> null_values;
471  for(unsigned int j = 0; j < GetPointerS<module>(Datapath)->get_in_port_size(); j++)
472  {
473  structural_objectRef port_in = GetPointerS<module>(Datapath)->get_in_port(j);
474  if(GetPointerS<port_o>(port_in)->get_is_extern())
475  {
476  if(!GetPointer<port_o>(port_in)->get_is_memory() || !is_top || master_port)
477  {
478  structural_objectRef ext_port;
479  if(port_in->get_kind() == port_vector_o_K)
480  {
481  ext_port =
482  SM->add_port_vector(GetPointerS<port_o>(port_in)->get_id(), port_o::IN,
483  GetPointerS<port_o>(port_in)->get_ports_size(), circuit, port_in->get_typeRef());
484  }
485  else
486  {
487  ext_port =
488  SM->add_port(GetPointerS<port_o>(port_in)->get_id(), port_o::IN, circuit, port_in->get_typeRef());
489  }
490  port_o::fix_port_properties(port_in, ext_port);
491  // adding connection between datapath extern port and top extern port
492  SM->add_connection(port_in, ext_port);
493  }
494  else
495  {
496  if(null_values.find(GET_TYPE_SIZE(port_in)) == null_values.end())
497  {
498  const auto const_obj = SM->add_constant("null_value_" + STR(GET_TYPE_SIZE(port_in)), circuit,
499  port_in->get_typeRef(), STR(0));
500  null_values[GET_TYPE_SIZE(port_in)] = const_obj;
501  }
502  SM->add_connection(port_in, null_values[GET_TYPE_SIZE(port_in)]);
503  }
504  }
505  else if(GetPointerS<port_o>(port_in)->get_is_memory())
506  {
507  if(!is_top || master_port)
508  {
509  structural_objectRef ext_port;
510  if(port_in->get_kind() == port_vector_o_K)
511  {
512  ext_port =
513  SM->add_port_vector(GetPointerS<port_o>(port_in)->get_id(), port_o::IN,
514  GetPointerS<port_o>(port_in)->get_ports_size(), circuit, port_in->get_typeRef());
515  }
516  else
517  {
518  ext_port =
519  SM->add_port(GetPointerS<port_o>(port_in)->get_id(), port_o::IN, circuit, port_in->get_typeRef());
520  }
521  port_o::fix_port_properties(port_in, ext_port);
522  // adding connection between datapath extern port and top extern port
523  SM->add_connection(port_in, ext_port);
524  }
525  else
526  {
527  if(null_values.find(GET_TYPE_SIZE(port_in)) == null_values.end())
528  {
529  structural_objectRef const_obj = SM->add_constant("null_value_" + STR(GET_TYPE_SIZE(port_in)), circuit,
530  port_in->get_typeRef(), STR(0));
531  null_values[GET_TYPE_SIZE(port_in)] = const_obj;
532  }
533  SM->add_connection(port_in, null_values[GET_TYPE_SIZE(port_in)]);
534  }
535  }
536  else if(GetPointerS<port_o>(port_in)->get_port_interface() != port_o::port_interface::PI_DEFAULT)
537  {
538  structural_objectRef ext_port;
539  if(port_in->get_kind() == port_vector_o_K)
540  {
541  ext_port =
542  SM->add_port_vector(GetPointerS<port_o>(port_in)->get_id(), port_o::IN,
543  GetPointerS<port_o>(port_in)->get_ports_size(), circuit, port_in->get_typeRef());
544  }
545  else
546  {
547  ext_port =
548  SM->add_port(GetPointerS<port_o>(port_in)->get_id(), port_o::IN, circuit, port_in->get_typeRef());
549  }
550  port_o::fix_port_properties(port_in, ext_port);
551  // adding connection between datapath interface port and top interface port
552  SM->add_connection(port_in, ext_port);
553  }
554  }
556  for(unsigned int j = 0; j < GetPointer<module>(Datapath)->get_out_port_size(); j++)
557  {
558  structural_objectRef port_out = GetPointer<module>(Datapath)->get_out_port(j);
559  if(GetPointer<port_o>(port_out)->get_is_memory() && is_top && !master_port)
560  {
561  continue;
562  }
563  if(GetPointer<port_o>(port_out)->get_is_extern())
564  {
565  structural_objectRef ext_port;
566  if(port_out->get_kind() == port_vector_o_K)
567  {
568  ext_port =
569  SM->add_port_vector(GetPointer<port_o>(port_out)->get_id(), port_o::OUT,
570  GetPointer<port_o>(port_out)->get_ports_size(), circuit, port_out->get_typeRef());
571  }
572  else
573  {
574  ext_port =
575  SM->add_port(GetPointer<port_o>(port_out)->get_id(), port_o::OUT, circuit, port_out->get_typeRef());
576  }
577  port_o::fix_port_properties(port_out, ext_port);
578  // adding connection between datapath extern port and top extern port
579  SM->add_connection(port_out, ext_port);
580  }
581  else if(GetPointer<port_o>(port_out)->get_is_memory())
582  {
583  structural_objectRef ext_port;
584  if(port_out->get_kind() == port_vector_o_K)
585  {
586  ext_port =
587  SM->add_port_vector(GetPointer<port_o>(port_out)->get_id(), port_o::OUT,
588  GetPointer<port_o>(port_out)->get_ports_size(), circuit, port_out->get_typeRef());
589  }
590  else
591  {
592  ext_port =
593  SM->add_port(GetPointer<port_o>(port_out)->get_id(), port_o::OUT, circuit, port_out->get_typeRef());
594  }
595  port_o::fix_port_properties(port_out, ext_port);
596  // adding connection between datapath extern port and top extern port
597  SM->add_connection(port_out, ext_port);
598  }
599  else if(GetPointer<port_o>(port_out)->get_port_interface() != port_o::port_interface::PI_DEFAULT)
600  {
601  structural_objectRef ext_port;
602  if(port_out->get_kind() == port_vector_o_K)
603  {
604  ext_port =
605  SM->add_port_vector(GetPointer<port_o>(port_out)->get_id(), port_o::OUT,
606  GetPointer<port_o>(port_out)->get_ports_size(), circuit, port_out->get_typeRef());
607  }
608  else
609  {
610  ext_port =
611  SM->add_port(GetPointer<port_o>(port_out)->get_id(), port_o::OUT, circuit, port_out->get_typeRef());
612  }
613  port_o::fix_port_properties(port_out, ext_port);
614  // adding connection between datapath interface port and top interface port
615  SM->add_connection(port_out, ext_port);
616  }
617  }
618 
620  for(unsigned int j = 0; j < GetPointer<module>(Datapath)->get_in_out_port_size(); j++)
621  {
622  structural_objectRef port_in_out = GetPointer<module>(Datapath)->get_in_out_port(j);
623  if(GetPointer<port_o>(port_in_out)->get_is_extern())
624  {
625  structural_objectRef ext_port;
626  if(port_in_out->get_kind() == port_vector_o_K)
627  {
628  ext_port = SM->add_port_vector(GetPointer<port_o>(port_in_out)->get_id(), port_o::IO,
629  GetPointer<port_o>(port_in_out)->get_ports_size(), circuit,
630  port_in_out->get_typeRef());
631  }
632  else
633  {
634  ext_port = SM->add_port(GetPointer<port_o>(port_in_out)->get_id(), port_o::IO, circuit,
635  port_in_out->get_typeRef());
636  }
637  port_o::fix_port_properties(port_in_out, ext_port);
638  // adding connection between datapath extern port and top extern port
639  SM->add_connection(port_in_out, ext_port);
640  }
641  }
646 }
647 
649 {
650  const auto Datapath = HLS->datapath->get_circ();
651  const auto Controller = HLS->controller->get_circ();
652 
653  for(const auto& selector : HLS->Rconn->GetSelectors())
654  {
655  for(const auto& l : selector.second)
656  {
657  structural_objectRef datapath_obj = l.second->get_structural_obj();
658  THROW_ASSERT(datapath_obj, "missing structural object associated with the selector " + l.second->get_string());
659  std::string datapath_name = datapath_obj->get_id();
660  structural_objectRef controller_obj = GetPointer<commandport_obj>(l.second)->get_controller_obj();
662  if(!controller_obj)
663  {
664  continue;
665  }
666  std::string controller_name = controller_obj->get_id();
667  structural_objectRef src = Controller->find_member(controller_name, port_o_K, Controller);
668  THROW_ASSERT(src, "Missing select port in the controller");
669  structural_objectRef tgt = Datapath->find_member(datapath_name, port_o_K, Datapath);
670  THROW_ASSERT(tgt, "Missing select port in the datapath");
671  structural_objectRef sign = SM->add_sign(datapath_name, circuit, src->get_typeRef());
672  SM->add_connection(src, sign);
673  SM->add_connection(sign, tgt);
674  }
675  }
676 }
static void propagate_memory_parameters(const structural_objectRef src, const structural_managerRef tgt)
Propagates the memory parameters from the source (innermost) module to the target (outermost) one...
Definition: memory.cpp:654
void add_connection(structural_objectRef src, structural_objectRef dest)
Create a connection between a source structural object and a destination structural object...
structural_managerRef SM
reference to the resulting circuit
Definition: top_entity.hpp:54
#define PRESENT_STATE_PORT_NAME
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
const HLS_managerRef HLSMgr
information about all the HLS synthesis
Definition: hls_step.hpp:205
Data structure representing the entire HLS information.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
DesignFlowStep_Status InternalExec() override
Execute the step.
Definition: top_entity.cpp:110
refcount< structural_type_descriptor > structural_type_descriptorRef
RefCount type definition of the structural_type_descriptor class structure.
File containing functions and utilities to support the printing of debug messagges.
#define PRINT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
#define NEXT_STATE_PORT_NAME
structural_managerRef datapath
Store the datapath description.
Definition: hls.hpp:155
#define START_PORT_NAME
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.
Base class for all command ports into datapath.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
#define GENERATED_LICENSE
const structural_objectRef get_circ() const
Get a reference to circ field.
RelationshipType
The relationship type.
const std::map< unsigned int, Selectors > & GetSelectors() const
Source must be executed to satisfy target.
const unsigned int funId
identifier of the function to be processed (0 means that it is a global step)
Base class for the top entity creation.
This class manages the circuit structures.
const HLS_deviceRef HLS_D
reference to the information representing the target for the synthesis
Definition: hls.hpp:107
exceptions managed by PandA
void add_ports(structural_objectRef circuit, structural_objectRef clock_port, structural_objectRef reset_port)
Adds the input/output ports to the circuit.
Definition: top_entity.cpp:355
virtual structural_objectRef find_member(const std::string &id, so_kind type, const structural_objectRef owner) const =0
Return the object named id of a given type which belongs to or it is associated with the object...
top_entity(const ParameterConstRef _parameters, const HLS_managerRef HLSMgr, unsigned int funId, const DesignFlowManagerConstRef design_flow_manager, const HLSFlowStep_Type=HLSFlowStep_Type::TOP_ENTITY_CREATION)
Constructor.
Definition: top_entity.cpp:70
Class specification of the manager of the technology library data structures.
#define RETURN_PORT_NAME
redefinition of map to manage ordered/unordered structures
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
Base class for all resources into datapath.
#define CLOCK_PORT_NAME
standard name for ports
structural_managerRef top
Store the top description.
Definition: hls.hpp:164
bool registered_inputs
true when the module has registered inputs
Definition: hls.hpp:147
virtual std::string get_kind_text() const =0
Virtual function used to get the string name of a structural_object instance.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
void set_top_info(const std::string &id, const technology_managerRef &LM, const std::string &Library="")
Data structure used to store the interconnection binding of datapath elements.
Data structure used to store the schedule of the operations.
#define DONE_PORT_NAME
~top_entity() override
Destructor.
HLSFlowStep_Type
Definition: hls_step.hpp:95
Class specification of the data structures used to manage technology information. ...
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.
#define flipflop_AR
flipflop with asynchronous reset
redefinition of set to manage ordered/unordered structures
#define LIBRARY_STD
standard library where all built-in ports are defined.
Datastructure to describe functions allocation in high-level synthesis.
virtual void add_input_register(structural_objectRef port_in, const std::string &port_prefix, structural_objectRef circuit, structural_objectRef clock_port, structural_objectRef reset_port, structural_objectRef e_port)
Add the register to store input parameters.
Definition: top_entity.cpp:327
static void fix_port_properties(structural_objectRef port_i, structural_objectRef cir_port)
copy the port properties from port_i to cir_port
virtual enum so_kind get_kind() const =0
Virtual function used to find the real type of a structural_object instance.
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
refcount< structural_manager > structural_managerRef
RefCount type definition of the structural_manager class structure.
void type_resize(unsigned long long new_bit_size)
Just resize the size of the bits of the object.
structural_objectRef add_constant(std::string id, structural_objectRef owner, structural_type_descriptorRef type, std::string value, unsigned int treenode=0)
Create a new constant;.
structural_objectRef add_module_from_technology_library(const std::string &id, const std::string &fu_name, const std::string &library_name, const structural_objectRef owner, const technology_managerConstRef TM)
Create a new object starting from a library component.
structural_managerRef controller
Store the controller description.
Definition: hls.hpp:158
#define GET_TYPE_SIZE(structural_obj)
Macro returning the size of the type of a structural object.
bool registered_done_port
true when the done port is registered
Definition: hls.hpp:149
This class describes all classes used to represent a structural object.
const structural_type_descriptorRef & get_typeRef() const
Return the type descriptor of the structural_object.
structural_managerRef control_flow_checker
Store the description of the control flow checker.
Definition: hls.hpp:161
#define register_STD
simple register without reset
static structural_objectRef add_sign(std::string id, structural_objectRef owner, structural_type_descriptorRef sign_type, unsigned int treenode=0)
Create a new signal.
Data structure used to store the functional-unit binding of the vertexes.
hlsRef HLS
HLS data structure of the function to be analyzed.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
#define DONE_PORT_NAME_CFC
It collects all the common strings covering PandA copyrights issues.
unsigned int functionId
this is the identifier of the function to be implemented
Definition: hls.hpp:87
#define RESET_PORT_NAME
Wrapper to call graph.
Class implementation of the structural_manager.
uint32_t sign
void add_command_signals(structural_objectRef circuit)
Adds the command signals to the circuit.
Definition: top_entity.cpp:648
int debug_level
The debug level.
refcount< const HLSFlowStepSpecialization > HLSFlowStepSpecializationConstRef
const refcount definition of the class
Definition: hls_step.hpp:93
#define flipflop_SR
flipflop with synchronous reset
#define DEBUG_LEVEL_VERBOSE
verbose debugging print is performed.
Data structure definition for high-level synthesis flow.
Superclass include.
static structural_objectRef add_port_vector(std::string id, port_o::port_direction pdir, unsigned int n_ports, structural_objectRef owner, structural_type_descriptorRef type_descr, unsigned int treenode=0)
Create a new port_vector.
conn_bindingRef Rconn
Store the refcounted interconnection of datapath elements.
Definition: hls.hpp:139
const CustomUnorderedSet< std::tuple< HLSFlowStep_Type, HLSFlowStepSpecializationConstRef, HLSFlowStep_Relationship > > ComputeHLSRelationships(const DesignFlowStep::RelationshipType relationship_type) const override
Return the set of analyses in relationship with this design step.
Definition: top_entity.cpp:80
#define GENERATED_COPYRIGHT
Datastructure to represent memory information in high-level synthesis.
HLS specialization of generic_device.
A brief description of the C++ Header File.
#define START_PORT_NAME_CFC
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...
Definition: exceptions.hpp:289

Generated on Mon Feb 12 2024 13:02:53 for PandA-2024.02 by doxygen 1.8.13