PandA-2024.02
cs_interface.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) 2016-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  */
40 #include "cs_interface.hpp"
41 
42 #include "BambuParameter.hpp"
43 #include "copyrights_strings.hpp"
44 #include "dbgPrintHelper.hpp"
45 #include "hls.hpp"
46 #include "hls_device.hpp"
47 #include "hls_manager.hpp"
48 #include "math_function.hpp"
49 #include "memory.hpp"
50 #include "memory_cs.hpp"
51 #include "structural_manager.hpp"
52 #include "structural_objects.hpp"
53 #include "technology_manager.hpp"
54 #include "utility.hpp"
55 
56 #include <string>
57 
58 cs_interface::cs_interface(const ParameterConstRef _Param, const HLS_managerRef _HLSMgr, unsigned int _funId,
59  const DesignFlowManagerConstRef _design_flow_manager,
60  const HLSFlowStep_Type _hls_flow_step_type)
61  : module_interface(_Param, _HLSMgr, _funId, _design_flow_manager, _hls_flow_step_type)
62 {
63  debug_level = parameters->get_class_debug_level(GET_CLASS(*this));
64  THROW_ASSERT(funId, "Function not set in minimal interface");
65 }
66 
67 cs_interface::~cs_interface() = default;
68 
70 {
71  const structural_managerRef SM = HLS->top;
72  if(!SM)
73  {
74  THROW_ERROR("Top component has not been created yet!");
75  }
76 
77  structural_objectRef wrappedObj = SM->get_circ();
78  std::string module_name = wrappedObj->get_id();
79 
81  const structural_type_descriptorRef internal_type(new structural_type_descriptor(module_name + "_int"));
82  structural_type_descriptorRef module_type =
84  SM_cs_interface->set_top_info(module_name, module_type);
85  wrappedObj->set_type(internal_type);
86  structural_objectRef interfaceObj = SM_cs_interface->get_circ();
87 
88  // add the core to the wrapper
89  wrappedObj->set_owner(interfaceObj);
90  wrappedObj->set_id(wrappedObj->get_id() + "_i0");
91  GetPointer<module>(interfaceObj)->add_internal_object(wrappedObj);
93  GetPointer<module>(interfaceObj)
94  ->set_description("Minimal interface for top component: " + wrappedObj->get_typeRef()->id_type);
95  GetPointer<module>(interfaceObj)->set_copyright(GENERATED_COPYRIGHT);
96  GetPointer<module>(interfaceObj)->set_authors("Component automatically generated by bambu");
97  GetPointer<module>(interfaceObj)->set_license(GENERATED_LICENSE);
98 
99  add_parameter_port(SM_cs_interface, interfaceObj, wrappedObj); // connect port
100  structural_objectRef clock_port, reset_port;
101  structural_objectRef port_ck = wrappedObj->find_member(CLOCK_PORT_NAME, port_o_K, wrappedObj);
102  clock_port = SM_cs_interface->add_port(GetPointer<port_o>(port_ck)->get_id(), port_o::IN, interfaceObj,
103  port_ck->get_typeRef());
104  SM_cs_interface->add_connection(clock_port, port_ck);
105 
106  structural_objectRef port_rst = wrappedObj->find_member(RESET_PORT_NAME, port_o_K, wrappedObj);
107  reset_port = SM_cs_interface->add_port(GetPointer<port_o>(port_rst)->get_id(), port_o::IN, interfaceObj,
108  port_rst->get_typeRef());
109  SM_cs_interface->add_connection(reset_port, port_rst);
110 
111  instantiate_component_parallel(SM_cs_interface, clock_port, reset_port); // instantiate memory_ctrl_top
112 
113  manage_extern_global_port_top(SM_cs_interface, wrappedObj, interfaceObj); // connect memory port for memory_ctrl_top
114 
115  memory::propagate_memory_parameters(HLS->top->get_circ(), SM_cs_interface);
116  // Generation completed, the new created module substitutes the current top-level one
117  HLS->top = SM_cs_interface;
119 }
120 
122  structural_objectRef top_module)
123 {
124  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - Connecting parameter ports");
125  for(unsigned int j = 0; j < GetPointer<module>(top_module)->get_in_port_size(); j++) // connect in
126  {
127  structural_objectRef port_i = GetPointer<module>(top_module)->get_in_port(j);
128  if(!GetPointer<port_o>(port_i)->get_is_memory())
129  {
130  std::string port_name = GetPointer<port_o>(port_i)->get_id();
131  if(port_name != CLOCK_PORT_NAME && port_name != RESET_PORT_NAME)
132  {
133  structural_objectRef port_obj = SM->add_port(port_name, port_o::IN, circuit, port_i->get_typeRef());
134  SM->add_connection(port_obj, port_i);
135  }
136  }
137  }
138  for(unsigned int j = 0; j < GetPointer<module>(top_module)->get_out_port_size(); j++) // connect out
139  {
140  structural_objectRef port_i = GetPointer<module>(top_module)->get_out_port(j);
141  if(!GetPointer<port_o>(port_i)->get_is_memory())
142  {
143  std::string port_name = GetPointer<port_o>(port_i)->get_id();
144  structural_objectRef port_obj = SM->add_port(port_name, port_o::OUT, circuit, port_i->get_typeRef());
145  SM->add_connection(port_i, port_obj);
146  }
147  }
148 }
149 
151  structural_objectRef reset_port)
152 {
153  const structural_objectRef circuit = SM->get_circ();
154  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Start to instantiate memory_ctrl_top");
156  std::string memory_ctrl_model;
157  if(parameters->getOption<unsigned int>(OPT_channels_number) != 1)
158  {
159  memory_ctrl_model = "memory_ctrl";
160  }
161  else
162  {
163  memory_ctrl_model = "memory_ctrl_single_input";
164  }
165  std::string memory_ctrl_name = "memory_ctrl_top";
166  std::string memory_ctrl_library = HLS->HLS_D->get_technology_manager()->get_library(memory_ctrl_model);
168  memory_ctrl_name, memory_ctrl_model, memory_ctrl_library, circuit, HLS->HLS_D->get_technology_manager());
169 
170  structural_objectRef clock_mem_ctrl = mem_ctrl_mod->find_member(CLOCK_PORT_NAME, port_o_K, mem_ctrl_mod);
171  structural_objectRef clock_sign = SM->add_sign("clock_mem_ctrl_signal", circuit, bool_type);
172  SM->add_connection(clock_sign, clock_port);
173  SM->add_connection(clock_sign, clock_mem_ctrl);
174 
175  structural_objectRef reset_mem_ctrl = mem_ctrl_mod->find_member(RESET_PORT_NAME, port_o_K, mem_ctrl_mod);
176  structural_objectRef reset_sign = SM->add_sign("reset_mem_ctrl_signal", circuit, bool_type);
177  SM->add_connection(reset_sign, reset_port);
178  SM->add_connection(reset_sign, reset_mem_ctrl);
179  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Instantiate memory_ctrl_top!");
180 
181  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Starting setting parameter memory_ctrl_top!");
182  GetPointer<module>(mem_ctrl_mod)
183  ->SetParameter("NUM_CHANNEL", STR(parameters->getOption<unsigned int>(OPT_channels_number)));
184  GetPointer<module>(mem_ctrl_mod)
185  ->SetParameter("NUM_BANK", STR(parameters->getOption<unsigned int>(OPT_memory_banks_number)));
186  auto addr_task = ceil_log2(parameters->getOption<unsigned long long int>(OPT_context_switch));
187  if(!addr_task)
188  {
189  addr_task = 1;
190  }
191  GetPointer<module>(mem_ctrl_mod)->SetParameter("ADDR_TASKS", STR(addr_task));
192  auto addr_kern = ceil_log2(parameters->getOption<unsigned long long>(OPT_num_accelerators));
193  if(!addr_kern)
194  {
195  addr_kern = 1;
196  }
197  GetPointer<module>(mem_ctrl_mod)->SetParameter("ADDR_ACC", STR(addr_kern));
198  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Parameter memory_ctrl_top setted!");
199 
200  resize_memory_ctrl_ports(mem_ctrl_mod);
201 }
202 
204 {
205  auto memory_channel = parameters->getOption<unsigned int>(OPT_channels_number);
206  auto num_banks = parameters->getOption<unsigned int>(OPT_memory_banks_number);
207  for(unsigned int j = 0; j < GetPointer<module>(mem_ctrl_mod)->get_in_port_size(); j++) // resize input port
208  {
209  structural_objectRef port_i = GetPointer<module>(mem_ctrl_mod)->get_in_port(j);
210  if(GetPointer<port_o>(port_i)->get_is_memory())
211  {
212  std::string port_name = GetPointer<port_o>(port_i)->get_id();
213  if(port_name.substr(0, 3) == "IN_")
214  {
215  resize_dimension_bus_port(num_banks, port_i);
216  }
217  else
218  {
219  resize_dimension_bus_port(memory_channel, port_i);
220  }
221  }
222  }
223  for(unsigned int j = 0; j < GetPointer<module>(mem_ctrl_mod)->get_out_port_size(); j++) // resize output port
224  {
225  structural_objectRef port_i = GetPointer<module>(mem_ctrl_mod)->get_out_port(j);
226  if(GetPointer<port_o>(port_i)->get_is_memory())
227  {
228  std::string port_name = GetPointer<port_o>(port_i)->get_id();
229  if(port_name.substr(0, 4) == "OUT_")
230  {
231  resize_dimension_bus_port(num_banks, port_i);
232  }
233  else
234  {
235  resize_dimension_bus_port(memory_channel, port_i);
236  }
237  }
238  }
239 }
240 
242 {
243  auto bus_data_bitsize = HLSMgr->Rmem->get_bus_data_bitsize();
244  auto bus_addr_bitsize = HLSMgr->get_address_bitsize();
245  auto bus_size_bitsize = HLSMgr->Rmem->get_bus_size_bitsize();
246  auto bus_tag_bitsize = GetPointer<memory_cs>(HLSMgr->Rmem)->get_bus_tag_bitsize();
247 
248  if(GetPointer<port_o>(port)->get_is_data_bus())
249  {
250  port->type_resize(bus_data_bitsize);
251  }
252  else if(GetPointer<port_o>(port)->get_is_addr_bus())
253  {
254  port->type_resize(bus_addr_bitsize);
255  }
256  else if(GetPointer<port_o>(port)->get_is_size_bus())
257  {
258  port->type_resize(bus_size_bitsize);
259  }
260  else if(GetPointer<port_o>(port)->get_is_tag_bus())
261  {
262  port->type_resize(bus_tag_bitsize);
263  }
264 
265  GetPointer<port_o>(port)->add_n_ports(vector_size, port);
266 }
267 
269  const structural_objectRef memory_module,
270  const structural_objectRef circuit)
271 {
272  structural_objectRef cir_port;
273  structural_objectRef memory_ctrl_port;
274  auto num_channel = parameters->getOption<unsigned int>(OPT_channels_number);
275  structural_objectRef memory_ctrl = circuit->find_member("memory_ctrl_top", component_o_K, circuit);
276  THROW_ASSERT(memory_ctrl, "NULL, memmory_ctrl");
277  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Connecting memory_port of memory_ctrl");
278  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Connecting memory_ctrl output to module input");
279  for(unsigned int j = 0; j < GetPointer<module>(memory_module)->get_in_port_size();
280  j++) // from memory_ctrl output to module input
281  {
282  structural_objectRef port_i = GetPointer<module>(memory_module)->get_in_port(j);
283  if(GetPointer<port_o>(port_i)->get_is_memory() && GetPointer<port_o>(port_i)->get_is_global() &&
284  GetPointer<port_o>(port_i)->get_is_extern())
285  {
286  std::string port_name = GetPointer<port_o>(port_i)->get_id();
287  memory_ctrl_port = memory_ctrl->find_member(port_name, port_vector_o_K, memory_ctrl);
288  structural_objectRef memory_Sign =
289  SM->add_sign_vector(port_name + "_signal", num_channel, circuit, port_i->get_typeRef());
290  THROW_ASSERT(!memory_ctrl_port || GetPointer<port_o>(memory_ctrl_port), "should be a port");
291  SM->add_connection(memory_ctrl_port, memory_Sign);
293  "---Connecting " + memory_Sign->get_path() + "(" + memory_Sign->get_kind_text() + ")-->" +
294  port_i->get_path() + "(" + port_i->get_kind_text() + ")");
295  SM->add_connection(memory_Sign, port_i);
296  }
297  }
298  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Connected memory_ctrl output to module input");
299  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Connecting module output to memory_ctrl input");
300  for(unsigned int j = 0; j < GetPointer<module>(memory_module)->get_out_port_size();
301  j++) // from module output to memory_ctrl input
302  {
303  structural_objectRef port_i = GetPointer<module>(memory_module)->get_out_port(j);
304  if(GetPointer<port_o>(port_i)->get_is_memory() && !GetPointer<port_o>(port_i)->get_is_global() &&
305  !GetPointer<port_o>(port_i)->get_is_extern())
306  {
307  std::string port_name = GetPointer<port_o>(port_i)->get_id();
308  memory_ctrl_port = memory_ctrl->find_member(port_name, port_vector_o_K, memory_ctrl);
309  structural_objectRef memory_Sign =
310  SM->add_sign_vector(port_name + "_signal", num_channel, circuit, port_i->get_typeRef());
311  THROW_ASSERT(!memory_ctrl_port || GetPointer<port_o>(memory_ctrl_port), "should be a port");
312  SM->add_connection(port_i, memory_Sign);
313  SM->add_connection(memory_Sign, memory_ctrl_port);
314  }
315  }
316  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Connected module output to memory_ctrl input");
317  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Connecting memory_ctrl input to input");
318 
319  for(unsigned int j = 0; j < GetPointer<module>(memory_ctrl)->get_in_port_size();
320  j++) // connect input memory_ctrl with input circuit
321  {
322  structural_objectRef port_i = GetPointer<module>(memory_ctrl)->get_in_port(j);
323  std::string port_name = GetPointer<port_o>(port_i)->get_id();
324  if(GetPointer<port_o>(port_i)->get_is_memory() && GetPointer<port_o>(port_i)->get_is_global() &&
325  GetPointer<port_o>(port_i)->get_is_extern() && port_name.substr(0, 3) == "IN_")
326  {
327  cir_port = circuit->find_member(port_name.erase(0, 3), port_i->get_kind(), circuit);
328  THROW_ASSERT(!cir_port || GetPointer<port_o>(cir_port), "should be a port or null");
329  if(!cir_port)
330  {
331  cir_port = SM->add_port_vector(port_name, port_o::IN, GetPointer<port_o>(port_i)->get_ports_size(), circuit,
332  port_i->get_typeRef());
333  port_o::fix_port_properties(port_i, cir_port);
334  }
335  SM->add_connection(cir_port, port_i);
336  }
337  }
338  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Connected memory_ctrl input to input");
339  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Connecting memory_ctrl output to output");
340  for(unsigned int j = 0; j < GetPointer<module>(memory_ctrl)->get_out_port_size();
341  j++) // connect output memory_ctrl with output circuit
342  {
343  structural_objectRef port_i = GetPointer<module>(memory_ctrl)->get_out_port(j);
344  std::string port_name = GetPointer<port_o>(port_i)->get_id();
345  if(GetPointer<port_o>(port_i)->get_is_memory() && !GetPointer<port_o>(port_i)->get_is_global() &&
346  !GetPointer<port_o>(port_i)->get_is_extern() && port_name.substr(0, 4) == "OUT_")
347  {
348  cir_port =
349  circuit->find_member(port_name.erase(0, 4), port_i->get_kind(), circuit); // delete OUT from port name
350  THROW_ASSERT(!cir_port || GetPointer<port_o>(cir_port), "should be a port or null");
351  if(!cir_port)
352  {
353  cir_port = SM->add_port_vector(port_name, port_o::OUT, GetPointer<port_o>(port_i)->get_ports_size(),
354  circuit, port_i->get_typeRef());
355  port_o::fix_port_properties(port_i, cir_port);
356  }
357  SM->add_connection(cir_port, port_i);
358  }
359  }
360  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Connected memory_ctrl output to output");
361  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Connected memory_port of memory_ctrl");
362 }
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...
#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;.
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;.
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.
#define GENERATED_LICENSE
const structural_objectRef get_circ() const
Get a reference to circ field.
void set_owner(const structural_objectRef new_owner)
set the owner of the structural object
mathematical utility function not provided by standard libraries
const unsigned int funId
identifier of the function to be processed (0 means that it is a global step)
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
void resize_dimension_bus_port(unsigned int vector_size, structural_objectRef port)
resize_dimension_bus_port
DesignFlowStep_Status InternalExec() override
Execute the step.
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.
void instantiate_component_parallel(const structural_managerRef SM, structural_objectRef clock_port, structural_objectRef reset_port)
instantiate_component_parallel
#define STR(s)
Macro which performs a lexical_cast to a string.
void add_parameter_port(const structural_managerRef SM, structural_objectRef circuit, structural_objectRef top_module)
add_parameter_port
#define CLOCK_PORT_NAME
standard name for ports
structural_managerRef top
Store the top description.
Definition: hls.hpp:164
virtual std::string get_kind_text() const =0
Virtual function used to get the string name of a structural_object instance.
T ceil_log2(T x)
Return the smallest n such that 2**n >= X.
~cs_interface() override
Destructor.
void set_top_info(const std::string &id, const technology_managerRef &LM, const std::string &Library="")
HLSFlowStep_Type
Definition: hls_step.hpp:95
const std::string get_path() const
Return a unique identifier of the structural object.
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.
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.
This file collects some utility functions and macros.
#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_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.
void resize_memory_ctrl_ports(structural_objectRef mem_ctrl_mod)
resize_memory_ctrl_ports
void manage_extern_global_port_top(const structural_managerRef SM, const structural_objectRef memory_module, const structural_objectRef circuit)
manage_memory_ports_parallel_chained_parallel
std::string id_type
Original type id of the structural object.
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.
void set_id(const std::string &s)
Set the identifier associated with the 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.
hlsRef HLS
HLS data structure of the function to be analyzed.
Class to generate the interface for the context switch project.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
It collects all the common strings covering PandA copyrights issues.
#define RESET_PORT_NAME
Class implementation of the structural_manager.
int debug_level
The debug level.
Data structure definition for high-level synthesis flow.
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.
#define GENERATED_COPYRIGHT
Datastructure to represent memory information in high-level synthesis.
HLS specialization of generic_device.
void set_type(const structural_type_descriptorRef &s)
Set the type of the structural_object.
cs_interface(const ParameterConstRef Param, const HLS_managerRef HLSMgr, unsigned int funId, const DesignFlowManagerConstRef design_flow_manager, const HLSFlowStep_Type hls_flow_step_type=HLSFlowStep_Type::INTERFACE_CS_GENERATION)
Constructor.
static structural_objectRef add_sign_vector(std::string id, unsigned int n_signs, structural_objectRef owner, structural_type_descriptorRef sign_type, unsigned int treenode=0)
#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