44 #include "config_HAVE_FLOPOCO.hpp" 58 #include <boost/algorithm/string/case_conv.hpp> 63 const DesignFlowManagerConstRef _design_flow_manager,
66 TM(_device->get_technology_manager()),
68 has_first_synthesis_id(0)
78 bool is_commutative =
true;
81 std::map<unsigned int, std::vector<std::string>> pipe_parameters;
82 std::map<unsigned int, std::vector<std::string>> portsize_parameters;
83 auto* fu_curr = GetPointer<functional_unit>(f_unit);
84 if(fu_curr && fu_curr->fu_template_name !=
"")
89 bool isTemplate =
false;
90 bool no_constants =
false;
91 if(!fu_curr && GetPointer<functional_unit_template>(f_unit))
93 fu_curr = GetPointer<functional_unit>(GetPointer<functional_unit_template>(f_unit)->FU);
95 no_constants = GetPointer<functional_unit_template>(f_unit)->no_constant_characterization;
98 std::string fu_name = fu_curr->functional_unit_name;
99 std::string fu_base_name = fu_name;
101 auto ops_end = Ops.end();
108 for(
auto ops = Ops.begin(); ops != ops_end; ++ops)
110 auto* curr_op = GetPointer<operation>(*ops);
111 is_commutative = is_commutative && curr_op->commutative;
112 auto supported_type_it_end = curr_op->supported_types.end();
113 if(curr_op->supported_types.begin() == curr_op->supported_types.end())
119 precision.insert(16);
120 precision.insert(64);
122 precision.insert(32);
126 for(
auto supported_type_it = curr_op->supported_types.begin(); supported_type_it != supported_type_it_end;
129 auto prec_it_end = supported_type_it->second.end();
130 auto prec_it = supported_type_it->second.begin();
131 if(prec_it == prec_it_end)
137 precision.insert(16);
138 precision.insert(64);
140 precision.insert(32);
144 for(; prec_it != prec_it_end; ++prec_it)
146 precision.insert(*prec_it);
151 std::string pipe_parameters_str = curr_op->pipe_parameters;
153 if(pipe_parameters_str !=
"")
155 std::vector<std::string> parameters_split =
SplitString(pipe_parameters_str,
"|");
156 const auto pp_it_end = parameters_split.end();
157 for(
auto pp_it = parameters_split.begin(); pp_it != pp_it_end; ++pp_it)
159 std::vector<std::string> precision_pipe_param_pair =
SplitString(*pp_it,
":");
160 THROW_ASSERT(precision_pipe_param_pair.size() == 2,
"malformed pipe parameter string");
161 std::vector<std::string> pipe_params =
SplitString(precision_pipe_param_pair[1],
",");
162 THROW_ASSERT(pipe_params.size() > 0,
"malformed pipe parameter string");
163 if(precision_pipe_param_pair[0] ==
"*")
165 for(
unsigned int prec : precision)
167 for(
const auto& pipe_param : pipe_params)
169 if(std::find(pipe_parameters[prec].begin(), pipe_parameters[prec].end(), pipe_param) ==
170 pipe_parameters[prec].end())
172 pipe_parameters[prec].push_back(pipe_param);
177 else if(precision_pipe_param_pair[0] ==
"DSPs_y_sizes")
181 for(
const auto& pipe_param : pipe_params)
183 pipe_parameters[DSP_y.first].push_back(pipe_param);
184 precision.insert(DSP_y.first);
188 else if(precision.find(static_cast<unsigned>(std::stoul(precision_pipe_param_pair[0]))) !=
191 for(
const auto& pipe_param : pipe_params)
194 pipe_parameters[static_cast<unsigned>(std::stoul(precision_pipe_param_pair[0]))].begin(),
195 pipe_parameters[static_cast<unsigned>(std::stoul(precision_pipe_param_pair[0]))].end(),
197 pipe_parameters[
static_cast<unsigned>(std::stoul(precision_pipe_param_pair[0]))].end())
199 pipe_parameters[
static_cast<unsigned>(std::stoul(precision_pipe_param_pair[0]))].push_back(
210 std::string portsize_parameters_str = curr_op->portsize_parameters;
211 if(portsize_parameters_str !=
"")
213 std::vector<std::string> parameters_split =
SplitString(portsize_parameters_str,
"|");
214 const auto pp_it_end = parameters_split.end();
215 for(
auto pp_it = parameters_split.begin(); pp_it != pp_it_end; ++pp_it)
217 std::vector<std::string> precision_portsize_param_pair =
SplitString(*pp_it,
":");
218 THROW_ASSERT(precision_portsize_param_pair.size() == 2,
"malformed portsize parameter string");
219 std::vector<std::string> portsize_params =
SplitString(precision_portsize_param_pair[1],
",");
220 THROW_ASSERT(portsize_params.size() > 0,
"malformed portsize parameter string");
221 if(precision_portsize_param_pair[0] ==
"*")
223 for(
unsigned int prec : precision)
225 for(
const auto& portsize_param : portsize_params)
227 if(std::find(portsize_parameters[prec].begin(), portsize_parameters[prec].end(),
228 portsize_param) == portsize_parameters[prec].end())
230 portsize_parameters[prec].push_back(portsize_param);
235 else if(precision.find(static_cast<unsigned>(std::stoul(precision_portsize_param_pair[0]))) !=
238 for(
const auto& portsize_param : portsize_params)
241 portsize_parameters[static_cast<unsigned>(std::stoul(precision_portsize_param_pair[0]))]
243 portsize_parameters[static_cast<unsigned>(std::stoul(precision_portsize_param_pair[0]))]
246 portsize_parameters[
static_cast<unsigned>(std::stoul(precision_portsize_param_pair[0]))].end())
248 portsize_parameters[
static_cast<unsigned>(std::stoul(precision_portsize_param_pair[0]))]
249 .push_back(portsize_param);
255 THROW_ERROR(
"malformed portsize parameter string");
262 if(Ops.begin() == Ops.end())
264 is_commutative =
false;
269 for(
unsigned int prec : precision)
276 size_t max_lut_size = 0;
277 if(
device->has_parameter(
"max_lut_size"))
279 max_lut_size =
device->get_parameter<
size_t>(
"max_lut_size");
283 if(
device->has_parameter(
"vendor"))
285 vendor =
device->get_parameter<std::string>(
"vendor");
286 boost::algorithm::to_lower(vendor);
288 bool is_xilinx = vendor ==
"xilinx";
289 bool is_lattice = vendor ==
"lattice";
290 bool is_altera = vendor ==
"altera";
291 bool is_nanoxplore = vendor ==
"nanoxplore";
297 (is_xilinx || is_altera || is_lattice || is_nanoxplore))
303 fu_base_name ==
XNOR_GATE_STD || fu_base_name ==
"split_signal" || fu_base_name ==
"FSL_handler" ||
304 fu_base_name ==
"extract_bit_expr_FU" 309 || fu_base_name.find(
CONSTANT_STD) != std::string::npos)
314 const module*
mod = GetPointer<module>(obj);
317 unsigned int n_port_to_be_specialized = 0;
318 for(
unsigned int i = 0; i < n_ports; ++i)
323 (GetPointer<port_o>(port_c) && GetPointer<port_o>(port_c)->get_is_memory()) ||
324 port_c->
get_id().find(
"sel_") == 0))
328 ++n_port_to_be_specialized;
330 unsigned int constPort;
332 size_t n_pipe_parameters = pipe_parameters[prec].size();
333 size_t n_iterations_pipe = n_pipe_parameters > 1 ? n_pipe_parameters : 1;
334 size_t n_portsize_parameters = portsize_parameters[prec].size();
335 size_t n_iterations_portsize = n_portsize_parameters > 1 ? n_portsize_parameters : 1;
337 for(
size_t portsize_index = 0; portsize_index < n_iterations_portsize; ++portsize_index)
340 "-->Considering portsize_index " +
STR(portsize_index));
341 for(
size_t stage_index = 0; stage_index < n_iterations_pipe; ++stage_index)
343 if(n_port_to_be_specialized <= 1 || !isTemplate || fu_base_name ==
MUX_GATE_STD ||
354 for(; constPort < n_ports + 1; ++constPort)
360 (GetPointer<port_o>(port_c) && GetPointer<port_o>(port_c)->get_is_memory()) ||
361 port_c->
get_id().find(
"sel_") == 0))
365 std::string template_parameters;
366 fu_name = fu_base_name;
367 template_parameters =
"";
370 for(
unsigned int iport = 0; iport < n_ports; ++iport)
375 (GetPointer<port_o>(port) && GetPointer<port_o>(port)->get_is_memory()) ||
376 port->
get_id().find(
"sel_") == 0)
380 if(template_parameters !=
"")
382 template_parameters +=
" ";
387 fu_name +=
"_" +
STR(1);
388 template_parameters +=
STR(1);
390 else if(iport == 1 and
391 (fu_base_name ==
"widen_mult_expr_FU" or fu_base_name ==
"ui_widen_mult_expr_FU" or
392 fu_base_name ==
"mult_expr_FU" or fu_base_name ==
"ui_mult_expr_FU") and
398 else if(iport != constPort)
400 fu_name +=
"_" +
STR(prec);
401 template_parameters +=
STR(prec);
406 fu_name +=
"_" +
STR(128 / prec);
407 template_parameters +=
" " +
STR(128 / prec);
412 fu_name +=
"_" +
STR(0);
413 template_parameters +=
STR(0);
425 if((fu_base_name ==
"widen_mult_expr_FU" or fu_base_name ==
"ui_widen_mult_expr_FU") and
431 else if((fu_base_name ==
"mult_expr_FU" or fu_base_name ==
"ui_mult_expr_FU") and
437 else if(GetPointer<port_o>(port)->get_is_doubled())
439 fu_name +=
"_" +
STR(2 * prec);
440 template_parameters +=
" " +
STR(2 * prec);
442 else if(GetPointer<port_o>(port)->get_is_halved())
444 fu_name +=
"_" +
STR(prec / 2);
445 template_parameters +=
" " +
STR(prec / 2);
449 fu_name +=
"_" +
STR(prec);
450 template_parameters +=
" " +
STR(prec);
456 if(GetPointer<port_o>(port)->get_is_doubled())
458 fu_name +=
"_" +
STR(128 / (2 * prec));
459 template_parameters +=
" " +
STR(128 / (2 * prec));
461 else if(GetPointer<port_o>(port)->get_is_halved())
463 fu_name +=
"_" +
STR(128 / (prec / 2));
464 template_parameters +=
" " +
STR(128 / (prec / 2));
468 fu_name +=
"_" +
STR(128 / prec);
469 template_parameters +=
" " +
STR(128 / prec);
474 if(n_pipe_parameters > 0)
476 fu_name +=
"_" + pipe_parameters[prec][stage_index];
477 template_parameters +=
" " + pipe_parameters[prec][stage_index];
479 if(n_portsize_parameters > 0)
481 fu_name +=
"_" + portsize_parameters[prec][portsize_index];
482 template_parameters +=
" " + portsize_parameters[prec][portsize_index];
491 if(GetPointer<functional_unit_template>(f_unit))
493 fun_unit = GetPointer<functional_unit_template>(f_unit)->FU;
500 fu = GetPointer<functional_unit>(tn);
506 fu = GetPointer<functional_unit>(tn);
509 AnalyzeCell(fu, prec, portsize_parameters.find(prec)->second, portsize_index,
510 pipe_parameters.find(prec)->second, stage_index, constPort, is_commutative,
516 "<--Considered portsize_index " +
STR(portsize_index));
527 if(
device->has_parameter(
"DSPs_y_sizes"))
529 THROW_ASSERT(
device->has_parameter(
"DSPs_x_sizes"),
"device description is not complete");
530 auto DSPs_x_sizes =
device->get_parameter<std::string>(
"DSPs_x_sizes");
531 auto DSPs_y_sizes =
device->get_parameter<std::string>(
"DSPs_y_sizes");
532 std::vector<std::string> DSPs_x_sizes_vec =
SplitString(DSPs_x_sizes,
",");
533 std::vector<std::string> DSPs_y_sizes_vec =
SplitString(DSPs_y_sizes,
",");
534 for(
size_t DSP_index = 0; DSP_index < DSPs_y_sizes_vec.size(); DSP_index++)
536 const auto DSPs_x_value =
static_cast<unsigned>(std::stoul(DSPs_x_sizes_vec[DSP_index]));
537 const auto DSPs_y_value =
static_cast<unsigned>(std::stoul(DSPs_y_sizes_vec[DSP_index]));
544 const std::string& name,
unsigned int prec)
546 auto* curr_fu = GetPointer<functional_unit>(fu_template);
551 specialized_fu->fu_template_name = curr_fu->functional_unit_name;
552 specialized_fu->characterizing_constant_value = curr_fu->characterizing_constant_value;
553 specialized_fu->memory_type = curr_fu->memory_type;
554 specialized_fu->channels_type = curr_fu->channels_type;
555 specialized_fu->memory_ctrl_type = curr_fu->memory_ctrl_type;
556 specialized_fu->CM = curr_fu->CM;
557 specialized_fu->XML_description = curr_fu->XML_description;
559 for(
auto itr = curr_fu->get_operations().begin(), end = curr_fu->get_operations().end(); itr < end; ++itr)
561 auto*
const op = GetPointer<operation>(*itr);
564 new_op->bounded = op->bounded;
569 new_op->time_m->set_execution_time(op->time_m->get_execution_time(), op->time_m->get_cycles());
570 new_op->time_m->set_synthesis_dependent(op->time_m->get_synthesis_dependent());
571 const ControlStep ii(op->time_m->get_initiation_time());
572 new_op->time_m->set_initiation_time(ii);
574 new_op->commutative = op->commutative;
575 auto supported_type_it_end = op->supported_types.end();
576 if(op->supported_types.begin() != op->supported_types.end())
578 for(
auto supported_type_it = op->supported_types.begin(); supported_type_it != supported_type_it_end;
581 new_op->supported_types[supported_type_it->first].push_back(prec);
technology_nodeRef create_template_instance(const technology_nodeRef &fu_template, const std::string &name, unsigned int prec)
Create a template instance to be specialized.
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
Collect information about resource area.
File containing functions and utilities to support the printing of debug messagges.
technology_nodeRef get_fu(const std::string &fu_name, const std::string &Library) const
Return the reference to a component given its name.
const std::string & get_id() const
Return the identifier associated with the structural_object.
std::string operation_name
name of the operation mappen on a given functional unit.
std::string fu_template_parameters
Template parameters.
const std::vector< std::string > SplitString(const std::string &input, const std::string &separators)
Function which splits a string into tokens.
T resize_1_8_pow2(T value)
FunctionalUnitStep(const generic_deviceRef _device, const DesignFlowManagerConstRef design_flow_manager, const ParameterConstRef parameters)
Constructor.
unsigned int get_out_port_size() const
Return the number of output ports.
mathematical utility function not provided by standard libraries
The base class for design step.
std::string functional_unit_name
name of the functional unit.
Collect information about resource performance.
const structural_objectRef get_in_port(unsigned int n) const
Return the ith input port.
const std::string & get_name() const override
Return the name of the operation.
Class specification of the manager of the technology library data structures.
This class specifies the characteristic of a particular functional unit.
void add(const technology_nodeRef &node)
redefinition of map to manage ordered/unordered structures
refcount< technology_node > technology_nodeRef
refcount definition of the class
Abstract class to iterate over all the cells of a template.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
s_type type
The type of the port or the signal.
#define CLOCK_PORT_NAME
standard name for ports
#define LUT_GATE_STD
FPGA modules.
unsigned int has_first_synthesis_id
The id of the first analyzed cell of a sequence of cells which differ for the position of the constan...
This class specifies the characteristic of a particular operation working on a given functional unit...
Data structure used to store the schedule of the operations.
Class specification of the data structures used to manage technology information. ...
const structural_objectRef get_out_port(unsigned int n) const
Return the ith output port.
redefinition of set to manage ordered/unordered structures
const ParameterConstRef parameters
Set of input parameters.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
unsigned int get_in_port_size() const
Return the number of input ports.
const technology_managerRef TM
Technology manager.
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.
static area_infoRef factory(const ParameterConstRef &Param)
Factory method.
virtual const std::string & get_name() const =0
Return the name of the technology node.
virtual void AnalyzeCell(functional_unit *fu, const unsigned int prec, const std::vector< std::string > &portsize_parameters, const size_t portsize_index, const std::vector< std::string > &pipe_parameters, const size_t stage_index, const unsigned int constPort, const bool is_commutative, size_t max_lut_size)=0
Analyze the single cell.
void Initialize() override
Initialize the step (i.e., like a constructor, but executed just before exec.
refcount< structural_object > structural_objectRef
RefCount type definition of the structural_object class structure.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
CustomMap< unsigned int, unsigned int > DSP_y_to_DSP_x
The sizes of available DSPs.
const generic_deviceRef device
device information
virtual void AnalyzeFu(const technology_nodeRef f_unit)
Analyze all the cells built starting from a template.
Class implementation of the structural_manager.
Generic device description.
Class specification of the manager for each library.
int debug_level
The debug level.
std::vector< technology_nodeRef > operation_vec
Type definition of a vector of functional_unit.
bool exist_NP_functionality(NP_functionaly_type type) const
Return true in case there exist a functionaly of the given type.
~FunctionalUnitStep() override
Destructor.
This class describes a generic module.
static time_infoRef factory(const ParameterConstRef Param)
library_managerRef get_library_manager(const std::string &Name) const
Return the library data structure corresponding to the given library id.
std::string get_library(const std::string &Name) const
Return the higher priority library where the given component is stored.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...