PandA-2024.02
BambuParameter.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 "BambuParameter.hpp"
42 #include "allocation_constants.hpp"
43 #include "cdfc_module_binding.hpp"
44 #include "chaining.hpp"
45 #include "clique_covering.hpp"
46 #include "compiler_constants.hpp"
47 #include "compiler_wrapper.hpp"
48 #include "config_HAVE_COIN_OR.hpp"
49 #include "config_HAVE_EXPERIMENTAL.hpp"
50 #include "config_HAVE_FLOPOCO.hpp"
51 #include "config_HAVE_GLPK.hpp"
52 #include "config_HAVE_HOST_PROFILING_BUILT.hpp"
53 #include "config_HAVE_I386_CLANG16_COMPILER.hpp"
54 #include "config_HAVE_ILP_BUILT.hpp"
55 #include "config_HAVE_LIBRARY_CHARACTERIZATION_BUILT.hpp"
56 #include "config_HAVE_LP_SOLVE.hpp"
57 #include "config_HAVE_VCD_BUILT.hpp"
58 #include "config_PANDA_DATA_INSTALLDIR.hpp"
59 #include "config_PANDA_LIB_INSTALLDIR.hpp"
60 #include "config_SKIP_WARNING_SECTIONS.hpp"
61 #include "constant_strings.hpp"
62 #include "cpu_time.hpp"
63 #include "datapath_creator.hpp"
64 #include "dbgPrintHelper.hpp"
65 #include "evaluation.hpp"
66 #include "fileIO.hpp"
67 #include "generic_device.hpp"
68 #include "language_writer.hpp"
69 #include "memory_allocation.hpp"
71 #include "parse_technology.hpp"
72 #include "string_manipulation.hpp"
73 #include "technology_manager.hpp"
74 #include "technology_node.hpp"
75 #include "tree_helper.hpp"
76 #include "utility.hpp"
77 
78 #if HAVE_HOST_PROFILING_BUILT
79 #include "host_profiling.hpp"
80 #endif
81 #if HAVE_ILP_BUILT
82 #include "meilp_solver.hpp"
83 #include "sdc_scheduling.hpp"
84 #endif
85 
86 #include <algorithm>
87 #include <cstdlib>
88 #include <cstring>
89 #include <filesystem>
90 #include <getopt.h>
91 #include <iosfwd>
92 #include <list>
93 #include <regex>
94 #include <string>
95 #include <thread>
96 #include <vector>
97 
99 #define OPT_ACCEPT_NONZERO_RETURN 256
100 #define INPUT_OPT_C_NO_PARSE (1 + OPT_ACCEPT_NONZERO_RETURN)
101 #define INPUT_OPT_C_PYTHON_NO_PARSE (1 + INPUT_OPT_C_NO_PARSE)
102 #define OPT_ACO_FLOW (1 + INPUT_OPT_C_PYTHON_NO_PARSE)
103 #define OPT_ACO_GENERATIONS (1 + OPT_ACO_FLOW)
104 #define OPT_ADDITIONAL_TOP (1 + OPT_ACO_GENERATIONS)
105 #define OPT_ALIGNED_ACCESS_PARAMETER (1 + OPT_ADDITIONAL_TOP)
106 #define OPT_AREA_WEIGHT (1 + OPT_ALIGNED_ACCESS_PARAMETER)
107 #define OPT_BACKEND_SCRIPT_EXTENSIONS_PARAMETER (1 + OPT_AREA_WEIGHT)
108 #define OPT_BACKEND_SDC_EXTENSIONS_PARAMETER (1 + OPT_BACKEND_SCRIPT_EXTENSIONS_PARAMETER)
109 #define OPT_INPUT_CONTEXT_SWITCH (1 + OPT_BACKEND_SDC_EXTENSIONS_PARAMETER)
110 #define OPT_DISABLE_BITVALUE_IPA (1 + OPT_INPUT_CONTEXT_SWITCH)
111 #define OPT_BRAM_HIGH_LATENCY (1 + OPT_DISABLE_BITVALUE_IPA)
112 #define OPT_CHANNELS_NUMBER (1 + OPT_BRAM_HIGH_LATENCY)
113 #define OPT_CHANNELS_TYPE (1 + OPT_CHANNELS_NUMBER)
114 #define OPT_CLOCK_PERIOD_RESOURCE_FRACTION (1 + OPT_CHANNELS_TYPE)
115 #define OPT_DEVICE_NAME (1 + OPT_CLOCK_PERIOD_RESOURCE_FRACTION)
116 #define OPT_DISABLE_BOUNDED_FUNCTION (1 + OPT_DEVICE_NAME)
117 #define OPT_ENABLE_FUNCTION_PROXY (1 + OPT_DISABLE_BOUNDED_FUNCTION)
118 #define OPT_DISABLE_FUNCTION_PROXY (1 + OPT_ENABLE_FUNCTION_PROXY)
119 #define OPT_CONNECT_IOB (1 + OPT_DISABLE_FUNCTION_PROXY)
120 #define OPT_DISTRAM_THRESHOLD (1 + OPT_CONNECT_IOB)
121 #define OPT_DO_NOT_CHAIN_MEMORIES (1 + OPT_DISTRAM_THRESHOLD)
122 #define OPT_EXPOSE_GLOBALS (1 + OPT_DO_NOT_CHAIN_MEMORIES)
123 #define OPT_ROM_DUPLICATION (1 + OPT_EXPOSE_GLOBALS)
124 #define OPT_DO_NOT_USE_ASYNCHRONOUS_MEMORIES (1 + OPT_ROM_DUPLICATION)
125 #define OPT_DSE (1 + OPT_DO_NOT_USE_ASYNCHRONOUS_MEMORIES)
126 #define OPT_DSP_ALLOCATION_COEFFICIENT (1 + OPT_DSE)
127 #define OPT_DSP_MARGIN_COMBINATIONAL (1 + OPT_DSP_ALLOCATION_COEFFICIENT)
128 #define OPT_DSP_MARGIN_PIPELINED (1 + OPT_DSP_MARGIN_COMBINATIONAL)
129 #define OPT_DSP_FRACTURING (1 + OPT_DSP_MARGIN_PIPELINED)
130 #define OPT_DUMP_CONSTRAINTS (1 + OPT_DSP_FRACTURING)
131 #define OPT_DISCREPANCY (1 + OPT_DUMP_CONSTRAINTS)
132 #define OPT_DISCREPANCY_FORCE (1 + OPT_DISCREPANCY)
133 #define OPT_DISCREPANCY_HW (1 + OPT_DISCREPANCY_FORCE)
134 #define OPT_DISCREPANCY_NO_LOAD_POINTERS (1 + OPT_DISCREPANCY_HW)
135 #define OPT_DISCREPANCY_ONLY (1 + OPT_DISCREPANCY_NO_LOAD_POINTERS)
136 #define OPT_DISCREPANCY_PERMISSIVE_PTRS (1 + OPT_DISCREPANCY_ONLY)
137 #define INPUT_OPT_DRY_RUN_EVALUATION (1 + OPT_DISCREPANCY_PERMISSIVE_PTRS)
138 #define OPT_ENABLE_IOB (1 + INPUT_OPT_DRY_RUN_EVALUATION)
139 #define OPT_EVALUATION (1 + OPT_ENABLE_IOB)
140 #define OPT_EVALUATION_MODE (1 + OPT_EVALUATION)
141 #define OPT_EXPERIMENTAL_SETUP (1 + OPT_EVALUATION_MODE)
142 #define OPT_FLOPOCO (1 + OPT_EXPERIMENTAL_SETUP)
143 #define OPT_GENERATE_VCD (1 + OPT_FLOPOCO)
144 #define OPT_GENERATION (1 + OPT_GENERATE_VCD)
145 #define OPT_HLS_DIV (1 + OPT_GENERATION)
146 #define OPT_HLS_FPDIV (1 + OPT_HLS_DIV)
147 #define OPT_HOST_PROFILING (1 + OPT_HLS_FPDIV)
148 #define OPT_ILP (1 + OPT_HOST_PROFILING)
149 #define OPT_ILP_NEWFORM (1 + OPT_ILP)
150 #define OPT_ILP_SOLVER (1 + OPT_ILP_NEWFORM)
151 #define INPUT_OPT_FILE_INPUT_DATA (1 + OPT_ILP_SOLVER)
152 #define OPT_INSERT_MEMORY_PROFILE (1 + INPUT_OPT_FILE_INPUT_DATA)
153 #define OPT_INSERT_VERIFICATION_OPERATION (1 + OPT_INSERT_MEMORY_PROFILE)
154 #define OPT_LIBM_STD_ROUNDING (1 + OPT_INSERT_VERIFICATION_OPERATION)
155 #define OPT_LIST_BASED (1 + OPT_LIBM_STD_ROUNDING)
156 #define OPT_LOGICAL_OPTIMIZATION (1 + OPT_LIST_BASED)
157 #define OPT_MAX_EVALUATIONS (1 + OPT_LOGICAL_OPTIMIZATION)
158 #define OPT_MAX_INHERITANCE (1 + OPT_MAX_EVALUATIONS)
159 #define OPT_MAX_SIM_CYCLES (1 + OPT_MAX_INHERITANCE)
160 #define OPT_MAX_ULP (1 + OPT_MAX_SIM_CYCLES)
161 #define OPT_MEMORY_MAPPED_TOP (1 + OPT_MAX_ULP)
162 #define OPT_MEM_DELAY_READ (1 + OPT_MEMORY_MAPPED_TOP)
163 #define OPT_MEM_DELAY_WRITE (1 + OPT_MEM_DELAY_READ)
164 #define OPT_TB_QUEUE_SIZE (1 + OPT_MEM_DELAY_WRITE)
165 #define OPT_MEMORY_BANKS_NUMBER (1 + OPT_TB_QUEUE_SIZE)
166 #define OPT_MIN_INHERITANCE (1 + OPT_MEMORY_BANKS_NUMBER)
167 #define OPT_MOSA_FLOW (1 + OPT_MIN_INHERITANCE)
168 #define OPT_NO_MIXED_DESIGN (1 + OPT_MOSA_FLOW)
169 #define OPT_NUM_ACCELERATORS (1 + OPT_NO_MIXED_DESIGN)
170 #define OPT_PARALLEL_CONTROLLER (1 + OPT_NUM_ACCELERATORS)
171 #define OPT_PERIOD_CLOCK (1 + OPT_PARALLEL_CONTROLLER)
172 #define OPT_CLOCK_NAME (1 + OPT_PERIOD_CLOCK)
173 #define OPT_RESET_NAME (1 + OPT_CLOCK_NAME)
174 #define OPT_START_NAME (1 + OPT_RESET_NAME)
175 #define OPT_DONE_NAME (1 + OPT_START_NAME)
176 #define OPT_POWER_OPTIMIZATION (1 + OPT_DONE_NAME)
177 #define OPT_PRAGMA_PARSE (1 + OPT_POWER_OPTIMIZATION)
178 #define OPT_PRETTY_PRINT (1 + OPT_PRAGMA_PARSE)
179 #define OPT_REGISTER_ALLOCATION (1 + OPT_PRETTY_PRINT)
180 #define OPT_REGISTERED_INPUTS (1 + OPT_REGISTER_ALLOCATION)
181 #define OPT_FSM_ENCODING (1 + OPT_REGISTERED_INPUTS)
182 #define OPT_RESET_TYPE (1 + OPT_FSM_ENCODING)
183 #define OPT_RESET_LEVEL (1 + OPT_RESET_TYPE)
184 #define OPT_DISABLE_REG_INIT_VALUE (1 + OPT_RESET_LEVEL)
185 #define OPT_SCHEDULING_MUX_MARGINS (1 + OPT_DISABLE_REG_INIT_VALUE)
186 #define OPT_USE_ALUS (1 + OPT_SCHEDULING_MUX_MARGINS)
187 #define OPT_SERIALIZE_MEMORY_ACCESSES (1 + OPT_USE_ALUS)
188 #define OPT_SILP (1 + OPT_SERIALIZE_MEMORY_ACCESSES)
189 #define OPT_SIMULATE (1 + OPT_SILP)
190 #define OPT_SKIP_PIPE_PARAMETER (1 + OPT_SIMULATE)
191 #define OPT_SOFT_FLOAT (1 + OPT_SKIP_PIPE_PARAMETER)
192 #define OPT_FP_SUB (1 + OPT_SOFT_FLOAT)
193 #define OPT_FP_RND (1 + OPT_FP_SUB)
194 #define OPT_FP_EXC (1 + OPT_FP_RND)
195 #define OPT_SOFT_FP (1 + OPT_FP_EXC)
196 #define OPT_STG (1 + OPT_SOFT_FP)
197 #define OPT_SPECULATIVE (1 + OPT_STG)
198 #define INPUT_OPT_TEST_MULTIPLE_NON_DETERMINISTIC_FLOWS (1 + OPT_SPECULATIVE)
199 #define INPUT_OPT_TEST_SINGLE_NON_DETERMINISTIC_FLOW (1 + INPUT_OPT_TEST_MULTIPLE_NON_DETERMINISTIC_FLOWS)
200 #define OPT_TESTBENCH (1 + INPUT_OPT_TEST_SINGLE_NON_DETERMINISTIC_FLOW)
201 #define OPT_TESTBENCH_ARGV (1 + OPT_TESTBENCH)
202 #define OPT_TESTBENCH_PARAM_SIZE (1 + OPT_TESTBENCH_ARGV)
203 #define OPT_TESTBENCH_MAP_MODE (1 + OPT_TESTBENCH_PARAM_SIZE)
204 #define OPT_TB_EXTRA_GCC_OPTIONS (1 + OPT_TESTBENCH_MAP_MODE)
205 #define OPT_TIME_WEIGHT (1 + OPT_TB_EXTRA_GCC_OPTIONS)
206 #define OPT_TIMING_MODEL (1 + OPT_TIME_WEIGHT)
207 #define OPT_TIMING_VIOLATION (1 + OPT_TIMING_MODEL)
208 #define OPT_TOP_FNAME (1 + OPT_TIMING_VIOLATION)
209 #define OPT_TOP_RTLDESIGN_NAME (1 + OPT_TOP_FNAME)
210 #define OPT_UNALIGNED_ACCESS_PARAMETER (1 + OPT_TOP_RTLDESIGN_NAME)
211 #define OPT_VHDL_LIBRARY_PARAMETER (1 + OPT_UNALIGNED_ACCESS_PARAMETER)
212 #define OPT_XML_CONFIG (1 + OPT_VHDL_LIBRARY_PARAMETER)
213 #define OPT_RANGE_ANALYSIS_MODE (1 + OPT_XML_CONFIG)
214 #define OPT_FP_FORMAT (1 + OPT_RANGE_ANALYSIS_MODE)
215 #define OPT_FP_FORMAT_PROPAGATE (1 + OPT_FP_FORMAT)
216 #define OPT_FP_FORMAT_INTERFACE (1 + OPT_FP_FORMAT_PROPAGATE)
217 #define OPT_PARALLEL_BACKEND (1 + OPT_FP_FORMAT_INTERFACE)
218 #define OPT_ARCHITECTURE_XML (1 + OPT_PARALLEL_BACKEND)
219 #define OPT_LATTICE_ROOT (1 + OPT_ARCHITECTURE_XML)
220 #define OPT_XILINX_ROOT (1 + OPT_LATTICE_ROOT)
221 #define OPT_MENTOR_ROOT (1 + OPT_XILINX_ROOT)
222 #define OPT_MENTOR_OPTIMIZER (1 + OPT_MENTOR_ROOT)
223 #define OPT_VERILATOR_PARALLEL (1 + OPT_MENTOR_OPTIMIZER)
224 #define OPT_ALTERA_ROOT (1 + OPT_VERILATOR_PARALLEL)
225 #define OPT_NANOXPLORE_ROOT (1 + OPT_ALTERA_ROOT)
226 #define OPT_NANOXPLORE_BYPASS (1 + OPT_NANOXPLORE_ROOT)
227 #define OPT_SHARED_INPUT_REGISTERS (1 + OPT_NANOXPLORE_BYPASS)
228 #define OPT_INLINE_FUNCTIONS (1 + OPT_SHARED_INPUT_REGISTERS)
229 #define OPT_AXI_BURST_TYPE (1 + OPT_INLINE_FUNCTIONS)
230 
232 #define PAR_LIST_BASED_OPT "parametric-list-based"
233 
234 static bool is_evaluation_objective_string(const std::vector<std::string>& obj_vec, const std::string& s)
235 {
236  return std::find(obj_vec.begin(), obj_vec.end(), s) != obj_vec.end();
237 }
238 
239 static void add_evaluation_objective_string(std::string& obj_string, const std::string& obj_to_add)
240 {
241  if(obj_string.empty())
242  {
243  obj_string = obj_to_add;
244  return;
245  }
246  auto obj_vec = string_to_container<std::set<std::string>>(obj_string, ",");
247  string_to_container(std::inserter(obj_vec, obj_vec.end()), obj_to_add, ",");
248  obj_string = container_to_string(obj_vec, ",");
249 }
250 
251 void BambuParameter::PrintHelp(std::ostream& os) const
252 {
253  os << "Usage:\n"
254  << " bambu [Options] <source_file> [<constraints_file>] [<technology_file>]\n\n"
255  << "Options:\n\n";
258  os << " --pretty-print=<file>.c\n"
259  << " C-based pretty print of the internal IRx\n\n"
260  << " --writer,-w<language>\n"
261  << " Output RTL language:\n"
262  << " V - Verilog (default)\n"
263  << " H - VHDL\n\n"
264  << " --no-mixed-design\n"
265  << " Avoid mixed output RTL language designs.\n\n"
266  << " --generate-tb=<file>\n"
267  << " Generate testbench using the given files.\n"
268  << " <file> must be a valid testbench XML file or a C/C++ file specifying\n"
269  << " a main function calling the top-level interface. (May be repeated)\n\n"
270  << " --generate-tb=elf:<exe>\n"
271  << " Generate testbench environment using <exe> as system simulation.\n"
272  << " <exe> must be an executable that dynamically loads the synthesized\n"
273  << " top-function symbol.\n\n"
274  << " --tb-extra-gcc-options=<string>\n"
275  << " Specify custom extra options to the compiler for testbench compilation only.\n\n"
276  << " --tb-arg=<arg>\n"
277  << " Passes <arg> to the testbench main function as an argument.\n"
278  << " The option may be repeated to pass multiple arguments in order.\n\n"
279  << " --tb-param-size=<param_name>:<byte_size>\n"
280  << " A comma-separated list of pairs representing a pointer parameter name and\n"
281  << " the size for the related memory space. Specifying this option will disable\n"
282  << " automated top-level function verification.\n\n"
283  << " --tb-memory-mapping=<arg>\n"
284  << " Testbench memory mapping mode:\n"
285  << " DEVICE - Emulate host/device memory mapping (default)\n"
286  << " SHARED - Emulate shared memory space between host and device\n"
287  << " (BEAWARE: no memory integrity checks in shared mode)\n\n"
288  << " --top-fname=<fun_name>\n"
289  << " Define the top function to be synthesized. (default=main)\n\n"
290  << " --top-rtldesign-name=<top_name>\n"
291  << " Define the top module name for the RTL backend.\n\n"
292  << " --inline-fname=<fun_name>[,<fun_name>]*\n"
293  << " Define functions to be always inlined.\n"
294  << " Automatic inlining is always performed using internal metrics.\n"
295  << " Maximum cost to allow function inlining is defined through\n"
296  << " --panda-parameter=inline-max-cost=<value>. (default=60)\n\n"
297  << " --file-input-data=<file_list>\n"
298  << " A comma-separated list of input files used by the C specification.\n\n"
299  << " --C-no-parse=<file>\n"
300  << " Specify a comma-separated list of C files used only during the\n"
301  << " co-simulation phase.\n\n"
302  << std::endl;
303 
304  PrintGccOptionsUsage(os);
305 
306  // Target options
307  os << " Target:\n\n"
308  << " --target-file=file, -b<file>\n"
309  << " Specify an XML description of the target device.\n\n"
310  << " --generate-interface=<type>\n"
311  << " Wrap the top level module with an external interface.\n"
312  << " Possible values for <type> and related interfaces:\n"
313  << " MINIMAL - minimal interface (default)\n"
314  << " INFER - top function is built with an hardware interface inferred from\n"
315  << " the pragmas or from the top function signature\n"
316  << " WB4 - WishBone 4 interface\n\n"
317  << " --architecture-xml=<filename>\n"
318  << " User-defined module architecture file.\n\n"
319  << " --memory-mapped-top\n"
320  << " Generate a memory mapped interface for the top level function.\n"
321  << " The start signal and each one of function parameter are mapped to a memory address\n\n"
322  << std::endl;
323 
324  // HLS options
325  os << " Scheduling:\n\n"
326  << " --parametric-list-based[=<type>]\n"
327  << " Perform priority list-based scheduling. This is the default scheduling algorithm\n"
328  << " in bambu. The optional <type> argument can be used to set options for\n"
329  << " list-based scheduling as follows:\n"
330  << " 0 - Dynamic mobility (default)\n"
331  << " 1 - Static mobility\n"
332  << " 2 - Priority-fixed mobility\n\n"
333 #if HAVE_ILP_BUILT
334  << " --speculative-sdc-scheduling,-s\n"
335  << " Perform scheduling by using speculative SDC.\n"
336  << " The speculative SDC is more conservative, in case \n"
337  << " --panda-parameter=enable-conservative-sdc=1 is passed.\n\n"
338 #endif
339  << " --pipelining,-p\n"
340  << " Perform functional pipelining starting from the top function.\n\n"
341  << " --pipelining,-p=<func_name>[=<init_interval>][,<func_name>[=<init_interval>]]*\n"
342  << " Perform pipelining of comma separated list of specified functions with optional \n"
343  << " initiation interval (default II=1).\n"
344  << " To pipeline softfloat operators it is possible to specify the __float_<op_name> prefix \n"
345  << " or simply __float to pipeline all softfloat library.\n\n"
346  << " --fixed-scheduling=<file>\n"
347  << " Provide scheduling as an XML file.\n\n"
348  << " --no-chaining\n"
349  << " Disable chaining optimization.\n\n"
350  << std::endl;
351 
352  // Binding options
353  os << " Binding:\n\n"
354  << " --register-allocation=<type>\n"
355  << " Set the algorithm used for register allocation. Possible values for the\n"
356  << " <type> argument are the following:\n"
357  << " WEIGHTED_TS - use weighted clique covering algorithm by\n"
358  << " exploiting the Tseng&Siewiorek heuristics\n"
359  << " (default)\n"
360  << " COLORING - use simple coloring algorithm\n"
361  << " WEIGHTED_COLORING - use weighted coloring algorithm\n"
362  << " CHORDAL_COLORING - use chordal coloring algorithm\n"
363  << " BIPARTITE_MATCHING - use bipartite matching algorithm\n"
364  << " TTT_CLIQUE_COVERING - use a weighted clique covering algorithm\n"
365  << " UNIQUE_BINDING - unique binding algorithm\n"
366  << "\n"
367  << " --module-binding=<type>\n"
368  << " Set the algorithm used for module binding. Possible values for the\n"
369  << " <type> argument are one the following:\n"
370  << " WEIGHTED_TS - solve the weighted clique covering problem by\n"
371  << " exploiting the Tseng&Siewiorek heuristics\n"
372  << " (default)\n"
373  << " WEIGHTED_COLORING - solve the weighted clique covering problem\n"
374  << " performing a coloring on the conflict graph\n"
375  << " COLORING - solve the unweighted clique covering problem\n"
376  << " performing a coloring on the conflict graph\n"
377  << " TTT_FAST - use Tomita, A. Tanaka, H. Takahashi maxima\n"
378  << " weighted cliques heuristic to solve the clique\n"
379  << " covering problem\n"
380  << " TTT_FAST2 - use Tomita, A. Tanaka, H. Takahashi maximal\n"
381  << " weighted cliques heuristic to incrementally\n"
382  << " solve the clique covering problem\n"
383  << " TTT_FULL - use Tomita, A. Tanaka, H. Takahashi maximal\n"
384  << " weighted cliques algorithm to solve the clique\n"
385  << " covering problem\n"
386  << " TTT_FULL2 - use Tomita, A. Tanaka, H. Takahashi maximal\n"
387  << " weighted cliques algorithm to incrementally\n"
388  << " solve the clique covering problem\n"
389  << " TS - solve the unweighted clique covering problem\n"
390  << " by exploiting the Tseng&Siewiorek heuristic\n"
391  << " BIPARTITE_MATCHING - solve the weighted clique covering problem\n"
392  << " exploiting the bipartite matching approach\n"
393  << " UNIQUE - use a 1-to-1 binding algorithm\n\n"
394  << std::endl;
395  os << " --shared-input-registers\n"
396  << " The module bindings and the register binding try to share more resources by \n"
397  << " sharing the input registers\n\n"
398  << std::endl;
399 
400  // Memory allocation options
401  os << " Memory allocation:\n\n"
402  << " --xml-memory-allocation=<xml_file_name>\n"
403  << " Specify the file where the XML configuration has been defined.\n\n"
404  << " --memory-allocation-policy=<type>\n"
405  << " Set the policy for memory allocation. Possible values for the <type>\n"
406  << " argument are the following:\n"
407  << " ALL_BRAM - all objects that need to be stored in memory\n"
408  << " are allocated on BRAMs (default)\n"
409  << " LSS - all local variables, static variables and\n"
410  << " strings are allocated on BRAMs\n"
411  << " GSS - all global variables, static variables and\n"
412  << " strings are allocated on BRAMs\n"
413  << " NO_BRAM - all objects that need to be stored in memory\n"
414  << " are allocated on an external memory\n"
415  << " EXT_PIPELINED_BRAM - all objects that need to be stored in memory\n"
416  << " are allocated on an external pipelined memory\n\n"
417  << " --base-address=address\n"
418  << " Define the starting address for objects allocated externally to the top\n"
419  << " module.\n\n"
420  << " --initial-internal-address=address\n"
421  << " Define the starting address for the objects allocated internally to the\n"
422  << " top module.\n\n"
423  << " --channels-type=<type>\n"
424  << " Set the type of memory connections.\n"
425  << " Possible values for <type> are:\n"
426  << " MEM_ACC_11 - the accesses to the memory have a single direct\n"
427  << " connection or a single indirect connection\n"
428  << " MEM_ACC_N1 - the accesses to the memory have n parallel direct\n"
429  << " connections or a single indirect connection\n"
430  << " MEM_ACC_NN - the accesses to the memory have n parallel direct\n"
431  << " connections or n parallel indirect connections (default)\n\n"
432  << " --channels-number=<n>\n"
433  << " Define the number of parallel direct or indirect accesses.\n\n"
434  << " --memory-ctrl-type=type\n"
435  << " Define which type of memory controller is used. Possible values for the\n"
436  << " <type> argument are the following:\n"
437  << " D00 - no extra delay (default)\n"
438  << " D10 - 1 clock cycle extra-delay for LOAD, 0 for STORE\n"
439  << " D11 - 1 clock cycle extra-delay for LOAD, 1 for STORE\n"
440  << " D21 - 2 clock cycle extra-delay for LOAD, 1 for STORE\n\n"
441  << " --memory-banks-number=<n>\n"
442  << " Define the number of memory banks.\n\n"
443  << " --sparse-memory[=on/off]\n"
444  << " Control how the memory allocation happens.\n"
445  << " on - allocate the data in addresses which reduce the decoding logic (default)\n"
446  << " off - allocate the data in a contiguous addresses.\n\n"
447  << " --do-not-use-asynchronous-memories\n"
448  << " Do not add asynchronous memories to the possible set of memories used\n"
449  << " by bambu during the memory allocation step.\n\n"
450  << " --distram-threshold=value\n"
451  << " Define the threshold in bitsize used to infer DISTRIBUTED/ASYNCHRONOUS RAMs (default 256).\n\n"
452  << " --serialize-memory-accesses\n"
453  << " Serialize the memory accesses using the GCC virtual use-def chains\n"
454  << " without taking into account any alias analysis information.\n\n"
455  << " --unaligned-access\n"
456  << " Use only memories supporting unaligned accesses.\n\n"
457  << " --aligned-access\n"
458  << " Assume that all accesses are aligned and so only memories supporting aligned\n\n"
459  << " accesses are used.\n\n"
460  << " --do-not-chain-memories\n"
461  << " When enabled LOADs and STOREs will not be chained with other\n"
462  << " operations.\n\n"
463  << " --rom-duplication\n"
464  << " Assume that read-only memories can be duplicated in case timing requires.\n\n"
465  << " --bram-high-latency=[3,4]\n"
466  << " Assume a 'high latency bram'-'faster clock frequency' block RAM memory\n"
467  << " based architectures:\n"
468  << " 3 => LOAD(II=1,L=3) STORE(1).\n"
469  << " 4 => LOAD(II=1,L=4) STORE(II=1,L=2).\n\n"
470  << " --mem-delay-read=value\n"
471  << " Define the external memory latency when LOAD are performed (default 2).\n\n"
472  << " --mem-delay-write=value\n"
473  << " Define the external memory latency when STORE are performed (default 1).\n\n"
474  << " --tb-queue-size=value\n"
475  << " Define the maximum number of requests accepted by the testbench (default 4).\n\n"
476  << " --expose-globals\n"
477  << " All global variables can be accessed from outside the accelerator.\n\n"
478  << " --data-bus-bitsize=<bitsize>\n"
479  << " Set the bitsize of the external data bus.\n\n"
480  << " --addr-bus-bitsize=<bitsize>\n"
481  << " Set the bitsize of the external address bus.\n\n"
482  << std::endl;
483 
484  // Options for Evaluation of HLS results
485  os << " Evaluation of HLS results:\n\n"
486  << " --simulate\n"
487  << " Simulate the RTL implementation.\n\n"
488  << " --simulator=<type>\n"
489  << " Specify the simulator used in generated simulation scripts:\n"
490  << " MODELSIM - Mentor Modelsim\n"
491  << " XSIM - Xilinx XSim\n"
492  // << " ISIM - Xilinx iSim\n"
493  // << " ICARUS - Verilog Icarus simulator\n"
494  << " VERILATOR - Verilator simulator\n\n"
495  << " --verilator-parallel[=num_threads]\n"
496  << " Enable multi-threaded simulation when using verilator\n\n"
497  << " --max-sim-cycles=<cycles>\n"
498  << " Specify the maximum number of cycles a HDL simulation may run.\n"
499  << " (default 200000000).\n\n"
500  << " --accept-nonzero-return\n"
501  << " Do not assume that application main must return 0.\n\n"
502  << " --generate-vcd\n"
503  << " Enable .vcd output file generation for waveform visualization (requires\n"
504  << " testbench generation).\n\n"
505  << " --evaluation[=type]\n"
506  << " Perform evaluation of the results.\n"
507  << " The value of 'type' selects the objectives to be evaluated\n"
508  << " If nothing is specified all the following are evaluated\n"
509  << " The 'type' argument can be a string containing any of the following\n"
510  << " strings, separated with commas, without spaces:\n"
511  << " AREA - Area usage\n"
512  << " AREAxTIME - Area x Latency product\n"
513  << " TIME - Latency for the average computation\n"
514  << " TOTAL_TIME - Latency for the whole computation\n"
515  << " CYCLES - n. of cycles for the average computation\n"
516  << " TOTAL_CYCLES - n. of cycles for the whole computation\n"
517  << " BRAMS - number of BRAMs\n"
518  << " DRAMS - number of DRAMs\n"
519  << " CLOCK_SLACK - Slack between actual and required clock period\n"
520  << " DSPS - number of DSPs\n"
521  << " FREQUENCY - Maximum target frequency\n"
522  << " PERIOD - Actual clock period\n"
523  << " REGISTERS - number of registers\n"
524  << "\n"
525 #if HAVE_EXPERIMENTAL
526  << " --evaluation-mode[=type]\n"
527  << " Perform evaluation of the results:\n"
528  << " EXACT: based on actual synthesis and simulation (default)\n"
529  << " LINEAR: based on linear regression. Unlike EXACT it supports\n"
530  << " only the evaluation of the following objectives:\n"
531  << " - AREA\n"
532  << " - CLOCK_SLACK\n"
533  << " - TIME\n"
534  << "\n"
535  << " --timing-violation\n"
536  << " Aborts if synthesized circuit does not meet the timing.\n\n"
537 #endif
538  << std::endl;
539 
540  // RTL synthesis options
541  os << " RTL synthesis:\n\n"
542  << " --clock-name=id\n"
543  << " Specify the clock signal name of the top interface (default = clock).\n\n"
544  << " --reset-name=id\n"
545  << " Specify the reset signal name of the top interface (default = reset).\n\n"
546  << " --start-name=id\n"
547  << " Specify the start signal name of the top interface (default = start_port).\n\n"
548  << " --done-name=id\n"
549  << " Specify the done signal name of the top interface (default = done_port).\n\n"
550  << " --clock-period=value\n"
551  << " Specify the period of the clock signal (default = 10ns).\n\n"
552  << " --backend-script-extensions=file\n"
553  << " Specify a file that will be included in the backend specific synthesis\n"
554  << " scripts.\n\n"
555  << " --backend-sdc-extensions=file\n"
556  << " Specify a file that will be included in the Synopsys Design Constraints\n"
557  << " file (SDC).\n\n"
558  << " --parallel-backend\n"
559  << " when possible enable a parallel synthesis backend\n"
560  << " --VHDL-library=libraryname\n"
561  << " Specify the library in which the VHDL generated files are compiled.\n\n"
562  << " --device-name=value\n"
563  << " Specify the name of the device. Three different cases are foreseen:\n"
564  << " - Xilinx: a comma separated string specifying device, speed grade\n"
565  << " and package (e.g.,: \"xc7z020,-1,clg484,VVD\")\n"
566  << " - Altera: a string defining the device string (e.g. EP2C70F896C6)\n"
567  << " - Lattice: a string defining the device string (e.g.\n"
568  << " LFE5U85F8BG756C)\n"
569  << " - NanoXplore: a string defining the device string (e.g. nx2h540tsc))\n\n"
570  << " --power-optimization\n"
571  << " Enable Xilinx power based optimization (default no).\n\n"
572  << " --connect-iob\n"
573  << " Connect primary input and output ports to IOBs.\n\n"
574  << " --soft-float (default)\n"
575  << " Enable the soft-based implementation of floating-point operations.\n"
576  << " Bambu uses as default a faithfully rounded version of softfloat with rounding mode\n"
577  << " equal to round to nearest even. Subnormal numbers are disabled by default.\n"
578  << " Default FP formats are e8m23b-127nih and e11m52b-1023nih for single and double \n"
579  << " precision floating-point types respectively.\n\n"
580 #if HAVE_FLOPOCO
581  << " --flopoco\n"
582  << " Enable the flopoco-based implementation of floating-point operations.\n\n"
583 #endif
584  << " --libm-std-rounding\n"
585  << " Enable the use of classical libm. This library combines a customized version of \n"
586  << " glibc, newlib and musl libm implementations into a single libm library synthetizable\n"
587  << " with bambu.\n"
588  << " Without this option, Bambu uses as default a faithfully rounded version of libm.\n\n"
589  << " --soft-fp\n"
590  << " Enable the use of soft_fp GCC library instead of bambu customized version of softfloat library.\n\n"
591  << " --max-ulp\n"
592  << " Define the maximal ULP (Unit in the last place, i.e., is the spacing\n"
593  << " between floating-point numbers) accepted.\n\n"
594  << " --fp-subnormal\n"
595  << " Enable the soft-based implementation of floating-point operations with\n"
596  << " subnormals support.\n\n"
597  << " --fp-exception-mode=<ieee|saturation|overflow>\n"
598  << " Set the soft-based exception handling mode:\n"
599  << " ieee - IEEE754 standard exceptions (default)\n"
600  << " saturation - Inf is replaced with max value, Nan becomes undefined behaviour\n"
601  << " overflow - Inf and Nan results in undefined behaviour\n\n"
602  << " --fp-rounding-mode=<nearest_even|truncate>\n"
603  << " Set the soft-based rounding handling mode:\n"
604  << " nearest_even - IEEE754 standard rounding mode (default)\n"
605  << " truncate - No rounding is applied\n\n"
606  << " --fp-format=<func_name>*e<exp_bits>m<frac_bits>b<exp_bias><rnd_mode><exc_mode><?spec><?sign>\n"
607  << " Define arbitrary precision floating-point format by function (use comma separated\n"
608  << " list for multiple definitions). (i.e.: e8m27b-127nihs represent IEEE754 single precision FP)\n"
609  << " func_name - Set arbitrary floating-point format for a specific function (using\n"
610  << " @ symbol here will resolve to the top function)\n"
611  << " (Arbitrary floating-point format will apply to specified function\n"
612  << " only, use --propagate-fp-format to extend it to called functions)\n"
613  << " exp_bits - Number of bits used by the exponent\n"
614  << " frac_bits - Number of bits used by the fractional value\n"
615  << " exp_bias - Bias applied to the unsigned value represented by the exponent bits\n"
616  << " rnd_mode - Rounding mode (exclusive option):\n"
617  << " n - nearest_even: IEEE754 standard rounding mode\n"
618  << " t - truncate : no rounding is applied\n"
619  << " exc_mode - Exception mode (exclusive option):\n"
620  << " i - ieee : IEEE754 standard exceptions\n"
621  << " a - saturation: Inf is replaced with max value, Nan becomes undefined behaviour\n"
622  << " o - overflow : Inf and Nan results in undefined behaviour\n"
623  << " spec - Floating-point specialization string (multiple choice):\n"
624  << " h - hidden one: IEEE754 standard representation with hidden one\n"
625  << " s - subnormals: IEEE754 subnormal numbers\n"
626  << " sign - Static sign representation (exclusive option):\n"
627  << " - IEEE754 dynamic sign is used if omitted\n"
628  << " 1 - all values are considered as negative numbers\n"
629  << " 0 - all values are considered as positive numbers\n\n"
630  << " --fp-format=inline-math\n"
631  << " The \"inline-math\" flag may be added to fp-format option to force floating-point\n"
632  << " arithmetic operators always inline policy\n\n"
633  << " --fp-format=inline-conversion\n"
634  << " The \"inline-conversion\" flag may be added to fp-format option to force floating-point\n"
635  << " conversion operators always inline policy\n\n"
636  << " --fp-format-interface\n"
637  << " User-defined floating-point format is applied to top interface signature if required\n"
638  << " (default modifies top function body only)\n\n"
639  << " --fp-format-propagate\n"
640  << " Propagate user-defined floating-point format to called function when possible\n\n"
641  << " --hls-div=<method>\n"
642  << " Perform the high-level synthesis of integer division and modulo\n"
643  << " operations starting from a C library based implementation or a HDL component:\n"
644  << " none - use a HDL based pipelined restoring division\n"
645  << " nr1 - use a C-based non-restoring division with unrolling factor equal to 1 (default)\n"
646  << " nr2 - use a C-based non-restoring division with unrolling factor equal to 2\n"
647  << " NR - use a C-based Newton-Raphson division\n"
648  << " as - use a C-based align divisor shift dividend method\n\n"
649  << " --hls-fpdiv=<method>\n"
650  << " Perform the high-level synthesis of floating point division \n"
651  << " operations starting from a C library based implementation:\n"
652  << " SRT4 - use a C-based Sweeney, Robertson, Tocher floating point division with radix 4 (default)\n"
653  << " G - use a C-based Goldschmidt floating point division.\n"
654  << " SF - use a C-based floating point division as describe in soft-fp library\n"
655  << " (it requires --soft-fp).\n"
656  << " --skip-pipe-parameter=<value>\n"
657  << " Used during the allocation of pipelined units. <value> specifies how\n"
658  << " many pipelined units, compliant with the clock period, will be skipped.\n"
659  << " (default=0).\n\n"
660  << " --reset-type=value\n"
661  << " Specify the type of reset:\n"
662  << " no - use registers without reset (default)\n"
663  << " async - use registers with asynchronous reset\n"
664  << " sync - use registers with synchronous reset\n\n"
665  << " --reset-level=value\n"
666  << " Specify if the reset is active high or low:\n"
667  << " low - use registers with active low reset (default)\n"
668  << " high - use registers with active high reset\n\n"
669  << " --disable-reg-init-value\n"
670  << " Used to remove the INIT value from registers (useful for ASIC designs)\n\n"
671  << " --registered-inputs=value\n"
672  << " Specify if inputs are registered or not:\n"
673  << " auto - inputs are registered only for proxy functions (default)\n"
674  << " top - inputs and return are registered only for top and proxy functions\n"
675  << " yes - all inputs are registered\n"
676  << " no - none of the inputs is registered\n\n"
677  << " --fsm-encoding=value\n"
678  << " auto - it depends on the target technology. VVD prefers one encoding\n"
679  << " while the other are fine with the standard binary encoding. (default)\n"
680  << " one-hot - one hot encoding\n"
681  << " binary - binary encoding\n\n"
682  << " --cprf=value\n"
683  << " Clock Period Resource Fraction (default = 1.0).\n\n"
684  << " --DSP-allocation-coefficient=value\n"
685  << " During the allocation step the timing of the DSP-based modules is\n"
686  << " multiplied by value (default = 1.0).\n\n"
687  << " --DSP-margin-combinational=value\n"
688  << " Timing of combinational DSP-based modules is multiplied by value.\n"
689  << " (default = 1.0).\n\n"
690  << " --DSP-margin-pipelined=value\n"
691  << " Timing of pipelined DSP-based modules is multiplied by value.\n"
692  << " (default = 1.0).\n\n"
693  << " --DSP-fracturing=[16,32]\n"
694  << " Restructure multiplication by fracturing the computation.\n"
695  << " 16 => All multiplications will be decomposed into multiplications with input size not larger than "
696  "16.\n"
697  << " 32 => All multiplications will be decomposed into multiplications with input size not larger than "
698  "32.\n\n"
699  << " --mux-margins=n\n"
700  << " Scheduling reserves a margin corresponding to the delay of n 32 bit\n"
701  << " multiplexers.\n\n"
702  << " --timing-model=value\n"
703  << " Specify the timing model used by HLS:\n"
704  << " EC - estimate timing overhead of glue logics and connections\n"
705  << " between resources (default)\n"
706  << " SIMPLE - just consider the resource delay\n\n"
707  << " --experimental-setup=<setup>\n"
708  << " Specify the experimental setup. This is a shorthand to set multiple\n"
709  << " options with a single command.\n"
710  << " Available values for <setup> are the following:\n"
711  << " BAMBU-AREA - this setup implies:\n"
712  << " -Os -D'printf(fmt, ...)='\n"
713  << " --memory-allocation-policy=ALL_BRAM\n"
714  << " --DSP-allocation-coefficient=1.75\n"
715  << " --distram-threshold=256\n"
716  << " --enable-function-proxy\n"
717  << " BAMBU-AREA-MP - this setup implies:\n"
718  << " -Os -D'printf(fmt, ...)='\n"
719  << " --channels-type=MEM_ACC_NN\n"
720  << " --channels-number=2\n"
721  << " --memory-allocation-policy=ALL_BRAM\n"
722  << " --DSP-allocation-coefficient=1.75\n"
723  << " --distram-threshold=256\n"
724  << " --enable-function-proxy\n"
725  << " BAMBU-BALANCED - this setup implies:\n"
726  << " -O2 -D'printf(fmt, ...)='\n"
727  << " --channels-type=MEM_ACC_11\n"
728  << " --memory-allocation-policy=ALL_BRAM\n"
729  << " -fgcse-after-reload -fipa-cp-clone\n"
730  << " -ftree-partial-pre -funswitch-loops\n"
731  << " -finline-functions -fdisable-tree-bswap\n"
732  << " --param max-inline-insns-auto=25\n"
733  << " -fno-tree-loop-ivcanon\n"
734  << " --distram-threshold=256\n"
735  << " -C='*'\n"
736  << " --disable-function-proxy\n"
737  << " BAMBU-BALANCED-MP - (default) this setup implies:\n"
738  << " -O2 -D'printf(fmt, ...)='\n"
739  << " --channels-type=MEM_ACC_NN\n"
740  << " --channels-number=2\n"
741  << " --memory-allocation-policy=ALL_BRAM\n"
742  << " -fgcse-after-reload -fipa-cp-clone\n"
743  << " -ftree-partial-pre -funswitch-loops\n"
744  << " -finline-functions -fdisable-tree-bswap\n"
745  << " --param max-inline-insns-auto=25\n"
746  << " -fno-tree-loop-ivcanon\n"
747  << " --disable-function-proxy\n"
748  << " -C='*'\n"
749  << " --distram-threshold=256\n"
750  << " BAMBU-TASTE - this setup concatenate the input files and\n"
751  << " passes these options to the compiler:\n"
752  << " -O2 -D'printf(fmt, ...)='\n"
753  << " --channels-type=MEM_ACC_NN\n"
754  << " --memory-allocation-policy=ALL_BRAM\n"
755  << " -fgcse-after-reload -fipa-cp-clone\n"
756  << " -ftree-partial-pre -funswitch-loops\n"
757  << " -finline-functions -fdisable-tree-bswap\n"
758  << " --param max-inline-insns-auto=25\n"
759  << " -fno-tree-loop-ivcanon\n"
760  << " --disable-function-proxy\n"
761  << " -C='*'\n"
762  << " --distram-threshold=256\n"
763  << " BAMBU-PERFORMANCE - this setup implies:\n"
764  << " -O3 -D'printf(fmt, ...)='\n"
765  << " --memory-allocation-policy=ALL_BRAM\n"
766  << " --distram-threshold=512\n"
767  << " --disable-function-proxy\n"
768  << " BAMBU-PERFORMANCE-MP - this setup implies:\n"
769  << " -O3 -D'printf(fmt, ...)='\n"
770  << " --channels-type=MEM_ACC_NN\n"
771  << " --channels-number=2\n"
772  << " --memory-allocation-policy=ALL_BRAM\n"
773  << " --distram-threshold=512\n"
774  << " --disable-function-proxy\n"
775  << " BAMBU - this setup implies:\n"
776  << " -O0 --channels-type=MEM_ACC_11\n"
777  << " --memory-allocation-policy=LSS\n"
778  << " --distram-threshold=256\n"
779  << " BAMBU092 - this setup implies:\n"
780  << " -O3 -D'printf(fmt, ...)='\n"
781  << " --timing-model=SIMPLE\n"
782  << " --DSP-margin-combinational=1.3\n"
783  << " --cprf=0.9 -skip-pipe-parameter=1\n"
784  << " --channels-type=MEM_ACC_11\n"
785  << " --memory-allocation-policy=LSS\n"
786  << " --distram-threshold=256\n"
787  << " VVD - this setup implies:\n"
788  << " -O3 -D'printf(fmt, ...)='\n"
789  << " --channels-type=MEM_ACC_NN\n"
790  << " --memory-allocation-policy=ALL_BRAM\n"
791  << " --distram-threshold=256\n"
792  << " --DSP-allocation-coefficient=1.75\n"
793  << " --cprf=0.875\n\n"
794  << std::endl;
795  os << " Other options:\n\n";
796  os << " --pragma-parse\n"
797  << " Perform source code parsing to extract information about pragmas.\n"
798  << " (default=no).\n\n";
799 #if HAVE_FROM_PRAGMA_BUILT
800  os << " --num-accelerators\n"
801  << " Set the number of physical accelerator instantiated in parallel sections. It must\n"
802  << " be a power of two (default=4).\n\n";
803 #endif
804 #if HAVE_ILP_BUILT
805  os << " --time, -t <time>\n"
806  << " Set maximum execution time (in seconds) for ILP solvers. (infinite).\n\n";
807 #endif
808 #if HAVE_HOST_PROFILING_BUILT
809  os << " --host-profiling\n"
810  << " Perform host-profiling.\n\n";
811 #endif
812  os << " --disable-bitvalue-ipa\n"
813  << " Disable inter-procedural bitvalue analysis.\n\n";
814  os << " --enable-function-proxy\n"
815  << " Enable function proxy. May reduce the resource usage.\n\n";
816  os << " --disable-function-proxy\n"
817  << " Disable function proxy. May increase FSMD parallelism.\n\n";
818  os << " --constraints,-C=<func_name>[=<num_resources>][,<func_name>[=<num_resources>]]*\n"
819  << " Perform resource sharing of functions inside the datapath,\n"
820  << " limiting the number of function instances to 'num_resources'.\n"
821  << " Functions are specified as a comma-separated list with an optional\n"
822  << " number of resources. (num_resources is by default equal to 1 when not specified).\n"
823  << " In case <num_resources> is equal to 'u', the function is unconstrained.\n"
824  << " If the first character of func_name is '*', then 'num_resources'\n"
825  << " applies to all functions having as a prefix 'func_name' with '*'\n"
826  << " character removed.\n"
827  << " In case we have -C='*', all functions have 1 instance constraint. \n\n"
828  << " --AXI-burst-type=value\n."
829  << " Specify the type of AXI burst when performing single beat operations:\n"
830  << " FIXED - fixed type burst (default)\n"
831  << " INCREMENTAL - incremental type burst\n\n";
832  os << std::endl;
833 
834  // Checks and debugging options
835  os << " Debug options:\n\n"
836  << " --discrepancy\n"
837  << " Performs automated discrepancy analysis between the execution\n"
838  << " of the original source code and the generated HDL (currently\n"
839  << " supports only Verilog). If a mismatch is detected reports\n"
840  << " useful information to the user.\n"
841  << " Uninitialized variables in C are legal, but if they are used\n"
842  << " before initialization in HDL it is possible to obtain X values\n"
843  << " in simulation. This is not necessarily wrong, so these errors\n"
844  << " are not reported by default to avoid reporting false positives.\n"
845  << " If you can guarantee that in your C code there are no\n"
846  << " uninitialized variables and you want the X values in HDL to be\n"
847  << " reported use the option --discrepancy-force-uninitialized.\n"
848  << " Note that the discrepancy of pointers relies on ASAN to properly\n"
849  << " allocate objects in memory. Unfortunately, there is a well-known\n"
850  << " bug on ASAN (https://github.com/google/sanitizers/issues/914)\n"
851  << " when -fsanitize=address is passed to GCC or CLANG.\n"
852  << " On some compiler versions this issues has been fixed but since the\n"
853  << " fix has not been upstreamed the bambu option --discrepancy may not\n"
854  << " work. To circumvent the issue, the user may perform the discrepancy\n"
855  << " by adding these two options: --discrepancy --discrepancy-permissive-ptrs.\n\n"
856  << " --discrepancy-force-uninitialized\n"
857  << " Reports errors due to uninitialized values in HDL.\n"
858  << " See the option --discrepancy for details\n\n"
859  << " --discrepancy-no-load-pointers\n"
860  << " Assume that the data loaded from memories in HDL are never used\n"
861  << " to represent addresses, unless they are explicitly assigned to\n"
862  << " pointer variables.\n"
863  << " The discrepancy analysis is able to compare pointers in software\n"
864  << " execution and addresses in hardware. By default all the values\n"
865  << " loaded from memory are treated as if they could contain addresses,\n"
866  << " even if they are integer variables. This is due to the fact that\n"
867  << " C code doing this tricks is valid and actually used in embedded\n"
868  << " systems, but it can lead to imprecise bug reports, because only\n"
869  << " pointers pointing to actual data are checked by the discrepancy\n"
870  << " analysis.\n"
871  << " If you can guarantee that your code always manipulates addresses\n"
872  << " using pointers and never using plain int, then you can use this\n"
873  << " option to get more precise bug reports.\n\n"
874  << " --discrepancy-only=comma,separated,list,of,function,names\n"
875  << " Restricts the discrepancy analysis only to the functions whose\n"
876  << " name is in the list passed as argument.\n\n"
877  << " --discrepancy-permissive-ptrs\n"
878  << " Do not trigger hard errors on pointer variables.\n\n"
879  << " --discrepancy-hw\n"
880  << " Hardware Discrepancy Analysis.\n\n"
881  << " --assert-debug\n"
882  << " Enable assertion debugging performed by Modelsim.\n"
883  << " (Mentor Modelsim should be selected to use this option)\n\n"
884  << std::endl;
885  // options defining where backend tools could be found
886  os << " Backend configuration:\n\n"
887  << " --mentor-visualizer\n"
888  << " Simulate the RTL implementation and then open Mentor Visualizer.\n"
889  << " (Mentor root has to be correctly set, see --mentor-root)\n\n"
890  << " --mentor-optimizer=<0|1>\n"
891  << " Enable or disable mentor optimizer. (default=enabled)\n\n"
892  << " --nanoxplore-bypass=<name>\n"
893  << " Define NanoXplore bypass when using NanoXplore. User may set NANOXPLORE_BYPASS\n"
894  << " variable otherwise.\n\n"
895  << " --altera-root=<path>\n"
896  << " Define Altera tools path. Given path is searched for Quartus.\n"
897  << " (default=/opt/altera:/opt/intelFPGA)\n\n"
898  << " --lattice-root=<path>\n"
899  << " Define Lattice tools path. Given path is searched for Diamond.\n"
900  << " (default=/opt/diamond:/usr/local/diamond)\n\n"
901  << " --mentor-root=<path>\n"
902  << " Define Mentor tools path. Given directory is searched for Modelsim and Visualizer\n"
903  << " (default=/opt/mentor)\n\n"
904  << " --nanoxplore-root=<path>\n"
905  << " Define NanoXplore tools path. Given directory is searched for NXMap.\n"
906  << " (default=/opt/NanoXplore)\n\n"
907  << " --xilinx-root=<path>\n"
908  << " Define Xilinx tools path. Given directory is searched for both ISE and Vivado\n"
909  << " (default=/opt/Xilinx)\n\n"
910  << std::endl;
911 }
912 
913 void BambuParameter::PrintProgramName(std::ostream& os) const
914 {
915  os << std::endl;
916  os << "********************************************************************************" << std::endl;
917  os << " ____ _" << std::endl;
918  os << " | __ ) __ _ _ __ ___ | |_ _ _" << std::endl;
919  os << R"( | _ \ / _` | '_ ` _ \| '_ \| | | |)" << std::endl;
920  os << " | |_) | (_| | | | | | | |_) | |_| |" << std::endl;
921  os << " |____/ \\__,_|_| |_| |_|_.__/ \\__,_|" << std::endl;
922  os << std::endl;
923  os << "********************************************************************************" << std::endl;
924  os << " High-Level Synthesis Tool" << std::endl;
925  os << std::endl;
926 }
927 
928 BambuParameter::BambuParameter(const std::string& _program_name, int _argc, char** const _argv)
929  : Parameter(_program_name, _argc, _argv)
930 {
931  SetDefaults();
932 }
933 
935 {
937 
939  bool scheduling_set_p = false;
941  int option_index;
942 
943  // Bambu short option. An option character in this string can be followed by a colon (`:') to indicate that it
944  // takes a required argument. If an option character is followed by two colons (`::'), its argument is optional;
945  // this is a GNU extension.
946  const char* const short_options = COMMON_SHORT_OPTIONS_STRING "o:t:u:H:sSC::b:w:p::" GCC_SHORT_OPTIONS_STRING;
947 
948  const struct option long_options[] = {
951  {"top-fname", required_argument, nullptr, OPT_TOP_FNAME},
952  {"top-rtldesign-name", required_argument, nullptr, OPT_TOP_RTLDESIGN_NAME},
953  {"time", required_argument, nullptr, 't'},
954  {"file-input-data", required_argument, nullptr, INPUT_OPT_FILE_INPUT_DATA},
956  {"circuit-dbg", required_argument, nullptr, 0},
958 #if HAVE_ILP_BUILT
959  {"speculative-sdc-scheduling", no_argument, nullptr, 's'},
960 #endif
961  {"pipelining", optional_argument, nullptr, 'p'},
962  {"serialize-memory-accesses", no_argument, nullptr, OPT_SERIALIZE_MEMORY_ACCESSES},
963  {PAR_LIST_BASED_OPT, optional_argument, nullptr, OPT_LIST_BASED}, // no short option
964 #if HAVE_ILP_BUILT
965  {"ilp-solver", required_argument, nullptr, OPT_ILP_SOLVER},
966  {"ilp", no_argument, nullptr, OPT_ILP},
967  {"ilp-newform", no_argument, nullptr, OPT_ILP_NEWFORM},
968  {"silp", no_argument, nullptr, OPT_SILP},
969 #endif
970  {"speculative", no_argument, nullptr, OPT_SPECULATIVE},
971  {"no-chaining", no_argument, nullptr, 0},
973  {"stg", required_argument, nullptr, OPT_STG},
975  {"module-binding", required_argument, nullptr, 0},
977  {"register-allocation", required_argument, nullptr, OPT_REGISTER_ALLOCATION},
978  {"storage-value-insertion", required_argument, nullptr, 0},
980  {"memory-allocation-policy", required_argument, nullptr, 0},
981  {"xml-memory-allocation", required_argument, nullptr, 0},
982  {"base-address", required_argument, nullptr, 0},
983  {"initial-internal-address", required_argument, nullptr, 0},
984  {"channels-type", required_argument, nullptr, 0},
985  {"channels-number", required_argument, nullptr, 0},
986  {"memory-ctrl-type", required_argument, nullptr, 0},
987  {"sparse-memory", optional_argument, nullptr, 0},
988  {"expose-globals", no_argument, nullptr, OPT_EXPOSE_GLOBALS},
989  // parameter based resource constraints
990  {"constraints", required_argument, nullptr, 'C'},
992  {"evaluation", optional_argument, nullptr, OPT_EVALUATION},
993 #if HAVE_EXPERIMENTAL
994  {"evaluation-mode", required_argument, nullptr, OPT_EVALUATION_MODE},
995  {"timing-simulation", no_argument, nullptr, 0},
996 #endif
997  {"timing-violation", no_argument, nullptr, OPT_TIMING_VIOLATION},
998  {"assert-debug", no_argument, nullptr, 0},
999  {"device-name", required_argument, nullptr, OPT_DEVICE_NAME},
1000  {"clock-period", required_argument, nullptr, OPT_PERIOD_CLOCK},
1001  {"clock-name", required_argument, nullptr, OPT_CLOCK_NAME},
1002  {"reset-name", required_argument, nullptr, OPT_RESET_NAME},
1003  {"start-name", required_argument, nullptr, OPT_START_NAME},
1004  {"done-name", required_argument, nullptr, OPT_DONE_NAME},
1005  {"power-optimization", no_argument, nullptr, OPT_POWER_OPTIMIZATION},
1006  {"connect-iob", no_argument, nullptr, OPT_CONNECT_IOB},
1007  {"reset-type", required_argument, nullptr, OPT_RESET_TYPE},
1008  {"reset-level", required_argument, nullptr, OPT_RESET_LEVEL},
1009  {"disable-reg-init-value", no_argument, nullptr, OPT_DISABLE_REG_INIT_VALUE},
1010  {"soft-float", no_argument, nullptr, OPT_SOFT_FLOAT},
1011 #if HAVE_FLOPOCO
1012  {"flopoco", no_argument, nullptr, OPT_FLOPOCO},
1013 #endif
1014  {"fp-subnormal", no_argument, nullptr, OPT_FP_SUB},
1015  {"fp-rounding-mode", required_argument, nullptr, OPT_FP_RND},
1016  {"fp-exception-mode", required_argument, nullptr, OPT_FP_EXC},
1017  {"libm-std-rounding", no_argument, nullptr, OPT_LIBM_STD_ROUNDING},
1018  {"soft-fp", no_argument, nullptr, OPT_SOFT_FP},
1019  {"hls-div", optional_argument, nullptr, OPT_HLS_DIV},
1020  {"hls-fpdiv", optional_argument, nullptr, OPT_HLS_FPDIV},
1021  {"max-ulp", required_argument, nullptr, OPT_MAX_ULP},
1022  {"skip-pipe-parameter", required_argument, nullptr, OPT_SKIP_PIPE_PARAMETER},
1023  {"unaligned-access", no_argument, nullptr, OPT_UNALIGNED_ACCESS_PARAMETER},
1024  {"aligned-access", no_argument, nullptr, OPT_ALIGNED_ACCESS_PARAMETER},
1025  {"backend-script-extensions", required_argument, nullptr, OPT_BACKEND_SCRIPT_EXTENSIONS_PARAMETER},
1026  {"backend-sdc-extensions", required_argument, nullptr, OPT_BACKEND_SDC_EXTENSIONS_PARAMETER},
1027  {"parallel-backend", no_argument, nullptr, OPT_PARALLEL_BACKEND},
1028  {"VHDL-library", required_argument, nullptr, OPT_VHDL_LIBRARY_PARAMETER},
1029  {"do-not-use-asynchronous-memories", no_argument, nullptr, OPT_DO_NOT_USE_ASYNCHRONOUS_MEMORIES},
1030  {"do-not-chain-memories", no_argument, nullptr, OPT_DO_NOT_CHAIN_MEMORIES},
1031  {"rom-duplication", no_argument, nullptr, OPT_ROM_DUPLICATION},
1032  {"bram-high-latency", optional_argument, nullptr, OPT_BRAM_HIGH_LATENCY},
1033  {"cprf", required_argument, nullptr, OPT_CLOCK_PERIOD_RESOURCE_FRACTION},
1034  {"experimental-setup", required_argument, nullptr, OPT_EXPERIMENTAL_SETUP},
1035  {"distram-threshold", required_argument, nullptr, OPT_DISTRAM_THRESHOLD},
1036  {"DSP-allocation-coefficient", required_argument, nullptr, OPT_DSP_ALLOCATION_COEFFICIENT},
1037  {"DSP-margin-combinational", required_argument, nullptr, OPT_DSP_MARGIN_COMBINATIONAL},
1038  {"DSP-margin-pipelined", required_argument, nullptr, OPT_DSP_MARGIN_PIPELINED},
1039  {"DSP-fracturing", optional_argument, nullptr, OPT_DSP_FRACTURING},
1040  {"mux-margins", required_argument, nullptr, OPT_SCHEDULING_MUX_MARGINS},
1041  {"use-ALUs", no_argument, nullptr, OPT_USE_ALUS},
1042  {"timing-model", required_argument, nullptr, OPT_TIMING_MODEL},
1043  {"registered-inputs", required_argument, nullptr, OPT_REGISTERED_INPUTS},
1044  {"fsm-encoding", required_argument, nullptr, OPT_FSM_ENCODING},
1046  {"target-file", required_argument, nullptr, 'b'},
1047  {"export-core", required_argument, nullptr, 0},
1049  {"writer", required_argument, nullptr, 'w'},
1050  {"no-mixed-design", no_argument, nullptr, OPT_NO_MIXED_DESIGN},
1051  {"pretty-print", required_argument, nullptr, OPT_PRETTY_PRINT},
1052  {"pragma-parse", no_argument, nullptr, OPT_PRAGMA_PARSE},
1053  {"generate-interface", required_argument, nullptr, 0},
1054  {"architecture-xml", required_argument, nullptr, OPT_ARCHITECTURE_XML},
1055  {"additional-top", required_argument, nullptr, OPT_ADDITIONAL_TOP},
1056  {"data-bus-bitsize", required_argument, nullptr, 0},
1057  {"addr-bus-bitsize", required_argument, nullptr, 0},
1058  {"generate-tb", required_argument, nullptr, OPT_TESTBENCH},
1059  {"tb-arg", required_argument, nullptr, OPT_TESTBENCH_ARGV},
1060  {"tb-param-size", required_argument, nullptr, OPT_TESTBENCH_PARAM_SIZE},
1061  {"tb-memory-mapping", required_argument, nullptr, OPT_TESTBENCH_MAP_MODE},
1062  {"tb-extra-gcc-options", required_argument, nullptr, OPT_TB_EXTRA_GCC_OPTIONS},
1063  {"max-sim-cycles", required_argument, nullptr, OPT_MAX_SIM_CYCLES},
1064  {"generate-vcd", no_argument, nullptr, OPT_GENERATE_VCD},
1065  {"simulate", no_argument, nullptr, OPT_SIMULATE},
1066  {"simulator", required_argument, nullptr, 0},
1067  {"enable-function-proxy", no_argument, nullptr, OPT_ENABLE_FUNCTION_PROXY},
1068  {"disable-function-proxy", no_argument, nullptr, OPT_DISABLE_FUNCTION_PROXY},
1069  {"disable-bounded-function", no_argument, nullptr, OPT_DISABLE_BOUNDED_FUNCTION},
1070  {"memory-mapped-top", no_argument, nullptr, OPT_MEMORY_MAPPED_TOP},
1071  {"mem-delay-read", required_argument, nullptr, OPT_MEM_DELAY_READ},
1072  {"mem-delay-write", required_argument, nullptr, OPT_MEM_DELAY_WRITE},
1073  {"tb-queue-size", required_argument, nullptr, OPT_TB_QUEUE_SIZE},
1074  {"host-profiling", no_argument, nullptr, OPT_HOST_PROFILING},
1075  {"disable-bitvalue-ipa", no_argument, nullptr, OPT_DISABLE_BITVALUE_IPA},
1076  {"discrepancy", no_argument, nullptr, OPT_DISCREPANCY},
1077  {"discrepancy-force-uninitialized", no_argument, nullptr, OPT_DISCREPANCY_FORCE},
1078  {"discrepancy-hw", no_argument, nullptr, OPT_DISCREPANCY_HW},
1079  {"discrepancy-no-load-pointers", no_argument, nullptr, OPT_DISCREPANCY_NO_LOAD_POINTERS},
1080  {"discrepancy-only", required_argument, nullptr, OPT_DISCREPANCY_ONLY},
1081  {"discrepancy-permissive-ptrs", no_argument, nullptr, OPT_DISCREPANCY_PERMISSIVE_PTRS},
1082  {"range-analysis-mode", optional_argument, nullptr, OPT_RANGE_ANALYSIS_MODE},
1083  {"fp-format", optional_argument, nullptr, OPT_FP_FORMAT},
1084  {"fp-format-propagate", optional_argument, nullptr, OPT_FP_FORMAT_PROPAGATE},
1085  {"fp-format-interface", optional_argument, nullptr, OPT_FP_FORMAT_INTERFACE},
1086 #if HAVE_FROM_PRAGMA_BUILT
1087  {"num-accelerators", required_argument, nullptr, OPT_NUM_ACCELERATORS},
1088  {"context_switch", optional_argument, nullptr, OPT_INPUT_CONTEXT_SWITCH},
1089 #endif
1090  {"memory-banks-number", required_argument, nullptr, OPT_MEMORY_BANKS_NUMBER},
1091  {"AXI-burst-type", optional_argument, nullptr, OPT_AXI_BURST_TYPE},
1092  {"C-no-parse", required_argument, nullptr, INPUT_OPT_C_NO_PARSE},
1093  {"C-python-no-parse", required_argument, nullptr, INPUT_OPT_C_PYTHON_NO_PARSE},
1094  {"accept-nonzero-return", no_argument, nullptr, OPT_ACCEPT_NONZERO_RETURN},
1095 #if !HAVE_UNORDERED
1096 #ifndef NDEBUG
1097  {"test-multiple-non-deterministic-flows", required_argument, nullptr,
1099  {"test-single-non-deterministic-flow", required_argument, nullptr, INPUT_OPT_TEST_SINGLE_NON_DETERMINISTIC_FLOW},
1100 #endif
1101 #endif
1102  {"dry-run-evaluation", no_argument, nullptr, INPUT_OPT_DRY_RUN_EVALUATION},
1103  {"altera-root", optional_argument, nullptr, OPT_ALTERA_ROOT},
1104  {"lattice-root", optional_argument, nullptr, OPT_LATTICE_ROOT},
1105  {"mentor-root", optional_argument, nullptr, OPT_MENTOR_ROOT},
1106  {"mentor-optimizer", optional_argument, nullptr, OPT_MENTOR_OPTIMIZER},
1107  {"nanoxplore-root", optional_argument, nullptr, OPT_NANOXPLORE_ROOT},
1108  {"nanoxplore-bypass", optional_argument, nullptr, OPT_NANOXPLORE_BYPASS},
1109  {"xilinx-root", optional_argument, nullptr, OPT_XILINX_ROOT},
1110  {"verilator-parallel", optional_argument, nullptr, OPT_VERILATOR_PARALLEL},
1111  {"shared-input-registers", no_argument, nullptr, OPT_SHARED_INPUT_REGISTERS},
1112  {"inline-fname", required_argument, nullptr, OPT_INLINE_FUNCTIONS},
1114  {nullptr, 0, nullptr, 0}
1115  };
1116 
1117  if(argc == 1) // Bambu called without arguments, it simple prints help message
1118  {
1119  PrintUsage(std::cout);
1120  return EXIT_SUCCESS;
1121  }
1122 
1123  while(true)
1124  {
1125  int next_option = getopt_long(argc, argv, short_options, long_options, &option_index);
1126 
1127  // no more options are available
1128  if(next_option == -1)
1129  {
1130  break;
1131  }
1132 
1133  switch(next_option)
1134  {
1136  case OPT_TOP_FNAME:
1137  {
1138  const auto top_fname = string_to_container<std::vector<std::string>>(std::string(optarg), ",");
1139  setOption(OPT_top_functions_names, container_to_string(top_fname, STR_CST_string_separator));
1140  if(top_fname.size() == 1)
1141  {
1142  setOption(OPT_top_file, optarg);
1143  }
1144  break;
1145  }
1147  {
1148  setOption(OPT_top_design_name, optarg);
1149  break;
1150  }
1151  case 'o':
1152  setOption(OPT_output_file, GetPath(optarg));
1153  break;
1154  case 'S':
1155  {
1156  setOption(OPT_serialize_output, true);
1157  break;
1158  }
1159  case 't':
1160  {
1161  setOption(OPT_ilp_max_time, optarg);
1162  break;
1163  }
1165  {
1166  const auto in_files = string_to_container<std::vector<std::string>>(optarg, ",");
1167  for(const auto& in_file : in_files)
1168  {
1169  std::filesystem::path file_path(GetPath(in_file));
1170  std::filesystem::path local_file(GetPath(file_path.filename().string()));
1171  if(!std::filesystem::exists(local_file))
1172  {
1173  std::filesystem::create_symlink(file_path.lexically_normal(), local_file);
1174  }
1175  }
1176  break;
1177  }
1178  case OPT_LIST_BASED: // enable list based scheduling
1179  {
1180  if(scheduling_set_p)
1181  {
1182  THROW_ERROR("BadParameters: only one scheduler can be specified");
1183  }
1184  scheduling_set_p = true;
1185  setOption(OPT_scheduling_algorithm, HLSFlowStep_Type::LIST_BASED_SCHEDULING);
1186  if(optarg)
1187  {
1188  setOption(OPT_scheduling_priority, optarg);
1189  }
1190  break;
1191  }
1192  case OPT_STG:
1193  {
1194  setOption(OPT_stg, true);
1195  if(optarg)
1196  {
1197  setOption(OPT_stg_algorithm, optarg);
1198  }
1199  break;
1200  }
1202  // register
1203  case OPT_REGISTER_ALLOCATION: // enable register allocation
1204  {
1205  if(std::string(optarg) == "COLORING")
1206  {
1207  setOption(OPT_register_allocation_algorithm, HLSFlowStep_Type::COLORING_REGISTER_BINDING);
1208  }
1209  else if(std::string(optarg) == "CHORDAL_COLORING")
1210  {
1211  setOption(OPT_register_allocation_algorithm, HLSFlowStep_Type::CHORDAL_COLORING_REGISTER_BINDING);
1212  }
1213  else if(std::string(optarg) == "WEIGHTED_COLORING")
1214  {
1215  setOption(OPT_register_allocation_algorithm, HLSFlowStep_Type::WEIGHTED_CLIQUE_REGISTER_BINDING);
1216  setOption(OPT_weighted_clique_register_algorithm, CliqueCovering_Algorithm::WEIGHTED_COLORING);
1217  }
1218  else if(std::string(optarg) == "BIPARTITE_MATCHING")
1219  {
1220  setOption(OPT_register_allocation_algorithm, HLSFlowStep_Type::WEIGHTED_CLIQUE_REGISTER_BINDING);
1221  setOption(OPT_weighted_clique_register_algorithm, CliqueCovering_Algorithm::BIPARTITE_MATCHING);
1222  }
1223  else if(std::string(optarg) == "TTT_CLIQUE_COVERING")
1224  {
1225  setOption(OPT_register_allocation_algorithm, HLSFlowStep_Type::WEIGHTED_CLIQUE_REGISTER_BINDING);
1226  setOption(OPT_weighted_clique_register_algorithm, CliqueCovering_Algorithm::TTT_CLIQUE_COVERING);
1227  }
1228  else if(std::string(optarg) == "WEIGHTED_TS")
1229  {
1230  setOption(OPT_register_allocation_algorithm, HLSFlowStep_Type::WEIGHTED_CLIQUE_REGISTER_BINDING);
1231  setOption(OPT_weighted_clique_register_algorithm, CliqueCovering_Algorithm::TS_WEIGHTED_CLIQUE_COVERING);
1232  }
1233  else if(std::string(optarg) == "UNIQUE_BINDING")
1234  {
1235  setOption(OPT_register_allocation_algorithm, HLSFlowStep_Type::UNIQUE_REGISTER_BINDING);
1236  }
1237  else
1238  {
1239  THROW_ERROR("BadParameters: register allocation not correctly specified");
1240  }
1241  break;
1242  }
1243  case OPT_TIMING_VIOLATION:
1244  {
1245  setOption(OPT_timing_violation_abort, true);
1246  break;
1247  }
1248  // parameter based function constraints
1249  case 'C':
1250  {
1251  if(optarg)
1252  {
1253  setOption(OPT_constraints_functions, optarg);
1254  }
1255  else
1256  {
1257  THROW_ERROR("BadParameters: -C option not correctly specified");
1258  }
1259  break;
1260  }
1262  case 'b':
1263  {
1264  setOption(OPT_target_device_file, optarg);
1265  break;
1266  }
1268  case OPT_EVALUATION:
1269  {
1270  // set OPT_evaluation, because the evaluation has to be performed
1271  setOption(OPT_evaluation, true);
1272  /*
1273  * check if OPT_evaluation_mode has already been decided (for
1274  * example with OPT_EVALUATION_MODE). In case it's already set, we
1275  * don't overwrite it since OPT_EVALUATION is meant to set the
1276  * objectives, not the mode, hence the mode set from other options
1277  * has precedence
1278  */
1279  if(getOption<Evaluation_Mode>(OPT_evaluation_mode) == Evaluation_Mode::NONE)
1280  {
1281  setOption(OPT_evaluation_mode, Evaluation_Mode::EXACT);
1282  }
1283  auto objective_string = getOption<std::string>(OPT_evaluation_objectives);
1284  const auto objective_vector = string_to_container<std::vector<std::string>>(objective_string, ",");
1285  objective_string = "";
1286  for(const auto& objective : objective_vector)
1287  {
1288  if(objective == "CYCLES")
1289  {
1290  objective_string += ",CYCLES";
1291  }
1292  else if(objective == "TOTAL_CYCLES")
1293  {
1294  objective_string += ",TOTAL_CYCLES";
1295  }
1296  }
1297  if(optarg == nullptr)
1298  {
1299  if(getOption<Evaluation_Mode>(OPT_evaluation_mode) == Evaluation_Mode::EXACT)
1300  {
1301  std::string to_add =
1302 #if HAVE_LIBRARY_CHARACTERIZATION_BUILT
1303  "AREAxTIME,"
1304  "AREA,"
1305  "REGISTERS,"
1306  "DSPS,"
1307  "BRAMS,"
1308  "DRAMS,"
1309  "PERIOD,"
1310  "CLOCK_SLACK,"
1311  "FREQUENCY,"
1312  "TIME,"
1313  "TOTAL_TIME,"
1314  "CYCLES,"
1315  "TOTAL_CYCLES"
1316 #else
1317  "CYCLES"
1318 #endif
1319  ;
1320  add_evaluation_objective_string(objective_string, to_add);
1321  }
1322  else
1323  {
1324  THROW_ERROR("BadParameters: invalid evaluation mode");
1325  }
1326  }
1327  else
1328  {
1329  add_evaluation_objective_string(objective_string, std::string(optarg));
1330  }
1331  setOption(OPT_evaluation_objectives, objective_string);
1332  break;
1333  }
1334  case OPT_SIMULATE:
1335  {
1336  /*
1337  * OPT_SIMULATE is a shorthand form OPT_EVALUATION with optarg =
1338  * CYCLES,TOTAL_CYCLES
1339  */
1340  // set OPT_evaluation, because the evaluation has to be performed
1341  setOption(OPT_evaluation, true);
1342  /*
1343  * check if OPT_evaluation_mode has already been decided (for
1344  * example with OPT_EVALUATION_MODE). in cas it's already set, we
1345  * don't overwrite it since OPT_SIMULATION is meant to set the
1346  * objectives, not the mode, hence the mode set from other options
1347  * has precedence
1348  */
1349  if(getOption<Evaluation_Mode>(OPT_evaluation_mode) == Evaluation_Mode::NONE)
1350  {
1351  setOption(OPT_evaluation_mode, Evaluation_Mode::EXACT);
1352  }
1353  else
1354  {
1355  THROW_ERROR("Simulation is only supported with EXACT evaluation mode");
1356  }
1357  auto objective_string = getOption<std::string>(OPT_evaluation_objectives);
1358  const auto objective_vector = string_to_container<std::vector<std::string>>(objective_string, ",");
1359  /*
1360  * look among the objectives of the evaluation. if "CYCLES" is
1361  * already there, the simulation will be executed.
1362  * if it's not, it's enough to add it to enable simulation
1363  */
1364  if(objective_string.empty())
1365  {
1366  objective_string = "CYCLES";
1367  }
1368  else if(std::find(objective_vector.begin(), objective_vector.end(), "CYCLES") == objective_vector.end())
1369  {
1370  objective_string = objective_string + ",CYCLES";
1371  }
1372  setOption(OPT_evaluation_objectives, objective_string);
1373  break;
1374  }
1375  case OPT_DEVICE_NAME:
1376  {
1377  auto values = string_to_container<std::vector<std::string>>(optarg, ",");
1378  setOption("device_name", "");
1379  setOption("device_speed", "");
1380  setOption("device_package", "");
1381  setOption("device_synthesis_tool", "");
1382  if(values.size() == 1)
1383  {
1384  setOption(OPT_device_string, values[0]);
1385  }
1386  else if(values.size() == 3)
1387  {
1388  setOption("device_name", values[0]);
1389  setOption("device_speed", values[1]);
1390  setOption("device_package", values[2]);
1391  }
1392  else if(values.size() == 4)
1393  {
1394  setOption("device_name", values[0]);
1395  setOption("device_speed", values[1]);
1396  setOption("device_package", values[2]);
1397  setOption("device_synthesis_tool", values[3]);
1398  }
1399  else
1400  {
1401  THROW_ERROR("Malformed device: " + std::string(optarg));
1402  }
1403  break;
1404  }
1405  case OPT_PERIOD_CLOCK:
1406  {
1407  setOption(OPT_clock_period, optarg);
1408  break;
1409  }
1410  case OPT_CLOCK_NAME:
1411  {
1412  setOption(OPT_clock_name, optarg);
1413  break;
1414  }
1415  case OPT_RESET_NAME:
1416  {
1417  setOption(OPT_reset_name, optarg);
1418  break;
1419  }
1420  case OPT_START_NAME:
1421  {
1422  setOption(OPT_start_name, optarg);
1423  break;
1424  }
1425  case OPT_DONE_NAME:
1426  {
1427  setOption(OPT_done_name, optarg);
1428  break;
1429  }
1431  {
1432  setOption("power_optimization", true);
1433  break;
1434  }
1435  case OPT_CONNECT_IOB:
1436  {
1437  setOption(OPT_connect_iob, true);
1438  THROW_WARNING("Input and output ports will be connected to I/O buffers in the generated design.");
1439  break;
1440  }
1441  case OPT_RESET_TYPE:
1442  {
1443  if(std::string(optarg) == "no")
1444  {
1445  setOption(OPT_reset_type, std::string(optarg));
1446  }
1447  else if(std::string(optarg) == "async")
1448  {
1449  setOption(OPT_reset_type, std::string(optarg));
1450  }
1451  else if(std::string(optarg) == "sync")
1452  {
1453  setOption(OPT_reset_type, std::string(optarg));
1454  }
1455  else
1456  {
1457  throw "BadParameters: reset type not correctly specified";
1458  }
1459  break;
1460  }
1461  case OPT_RESET_LEVEL:
1462  {
1463  if(std::string(optarg) == "high")
1464  {
1465  setOption(OPT_reset_level, true);
1466  }
1467  else if(std::string(optarg) == "low")
1468  {
1469  setOption(OPT_reset_level, false);
1470  }
1471  else
1472  {
1473  throw "BadParameters: reset edge type not correctly specified";
1474  }
1475  break;
1476  }
1478  {
1479  setOption(OPT_reg_init_value, false);
1480  break;
1481  }
1482 #if HAVE_ILP_BUILT
1483  case 's':
1484  {
1485  if(scheduling_set_p &&
1486  getOption<HLSFlowStep_Type>(OPT_scheduling_algorithm) != HLSFlowStep_Type::SDC_SCHEDULING)
1487  {
1488  THROW_ERROR("BadParameters: only one scheduler can be specified");
1489  }
1490  scheduling_set_p = true;
1491  setOption(OPT_scheduling_algorithm, HLSFlowStep_Type::SDC_SCHEDULING);
1492  std::string defines;
1493  if(isOption(OPT_gcc_defines))
1494  {
1495  defines = getOption<std::string>(OPT_gcc_defines) + STR_CST_string_separator;
1496  }
1497  defines += std::string("PANDA_SDC");
1498  setOption(OPT_gcc_defines, defines);
1499  break;
1500  }
1501 #endif
1502  case 'p':
1503  {
1504  setOption(OPT_pipelining, "@ll");
1505  if(optarg)
1506  {
1507  setOption(OPT_pipelining, optarg);
1508  }
1509  break;
1510  }
1512  {
1513  setOption(OPT_gcc_serialize_memory_accesses, true);
1514  break;
1515  }
1516  case OPT_SOFT_FLOAT:
1517  {
1518  setOption(OPT_soft_float, true);
1519  break;
1520  }
1521 #if HAVE_FLOPOCO
1522  case OPT_FLOPOCO:
1523  {
1524  setOption(OPT_soft_float, false);
1525  break;
1526  }
1527 #endif
1528  case OPT_FP_SUB:
1529  {
1530  setOption(OPT_fp_subnormal, true);
1531  break;
1532  }
1533  case OPT_FP_RND:
1534  {
1535  setOption(OPT_fp_rounding_mode, std::string(optarg));
1536  break;
1537  }
1538  case OPT_FP_EXC:
1539  {
1540  setOption(OPT_fp_exception_mode, std::string(optarg));
1541  break;
1542  }
1543  case OPT_LIBM_STD_ROUNDING:
1544  {
1545  setOption(OPT_libm_std_rounding, true);
1546  break;
1547  }
1548  case OPT_SOFT_FP:
1549  {
1550  setOption(OPT_soft_fp, true);
1551  setOption(OPT_hls_fpdiv, "SF");
1552  break;
1553  }
1554  case OPT_HLS_DIV:
1555  {
1556  if(optarg && std::string(optarg) == "nr1")
1557  {
1558  setOption(OPT_hls_div, optarg);
1559  }
1560  else if(optarg && std::string(optarg) == "nr2")
1561  {
1562  setOption(OPT_hls_div, optarg);
1563  }
1564  else if(optarg && std::string(optarg) == "as")
1565  {
1566  setOption(OPT_hls_div, optarg);
1567  }
1568  else if(optarg && std::string(optarg) == "none")
1569  {
1570  setOption(OPT_hls_div, optarg);
1571  }
1572  else if(optarg && std::string(optarg) == "NR")
1573  {
1574  setOption(OPT_hls_div, optarg);
1575  }
1576  else
1577  {
1578  THROW_ERROR("BadParameters: unknown HLS division algorithm");
1579  }
1580  break;
1581  }
1582  case OPT_HLS_FPDIV:
1583  {
1584  setOption(OPT_hls_fpdiv, "SRT4");
1585  if(optarg && (std::string(optarg) == "G" || std::string(optarg) == "SF"))
1586  {
1587  setOption(OPT_hls_fpdiv, optarg);
1588  }
1589  break;
1590  }
1592  {
1593  setOption(OPT_clock_period_resource_fraction, optarg);
1594  break;
1595  }
1597  {
1598  setOption(OPT_scheduling_mux_margins, optarg);
1599  break;
1600  }
1601  case OPT_USE_ALUS:
1602  {
1603  setOption(OPT_use_ALUs, true);
1604  break;
1605  }
1606  case OPT_TIMING_MODEL:
1607  {
1608  if(std::string(optarg) == "SIMPLE")
1609  {
1610  setOption(OPT_estimate_logic_and_connections, false);
1611  }
1612  else if(std::string(optarg) == "EC")
1613  {
1614  setOption(OPT_estimate_logic_and_connections, true);
1615  }
1616  else
1617  {
1618  throw "BadParameters: unknown timing model";
1619  }
1620  break;
1621  }
1622  case OPT_REGISTERED_INPUTS:
1623  {
1624  setOption(OPT_registered_inputs, optarg);
1625  break;
1626  }
1627  case OPT_FSM_ENCODING:
1628  {
1629  setOption(OPT_fsm_encoding, optarg);
1630  break;
1631  }
1632  case OPT_MAX_ULP:
1633  {
1634  if(std::regex_search(std::string(optarg), std::regex("^\\d+(\\.\\d+)?$")))
1635  {
1636  setOption(OPT_max_ulp, optarg);
1637  }
1638  else
1639  {
1640  THROW_ERROR("BadParameters: max ulp value must be a number.");
1641  }
1642  break;
1643  }
1645  {
1646  setOption(OPT_skip_pipe_parameter, optarg);
1647  break;
1648  }
1650  {
1651  setOption(OPT_unaligned_access, true);
1652  break;
1653  }
1655  {
1656  setOption(OPT_aligned_access, true);
1657  break;
1658  }
1660  {
1661  setOption(OPT_backend_script_extensions, optarg);
1662  break;
1663  }
1665  {
1666  setOption(OPT_backend_sdc_extensions, optarg);
1667  break;
1668  }
1669  case OPT_PARALLEL_BACKEND:
1670  {
1671  setOption(OPT_parallel_backend, true);
1672  break;
1673  }
1675  {
1676  setOption(OPT_VHDL_library, optarg);
1677  break;
1678  }
1680  {
1681  setOption(OPT_use_asynchronous_memories, false);
1682  break;
1683  }
1684  case OPT_DISTRAM_THRESHOLD:
1685  {
1686  setOption(OPT_distram_threshold, optarg);
1687  break;
1688  }
1690  {
1691  setOption(OPT_do_not_chain_memories, true);
1692  break;
1693  }
1694  case OPT_ROM_DUPLICATION:
1695  {
1696  setOption(OPT_rom_duplication, true);
1697  break;
1698  }
1699  case OPT_BRAM_HIGH_LATENCY:
1700  {
1701  setOption(OPT_bram_high_latency, "_3");
1702  if(optarg && std::string(optarg) == "4")
1703  {
1704  setOption(OPT_bram_high_latency, "_4");
1705  }
1706  break;
1707  }
1708  case OPT_EXPOSE_GLOBALS:
1709  {
1710  setOption(OPT_expose_globals, true);
1711  break;
1712  }
1714  {
1715  setOption(OPT_experimental_setup, optarg);
1716  break;
1717  }
1719  {
1720  setOption(OPT_DSP_allocation_coefficient, optarg);
1721  break;
1722  }
1724  {
1725  setOption(OPT_DSP_margin_combinational, optarg);
1726  break;
1727  }
1729  {
1730  setOption(OPT_DSP_margin_pipelined, optarg);
1731  break;
1732  }
1733  case OPT_DSP_FRACTURING:
1734  {
1735  setOption(OPT_DSP_fracturing, 16);
1736  if(optarg && std::string(optarg) == "32")
1737  {
1738  setOption(OPT_DSP_fracturing, "32");
1739  }
1740  break;
1741  }
1743  case 'w':
1744  {
1745  if(std::string(optarg) == "V")
1746  {
1747  setOption(OPT_writer_language, static_cast<int>(HDLWriter_Language::VERILOG));
1748  }
1749  else if(std::string(optarg) == "H")
1750  {
1751  setOption(OPT_writer_language, static_cast<int>(HDLWriter_Language::VHDL));
1752  }
1753  else
1754  {
1755  throw "BadParameters: backend language not correctly specified";
1756  }
1757  break;
1758  }
1759  case OPT_PRETTY_PRINT:
1760  {
1761  std::filesystem::path pp_src(GetPath(optarg));
1762  if(!pp_src.has_extension())
1763  {
1764  pp_src.append(".c");
1765  }
1766  if(pp_src.extension() != ".c")
1767  {
1768  throw "BadParameters: pretty print output file must have .c extension";
1769  }
1770  setOption(OPT_pretty_print, pp_src.string());
1771  break;
1772  }
1773  case OPT_PRAGMA_PARSE:
1774  {
1775  setOption(OPT_parse_pragma, true);
1776  break;
1777  }
1778  case OPT_TESTBENCH:
1779  {
1780  setOption(OPT_generate_testbench, true);
1781  auto arg = TrimSpaces(std::string(optarg));
1782  std::error_code ec;
1783  if(starts_with(arg, "elf:"))
1784  {
1785  arg = arg.substr(4);
1786  if(std::filesystem::exists(GetPath(arg), ec))
1787  {
1788  setOption(OPT_testbench_input_file, "elf:" + GetPath(arg));
1789  }
1790  else
1791  {
1792  THROW_ERROR("BadParameters: testbench executable does not exist.");
1793  }
1794  }
1795  else if(std::filesystem::exists(GetPath(arg), ec))
1796  {
1797  std::string prev;
1798  if(isOption(OPT_testbench_input_file))
1799  {
1800  prev = getOption<std::string>(OPT_testbench_input_file) + STR_CST_string_separator;
1801  }
1802  setOption(OPT_testbench_input_file, prev + GetPath(arg));
1803  }
1804  else
1805  {
1806  std::string prev;
1807  if(isOption(OPT_testbench_input_string))
1808  {
1809  prev = getOption<std::string>(OPT_testbench_input_string) + STR_CST_string_separator;
1810  }
1811  setOption(OPT_testbench_input_string, prev + arg);
1812  }
1813  break;
1814  }
1815  case OPT_TESTBENCH_ARGV:
1816  {
1817  std::string cosim_argv;
1818  if(isOption(OPT_testbench_argv))
1819  {
1820  cosim_argv = getOption<std::string>(OPT_testbench_argv) + " ";
1821  }
1822  setOption(OPT_testbench_argv, cosim_argv + std::string(optarg));
1823  break;
1824  }
1826  {
1827  std::string param_size(optarg);
1828  if(!std::regex_match(param_size, std::regex("^([\\w\\d]+:\\d+)(,[\\w\\d]+:\\d+)*$")))
1829  {
1830  THROW_ERROR("BadParameters: testbench top-level parameter size format not valid");
1831  }
1832  boost::replace_all(param_size, ",", STR_CST_string_separator);
1833  if(isOption(OPT_testbench_param_size))
1834  {
1835  param_size = getOption<std::string>(OPT_testbench_param_size) + STR_CST_string_separator + param_size;
1836  }
1837  setOption(OPT_testbench_param_size, param_size);
1838  break;
1839  }
1841  {
1842  std::string map_mode(optarg);
1843  if(map_mode != "DEVICE" && map_mode != "SHARED")
1844  {
1845  THROW_ERROR("BadParameters: testbench memory mapping mode not valid");
1846  }
1847  setOption(OPT_testbench_map_mode, map_mode);
1848  break;
1849  }
1851  {
1852  std::string tb_extra_gcc_options;
1853  if(isOption(OPT_tb_extra_gcc_options))
1854  {
1855  tb_extra_gcc_options = getOption<std::string>(OPT_tb_extra_gcc_options) + " ";
1856  }
1857  setOption(OPT_tb_extra_gcc_options, tb_extra_gcc_options + std::string(optarg));
1858  break;
1859  }
1860  case OPT_MAX_SIM_CYCLES:
1861  {
1862  setOption(OPT_max_sim_cycles, optarg);
1863  break;
1864  }
1865  case OPT_GENERATE_VCD:
1866  {
1867  setOption(OPT_generate_vcd, true);
1868  break;
1869  }
1870  case OPT_ADDITIONAL_TOP:
1871  {
1872  setOption(OPT_additional_top, optarg);
1873  break;
1874  }
1876  {
1877  setOption(OPT_disable_function_proxy, false);
1878  break;
1879  }
1881  {
1882  setOption(OPT_disable_function_proxy, true);
1883  break;
1884  }
1886  {
1887  setOption(OPT_disable_bounded_function, true);
1888  break;
1889  }
1890  case OPT_MEMORY_MAPPED_TOP:
1891  {
1892  setOption(OPT_memory_mapped_top, true);
1893  break;
1894  }
1895  case OPT_MEM_DELAY_READ:
1896  {
1897  setOption(OPT_mem_delay_read, optarg);
1898  break;
1899  }
1900  case OPT_MEM_DELAY_WRITE:
1901  {
1902  setOption(OPT_mem_delay_write, optarg);
1903  break;
1904  }
1905  case OPT_TB_QUEUE_SIZE:
1906  {
1907  setOption(OPT_tb_queue_size, optarg);
1908  break;
1909  }
1910 #if HAVE_HOST_PROFILING_BUILT
1911  case OPT_HOST_PROFILING:
1912  {
1913  setOption(OPT_profiling_method, static_cast<int>(HostProfiling_Method::PM_BBP));
1914  break;
1915  }
1916 #endif
1917  case OPT_NO_MIXED_DESIGN:
1918  {
1919  setOption<bool>(OPT_mixed_design, false);
1920  break;
1921  }
1923  {
1924  setOption(OPT_bitvalue_ipa, false);
1925  break;
1926  }
1927  case OPT_DISCREPANCY:
1928  {
1929  setOption(OPT_discrepancy, true);
1930  break;
1931  }
1933  {
1934  setOption(OPT_discrepancy, true);
1935  setOption(OPT_discrepancy_no_load_pointers, true);
1936  break;
1937  }
1938  case OPT_DISCREPANCY_FORCE:
1939  {
1940  setOption(OPT_discrepancy, true);
1941  setOption(OPT_discrepancy_force, true);
1942  break;
1943  }
1944  case OPT_DISCREPANCY_HW:
1945  {
1946  setOption(OPT_discrepancy_hw, true);
1947  break;
1948  }
1949  case OPT_DISCREPANCY_ONLY:
1950  {
1951  setOption(OPT_discrepancy, true);
1952  std::vector<std::string> splitted = SplitString(optarg, " ,");
1953  std::string discrepancy_functions;
1954  for(auto& f : splitted)
1955  {
1956  boost::trim(f);
1957  discrepancy_functions += f + STR_CST_string_separator;
1958  }
1959  setOption(OPT_discrepancy_only, discrepancy_functions);
1960  break;
1961  }
1963  {
1964  setOption(OPT_discrepancy, true);
1965  setOption(OPT_discrepancy_permissive_ptrs, true);
1966  break;
1967  }
1969  {
1970  setOption(OPT_range_analysis_mode, optarg);
1971  break;
1972  }
1973  case OPT_FP_FORMAT:
1974  {
1975  setOption(OPT_fp_format, optarg);
1976  break;
1977  }
1979  {
1980  setOption(OPT_fp_format_propagate, true);
1981  break;
1982  }
1984  {
1985  setOption(OPT_fp_format_interface, true);
1986  break;
1987  }
1988 #if HAVE_FROM_PRAGMA_BUILT
1989  case OPT_NUM_ACCELERATORS:
1990  {
1991  auto num_acc = std::stoull(std::string(optarg));
1992  if((num_acc != 0) && ((num_acc & (num_acc - 1)) == 0))
1993  {
1994  setOption(OPT_num_accelerators, std::string(optarg));
1995  }
1996  else
1997  {
1998  THROW_ERROR("Currently the number of physical accelerator has to be a power of two");
1999  };
2000  break;
2001  }
2003  {
2004  if(optarg)
2005  {
2006  const auto num = std::stoull(std::string(optarg));
2007  if(!num)
2008  {
2009  throw "Bad parameters: number of contexts must be a positive integer.";
2010  }
2011  setOption(OPT_context_switch, std::string(optarg));
2012  break;
2013  }
2014  else
2015  {
2016  setOption(OPT_context_switch, "4");
2017  break;
2018  }
2019  }
2020 #endif
2022  {
2023  setOption(OPT_memory_banks_number, std::string(optarg));
2024  break;
2025  }
2026  case OPT_AXI_BURST_TYPE:
2027  {
2028  std::string burst_type(optarg);
2029  if(burst_type == "FIXED")
2030  {
2031  setOption(OPT_axi_burst_type, 0);
2032  }
2033  else if(burst_type == "INCREMENTAL")
2034  {
2035  setOption(OPT_axi_burst_type, 1);
2036  }
2037  else
2038  {
2039  THROW_ERROR("AXI burst type not recognized: currently only FIXED and INCREMENTAL mode are supported");
2040  };
2041  break;
2042  }
2044  {
2045  setOption(OPT_no_return_zero, true);
2046  break;
2047  }
2048  case INPUT_OPT_C_NO_PARSE:
2049  {
2050  std::string no_parse;
2051  if(isOption(OPT_no_parse_files))
2052  {
2053  no_parse += getOption<std::string>(OPT_no_parse_files) + STR_CST_string_separator;
2054  }
2055  auto paths = SplitString(optarg, ",");
2056  for(auto& path : paths)
2057  {
2058  path = GetPath(path);
2059  }
2060  setOption(OPT_no_parse_files, no_parse + container_to_string(paths, STR_CST_string_separator));
2061  break;
2062  }
2064  {
2065  std::vector<std::string> Splitted = SplitString(optarg, " ,");
2066  std::string no_parse_c_python_files;
2067  for(auto& i : Splitted)
2068  {
2069  boost::trim(i);
2070  no_parse_c_python_files += GetPath(i) + " ";
2071  }
2072  setOption(OPT_no_parse_c_python, no_parse_c_python_files);
2073  break;
2074  }
2075 #if !HAVE_UNORDERED
2076 #ifndef NDEBUG
2078  {
2079  setOption(OPT_test_multiple_non_deterministic_flows, std::string(optarg));
2080  break;
2081  }
2083  {
2084  setOption(OPT_test_single_non_deterministic_flow, std::string(optarg));
2085  break;
2086  }
2087 #endif
2088 #endif
2090  {
2091  setOption(OPT_evaluation_mode, Evaluation_Mode::DRY_RUN);
2092  break;
2093  }
2094  case OPT_ARCHITECTURE_XML:
2095  {
2096  auto XMLfilename = GetPath(optarg);
2097  if(!std::filesystem::exists(std::filesystem::path(XMLfilename)))
2098  {
2099  THROW_ERROR("The file " + XMLfilename + " passed to --architecture-xml option does not exist");
2100  }
2101  setOption(OPT_architecture_xml, XMLfilename);
2102  break;
2103  }
2104  case OPT_ALTERA_ROOT:
2105  {
2106  setOption(OPT_altera_root, GetPath(optarg));
2107  break;
2108  }
2109  case OPT_LATTICE_ROOT:
2110  {
2111  setOption(OPT_lattice_root, GetPath(optarg));
2112  break;
2113  }
2114  case OPT_MENTOR_ROOT:
2115  {
2116  setOption(OPT_mentor_root, GetPath(optarg));
2117  break;
2118  }
2119  case OPT_MENTOR_OPTIMIZER:
2120  {
2121  setOption(OPT_mentor_optimizer, static_cast<bool>(std::stoi(optarg)));
2122  break;
2123  }
2124  case OPT_NANOXPLORE_ROOT:
2125  {
2126  setOption(OPT_nanoxplore_root, GetPath(optarg));
2127  break;
2128  }
2129  case OPT_NANOXPLORE_BYPASS:
2130  {
2131  setOption(OPT_nanoxplore_bypass, std::string(optarg));
2132  break;
2133  }
2135  {
2136  setOption(OPT_verilator_parallel, std::to_string(std::thread::hardware_concurrency()));
2137  if(optarg)
2138  {
2139  setOption(OPT_verilator_parallel, std::string(optarg));
2140  }
2141  break;
2142  }
2143  case OPT_XILINX_ROOT:
2144  {
2145  setOption(OPT_xilinx_root, GetPath(optarg));
2146  break;
2147  }
2149  {
2150  setOption(OPT_shared_input_registers, true);
2151  break;
2152  }
2153  case OPT_INLINE_FUNCTIONS:
2154  {
2155  setOption(OPT_inline_functions, std::string(optarg));
2156  break;
2157  }
2158  case 0:
2159  {
2160  if(strcmp(long_options[option_index].name, "module-binding") == 0)
2161  {
2162  if(std::string(optarg) == "TTT_FAST")
2163  {
2164  setOption(OPT_fu_binding_algorithm, HLSFlowStep_Type::CDFC_MODULE_BINDING);
2165  setOption(OPT_cdfc_module_binding_algorithm, CliqueCovering_Algorithm::TTT_CLIQUE_COVERING_FAST);
2166  }
2167  else if(std::string(optarg) == "TTT_FAST2")
2168  {
2169  setOption(OPT_fu_binding_algorithm, HLSFlowStep_Type::CDFC_MODULE_BINDING);
2170  setOption(OPT_cdfc_module_binding_algorithm, CliqueCovering_Algorithm::TTT_CLIQUE_COVERING_FAST2);
2171  }
2172  else if(std::string(optarg) == "TTT_FULL")
2173  {
2174  setOption(OPT_fu_binding_algorithm, HLSFlowStep_Type::CDFC_MODULE_BINDING);
2175  setOption(OPT_cdfc_module_binding_algorithm, CliqueCovering_Algorithm::TTT_CLIQUE_COVERING);
2176  }
2177  else if(std::string(optarg) == "TTT_FULL2")
2178  {
2179  setOption(OPT_fu_binding_algorithm, HLSFlowStep_Type::CDFC_MODULE_BINDING);
2180  setOption(OPT_cdfc_module_binding_algorithm, CliqueCovering_Algorithm::TTT_CLIQUE_COVERING2);
2181  }
2182  else if(std::string(optarg) == "TS")
2183  {
2184  setOption(OPT_fu_binding_algorithm, HLSFlowStep_Type::CDFC_MODULE_BINDING);
2185  setOption(OPT_cdfc_module_binding_algorithm, CliqueCovering_Algorithm::TS_CLIQUE_COVERING);
2186  }
2187  else if(std::string(optarg) == "WEIGHTED_TS")
2188  {
2189  setOption(OPT_fu_binding_algorithm, HLSFlowStep_Type::CDFC_MODULE_BINDING);
2190  setOption(OPT_cdfc_module_binding_algorithm, CliqueCovering_Algorithm::TS_WEIGHTED_CLIQUE_COVERING);
2191  }
2192  else if(std::string(optarg) == "COLORING")
2193  {
2194  setOption(OPT_fu_binding_algorithm, HLSFlowStep_Type::CDFC_MODULE_BINDING);
2195  setOption(OPT_cdfc_module_binding_algorithm, CliqueCovering_Algorithm::COLORING);
2196  }
2197  else if(std::string(optarg) == "WEIGHTED_COLORING")
2198  {
2199  setOption(OPT_fu_binding_algorithm, HLSFlowStep_Type::CDFC_MODULE_BINDING);
2200  setOption(OPT_cdfc_module_binding_algorithm, CliqueCovering_Algorithm::WEIGHTED_COLORING);
2201  }
2202  else if(std::string(optarg) == "BIPARTITE_MATCHING")
2203  {
2204  setOption(OPT_fu_binding_algorithm, HLSFlowStep_Type::CDFC_MODULE_BINDING);
2205  setOption(OPT_cdfc_module_binding_algorithm, CliqueCovering_Algorithm::BIPARTITE_MATCHING);
2206  }
2207  else if(std::string(optarg) == "UNIQUE")
2208  {
2209  setOption(OPT_fu_binding_algorithm, HLSFlowStep_Type::UNIQUE_MODULE_BINDING);
2210  }
2211  else
2212  {
2213  throw "BadParameters: module binding option not correctly specified";
2214  }
2215  break;
2216  }
2217  if(strcmp(long_options[option_index].name, "xml-memory-allocation") == 0)
2218  {
2219  setOption(OPT_xml_memory_allocation, GetPath(optarg));
2220  break;
2221  }
2222  if(strcmp(long_options[option_index].name, "memory-allocation-policy") == 0)
2223  {
2224  if(std::string(optarg) == "LSS")
2225  {
2226  setOption(OPT_memory_allocation_policy, MemoryAllocation_Policy::LSS);
2227  }
2228  else if(std::string(optarg) == "GSS")
2229  {
2230  setOption(OPT_memory_allocation_policy, MemoryAllocation_Policy::GSS);
2231  }
2232  else if(std::string(optarg) == "ALL_BRAM")
2233  {
2234  setOption(OPT_memory_allocation_policy, MemoryAllocation_Policy::ALL_BRAM);
2235  }
2236  else if(std::string(optarg) == "NO_BRAM")
2237  {
2238  setOption(OPT_memory_allocation_policy, MemoryAllocation_Policy::NO_BRAM);
2239  }
2240  else if(std::string(optarg) == "EXT_PIPELINED_BRAM")
2241  {
2242  setOption(OPT_memory_allocation_policy, MemoryAllocation_Policy::EXT_PIPELINED_BRAM);
2243  }
2244  else
2245  {
2246  throw "BadParameters: memory allocation policy option not correctly specified";
2247  }
2248  break;
2249  }
2250  if(strcmp(long_options[option_index].name, "base-address") == 0)
2251  {
2252  setOption(OPT_base_address, optarg);
2253  break;
2254  }
2255  if(strcmp(long_options[option_index].name, "initial-internal-address") == 0)
2256  {
2257  setOption(OPT_initial_internal_address, optarg);
2258  break;
2259  }
2260  if(strcmp(long_options[option_index].name, "channels-type") == 0)
2261  {
2262  if(std::string(optarg) == CHANNELS_TYPE_MEM_ACC_11)
2263  {
2265  if(!isOption(OPT_channels_number))
2266  {
2267  setOption(OPT_channels_number, 1);
2268  }
2269  }
2270  else if(std::string(optarg) == CHANNELS_TYPE_MEM_ACC_N1)
2271  {
2273  }
2274  else if(std::string(optarg) == CHANNELS_TYPE_MEM_ACC_NN)
2275  {
2277  }
2278  else
2279  {
2280  throw "BadParameters: memory accesses type not correctly specified";
2281  }
2282  break;
2283  }
2284  if(strcmp(long_options[option_index].name, "channels-number") == 0)
2285  {
2286  setOption(OPT_channels_number, optarg);
2287  if(std::string(optarg) == "1" && !isOption(OPT_channels_type))
2288  {
2290  }
2291  break;
2292  }
2293  if(strcmp(long_options[option_index].name, "memory-ctrl-type") == 0)
2294  {
2295  if(std::string(optarg) == "D00")
2296  {
2297  setOption(OPT_memory_controller_type, optarg);
2298  }
2299  else if(std::string(optarg) == "D10")
2300  {
2301  setOption(OPT_memory_controller_type, optarg);
2302  }
2303  else if(std::string(optarg) == "D11")
2304  {
2305  setOption(OPT_memory_controller_type, optarg);
2306  }
2307  else if(std::string(optarg) == "D21")
2308  {
2309  setOption(OPT_memory_controller_type, optarg);
2310  }
2311  else
2312  {
2313  throw "BadParameters: memory controller type not correctly specified";
2314  }
2315  break;
2316  }
2317  if(strcmp(long_options[option_index].name, "sparse-memory") == 0)
2318  {
2319  if(!optarg || std::string(optarg) == "on")
2320  {
2321  setOption(OPT_sparse_memory, true);
2322  }
2323  else if(std::string(optarg) == "off")
2324  {
2325  setOption(OPT_sparse_memory, false);
2326  }
2327  else
2328  {
2329  throw "BadParameters: sparse-memory option not expected";
2330  }
2331  break;
2332  }
2333  if(strcmp(long_options[option_index].name, "assert-debug") == 0)
2334  {
2335  setOption(OPT_assert_debug, true);
2336  break;
2337  }
2339  if(strcmp(long_options[option_index].name, "no-chaining") == 0)
2340  {
2341  setOption(OPT_chaining, false);
2342  break;
2343  }
2344  if(strcmp(long_options[option_index].name, "generate-interface") == 0)
2345  {
2346  setOption(OPT_interface, true);
2347  if(std::string(optarg) == "MINIMAL")
2348  {
2350  }
2351  else if(std::string(optarg) == "INFER")
2352  {
2354  }
2355  else if(std::string(optarg) == "WB4")
2356  {
2358  setOption(OPT_memory_mapped_top, true);
2359  setOption(OPT_memory_allocation_policy, MemoryAllocation_Policy::NO_BRAM);
2360  setOption(OPT_channels_number, 1);
2362  }
2363  else
2364  {
2365  THROW_ERROR("Not supported interface: |" + std::string(optarg) + "|");
2366  }
2367  break;
2368  }
2369  if(strcmp(long_options[option_index].name, "data-bus-bitsize") == 0)
2370  {
2371  setOption(OPT_data_bus_bitsize, std::stoi(optarg));
2372  break;
2373  }
2374  if(strcmp(long_options[option_index].name, "addr-bus-bitsize") == 0)
2375  {
2376  setOption(OPT_addr_bus_bitsize, std::stoi(optarg));
2377  break;
2378  }
2379  if(strcmp(long_options[option_index].name, "simulator") == 0)
2380  {
2381  setOption(OPT_simulator, std::string(optarg));
2382  break;
2383  }
2384 #if(__GNUC__ >= 7)
2385  [[gnu::fallthrough]];
2386 #endif
2387  }
2389  default:
2390  {
2391  bool exit_success = false;
2392  bool res = ManageGccOptions(next_option, optarg);
2393  if(res)
2394  {
2395  res = ManageDefaultOptions(next_option, optarg, exit_success);
2396  }
2397  if(exit_success)
2398  {
2399  return EXIT_SUCCESS;
2400  }
2401  if(res)
2402  {
2403  return PARAMETER_NOTPARSED;
2404  }
2405  }
2406  }
2407  }
2408 
2409 #if HAVE_EXPERIMENTAL
2410  if(isOption(OPT_gcc_write_xml))
2411  {
2412  const std::string filenameXML = getOption<std::string>(OPT_gcc_write_xml);
2413  write_xml_configuration_file(GetPath(filenameXML));
2414  PRINT_MSG("Configuration saved into file \"" + filenameXML + "\"");
2415  return EXIT_SUCCESS;
2416  }
2417 #endif
2418 
2419  std::string cat_args;
2420 
2421  for(int i = 0; i < argc; i++)
2422  {
2423  cat_args += std::string(argv[i]) + " ";
2424  }
2425  setOption(OPT_cat_args, cat_args);
2426 
2427  INDENT_OUT_MEX(OUTPUT_LEVEL_MINIMUM, getOption<int>(OPT_output_level),
2428  " == Bambu executed with: " + cat_args + "\n");
2429 
2430  while(optind < argc)
2431  {
2432  const auto filename = GetPath(argv[optind]);
2433  const auto file_type = GetFileFormat(filename, true);
2434  if(file_type == Parameters_FileFormat::FF_XML_CON)
2435  {
2436  setOption(OPT_constraints_file, filename);
2437  }
2438  else if(file_type == Parameters_FileFormat::FF_XML_TEC)
2439  {
2440  const auto tech_files = isOption(OPT_technology_file) ?
2441  getOption<std::string>(OPT_technology_file) + STR_CST_string_separator :
2442  "";
2443  setOption(OPT_technology_file, tech_files + argv[optind]);
2444  }
2445 #if HAVE_FROM_AADL_ASN_BUILT
2446  else if(file_type == Parameters_FileFormat::FF_AADL)
2447  {
2448  const auto input_file =
2449  isOption(OPT_input_file) ? getOption<std::string>(OPT_input_file) + STR_CST_string_separator : "";
2450  setOption(OPT_input_file, input_file + filename);
2451  setOption(OPT_input_format, static_cast<int>(Parameters_FileFormat::FF_AADL));
2452  }
2453 #endif
2454  else if(file_type == Parameters_FileFormat::FF_C || file_type == Parameters_FileFormat::FF_OBJECTIVEC ||
2455  file_type == Parameters_FileFormat::FF_CPP || file_type == Parameters_FileFormat::FF_FORTRAN ||
2456  file_type == Parameters_FileFormat::FF_LLVM || file_type == Parameters_FileFormat::FF_LLVM_CPP)
2457  {
2458  const auto input_file =
2459  isOption(OPT_input_file) ? getOption<std::string>(OPT_input_file) + STR_CST_string_separator : "";
2460  setOption(OPT_input_file, input_file + filename);
2461  setOption(OPT_input_format, static_cast<int>(file_type));
2462  }
2463  else if(file_type == Parameters_FileFormat::FF_RAW ||
2464  (isOption(OPT_input_format) &&
2465  getOption<Parameters_FileFormat>(OPT_input_format) == Parameters_FileFormat::FF_RAW))
2466  {
2467  const auto input_file =
2468  isOption(OPT_input_file) ? getOption<std::string>(OPT_input_file) + STR_CST_string_separator : "";
2469  setOption(OPT_input_file, input_file + filename);
2470  setOption(OPT_input_format, static_cast<int>(Parameters_FileFormat::FF_RAW));
2471  if(!isOption(OPT_pretty_print))
2472  {
2473  setOption(OPT_pretty_print, GetPath("_a.c"));
2474  }
2475  }
2476  else
2477  {
2478  THROW_ERROR("Unexpected file extension: " + std::string(argv[optind]));
2479  }
2480  optind++;
2481  }
2482 
2483  CheckParameters();
2484 
2485  return PARAMETER_PARSED;
2486 }
2487 
2489 {
2490  const auto default_compiler = getOption<CompilerWrapper_CompilerTarget>(OPT_default_compiler);
2491 
2492  if(kill_printf)
2493  {
2494  std::string defines;
2495  if(isOption(OPT_gcc_defines))
2496  {
2497  defines = getOption<std::string>(OPT_gcc_defines) + STR_CST_string_separator;
2498  }
2499  defines += "printf(fmt, ...)=";
2500  setOption(OPT_gcc_defines, defines);
2501  }
2502  if(getOption<std::string>(OPT_top_functions_names) == "main")
2503  {
2504  std::string optimizations;
2505  if(isOption(OPT_gcc_optimizations))
2506  {
2507  optimizations = getOption<std::string>(OPT_gcc_optimizations);
2508  }
2509  THROW_ASSERT(isOption(OPT_input_file), "Input file not specified");
2510  if(getOption<std::string>(OPT_input_file).find(STR_CST_string_separator) == std::string::npos &&
2511  !isOption(OPT_top_design_name))
2512  {
2513  if(optimizations != "")
2514  {
2515  optimizations += STR_CST_string_separator;
2516  }
2517  optimizations += "whole-program";
2518  }
2519  if(isOption(OPT_top_design_name))
2520  {
2521  if(optimizations != "")
2522  {
2523  optimizations += STR_CST_string_separator;
2524  }
2525  optimizations += "no-ipa-cp" + STR_CST_string_separator + "no-ipa-cp-clone";
2526  }
2527  if(optimizations.size())
2528  {
2529  setOption(OPT_gcc_optimizations, optimizations);
2530  }
2531  }
2533  if(!isOption(OPT_gcc_m32_mx32))
2534  {
2535  if(CompilerWrapper::hasCompilerM64(default_compiler))
2536  {
2537  setOption(OPT_gcc_m32_mx32, "-m64");
2538  }
2539  if(CompilerWrapper::hasCompilerMX32(default_compiler))
2540  {
2541  setOption(OPT_gcc_m32_mx32, "-mx32");
2542  }
2543  if(CompilerWrapper::hasCompilerGCCM32(default_compiler))
2544  {
2545  setOption(OPT_gcc_m32_mx32, "-m32 -mno-sse2");
2546  }
2547  if(CompilerWrapper::hasCompilerCLANGM32(default_compiler))
2548  {
2549  setOption(OPT_gcc_m32_mx32, "-m32");
2550  }
2551  }
2552 }
2553 
2555 {
2557 
2558  if(isOption(OPT_aligned_access) && getOption<bool>(OPT_aligned_access) && isOption(OPT_unaligned_access) &&
2559  getOption<bool>(OPT_unaligned_access))
2560  {
2561  THROW_ERROR("Both --unaligned-access and --aligned-access have been specified");
2562  }
2563 
2564  if(!isOption(OPT_top_functions_names))
2565  {
2566  if(getOption<HLSFlowStep_Type>(OPT_interface_type) == HLSFlowStep_Type::INFERRED_INTERFACE_GENERATION)
2567  {
2568  THROW_ERROR("Top function name must be specified when interface inferece is enabled.");
2569  }
2570  setOption(OPT_top_functions_names, "main");
2571  THROW_WARNING("Top function name was not specified: main will be set as top");
2572  }
2573  if(getOption<std::string>(OPT_top_functions_names) == "main")
2574  {
2575  THROW_WARNING("Using 'main' as top function name is strongly discouraged.");
2576  THROW_WARNING(" Please note that C simulation output may be truncated down to 8-bits.");
2577  }
2578  if((isOption(OPT_input_format) &&
2579  getOption<Parameters_FileFormat>(OPT_input_format) == Parameters_FileFormat::FF_RAW) ||
2580  getOption<std::string>(OPT_top_functions_names) == "main" || isOption(OPT_testbench_param_size))
2581  {
2582  std::string gcc_defines = "CUSTOM_VERIFICATION";
2583  if(isOption(OPT_gcc_defines))
2584  {
2585  gcc_defines += STR_CST_string_separator + getOption<std::string>(OPT_gcc_defines);
2586  }
2587  setOption(OPT_gcc_defines, gcc_defines);
2588  }
2589 
2590  const auto sorted_dirs = [](const std::string& parent_dir) {
2591  std::vector<std::filesystem::path> sorted_paths;
2592  std::copy_if(std::filesystem::directory_iterator(parent_dir), std::filesystem::directory_iterator(),
2593  std::back_inserter(sorted_paths), [](const auto& it) { return std::filesystem::is_directory(it); });
2594  std::sort(sorted_paths.begin(), sorted_paths.end(), NaturalVersionOrder);
2595  return sorted_paths;
2596  };
2597 
2598  const auto altera_dirs = SplitString(getOption<std::string>(OPT_altera_root), ":");
2599  removeOption(OPT_altera_root);
2600  const auto search_quartus = [&](const std::string& dir) {
2601  if(std::filesystem::exists(dir + "/quartus/bin/quartus_sh"))
2602  {
2603  if(system(STR("bash -c \"if [ $(" + dir +
2604  "/quartus/bin/quartus_sh --version | grep Version | sed -E 's/Version ([0-9]+).*/\\1/') -lt 14 "
2605  "]; then exit 1; else exit 0; fi\" > /dev/null 2>&1")
2606  .c_str()))
2607  {
2608  setOption(OPT_quartus_13_settings, "export PATH=$PATH:" + dir + "/quartus/bin/");
2609  if(system(STR("bash -c \"" + dir + "/quartus/bin/quartus_sh --help | grep '--64bit'\" > /dev/null 2>&1")
2610  .c_str()) == 0)
2611  {
2612  setOption(OPT_quartus_13_64bit, true);
2613  }
2614  else
2615  {
2616  setOption(OPT_quartus_13_64bit, false);
2617  }
2618  }
2619  else
2620  {
2621  setOption(OPT_quartus_settings, "export PATH=$PATH:" + dir + "/quartus/bin/");
2622  }
2623  }
2624  };
2625  for(const auto& altera_dir : altera_dirs)
2626  {
2627  if(std::filesystem::is_directory(altera_dir))
2628  {
2629  for(const auto& ver_dir : sorted_dirs(altera_dir))
2630  {
2631  search_quartus(ver_dir.string());
2632  }
2633  search_quartus(altera_dir);
2634  }
2635  }
2636 
2638  const auto lattice_dirs = SplitString(getOption<std::string>(OPT_lattice_root), ":");
2639  removeOption(OPT_lattice_root);
2640  auto has_lattice = 0; // 0 = not found, 1 = 32-bit version, 2 = 64-bit version
2641  const auto search_lattice = [&](const std::string& dir) {
2642  if(std::filesystem::exists(dir + "/bin/lin/diamondc"))
2643  {
2644  has_lattice = 1;
2645  setOption(OPT_lattice_root, dir);
2646  }
2647  else if(std::filesystem::exists(dir + "/bin/lin64/diamondc"))
2648  {
2649  has_lattice = 2;
2650  setOption(OPT_lattice_root, dir);
2651  }
2652  if(std::filesystem::exists(dir + "/cae_library/synthesis/verilog/pmi_def.v"))
2653  {
2654  setOption(OPT_lattice_pmi_def, dir + "/cae_library/synthesis/verilog/pmi_def.v");
2655  }
2656  if(std::filesystem::exists(dir + "/cae_library/simulation/verilog/pmi/pmi_dsp_mult.v") &&
2657  std::filesystem::exists(dir + "/cae_library/simulation/verilog/pmi/pmi_ram_dp_true_be.v"))
2658  {
2659  setOption(OPT_lattice_inc_dirs, dir + "/cae_library/");
2660  }
2661  };
2662  for(const auto& lattice_dir : lattice_dirs)
2663  {
2664  if(std::filesystem::is_directory(lattice_dir))
2665  {
2666  for(const auto& ver_dir : sorted_dirs(lattice_dir))
2667  {
2668  search_lattice(ver_dir.string());
2669  }
2670  search_lattice(lattice_dir);
2671  }
2672  }
2673  if(has_lattice == 1)
2674  {
2675  const auto lattice_dir = getOption<std::string>(OPT_lattice_root);
2676  setOption(OPT_lattice_settings, "export TEMP=/tmp;export LSC_INI_PATH=\"\";"
2677  "export LSC_DIAMOND=true;"
2678  "export TCL_LIBRARY=" +
2679  lattice_dir +
2680  "/tcltk/lib/tcl8.5;"
2681  "export FOUNDRY=" +
2682  lattice_dir +
2683  "/ispfpga;"
2684  "export PATH=$FOUNDRY/bin/lin:" +
2685  lattice_dir + "/bin/lin:$PATH");
2686  }
2687  else if(has_lattice == 2)
2688  {
2689  const auto lattice_dir = getOption<std::string>(OPT_lattice_root);
2690  setOption(OPT_lattice_settings, "export TEMP=/tmp;export LSC_INI_PATH=\"\";"
2691  "export LSC_DIAMOND=true;"
2692  "export TCL_LIBRARY=" +
2693  lattice_dir +
2694  "/tcltk/lib/tcl8.5;"
2695  "export FOUNDRY=" +
2696  lattice_dir +
2697  "/ispfpga;"
2698  "export PATH=$FOUNDRY/bin/lin64:" +
2699  lattice_dir + "/bin/lin64:$PATH");
2700  }
2701 
2703  const auto mentor_dirs = SplitString(getOption<std::string>(OPT_mentor_root), ":");
2704  removeOption(OPT_mentor_root);
2705  const auto search_mentor = [&](const std::string& dir) {
2706  if(std::filesystem::exists(dir + "/bin/vsim"))
2707  {
2708  setOption(OPT_mentor_modelsim_bin, dir + "/bin");
2709  }
2710  };
2711  for(const auto& mentor_dir : mentor_dirs)
2712  {
2713  if(std::filesystem::is_directory(mentor_dir))
2714  {
2715  for(const auto& ver_dir : sorted_dirs(mentor_dir))
2716  {
2717  search_mentor(ver_dir.string());
2718  }
2719  search_mentor(mentor_dir);
2720  }
2721  }
2722 
2724  const auto nanox_dirs = SplitString(getOption<std::string>(OPT_nanoxplore_root), ":");
2725  removeOption(OPT_nanoxplore_root);
2726  const auto search_xmap = [&](const std::string& dir) {
2727  if(std::filesystem::exists(dir + "/bin/nxpython"))
2728  {
2729  setOption(OPT_nanoxplore_root, dir);
2730  }
2731  };
2732  for(const auto& nanox_dir : nanox_dirs)
2733  {
2734  if(std::filesystem::is_directory(nanox_dir))
2735  {
2736  search_xmap(nanox_dir);
2737  for(const auto& ver_dir : sorted_dirs(nanox_dir))
2738  {
2739  search_xmap(ver_dir.string());
2740  }
2741  }
2742  }
2743 
2745  const auto target_64 = true;
2746  const auto xilinx_dirs = SplitString(getOption<std::string>(OPT_xilinx_root), ":");
2747  removeOption(OPT_xilinx_root);
2748  const auto search_xilinx = [&](const std::string& dir) {
2749  if(std::filesystem::exists(dir + "/ISE"))
2750  {
2751  if(target_64 && std::filesystem::exists(dir + "/settings64.sh"))
2752  {
2753  setOption(OPT_xilinx_settings, dir + "/settings64.sh");
2754  setOption(OPT_xilinx_root, dir);
2755  }
2756  else if(std::filesystem::exists(dir + "/settings32.sh"))
2757  {
2758  setOption(OPT_xilinx_settings, dir + "/settings32.sh");
2759  setOption(OPT_xilinx_root, dir);
2760  }
2761  if(std::filesystem::exists(dir + "/ISE/verilog/src/glbl.v"))
2762  {
2763  setOption(OPT_xilinx_glbl, dir + "/ISE/verilog/src/glbl.v");
2764  }
2765  }
2766  };
2767  const auto search_xilinx_vivado = [&](const std::string& dir) {
2768  if(std::filesystem::exists(dir + "/ids_lite"))
2769  {
2770  if(target_64 && std::filesystem::exists(dir + "/settings64.sh"))
2771  {
2772  setOption(OPT_xilinx_vivado_settings, dir + "/settings64.sh");
2773  setOption(OPT_xilinx_root, dir);
2774  }
2775  else if(std::filesystem::exists(dir + "/settings32.sh"))
2776  {
2777  setOption(OPT_xilinx_vivado_settings, dir + "/settings32.sh");
2778  setOption(OPT_xilinx_root, dir);
2779  }
2780  if(std::filesystem::exists(dir + "/data/verilog/src/glbl.v"))
2781  {
2782  setOption(OPT_xilinx_glbl, dir + "/data/verilog/src/glbl.v");
2783  }
2784  }
2785  };
2786  for(const auto& xilinx_dir : xilinx_dirs)
2787  {
2788  if(std::filesystem::is_directory(xilinx_dir))
2789  {
2790  for(const auto& ver_dir : sorted_dirs(xilinx_dir))
2791  {
2792  for(const auto& ise_dir : std::filesystem::directory_iterator(ver_dir))
2793  {
2794  const auto ise_path = ise_dir.path().string();
2795  if(std::filesystem::is_directory(ise_dir) && ise_path.find("ISE") > ise_path.find_last_of('/'))
2796  {
2797  search_xilinx(ise_path);
2798  }
2799  }
2800  }
2801  search_xilinx(xilinx_dir);
2802  }
2803  }
2804  for(const auto& xilinx_dir : xilinx_dirs)
2805  {
2806  if(std::filesystem::is_directory(xilinx_dir))
2807  {
2808  for(const auto& vivado_dir : std::filesystem::directory_iterator(xilinx_dir))
2809  {
2810  const auto vivado_path = vivado_dir.path().string();
2811  if(std::filesystem::is_directory(vivado_dir) && vivado_path.find("Vivado") > vivado_path.find_last_of('/'))
2812  {
2813  for(const auto& ver_dir : sorted_dirs(vivado_path))
2814  {
2815  search_xilinx_vivado(ver_dir.string());
2816  }
2817  }
2818  }
2819  search_xilinx_vivado(xilinx_dir);
2820  }
2821  }
2822 
2823  if(!isOption(OPT_simulator))
2824  {
2825  if(isOption(OPT_mentor_modelsim_bin))
2826  {
2827  setOption(OPT_simulator, "MODELSIM");
2828  }
2829  else if(isOption(OPT_xilinx_vivado_settings))
2830  {
2831  setOption(OPT_simulator, "XSIM");
2832  }
2833  else
2834  {
2835  setOption(OPT_simulator, "VERILATOR");
2836  }
2837  }
2838 
2839  if(getOption<std::string>(OPT_simulator) == "VERILATOR")
2840  {
2842  setOption(OPT_verilator, system("which verilator > /dev/null 2>&1") == 0);
2843  }
2844 
2845 #if HAVE_TASTE
2846  if(isOption(OPT_input_format) &&
2847  getOption<Parameters_FileFormat>(OPT_input_format) == Parameters_FileFormat::FF_AADL)
2848  {
2849  setOption(OPT_generate_taste_architecture, true);
2850  setOption(OPT_clock_period, 20);
2851  setOption(OPT_writer_language, static_cast<int>(HDLWriter_Language::VHDL));
2852  setOption(OPT_interface_type, HLSFlowStep_Type::TASTE_INTERFACE_GENERATION);
2854  setOption(OPT_channels_number, 2);
2855  setOption("device_name", "xc4vlx100");
2856  setOption("device_speed", "-10");
2857  setOption("device_package", "ff1513");
2858  setOption("device_synthesis_tool", "");
2859  if(getOption<std::string>(OPT_bram_high_latency) != "")
2860  {
2861  THROW_ERROR("High latency BRAM cannot be used in taste architecture");
2862  }
2863  }
2864 #endif
2865 
2867  if(!isOption(OPT_device_string))
2868  {
2869  std::string device_string = getOption<std::string>("device_name") + getOption<std::string>("device_speed") +
2870  getOption<std::string>("device_package");
2871  if(isOption("device_synthesis_tool") && getOption<std::string>("device_synthesis_tool") != "")
2872  {
2873  device_string += "-" + getOption<std::string>("device_synthesis_tool");
2874  }
2875  setOption(OPT_device_string, device_string);
2876  }
2877 
2878  const auto device_name = getOption<std::string>("device_name");
2879  if(device_name.find("nangate45") != std::string::npos || device_name.find("asap7") != std::string::npos)
2880  {
2881  if(!isOption(OPT_memory_allocation_policy) ||
2882  getOption<MemoryAllocation_Policy>(OPT_memory_allocation_policy) != MemoryAllocation_Policy::NO_BRAM)
2883  {
2884  THROW_WARNING(
2885  "ASIC synthesis does not support internal memory, switching memory allocation policy to NO_BRAM.");
2886  setOption(OPT_memory_allocation_policy, MemoryAllocation_Policy::NO_BRAM);
2887  }
2888  }
2889 
2890  if(isOption(OPT_channels_type) &&
2891  (getOption<MemoryAllocation_ChannelsType>(OPT_channels_type) == MemoryAllocation_ChannelsType::MEM_ACC_N1 ||
2892  getOption<MemoryAllocation_ChannelsType>(OPT_channels_type) == MemoryAllocation_ChannelsType::MEM_ACC_NN) &&
2893  !isOption(OPT_channels_number))
2894  {
2895  setOption(OPT_channels_number, 2);
2896  }
2897 
2899  if(isOption(OPT_generate_vcd) && getOption<bool>(OPT_generate_vcd))
2900  {
2901  setOption(OPT_assert_debug, true);
2902  }
2903  if(getOption<int>(OPT_debug_level) >= DEBUG_LEVEL_VERY_PEDANTIC)
2904  {
2905  setOption(OPT_assert_debug, true);
2906  }
2907 
2909  if(getOption<HLSFlowStep_Type>(OPT_controller_architecture) == HLSFlowStep_Type::FSM_CONTROLLER_CREATOR ||
2910  getOption<HLSFlowStep_Type>(OPT_controller_architecture) == HLSFlowStep_Type::FSM_CS_CONTROLLER_CREATOR ||
2911  getOption<HLSFlowStep_Type>(OPT_controller_architecture) == HLSFlowStep_Type::PIPELINE_CONTROLLER_CREATOR)
2912  {
2913  setOption(OPT_stg, true);
2914  }
2915 
2917  setOption(OPT_chaining_algorithm, HLSFlowStep_Type::SCHED_CHAINING);
2918 
2920  if(getOption<bool>(OPT_evaluation))
2921  {
2922  THROW_ASSERT(isOption(OPT_evaluation_objectives), "missing evaluation objectives");
2923  auto objective_string = getOption<std::string>(OPT_evaluation_objectives);
2924  THROW_ASSERT(!objective_string.empty(), "");
2925  auto objective_vector = string_to_container<std::vector<std::string>>(objective_string, ",");
2926 
2927  if(getOption<Evaluation_Mode>(OPT_evaluation_mode) == Evaluation_Mode::EXACT)
2928  {
2929  if(is_evaluation_objective_string(objective_vector, "AREAxTIME"))
2930  {
2931  add_evaluation_objective_string(objective_string, "AREA,TIME");
2932  setOption(OPT_evaluation_objectives, objective_string);
2933  objective_vector = string_to_container<std::vector<std::string>>(objective_string, ",");
2934  }
2935 
2936  if(is_evaluation_objective_string(objective_vector, "TIME") ||
2937  is_evaluation_objective_string(objective_vector, "TOTAL_TIME") ||
2938  is_evaluation_objective_string(objective_vector, "CYCLES") ||
2939  is_evaluation_objective_string(objective_vector, "TOTAL_CYCLES"))
2940  {
2941  if(getOption<std::string>(OPT_simulator) == "MODELSIM" && !isOption(OPT_mentor_modelsim_bin))
2942  {
2943  THROW_ERROR("Mentor Modelsim was not detected by Bambu. Please check --mentor-root option is correct.");
2944  }
2945  else if(getOption<std::string>(OPT_simulator) == "XSIM" && !isOption(OPT_xilinx_vivado_settings))
2946  {
2947  THROW_ERROR("Xilinx XSim was not detected by Bambu. Please check --xilinx-root option is correct.");
2948  }
2949  else if(getOption<std::string>(OPT_simulator) == "VERILATOR" && !isOption(OPT_verilator))
2950  {
2951  THROW_ERROR("Verilator was not detected by Bambu. Please make sure it is installed in the system.");
2952  }
2953  if(!getOption<bool>(OPT_generate_testbench))
2954  {
2955  setOption(OPT_generate_testbench, true);
2956  setOption(OPT_testbench_input_file, GetPath("test.xml"));
2957  }
2958  if(getOption<std::list<std::string>>(OPT_top_functions_names).size() > 1)
2959  {
2960  THROW_ERROR("Simulation cannot be enabled with multiple top functions");
2961  }
2962  if(isOption(OPT_device_string) && starts_with(getOption<std::string>(OPT_device_string), "LFE"))
2963  {
2964  if(getOption<std::string>(OPT_simulator) == "VERILATOR")
2965  {
2966  THROW_WARNING("Simulation of Lattice device may not work with VERILATOR. Recent versions ignore some "
2967  "issue in Verilog Lattice libraries.");
2968  }
2969  if(!isOption(OPT_lattice_settings))
2970  {
2971  THROW_ERROR("Simulation of Lattice devices requires to enable Lattice support. See documentation "
2972  "about --lattice-root option.");
2973  }
2974  }
2975  }
2976  const auto is_valid_evaluation_mode = [](const std::string& s) -> bool {
2977  return s == "AREA" || s == "AREAxTIME" || s == "TIME" || s == "TOTAL_TIME" || s == "CYCLES" ||
2978  s == "TOTAL_CYCLES" || s == "BRAMS" || s == "DRAMS" || s == "CLOCK_SLACK" || s == "DSPS" ||
2979  s == "FREQUENCY" || s == "PERIOD" || s == "REGISTERS";
2980  };
2981  if(!all_of(objective_vector.begin(), objective_vector.end(), is_valid_evaluation_mode))
2982  {
2983  THROW_ERROR("BadParameters: evaluation mode EXACT does not support the selected evaluation objectives.");
2984  }
2985  }
2986  else
2987  {
2988  THROW_ERROR("BadParameters: invalid evaluation mode");
2989  }
2990  }
2991 
2992  if(getOption<HLSFlowStep_Type>(OPT_interface_type) == HLSFlowStep_Type::INFERRED_INTERFACE_GENERATION)
2993  {
2994  setOption(OPT_expose_globals, false);
2995  }
2996 
2997  if(!getOption<bool>(OPT_expose_globals))
2998  {
2999  if(getOption<MemoryAllocation_Policy>(OPT_memory_allocation_policy) == MemoryAllocation_Policy::NONE &&
3000  getOption<HLSFlowStep_Type>(OPT_interface_type) != HLSFlowStep_Type::WB4_INTERFACE_GENERATION)
3001  {
3002  setOption(OPT_memory_allocation_policy, MemoryAllocation_Policy::ALL_BRAM);
3003  }
3004  }
3006 
3007  const auto default_compiler = getOption<CompilerWrapper_CompilerTarget>(OPT_default_compiler);
3008  const auto flag_cpp = isOption(OPT_input_format) &&
3009  (getOption<Parameters_FileFormat>(OPT_input_format) == Parameters_FileFormat::FF_CPP ||
3010  getOption<Parameters_FileFormat>(OPT_input_format) == Parameters_FileFormat::FF_LLVM_CPP);
3011  if(flag_cpp)
3012  {
3014  std::string includes =
3015  "-isystem " + relocate_compiler_path(std::string(PANDA_DATA_INSTALLDIR "/panda/ac_types/include")) +
3016  " -isystem " + relocate_compiler_path(std::string(PANDA_DATA_INSTALLDIR "/panda/ac_math/include"));
3017  if(isOption(OPT_gcc_includes))
3018  {
3019  includes = getOption<std::string>(OPT_gcc_includes) + " " + includes;
3020  }
3021  setOption(OPT_gcc_includes, includes);
3022  if(!isOption(OPT_gcc_standard))
3023  {
3024  if(CompilerWrapper::isGccCheck(default_compiler) &&
3026  {
3027  setOption(OPT_gcc_standard, "gnu++98");
3028  }
3029  else
3030  {
3031  setOption(OPT_gcc_standard, "gnu++14");
3032  }
3033  }
3034  }
3035  else if(!isOption(OPT_gcc_standard))
3036  {
3037  if(CompilerWrapper::isGccCheck(default_compiler) &&
3039  {
3040  setOption(OPT_gcc_standard, "gnu90");
3041  }
3042  else
3043  {
3044  setOption(OPT_gcc_standard, "gnu11");
3045  }
3046  }
3047 #if HAVE_I386_CLANG16_COMPILER
3048  if(CompilerWrapper::isGccCheck(default_compiler))
3049  {
3050  std::string gcc_warnings;
3051  if(isOption(OPT_gcc_warnings))
3052  {
3053  gcc_warnings = getOption<std::string>(OPT_gcc_warnings) + STR_CST_string_separator;
3054  }
3055  const auto addWarning = [&](const std::string& warn) {
3056  if(gcc_warnings.find(boost::replace_first_copy(warn, "no-", "")) == std::string::npos)
3057  {
3058  gcc_warnings += warn + STR_CST_string_separator;
3059  }
3060  };
3061  addWarning("no-incompatible-function-pointer-types");
3062  addWarning("no-implicit-function-declaration");
3063  addWarning("no-int-conversion");
3064  setOption(OPT_gcc_warnings, gcc_warnings);
3065  }
3066 #endif
3067  if(getOption<bool>(OPT_parse_pragma))
3068  {
3069  if(isOption(OPT_disable_function_proxy) && !getOption<bool>(OPT_disable_function_proxy))
3070  {
3071  THROW_ERROR("function proxy has to be disabled when pragmas are parsed");
3072  }
3073  setOption(OPT_disable_function_proxy, true);
3074  }
3075  if(isOption(OPT_discrepancy_hw) && getOption<bool>(OPT_discrepancy_hw))
3076  {
3077  if(isOption(OPT_disable_function_proxy))
3078  {
3079  if(getOption<bool>(OPT_disable_function_proxy))
3080  {
3081  THROW_ERROR("--discrepancy-hw Hardware Discrepancy Analysis only works with function proxies");
3082  }
3083  }
3084  else
3085  {
3086  setOption(OPT_disable_function_proxy, false);
3087  if(isOption(OPT_constraints_functions))
3088  {
3089  THROW_ERROR("--discrepancy-hw Hardware Discrepancy Analysis only works with function proxies and not with "
3090  "-C defined");
3091  }
3092  }
3093  }
3095  // TODO: check this, function proxies should work properly even with multiple top functions
3096  if(getOption<std::list<std::string>>(OPT_top_functions_names).size() > 1)
3097  {
3098  if(isOption(OPT_disable_function_proxy))
3099  {
3100  if(!getOption<bool>(OPT_disable_function_proxy))
3101  {
3102  THROW_ERROR("multiple top functions does not work with function proxies");
3103  }
3104  }
3105  else
3106  {
3107  setOption(OPT_disable_function_proxy, true);
3108  }
3109  }
3110 
3112  if(getOption<std::string>(OPT_experimental_setup) == "VVD")
3113  {
3114  if(!isOption(OPT_compiler_opt_level))
3115  {
3116  setOption(OPT_compiler_opt_level, CompilerWrapper_OptimizationSet::O3);
3117  }
3118  if(!isOption(OPT_channels_type))
3119  {
3121  }
3122  if(!isOption(OPT_channels_number))
3123  {
3124  setOption(OPT_channels_number, 2);
3125  }
3126  if(getOption<MemoryAllocation_Policy>(OPT_memory_allocation_policy) == MemoryAllocation_Policy::NONE)
3127  {
3128  setOption(OPT_memory_allocation_policy, MemoryAllocation_Policy::ALL_BRAM);
3129  }
3130  setOption(OPT_DSP_allocation_coefficient, 1.75);
3131  setOption(OPT_clock_period_resource_fraction, "0.875");
3132  setOption(OPT_expose_globals, false);
3133  if(!isOption(OPT_distram_threshold))
3134  {
3135  setOption(OPT_distram_threshold, 256);
3136  }
3138  if(!isOption(OPT_disable_function_proxy))
3139  {
3140  setOption(OPT_disable_function_proxy, true);
3141  }
3142  }
3143  else if(getOption<std::string>(OPT_experimental_setup) == "BAMBU092")
3144  {
3145  if(!isOption(OPT_compiler_opt_level))
3146  {
3147  setOption(OPT_compiler_opt_level, CompilerWrapper_OptimizationSet::O0);
3148  }
3149  setOption(OPT_estimate_logic_and_connections, false);
3150  setOption(OPT_clock_period_resource_fraction, "0.9");
3151  setOption(OPT_DSP_margin_combinational, 1.3);
3152  setOption(OPT_skip_pipe_parameter, 1);
3153  if(!isOption(OPT_distram_threshold))
3154  {
3155  setOption(OPT_distram_threshold, 256);
3156  }
3158  if(!isOption(OPT_disable_function_proxy))
3159  {
3160  setOption(OPT_disable_function_proxy, true);
3161  }
3162  }
3163  else if(getOption<std::string>(OPT_experimental_setup) == "BAMBU-BALANCED" ||
3164  getOption<std::string>(OPT_experimental_setup) == "BAMBU-BALANCED-MP" ||
3165  getOption<std::string>(OPT_experimental_setup) == "BAMBU-TASTE")
3166  {
3167  std::string tuning_optimizations;
3168  if(!isOption(OPT_compiler_opt_level))
3169  {
3170  setOption(OPT_compiler_opt_level, CompilerWrapper_OptimizationSet::O2);
3172  if(CompilerWrapper::isGccCheck(default_compiler))
3173  {
3174  tuning_optimizations += "inline-functions" + STR_CST_string_separator + "gcse-after-reload" +
3176  "unswitch-loops" + STR_CST_string_separator + "no-tree-loop-ivcanon";
3177  if(default_compiler == CompilerWrapper_CompilerTarget::CT_I386_GCC49 ||
3178  default_compiler == CompilerWrapper_CompilerTarget::CT_I386_GCC5 ||
3179  default_compiler == CompilerWrapper_CompilerTarget::CT_I386_GCC6 ||
3180  default_compiler == CompilerWrapper_CompilerTarget::CT_I386_GCC7 ||
3182  {
3183  tuning_optimizations +=
3184  STR_CST_string_separator + "tree-partial-pre" + STR_CST_string_separator + "disable-tree-bswap";
3185  }
3186  if(default_compiler == CompilerWrapper_CompilerTarget::CT_I386_GCC7 ||
3188  {
3189  tuning_optimizations += STR_CST_string_separator + "no-store-merging";
3190  }
3191  }
3193  else if(CompilerWrapper::isClangCheck(default_compiler))
3194  {
3195  tuning_optimizations += "inline-functions";
3196  }
3197  }
3198  std::string optimizations;
3199  if(isOption(OPT_gcc_optimizations))
3200  {
3201  optimizations += getOption<std::string>(OPT_gcc_optimizations);
3202  }
3203  if(optimizations != "" && tuning_optimizations != "")
3204  {
3205  optimizations += STR_CST_string_separator;
3206  }
3207  optimizations += tuning_optimizations;
3208  if(optimizations != "")
3209  {
3210  setOption(OPT_gcc_optimizations, optimizations);
3211  }
3212 #if 0
3213  std::string parameters;
3214  if(isOption(OPT_gcc_parameters))
3215  parameters = getOption<std::string>(OPT_gcc_parameters) + STR_CST_string_separator;
3216  setOption(OPT_gcc_parameters, parameters + "max-inline-insns-auto=25");
3217 #endif
3218  if(getOption<std::string>(OPT_experimental_setup) == "BAMBU-BALANCED-MP")
3219  {
3220  if(!isOption(OPT_channels_type))
3221  {
3223  }
3224  if(!isOption(OPT_channels_number))
3225  {
3226  setOption(OPT_channels_number, 2);
3227  }
3228  }
3229  if(getOption<MemoryAllocation_Policy>(OPT_memory_allocation_policy) == MemoryAllocation_Policy::NONE)
3230  {
3231  setOption(OPT_memory_allocation_policy, MemoryAllocation_Policy::ALL_BRAM);
3232  }
3233  if(!isOption(OPT_distram_threshold))
3234  {
3235  setOption(OPT_distram_threshold, 256);
3236  }
3238  if(getOption<std::string>(OPT_experimental_setup) == "BAMBU-TASTE")
3239  {
3240  const auto source_files = getOption<CustomSet<std::string>>(OPT_input_file);
3241  if(source_files.size() > 1 && isOption(OPT_input_format) &&
3242  getOption<Parameters_FileFormat>(OPT_input_format) == Parameters_FileFormat::FF_C)
3243  {
3244  auto concat_filename = std::filesystem::path(getOption<std::string>(OPT_output_temporary_directory) + "/" +
3245  unique_path(std::string(STR_CST_concat_c_file)).string())
3246  .string();
3247  std::ofstream filestream(concat_filename.c_str());
3248  for(const auto& source_file : source_files)
3249  {
3250  filestream << "#include \"" << source_file << "\"\n";
3251  }
3252  filestream.close();
3253  setOption(OPT_input_file, concat_filename);
3254  }
3255  }
3256  if(!isOption(OPT_disable_function_proxy))
3257  {
3258  setOption(OPT_disable_function_proxy, true);
3259  if(!isOption(OPT_constraints_functions))
3260  {
3261  setOption(OPT_constraints_functions, "*");
3262  }
3263  }
3264  }
3265  else if(getOption<std::string>(OPT_experimental_setup) == "BAMBU-PERFORMANCE-MP")
3266  {
3267  if(!isOption(OPT_compiler_opt_level))
3268  {
3269  setOption(OPT_compiler_opt_level, CompilerWrapper_OptimizationSet::O3);
3270  }
3271  if(!isOption(OPT_channels_type))
3272  {
3274  }
3275  if(!isOption(OPT_channels_number))
3276  {
3277  setOption(OPT_channels_number, 2);
3278  }
3279  if(getOption<MemoryAllocation_Policy>(OPT_memory_allocation_policy) == MemoryAllocation_Policy::NONE)
3280  {
3281  setOption(OPT_memory_allocation_policy, MemoryAllocation_Policy::ALL_BRAM);
3282  }
3283  if(!isOption(OPT_distram_threshold))
3284  {
3285  setOption(OPT_distram_threshold, 512);
3286  }
3288  if(!isOption(OPT_disable_function_proxy))
3289  {
3290  setOption(OPT_disable_function_proxy, true);
3291  }
3292  }
3293  else if(getOption<std::string>(OPT_experimental_setup) == "BAMBU-PERFORMANCE")
3294  {
3295  if(!isOption(OPT_compiler_opt_level))
3296  {
3297  setOption(OPT_compiler_opt_level, CompilerWrapper_OptimizationSet::O3);
3298  }
3299  if(getOption<MemoryAllocation_Policy>(OPT_memory_allocation_policy) == MemoryAllocation_Policy::NONE)
3300  {
3301  setOption(OPT_memory_allocation_policy, MemoryAllocation_Policy::ALL_BRAM);
3302  }
3303  if(!isOption(OPT_distram_threshold))
3304  {
3305  setOption(OPT_distram_threshold, 512);
3306  }
3308  if(!isOption(OPT_disable_function_proxy))
3309  {
3310  setOption(OPT_disable_function_proxy, true);
3311  }
3312  }
3313  else if(getOption<std::string>(OPT_experimental_setup) == "BAMBU-AREA-MP")
3314  {
3315  if(!isOption(OPT_compiler_opt_level))
3316  {
3317  setOption(OPT_compiler_opt_level, CompilerWrapper_OptimizationSet::Os);
3318  }
3319  std::string optimizations;
3320  if(isOption(OPT_gcc_optimizations))
3321  {
3322  optimizations += getOption<std::string>(OPT_gcc_optimizations);
3323  }
3324  std::string tuning_optimizations = "no-unroll-loops";
3325  if(optimizations != "" && tuning_optimizations != "")
3326  {
3327  optimizations += STR_CST_string_separator;
3328  }
3329  optimizations += tuning_optimizations;
3330  if(optimizations != "")
3331  {
3332  setOption(OPT_gcc_optimizations, optimizations);
3333  }
3334  if(!isOption(OPT_channels_type))
3335  {
3337  }
3338  if(!isOption(OPT_channels_number))
3339  {
3340  setOption(OPT_channels_number, 2);
3341  }
3342  if(getOption<MemoryAllocation_Policy>(OPT_memory_allocation_policy) == MemoryAllocation_Policy::NONE)
3343  {
3344  setOption(OPT_memory_allocation_policy, MemoryAllocation_Policy::ALL_BRAM);
3345  }
3346  setOption(OPT_DSP_allocation_coefficient, 1.75);
3347  if(!isOption(OPT_distram_threshold))
3348  {
3349  setOption(OPT_distram_threshold, 256);
3350  }
3352  if(!isOption(OPT_disable_function_proxy))
3353  {
3354  if(!isOption(OPT_constraints_functions))
3355  {
3356  setOption(OPT_disable_function_proxy, false);
3357  }
3358  else
3359  {
3360  setOption(OPT_disable_function_proxy, true);
3361  }
3362  }
3363  }
3364  else if(getOption<std::string>(OPT_experimental_setup) == "BAMBU-AREA")
3365  {
3366  if(!isOption(OPT_compiler_opt_level))
3367  {
3368  setOption(OPT_compiler_opt_level, CompilerWrapper_OptimizationSet::Os);
3369  }
3370  std::string optimizations;
3371  if(isOption(OPT_gcc_optimizations))
3372  {
3373  optimizations += getOption<std::string>(OPT_gcc_optimizations);
3374  }
3375  std::string tuning_optimizations = "no-unroll-loops";
3376  if(optimizations != "" && tuning_optimizations != "")
3377  {
3378  optimizations += STR_CST_string_separator;
3379  }
3380  optimizations += tuning_optimizations;
3381  if(optimizations != "")
3382  {
3383  setOption(OPT_gcc_optimizations, optimizations);
3384  }
3385  if(getOption<MemoryAllocation_Policy>(OPT_memory_allocation_policy) == MemoryAllocation_Policy::NONE)
3386  {
3387  setOption(OPT_memory_allocation_policy, MemoryAllocation_Policy::ALL_BRAM);
3388  }
3389  setOption(OPT_DSP_allocation_coefficient, 1.75);
3390  if(!isOption(OPT_distram_threshold))
3391  {
3392  setOption(OPT_distram_threshold, 256);
3393  }
3395  if(!isOption(OPT_disable_function_proxy))
3396  {
3397  if(!isOption(OPT_constraints_functions))
3398  {
3399  setOption(OPT_disable_function_proxy, false);
3400  }
3401  else
3402  {
3403  setOption(OPT_disable_function_proxy, true);
3404  }
3405  }
3406  }
3407  else if(getOption<std::string>(OPT_experimental_setup) == "BAMBU")
3408  {
3409  if(!isOption(OPT_compiler_opt_level))
3410  {
3411  setOption(OPT_compiler_opt_level, CompilerWrapper_OptimizationSet::O0);
3412  }
3413  if(!isOption(OPT_distram_threshold))
3414  {
3415  setOption(OPT_distram_threshold, 256);
3416  }
3418  if(!isOption(OPT_disable_function_proxy))
3419  {
3420  if(!isOption(OPT_constraints_functions))
3421  {
3422  setOption(OPT_disable_function_proxy, false);
3423  }
3424  else
3425  {
3426  setOption(OPT_disable_function_proxy, true);
3427  }
3428  }
3429  }
3430  else
3431  {
3432  THROW_ERROR("Experimental setup not recognized: " + getOption<std::string>(OPT_experimental_setup));
3433  }
3434 
3435  add_bambu_library("bambu");
3436 
3437  if(isOption(OPT_soft_float) && getOption<bool>(OPT_soft_float))
3438  {
3439  if(isOption(OPT_soft_fp) && getOption<bool>(OPT_soft_fp))
3440  {
3441  add_bambu_library("soft-fp");
3442  }
3443  else if(getOption<std::string>(OPT_hls_fpdiv) != "SRT4" && getOption<std::string>(OPT_hls_fpdiv) != "G")
3444  {
3445  THROW_ERROR("--hls-fpdiv=SF requires --soft-fp option");
3446  }
3447  else if(isOption(OPT_fp_subnormal) && getOption<bool>(OPT_fp_subnormal))
3448  {
3449  add_bambu_library("softfloat_subnormals");
3450  }
3451  else
3452  {
3453  add_bambu_library("softfloat");
3454  }
3455  }
3456 
3457  if(isOption(OPT_hls_div) && getOption<std::string>(OPT_hls_div) != "none")
3458  {
3459  add_bambu_library("hls-div" + getOption<std::string>(OPT_hls_div));
3460  }
3461  add_bambu_library("hls-cdiv");
3462 #if HAVE_FROM_PRAGMA_BUILT
3463  if(getOption<bool>(OPT_parse_pragma))
3464  {
3465  if(isOption(OPT_context_switch))
3466  {
3467  if(getOption<unsigned int>(OPT_channels_number) >= getOption<unsigned int>(OPT_memory_banks_number))
3468  {
3469  THROW_ERROR("This configuration doesn't support a number of channel equal or greater than the number of "
3470  "memory_bank");
3471  }
3472  if(getOption<std::string>(OPT_registered_inputs) != "auto")
3473  {
3474  THROW_ERROR("Registered inputs option cannot be set for context switch architecture");
3475  }
3476  auto v = getOption<unsigned int>(OPT_channels_number); // we want to see if v is a power of 2
3477  bool f; // the result goes here
3478  f = v && !(v & (v - 1));
3479  if(!f)
3480  {
3481  THROW_ERROR("Number of channel must be a power of 2");
3482  }
3483  v = getOption<unsigned int>(OPT_memory_banks_number); // we want to see if v is a power of 2
3484  f = v && !(v & (v - 1));
3485  if(!f)
3486  {
3487  THROW_ERROR("Number of bank must be a power of 2");
3488  }
3489  setOption(OPT_function_allocation_algorithm, HLSFlowStep_Type::OMP_FUNCTION_ALLOCATION_CS);
3490  setOption(OPT_memory_allocation_algorithm, HLSFlowStep_Type::DOMINATOR_MEMORY_ALLOCATION_CS);
3492  setOption(OPT_datapath_architecture, HLSFlowStep_Type::DATAPATH_CS_CREATOR);
3493  setOption(OPT_controller_architecture, HLSFlowStep_Type::FSM_CS_CONTROLLER_CREATOR);
3495  }
3496  else
3497  {
3498  setOption(OPT_function_allocation_algorithm, HLSFlowStep_Type::OMP_FUNCTION_ALLOCATION);
3499  }
3500  add_bambu_library("pthread");
3501  }
3502 #endif
3503 
3504  if(isOption(OPT_gcc_libraries))
3505  {
3506  const auto libraries = getOption<CustomSet<std::string>>(OPT_gcc_libraries);
3507  for(const auto& library : libraries)
3508  {
3509  add_bambu_library(library);
3510  }
3511  }
3512 
3514  if(getOption<MemoryAllocation_Policy>(OPT_memory_allocation_policy) == MemoryAllocation_Policy::NONE)
3515  {
3516  setOption(OPT_memory_allocation_policy, MemoryAllocation_Policy::LSS);
3517  }
3518 
3520  if(isOption(OPT_initial_internal_address) && (getOption<unsigned long long int>(OPT_base_address) == 0 ||
3521  getOption<unsigned int>(OPT_initial_internal_address) == 0))
3522  {
3523  std::string optimizations;
3524  if(isOption(OPT_gcc_optimizations))
3525  {
3526  optimizations = getOption<std::string>(OPT_gcc_optimizations) + STR_CST_string_separator;
3527  }
3528  setOption(OPT_gcc_optimizations, optimizations + "no-delete-null-pointer-checks");
3529  }
3530 
3532  if(isOption(OPT_memory_banks_number) && getOption<int>(OPT_memory_banks_number) > 1)
3533  {
3535  }
3536  if(!isOption(OPT_channels_type))
3537  {
3539  setOption(OPT_channels_number, 1);
3540  }
3541  if(isOption(OPT_channels_number) &&
3542  getOption<MemoryAllocation_ChannelsType>(OPT_channels_type) == MemoryAllocation_ChannelsType::MEM_ACC_11)
3543  {
3544  if(getOption<unsigned int>(OPT_channels_number) != 1)
3545  {
3546  THROW_ERROR("the number of channels cannot be specified for MEM_ACC_11");
3547  }
3548  }
3549 
3550  if(getOption<HLSFlowStep_Type>(OPT_interface_type) == HLSFlowStep_Type::WB4_INTERFACE_GENERATION)
3551  {
3552  if(getOption<MemoryAllocation_ChannelsType>(OPT_channels_type) == MemoryAllocation_ChannelsType::MEM_ACC_NN)
3553  {
3554  THROW_ERROR("Wishbone 4 interface does not yet support multi-channel architectures (MEM_ACC_NN)");
3555  }
3556 
3557  if(getOption<MemoryAllocation_Policy>(OPT_memory_allocation_policy) == MemoryAllocation_Policy::ALL_BRAM)
3558  {
3559  THROW_ERROR("Wishbone 4 interface does not yet support --memory-allocation-policy=ALL_BRAM");
3560  }
3561  else if(getOption<MemoryAllocation_Policy>(OPT_memory_allocation_policy) ==
3563  {
3564  THROW_ERROR("Wishbone 4 interface does not yet support --memory-allocation-policy=EXT_PIPELINED_BRAM");
3565  }
3566  }
3567 
3568  if(getOption<bool>(OPT_memory_mapped_top) &&
3569  (isOption(OPT_clock_name) || isOption(OPT_reset_name) || isOption(OPT_start_name) || isOption(OPT_done_name)))
3570  {
3571  THROW_ERROR("Memory mapped top interface does not allow the renaming of the control signals");
3572  }
3573 
3574  if(!getOption<bool>(OPT_gcc_include_sysdir))
3575  {
3576  if(!isOption(OPT_input_file))
3577  {
3578  THROW_ERROR("No input file specified");
3579  }
3580  if(isOption(OPT_gcc_optimizations) &&
3581  getOption<std::string>(OPT_input_file).find(STR_CST_string_separator) != std::string::npos &&
3582  getOption<std::string>(OPT_gcc_optimizations).find("whole-program") != std::string::npos &&
3583  getOption<std::string>(OPT_gcc_optimizations).find("no-whole-program") == std::string::npos)
3584  {
3585  THROW_ERROR("-fwhole-program cannot be used with multiple input files");
3586  }
3587  }
3588  if(isOption(OPT_discrepancy) && getOption<bool>(OPT_discrepancy) && isOption(OPT_discrepancy_hw) &&
3589  getOption<bool>(OPT_discrepancy_hw))
3590  {
3591  THROW_ERROR("--discrepancy and --discrepancy-hw are mutually exclusive");
3592  }
3593  if(isOption(OPT_discrepancy_hw) && getOption<bool>(OPT_discrepancy_hw) &&
3594  getOption<HLSFlowStep_Type>(OPT_controller_architecture) != HLSFlowStep_Type::FSM_CONTROLLER_CREATOR)
3595  {
3596  THROW_ERROR("--discrepancy-hw is only compatible with classic FSM controllers");
3597  }
3598  if(isOption(OPT_discrepancy_hw) && getOption<bool>(OPT_discrepancy_hw) &&
3599  static_cast<HDLWriter_Language>(getOption<unsigned int>(OPT_writer_language)) != HDLWriter_Language::VERILOG)
3600  {
3601  THROW_ERROR("--discrepancy-hw is only compatible with Verilog");
3602  }
3603  if(isOption(OPT_discrepancy_hw) && getOption<bool>(OPT_discrepancy_hw) &&
3604  getOption<HLSFlowStep_Type>(OPT_function_allocation_algorithm) != HLSFlowStep_Type::DOMINATOR_FUNCTION_ALLOCATION)
3605  {
3606  THROW_ERROR("--discrepancy-hw Hardware Discrepancy Analysis only works with dominator function allocation");
3607  }
3608  if(isOption(OPT_discrepancy) && getOption<bool>(OPT_discrepancy))
3609  {
3610  if(default_compiler == CompilerWrapper_CompilerTarget::CT_I386_GCC49)
3611  {
3612  THROW_WARNING("discrepancy analysis can report false positives with old compilers, use --compiler=I386_GCC5 "
3613  "or higher to avoid them");
3614  }
3615  }
3616  if((isOption(OPT_generate_vcd) && getOption<bool>(OPT_generate_vcd)) ||
3617  (isOption(OPT_discrepancy) && getOption<bool>(OPT_discrepancy)))
3618  {
3619  if(!isOption(OPT_generate_testbench) || !getOption<bool>(OPT_generate_testbench))
3620  {
3621  THROW_ERROR("Testbench generation required. (--generate-tb or --simulate undeclared).");
3622  }
3623  }
3624 
3625  if(isOption(OPT_no_parse_c_python) && !isOption(OPT_tb_extra_gcc_options))
3626  {
3627  THROW_ERROR("Include directories and library directories for Python bindings are missing.\n"
3628  "use --tb-extra-gcc-options=\"string\" to provide them");
3629  }
3630  setOption<unsigned int>(OPT_host_compiler, static_cast<unsigned int>(default_compiler));
3631  if(isOption(OPT_lattice_settings))
3632  {
3633  if(isOption(OPT_evaluation_objectives) &&
3634  getOption<std::string>(OPT_evaluation_objectives).find("AREA") != std::string::npos &&
3635  isOption(OPT_device_string) && starts_with(getOption<std::string>(OPT_device_string), "LFE") &&
3636  !getOption<bool>(OPT_connect_iob))
3637  {
3638  THROW_WARNING("--connect-iob must be used when target is a Lattice board");
3639  }
3640  }
3642  if(getOption<int>(OPT_gcc_openmp_simd))
3643  {
3644  setOption(OPT_bitvalue_ipa, false);
3645  }
3646  if(getOption<int>(OPT_gcc_openmp_simd) || getOption<bool>(OPT_parse_pragma))
3647  {
3648  const auto flist = getOption<std::list<std::string>>(OPT_input_file);
3649  std::string includes = isOption(OPT_gcc_includes) ? getOption<std::string>(OPT_gcc_includes) : "";
3650  for(const auto& src : flist)
3651  {
3652  includes += " -iquote " + std::filesystem::path(src).parent_path().string();
3653  }
3654  setOption(OPT_gcc_includes, includes);
3655  }
3656 
3657  if(starts_with(getOption<std::string>(OPT_device_string), "nx"))
3658  {
3659  THROW_WARNING("Asynchronous memories are disabled by default when targeting NanoXplore devices");
3660  setOption(OPT_use_asynchronous_memories, false);
3661  }
3662 }
3663 
3665 {
3666  // ---------- general options ----------- //
3668  setOption(OPT_dot_directory, GetPath("./HLS_output/dot/"));
3669  setOption(OPT_output_directory, GetPath("./HLS_output/"));
3670  setOption(OPT_simulation_output, GetPath("results.txt"));
3671  setOption(OPT_profiling_output, GetPath("profiling_results.txt"));
3674  auto sim_dir = getOption<std::string>(OPT_output_directory) + "/simulation/";
3675  if(std::filesystem::exists(sim_dir))
3676  {
3677  std::filesystem::remove_all(sim_dir);
3678  }
3679 
3681  setOption(OPT_output_level, OUTPUT_LEVEL_MINIMUM);
3682  setOption(OPT_debug_level, DEBUG_LEVEL_NONE);
3683  setOption(OPT_print_dot, false);
3685  setOption(OPT_ilp_max_time, 0);
3686 
3688  setOption(OPT_parse_pragma, false);
3689  setOption(OPT_ignore_parallelism, false);
3690 
3691  setOption(OPT_frontend_statistics, false);
3692 
3696 
3698  setOption(OPT_generate_testbench, false);
3699  setOption(OPT_max_sim_cycles, 200000000);
3700  setOption(OPT_chaining, true);
3701 
3703  setOption("dumpConstraints", false);
3704  setOption("dumpConstraints_file", "Constraints.xml");
3705 
3708  setOption(OPT_scheduling_algorithm, HLSFlowStep_Type::LIST_BASED_SCHEDULING);
3709  setOption(OPT_scheduling_priority, ParametricListBased_Metric::DYNAMIC_MOBILITY);
3711 #if HAVE_ILP_BUILT
3712 #if HAVE_GLPK
3713  setOption(OPT_ilp_solver, meilp_solver::GLPK);
3714 #elif HAVE_COIN_OR
3715  setOption(OPT_ilp_solver, meilp_solver::COIN_OR);
3716 #elif HAVE_LP_SOLVE
3717  setOption(OPT_ilp_solver, meilp_solver::LP_SOLVE);
3718 #endif
3719 #endif
3720  setOption(OPT_speculative, false);
3722 
3725  setOption(OPT_fu_binding_algorithm, HLSFlowStep_Type::CDFC_MODULE_BINDING);
3726  setOption(OPT_cdfc_module_binding_algorithm, CliqueCovering_Algorithm::TS_WEIGHTED_CLIQUE_COVERING);
3727 
3730  setOption(OPT_stg, false);
3732  setOption(OPT_stg_algorithm, HLSFlowStep_Type::BB_STG_CREATOR);
3733 
3735  setOption(OPT_liveness_algorithm, HLSFlowStep_Type::FSM_NI_SSA_LIVENESS);
3736 
3739  setOption(OPT_register_allocation_algorithm, HLSFlowStep_Type::WEIGHTED_CLIQUE_REGISTER_BINDING);
3740  setOption(OPT_weighted_clique_register_algorithm, CliqueCovering_Algorithm::TS_WEIGHTED_CLIQUE_COVERING);
3742  setOption(OPT_storage_value_insertion_algorithm, HLSFlowStep_Type::VALUES_SCHEME_STORAGE_VALUE_INSERTION);
3743  setOption(OPT_reset_type, "no");
3744  setOption(OPT_reset_level, false);
3745  setOption(OPT_reg_init_value, true);
3746 
3747  setOption(OPT_shared_input_registers, false);
3748 
3750  setOption(OPT_function_allocation_algorithm, HLSFlowStep_Type::DOMINATOR_FUNCTION_ALLOCATION);
3751 
3753  setOption(OPT_disable_bounded_function, false);
3754 
3756  setOption(OPT_memory_mapped_top, false);
3757 
3758  setOption(OPT_mem_delay_read, 2);
3759  setOption(OPT_mem_delay_write, 1);
3760  setOption(OPT_tb_queue_size, 4);
3761 
3763  setOption(OPT_memory_allocation_algorithm, HLSFlowStep_Type::DOMINATOR_MEMORY_ALLOCATION);
3764  setOption(OPT_memory_allocation_policy, MemoryAllocation_Policy::NONE);
3765  setOption(OPT_base_address, 1073741824); // 1Gbytes maximum address space reserved for the accelerator
3766  setOption(OPT_memory_controller_type, "D00");
3767  setOption(OPT_sparse_memory, true);
3768  setOption(OPT_expose_globals, false);
3769 
3772  setOption(OPT_datapath_interconnection_algorithm, HLSFlowStep_Type::MUX_INTERCONNECTION_BINDING);
3774  setOption(OPT_datapath_architecture, HLSFlowStep_Type::CLASSIC_DATAPATH_CREATOR);
3775 
3778  setOption(OPT_controller_architecture, HLSFlowStep_Type::FSM_CONTROLLER_CREATOR);
3779 
3782  setOption(OPT_top_file, "top");
3783 
3785  setOption(OPT_writer_language, static_cast<int>(HDLWriter_Language::VERILOG));
3786 
3788  setOption(OPT_interface, true);
3790  setOption(OPT_additional_top, "");
3791 
3793  setOption(OPT_evaluation, false);
3794  setOption(OPT_evaluation_mode, Evaluation_Mode::NONE);
3795  setOption(OPT_evaluation_objectives, "");
3796 
3797  setOption(OPT_altera_root, "/opt/altera:/opt/intelFPGA");
3798  setOption(OPT_lattice_root, "/opt/diamond:/usr/local/diamond");
3799  setOption(OPT_mentor_root, "/opt/mentor");
3800  setOption(OPT_mentor_optimizer, true);
3801  setOption(OPT_nanoxplore_root, "/opt/NanoXplore");
3802  setOption(OPT_xilinx_root, "/opt/Xilinx");
3803 
3805  setOption("device_name", "xc7z020");
3806  setOption("device_speed", "-1");
3807  setOption("device_package", "clg484");
3808  setOption("device_synthesis_tool", "VVD");
3809  setOption(OPT_timing_violation_abort, false);
3810  setOption(OPT_export_core, false);
3811  setOption(OPT_connect_iob, false);
3812 
3814  setOption(OPT_default_compiler, CompilerWrapper::getDefaultCompiler());
3815  setOption(OPT_compatible_compilers, CompilerWrapper::getCompatibleCompilers());
3816 
3817  setOption(OPT_without_transformation, true);
3818  setOption(OPT_compute_size_of, true);
3819  setOption(OPT_precision, 3);
3820  setOption(OPT_gcc_c, true);
3821  setOption(OPT_gcc_config, false);
3822  setOption(OPT_gcc_costs, false);
3823  setOption(OPT_gcc_optimization_set, CompilerWrapper_OptimizationSet::OBAMBU);
3824  setOption(OPT_gcc_include_sysdir, false);
3825 
3826  std::string defines;
3827  if(isOption(OPT_gcc_defines))
3828  {
3829  defines = getOption<std::string>(OPT_gcc_defines) + STR_CST_string_separator;
3830  }
3831  defines += "__BAMBU__";
3832  setOption(OPT_gcc_defines, defines);
3833 
3834  setOption(OPT_soft_float, true);
3835  setOption(OPT_hls_div, "NR");
3836  setOption(OPT_hls_fpdiv, "SRT4");
3837  setOption(OPT_max_ulp, 1.0);
3838  setOption(OPT_skip_pipe_parameter, 0);
3839  setOption(OPT_unaligned_access, false);
3840  setOption(OPT_aligned_access, false);
3841  setOption(OPT_gcc_serialize_memory_accesses, false);
3842  setOption(OPT_use_asynchronous_memories, true);
3843  setOption(OPT_do_not_chain_memories, false);
3844  setOption(OPT_bram_high_latency, "");
3845  setOption(OPT_experimental_setup, "BAMBU-BALANCED-MP");
3846  setOption(OPT_DSP_margin_combinational, 1.0);
3847  setOption(OPT_DSP_margin_pipelined, 1.0);
3848  setOption(OPT_DSP_allocation_coefficient, NUM_CST_allocation_default_allocation_coefficient);
3849  setOption(OPT_estimate_logic_and_connections, true);
3850  setOption(OPT_registered_inputs, "auto");
3851  setOption(OPT_fsm_encoding, "auto");
3852  setOption(OPT_scheduling_mux_margins, 0.0);
3853  setOption(OPT_no_return_zero, false);
3854  setOption(OPT_bitvalue_ipa, true);
3855  setOption(OPT_range_analysis_mode, "");
3856  setOption(OPT_fp_format, "");
3857  setOption(OPT_fp_format_propagate, false);
3858  setOption(OPT_parallel_backend, false);
3859 
3860 #if HAVE_HOST_PROFILING_BUILT
3861  setOption(OPT_exec_argv, STR_CST_string_separator);
3862  setOption(OPT_profiling_method, static_cast<int>(HostProfiling_Method::PM_NONE));
3863  setOption(OPT_host_compiler, CompilerWrapper::getDefaultCompiler());
3864 #endif
3865  setOption(OPT_clock_period, 10.0);
3866  setOption(OPT_clock_period_resource_fraction, "1.0");
3867  setOption(OPT_mixed_design, true);
3868 #if HAVE_TASTE
3869  setOption(OPT_generate_taste_architecture, false);
3870 #endif
3871 #if HAVE_FROM_PRAGMA_BUILT
3872  setOption(OPT_num_accelerators, 4);
3873 #endif
3874  setOption(OPT_memory_banks_number, 1);
3875 
3877  setOption(OPT_testbench_map_mode, "DEVICE");
3878 
3879  panda_parameters["CSE_size"] = "2";
3880  panda_parameters["PortSwapping"] = "1";
3881  // panda_parameters["enable-CSROA"] = "1";
3882  panda_parameters["MAX_LUT_INT_SIZE"] = "8";
3883 }
3884 
3886 {
3887  auto preferred_compiler = getOption<CompilerWrapper_CompilerTarget>(OPT_default_compiler);
3888  std::string archive_files;
3889  bool is_subnormals = isOption(OPT_fp_subnormal) && getOption<bool>(OPT_fp_subnormal);
3890  std::string VSuffix = "";
3891  if(is_subnormals && lib == "m")
3892  {
3893  if(isOption(OPT_libm_std_rounding) && getOption<int>(OPT_libm_std_rounding))
3894  {
3895  VSuffix = "_subnormals_std";
3896  }
3897  else
3898  {
3899  VSuffix = "_subnormals";
3900  }
3901  }
3902  else if(lib == "m")
3903  {
3904  if(isOption(OPT_libm_std_rounding) && getOption<int>(OPT_libm_std_rounding))
3905  {
3906  VSuffix = "_std";
3907  }
3908  }
3909  if(isOption(OPT_archive_files))
3910  {
3911  archive_files = getOption<std::string>(OPT_archive_files) + STR_CST_string_separator;
3912  }
3913 
3914  setOption(OPT_archive_files, archive_files + relocate_compiler_path(PANDA_LIB_INSTALLDIR "/panda/lib", true) + lib +
3915  "_" + CompilerWrapper::getCompilerSuffix(preferred_compiler) + VSuffix + ".a");
3916 }
void write_xml_configuration_file(const std::string &filename)
Write an XML configuration file with the parameters actually stored.
Definition: Parameter.cpp:266
Class to compute evaluations about high-level synthesis.
Input function used to read the technology data structures.
#define CHANNELS_TYPE_MEM_ACC_N1
#define OPT_FP_FORMAT_INTERFACE
#define OPT_CLOCK_NAME
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
#define OPT_SIMULATE
#define OPT_PRETTY_PRINT
Module binding based on the analysis of the control data flow chained graph.
static void add_evaluation_objective_string(std::string &obj_string, const std::string &obj_to_add)
int exit_code
NOTE: this file must be included only by source code of the executable (i.e., the file with the main)...
static int getCompatibleCompilers()
static int debug_level
debug level (set by Parameter)
#define OPT_MAX_SIM_CYCLES
void setOption(const std::string &name, const G value)
Sets the value of an option.
Definition: Parameter.hpp:516
#define OPT_LATTICE_ROOT
#define OPT_BACKEND_SDC_EXTENSIONS_PARAMETER
File containing functions and utilities to support the printing of debug messagges.
#define OPT_RESET_NAME
#define OPT_NANOXPLORE_ROOT
#define CHANNELS_TYPE_MEM_ACC_NN
#define STR_CST_string_separator
The character used to separate concatenated string.
Definition: utility.hpp:61
This header file includes four different algorithms heuristically solving the clique covering problem...
std::string filename
#define OPT_UNALIGNED_ACCESS_PARAMETER
#define OPT_TESTBENCH
#define OPT_DISABLE_REG_INIT_VALUE
char **const argv
The input parameters;.
Definition: Parameter.hpp:311
#define OPT_ENABLE_FUNCTION_PROXY
const std::vector< std::string > SplitString(const std::string &input, const std::string &separators)
Function which splits a string into tokens.
#define COMMON_SHORT_OPTIONS_STRING
define the default tool short option string
Definition: Parameter.hpp:201
only external memory access Datapath see only 1 memory port, while the bus manage parallel accesses ...
bool NaturalVersionOrder(const std::filesystem::path &_x, const std::filesystem::path &_y)
Definition: fileIO.cpp:195
static bool is_evaluation_objective_string(const std::vector< std::string > &obj_vec, const std::string &s)
#define OPT_DISABLE_FUNCTION_PROXY
#define INDENT_OUT_MEX(outLevel, curOutLevel, mex)
all objects that need to be stored in memory are allocated on an external pipelined memory ...
#define OPT_DISCREPANCY_ONLY
void add_bambu_library(std::string lib)
add the library to the raw to be considered
#define STR_CST_concat_c_file
concatenated C temporary file
#define OPT_VHDL_LIBRARY_PARAMETER
static int getDefaultCompiler()
static bool hasCompilerM64(CompilerWrapper_CompilerTarget ct)
#define OPT_TESTBENCH_MAP_MODE
#define OPT_DSP_ALLOCATION_COEFFICIENT
#define OPT_SERIALIZE_MEMORY_ACCESSES
#define OPT_DISCREPANCY_NO_LOAD_POINTERS
#define OPT_AXI_BURST_TYPE
#define OPT_TB_EXTRA_GCC_OPTIONS
#define OPT_INPUT_CONTEXT_SWITCH
static bool isCurrentOrNewer(CompilerWrapper_CompilerTarget ct, CompilerWrapper_CompilerTarget compare)
#define OPT_RESET_TYPE
#define OPT_EXPERIMENTAL_SETUP
Class specification of the manager of the technology library data structures.
all objects that need to be stored in memory are allocated on an external memory
int Exec() override
Execute parameter parsing.
#define INPUT_OPT_DRY_RUN_EVALUATION
static bool isGccCheck(CompilerWrapper_CompilerTarget ct)
#define OPT_INLINE_FUNCTIONS
#define OPT_NANOXPLORE_BYPASS
#define OUTPUT_LEVEL_MINIMUM
minimum debugging print is performed.
Include a set of utilities used to manage CPU time measures.
#define OPT_BRAM_HIGH_LATENCY
void PrintUsage(std::ostream &os) const
Print the usage of this tool = PrintHeader() + PrintHelp()
Definition: Parameter.cpp:392
#define OPT_BACKEND_SCRIPT_EXTENSIONS_PARAMETER
#define OPT_STG
#define OPT_DSP_FRACTURING
#define OPT_ADDITIONAL_TOP
#define THROW_WARNING(str_expr)
helper function used to throw a warning in a standard way: though it uses PRINT_DBG_MEX, the debug level used is such that the message is always printed
Definition: exceptions.hpp:300
#define STR(s)
Macro which performs a lexical_cast to a string.
#define OPT_SOFT_FLOAT
Auxiliary methods for manipulating string.
void PrintHelp(std::ostream &os) const override
Print the usage of this tool.
#define OPT_RANGE_ANALYSIS_MODE
#define OPT_DISCREPANCY_HW
#define OPT_GENERATE_VCD
#define OPT_ILP
#define OPT_PARALLEL_BACKEND
Parameters_FileFormat GetFileFormat(const std::filesystem::path &file, bool check_cml_root_node=false) const
Return the file format given the file name or the extension.
Definition: Parameter.cpp:938
#define OPT_DSP_MARGIN_PIPELINED
std::filesystem::path unique_path(const std::filesystem::path &model)
Definition: fileIO.cpp:286
#define NUM_CST_allocation_default_allocation_coefficient
The default value for coefficient of PIPELINE STAGE 0.
bool starts_with(const std::string &str, const std::string &pattern)
#define OPT_LIST_BASED
#define OPT_MEM_DELAY_WRITE
#define OPT_TOP_FNAME
#define OPT_NUM_ACCELERATORS
void SetDefaults() override
Sets default values.
#define OPT_DISCREPANCY_PERMISSIVE_PTRS
#define OPT_FLOPOCO
#define OPT_FP_FORMAT
#define INPUT_OPT_TEST_SINGLE_NON_DETERMINISTIC_FLOW
#define OPT_PERIOD_CLOCK
all global variables, static variables and strings are allocated on BRAMs
#define GCC_SHORT_OPTIONS_STRING
define the GCC short option string
Definition: Parameter.hpp:236
#define OPT_RESET_LEVEL
This class writes different HDL based descriptions (VHDL, Verilog, SystemC) starting from a structura...
Abstract class for passes performing a dynamic profiling of loops, paths or both by means of predepen...
Class specification of the data structures used to manage technology information. ...
#define OPT_EVALUATION_MODE
#define OPT_TOP_RTLDESIGN_NAME
Basic blocks profiling.
#define OPT_MENTOR_OPTIMIZER
#define PARAMETER_PARSED
An integer value to return if parameters have been right parsed.
Definition: Parameter.hpp:93
virtual void CheckParameters()=0
Checks the compatibility among the different parameters and determines the implications.
Definition: Parameter.cpp:139
#define OPT_ALIGNED_ACCESS_PARAMETER
#define OPT_EXPOSE_GLOBALS
#define OPT_ILP_SOLVER
#define OPT_FP_EXC
utility function used to read files.
#define OPT_FP_SUB
Class definition of the sdc scheduling.
#define OPT_SPECULATIVE
#define OPT_DEVICE_NAME
#define OPT_DISTRAM_THRESHOLD
#define OPT_SOFT_FP
#define OPT_TIMING_VIOLATION
This file collects some utility functions and macros.
#define OPT_HLS_FPDIV
Base class to allocate memories in high-level synthesis.
#define OPT_CONNECT_IOB
#define DEBUG_LEVEL_NONE
no debugging print is performed.
static bool isClangCheck(CompilerWrapper_CompilerTarget ct)
constexpr void string_to_container(_OutputIt first, const std::string &str, const std::string &separator, bool trim_empty=true)
Definition: utility.hpp:148
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
#define OPT_POWER_OPTIMIZATION
#define OPT_SHARED_INPUT_REGISTERS
void add_experimental_setup_compiler_options(bool kill_printf)
add the following GCC options: -fwhole-program -fno-ipa-cp -fno-ipa-cp-clone and -D&#39;printf(fmt, ...)=&#39;
static bool hasCompilerGCCM32(CompilerWrapper_CompilerTarget ct)
static bool hasCompilerMX32(CompilerWrapper_CompilerTarget ct)
#define OPT_ARCHITECTURE_XML
None profiling method selected.
This file collects some utility functions.
std::string TrimSpaces(const std::string &value)
#define INPUT_OPT_TEST_MULTIPLE_NON_DETERMINISTIC_FLOWS
#define OPT_NO_MIXED_DESIGN
#define OPT_DISABLE_BOUNDED_FUNCTION
#define COMMON_LONG_OPTIONS
define default TOOL long options
Definition: Parameter.hpp:204
BambuParameter(const std::string &program_name, int argc, char **const argv)
Constructor.
#define OPT_DONE_NAME
constants used by HLS constants
class supporting the chaining optimization in high level synthesis
static bool hasCompilerCLANGM32(CompilerWrapper_CompilerTarget ct)
int get_class_debug_level(const std::string &class_name, int debug_level=-1) const
Return the debug level for a specific class.
Definition: Parameter.cpp:323
Class definition of the list_based structure.
#define OPT_FSM_ENCODING
for each memory at maximum n parallel direct accesses and one indirect access
void CheckParameters() override
Check the compatibility among the different parameters and compute implicated parameters.
#define OPT_START_NAME
std::string GetPath(std::filesystem::path path)
Definition: fileIO.hpp:140
#define OPT_ALTERA_ROOT
void PrintProgramName(std::ostream &os) const override
Print the name of the program to be included in the header.
#define OPT_MENTOR_ROOT
#define OPT_ILP_NEWFORM
#define OPT_MEMORY_MAPPED_TOP
#define OPT_ROM_DUPLICATION
all local variables, static variables and strings are allocated on BRAMs
#define OPT_DISCREPANCY
for each memory at maximum one direct access and one indirect access
#define OPT_DO_NOT_CHAIN_MEMORIES
#define OPT_SILP
#define OPT_FP_FORMAT_PROPAGATE
#define OPT_MAX_ULP
Bambu optimizationss + OPT_compiler_opt_level.
void getOption(const std::string &name, G &variable) const
Returns the value of an option.
Definition: Parameter.hpp:457
#define OPT_HLS_DIV
#define OPT_EVALUATION
constant strings
#define OPT_DISABLE_BITVALUE_IPA
std::string container_to_string(_InputIt first, _InputIt last, const std::string &separator, bool trim_empty=true)
Definition: utility.hpp:122
#define OPT_DO_NOT_USE_ASYNCHRONOUS_MEMORIES
#define OPT_DSP_MARGIN_COMBINATIONAL
void PrintGeneralOptionsUsage(std::ostream &os) const
Print the usage of the general common options.
Definition: Parameter.cpp:1105
#define PAR_LIST_BASED_OPT
constant correspond to the "parametric list based option"
Generic device description.
bool isOption(const std::string &name) const
Tests if an option has been stored.
Definition: Parameter.hpp:548
void PrintOutputOptionsUsage(std::ostream &os) const
Print the usage of the output common options.
Definition: Parameter.cpp:1123
#define CHANNELS_TYPE_MEM_ACC_11
int argc
The number of input paramters.
Definition: Parameter.hpp:308
#define OPT_HOST_PROFILING
#define OPT_PRAGMA_PARSE
#define OPT_DISCREPANCY_FORCE
#define GCC_LONG_OPTIONS
Definition: Parameter.hpp:248
#define PRINT_MSG(mex)
all objects that need to be stored in memory are allocated on BRAMs
#define OPT_CLOCK_PERIOD_RESOURCE_FRACTION
#define OPT_TESTBENCH_PARAM_SIZE
#define OPT_TB_QUEUE_SIZE
#define OPT_ACCEPT_NONZERO_RETURN
Design Space Exploration.
#define OPT_REGISTERED_INPUTS
#define OPT_VERILATOR_PARALLEL
#define OPT_REGISTER_ALLOCATION
std::string relocate_compiler_path(const std::string &path, bool resolve_path=false)
Definition: fileIO.hpp:149
bool ManageDefaultOptions(int next_option, char *optarg_param, bool &exit_success)
Manage default options (common to all tools)
Definition: Parameter.cpp:398
#define OPT_MEMORY_BANKS_NUMBER
#define INPUT_OPT_C_NO_PARSE
#define OPT_USE_ALUS
#define OPT_MEM_DELAY_READ
#define OPT_XILINX_ROOT
#define OPT_SCHEDULING_MUX_MARGINS
#define OPT_LIBM_STD_ROUNDING
#define OPT_TIMING_MODEL
#define OPT_FP_RND
#define INPUT_OPT_FILE_INPUT_DATA
static std::string getCompilerSuffix(CompilerWrapper_CompilerTarget pc)
#define PARAMETER_NOTPARSED
Definition: Parameter.hpp:94
#define INPUT_OPT_C_PYTHON_NO_PARSE
CustomMap< std::string, std::string > panda_parameters
Map between the name of a parameter and the related string-form value.
Definition: Parameter.hpp:317
bool removeOption(const enum enum_option name)
Remove an option.
Definition: Parameter.hpp:578
#define OPT_SKIP_PIPE_PARAMETER
This class provide an interface to different solvers.
#define OPT_TESTBENCH_ARGV
#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
Implementation of the wrapper to Gcc for C sources.

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