PandA-2024.02
conn_binding_cs.cpp
Go to the documentation of this file.
1 /*
2  *
3  *
4  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
5  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
6  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
7  * _/ _/ _/ _/ _/ _/ _/ _/ _/
8  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
9  *
10  * ***********************************************
11  * PandA Project
12  * URL: http://panda.dei.polimi.it
13  * Politecnico di Milano - DEIB
14  * System Architectures Group
15  * ***********************************************
16  * Copyright (c) 2016-2024 Politecnico di Milano
17  *
18  * This file is part of the PandA framework.
19  *
20  * The PandA framework is free software; you can redistribute it and/or modify
21  * it under the terms of the GNU General Public License as published by
22  * the Free Software Foundation; either version 3 of the License, or
23  * (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28  * GNU General Public License for more details.
29  *
30  * You should have received a copy of the GNU General Public License
31  * along with this program. If not, see <http://www.gnu.org/licenses/>.
32  *
33  */
41 #include "conn_binding_cs.hpp"
42 
43 #include "Parameter.hpp"
44 #include "dbgPrintHelper.hpp"
45 #include "hls.hpp"
46 #include "hls_device.hpp"
47 #include "hls_manager.hpp"
48 #include "omp_functions.hpp"
49 #include "structural_manager.hpp"
50 #include "structural_objects.hpp"
51 #include "technology_manager.hpp"
52 #include "technology_node.hpp"
53 #include "utility.hpp"
54 
55 #include <string>
56 
58  : conn_binding(_BH, _parameters)
59 {
60  debug_level = _parameters->get_class_debug_level(GET_CLASS(*this));
61 }
62 
64 
66 {
67  conn_binding::add_to_SM(HLSMgr, HLS, SM);
69 }
70 
72 {
74  const structural_managerRef SM = HLS->datapath;
75  const structural_objectRef circuit = SM->get_circ();
76 
77  bool addedLoad = false;
78  bool addedStore = false;
79  bool andStartMemOp_required = false;
80 
81  for(unsigned int j = 0; j < GetPointer<module>(circuit)->get_in_port_size(); j++)
82  {
83  structural_objectRef port_i = GetPointer<module>(circuit)->get_in_port(j);
84  std::string port_name = GetPointer<port_o>(port_i)->get_id();
85  std::size_t found = port_name.find("LOAD");
86  if(found != std::string::npos)
87  {
88  addedLoad = true;
89  }
90  found = port_name.find("STORE");
91  if(found != std::string::npos)
92  {
93  addedStore = true;
94  }
95  }
96  for(unsigned int j = 0; j < GetPointer<module>(circuit)->get_internal_objects_size(); j++)
97  {
98  structural_objectRef curr_gate = GetPointer<module>(circuit)->get_internal_object(j);
99  if(GET_TYPE_NAME(curr_gate) == "mem_ctrl_kernel")
100  {
101  structural_objectRef portStart = curr_gate->find_member(STR(START_PORT_NAME), port_o_K, curr_gate);
102  structural_objectRef startMemOp = GetPointer<port_o>(portStart)->find_bounded_object();
103  THROW_ASSERT(startMemOp != nullptr, "No start port for mem_ctrl_found");
104  andStartMemOp_required = true;
105  break;
106  }
107  }
108  // search in module and find one with suspension
109  unsigned int num_suspension = 0;
110  unsigned int n_elements = GetPointer<module>(circuit)->get_internal_objects_size();
111  unsigned int i = 0;
112  for(i = 0; i < n_elements; i++)
113  {
114  structural_objectRef curr_gate = GetPointer<module>(circuit)->get_internal_object(i);
115  if(curr_gate->find_member(STR(SUSPENSION), port_o_K, curr_gate) != nullptr and
116  curr_gate->get_id() != "scheduler_kernel")
117  {
118  ++num_suspension;
119  }
120  }
121 
122  if(num_suspension == 0 && !addedLoad && !addedStore && !andStartMemOp_required)
123  {
124  structural_objectRef suspension_datapath = circuit->find_member(STR(SUSPENSION), port_o_K, circuit);
125  structural_objectRef constantFalse(new constant_o(debug_level, SM->get_circ(), "0"));
126  constantFalse->set_type(bool_type);
127  GetPointer<module>(circuit)->add_internal_object(constantFalse);
128  SM->add_connection(constantFalse, suspension_datapath);
129  return;
130  }
132  "suspensionOr", OR_GATE_STD, HLS->HLS_D->get_technology_manager()->get_library(OR_GATE_STD), circuit,
133  HLS->HLS_D->get_technology_manager());
134  structural_objectRef port_in_or = suspensionOr->find_member("in", port_vector_o_K, suspensionOr);
135  structural_objectRef port_out_or = suspensionOr->find_member("out1", port_o_K, suspensionOr);
136  structural_objectRef out_or_sign = SM->add_sign("out_or_signal", circuit, bool_type);
137  SM->add_connection(port_out_or, out_or_sign);
138 
139  if(GetPointer<port_o>(port_in_or)->get_ports_size() != 0)
140  {
141  THROW_ERROR("Or start with more than 0 input port");
142  }
143  else
144  {
145  GetPointer<port_o>(port_in_or)->add_n_ports(2, port_in_or);
146  }
147  for(unsigned int j = 0; j < GetPointer<module>(circuit)->get_in_port_size(); j++)
148  {
149  structural_objectRef port_i = GetPointer<module>(circuit)->get_in_port(j);
150  std::string port_name = GetPointer<port_o>(port_i)->get_id();
151  std::size_t found = port_name.find("LOAD");
152  if(found != std::string::npos)
153  {
154  SM->add_connection(port_i, GetPointer<port_o>(port_in_or)->get_port(0));
155  }
156  found = port_name.find("STORE");
157  if(found != std::string::npos)
158  {
159  SM->add_connection(port_i, GetPointer<port_o>(port_in_or)->get_port(1));
160  }
161  }
162 
163  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Added or_suspension local");
164 
165  structural_objectRef out_and_sign = SM->add_sign("out_and_signal", circuit, bool_type);
167  "andStartMemOp", AND_GATE_STD, HLS->HLS_D->get_technology_manager()->get_library(OR_GATE_STD), circuit,
168  HLS->HLS_D->get_technology_manager());
169  structural_objectRef port_in_and = andStartMemOp->find_member("in", port_vector_o_K, andStartMemOp);
170  structural_objectRef port_out_and = andStartMemOp->find_member("out1", port_o_K, andStartMemOp);
171  SM->add_connection(port_out_and, out_and_sign);
172 
173  if(GetPointer<port_o>(port_in_and)->get_ports_size() != 0)
174  {
175  THROW_ERROR("And start with more than 0 input port");
176  }
177  else
178  {
179  GetPointer<port_o>(port_in_and)->add_n_ports(2, port_in_and);
180  }
181 
182  SM->add_connection(out_or_sign, GetPointer<port_o>(port_in_and)->get_port(0)); // connected out or
183 
184  for(unsigned int j = 0; j < GetPointer<module>(circuit)->get_internal_objects_size(); j++)
185  {
186  structural_objectRef curr_gate = GetPointer<module>(circuit)->get_internal_object(j);
187  if(GET_TYPE_NAME(curr_gate) == "mem_ctrl_kernel")
188  {
189  structural_objectRef portStart = curr_gate->find_member(STR(START_PORT_NAME), port_o_K, curr_gate);
190  structural_objectRef startMemOp = GetPointer<port_o>(portStart)->find_bounded_object();
191  THROW_ASSERT(startMemOp != nullptr, "No start port for mem_ctrl_found");
192  SM->add_connection(startMemOp, GetPointer<port_o>(port_in_and)->get_port(1));
193  break;
194  }
195  }
196  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Added and_suspension");
197 
199  "suspensionOrGlobal", OR_GATE_STD, HLS->HLS_D->get_technology_manager()->get_library(OR_GATE_STD), circuit,
200  HLS->HLS_D->get_technology_manager());
201  structural_objectRef port_in_or_glo = suspensionOrGlo->find_member("in", port_vector_o_K, suspensionOrGlo);
202  structural_objectRef port_out_or_glo = suspensionOrGlo->find_member("out1", port_o_K, suspensionOrGlo);
203 
204  // search in module and find one with suspension
205  if(GetPointer<port_o>(port_in_or_glo)->get_ports_size() != 0)
206  {
207  THROW_ERROR("Or start with more than 0 input port");
208  }
209  else
210  {
211  GetPointer<port_o>(port_in_or_glo)->add_n_ports(1 + num_suspension, port_in_or_glo);
212  }
213  SM->add_connection(out_and_sign, GetPointer<port_o>(port_in_or_glo)->get_port(0));
214 
215  if(num_suspension > 0)
216  {
217  unsigned int num_signal_or = 0;
218  for(i = 0; i < n_elements; i++)
219  {
220  structural_objectRef curr_gate = GetPointer<module>(circuit)->get_internal_object(i);
221  structural_objectRef port_suspension_module = curr_gate->find_member(STR(SUSPENSION), port_o_K, curr_gate);
222  if(port_suspension_module != nullptr and curr_gate->get_id() != "scheduler_kernel")
223  {
224  structural_objectRef suspension_sign =
225  SM->add_sign(STR(SUSPENSION) + "_signal_" + STR(i), circuit, bool_type);
226  SM->add_connection(port_suspension_module, suspension_sign);
227  SM->add_connection(suspension_sign, GetPointer<port_o>(port_in_or_glo)->get_port(num_signal_or + 1));
228  ++num_signal_or;
229  }
230  }
231  }
232 
233  connectOutOr(HLSMgr, HLS, port_out_or_glo);
234 }
235 
237 {
238  const structural_managerRef SM = HLS->datapath;
239  const structural_objectRef circuit = SM->get_circ();
240  auto omp_functions = GetPointer<OmpFunctions>(HLSMgr->Rfuns);
241  if(omp_functions->kernel_functions.find(HLS->functionId) != omp_functions->kernel_functions.end())
242  {
243  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Connecting out or of kernel");
244  structural_objectRef scheduler = circuit->find_member("scheduler_kernel", component_o_K, circuit);
247  structural_objectRef suspension_scheduler = scheduler->find_member(STR(SUSPENSION), port_o_K, scheduler);
248  structural_objectRef suspension_sign_out = SM->add_sign(STR(SUSPENSION) + "_signal", circuit, bool_type);
249  SM->add_connection(port_out_or, suspension_sign_out);
250  SM->add_connection(suspension_sign_out, suspension_scheduler);
251  }
252  else
253  {
254  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Connecting out or");
255  structural_objectRef suspension_datapath = circuit->find_member(STR(SUSPENSION), port_o_K, circuit);
256  SM->add_connection(port_out_or, suspension_datapath);
257  }
258  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Suspension signal correctly connected!");
259 }
void add_connection(structural_objectRef src, structural_objectRef dest)
Create a connection between a source structural object and a destination structural object...
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
#define OR_GATE_STD
Data structure representing the entire HLS information.
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;.
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.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
const structural_objectRef get_circ() const
Get a reference to circ field.
#define AND_GATE_STD
virtual void add_to_SM(const HLS_managerRef HLSMgr, const hlsRef HLS, const structural_managerRef SM)
Add the interconnection to the structural representation of the datapath.
generic_objRef get_port(unsigned int var, direction_type dir)
Returns reference to generic object associated to a given variable, for a specific port direction...
const HLS_deviceRef HLS_D
reference to the information representing the target for the synthesis
Definition: hls.hpp:107
void add_to_SM(const HLS_managerRef HLSMgr, const hlsRef HLS, const structural_managerRef SM) override
add_to_SM
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...
Class specification of the manager of the technology library data structures.
~conn_binding_cs() override
Destructor.
#define GET_TYPE_NAME(structural_obj)
Macro returning the string name of a type.
#define STR(s)
Macro which performs a lexical_cast to a string.
void connectOutOr(const HLS_managerRef HLSMgr, const hlsRef HLS, structural_objectRef port_out_or)
connectOutOr depending if module is kernel or another connect out
Class specification of the data structures used to manage technology information. ...
Class managing the interconnection binding.
void instantiate_suspension_component(const HLS_managerRef HLSMgr, const hlsRef HLS)
connect_suspension_component
This file collects some utility functions and macros.
conn_binding_cs(const BehavioralHelperConstRef BH, const ParameterConstRef parameters)
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
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.
This class describes all classes used to represent a structural object.
static structural_objectRef add_sign(std::string id, structural_objectRef owner, structural_type_descriptorRef sign_type, unsigned int treenode=0)
Create a new signal.
unsigned int size_t
Definition: test.c:1
this class is used to manage the command-line or XML options.
unsigned int functionId
this is the identifier of the function to be implemented
Definition: hls.hpp:87
Class implementation of the structural_manager.
This class describes a constant value.
int debug_level
control the verbosity during the debugging
Datastructure to describe functions allocation in high-level synthesis.
Data structure definition for high-level synthesis flow.
#define SUSPENSION
HLS specialization of generic_device.
void set_type(const structural_type_descriptorRef &s)
Set the type of the structural_object.
#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