48 #include "config_SKIP_WARNING_SECTIONS.hpp" 50 #include "config_WPEDANTIC.hpp" 78 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 79 #pragma GCC diagnostic push 80 #pragma GCC diagnostic ignored "-Wshadow" 81 #pragma GCC diagnostic ignored "-Wconversion" 82 #pragma GCC diagnostic ignored "-Wold-style-cast" 83 #pragma GCC diagnostic ignored "-Wsign-conversion" 84 #pragma GCC diagnostic ignored "-Wredundant-decls" 85 #pragma GCC diagnostic ignored "-Wunused-parameter" 87 #pragma GCC diagnostic ignored "-Wpedantic" 90 #pragma GCC diagnostic warning "-Wshadow" 91 #pragma GCC diagnostic warning "-Wconversion" 92 #pragma GCC diagnostic warning "-Wold-style-cast" 93 #pragma GCC diagnostic warning "-Wsign-conversion" 94 #pragma GCC diagnostic warning "-Wredundant-decls" 95 #pragma GCC diagnostic warning "-Wunused-parameter" 97 #pragma GCC diagnostic warning "-Wpedantic" 103 #include "FP2Fix.hpp" 104 #include "FPAdderSinglePath.hpp" 109 #include "FPMultiplier.hpp" 111 #include "FPSqrt.hpp" 112 #include "FPSqrtPoly.hpp" 117 #include "Fix2FP.hpp" 118 #include "InputIEEE.hpp" 119 #include "Operator.hpp" 120 #include "OutputIEEE.hpp" 121 #include "Target.hpp" 122 #include "Targets/CycloneII.hpp" 123 #include "Targets/CycloneV.hpp" 124 #include "Targets/Spartan3.hpp" 125 #include "Targets/StratixII.hpp" 126 #include "Targets/StratixIII.hpp" 127 #include "Targets/StratixIV.hpp" 128 #include "Targets/Virtex4.hpp" 129 #include "Targets/Virtex5.hpp" 130 #include "Targets/Virtex6.hpp" 132 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 133 #pragma GCC diagnostic pop 139 #define OPLIST oplist 157 const std::string& FU_target)
160 debug_level(_debug_level),
167 if(
"Spartan-3" == FU_target)
169 target =
new flopoco::Spartan3();
171 else if(
"Virtex-4" == FU_target)
173 target =
new flopoco::Virtex4();
175 else if(
"Virtex-5" == FU_target)
177 target =
new flopoco::Virtex5();
179 else if(
"Virtex-6" == FU_target)
181 target =
new flopoco::Virtex6();
183 else if(FU_target.find(
"Virtex-7") != std::string::npos)
185 target =
new flopoco::Virtex6();
187 else if(FU_target.find(
"Ultrascale") != std::string::npos)
189 target =
new flopoco::Virtex6();
191 else if(FU_target.find(
"Zynq") != std::string::npos)
193 target =
new flopoco::Virtex6();
195 else if(FU_target.find(
"Artix-7") != std::string::npos)
197 target =
new flopoco::Virtex6();
199 else if(FU_target.find(
"CycloneII") != std::string::npos)
201 target =
new flopoco::CycloneII();
203 else if(FU_target.find(
"CycloneV") != std::string::npos)
205 target =
new flopoco::CycloneV();
207 else if(FU_target.find(
"StratixII") != std::string::npos)
209 target =
new flopoco::StratixII();
211 else if(FU_target.find(
"StratixIII") != std::string::npos)
213 target =
new flopoco::StratixIII();
215 else if(FU_target.find(
"StratixIV") != std::string::npos)
217 target =
new flopoco::StratixIV();
219 else if(FU_target.find(
"StratixV") != std::string::npos)
221 target =
new flopoco::StratixIV();
223 else if(FU_target.find(
"LatticeECP3") != std::string::npos)
225 target =
new flopoco::CycloneII();
227 else if(FU_target.find(
"LatticeECP5") != std::string::npos)
229 target =
new flopoco::CycloneII();
231 else if(
"NG-MEDIUM" == FU_target)
233 target =
new flopoco::Virtex5();
235 else if(
"NG-LARGE" == FU_target)
237 target =
new flopoco::Virtex5();
239 else if(
"NG-ULTRA" == FU_target)
241 target =
new flopoco::Virtex6();
243 else if(FU_target.find(
"Generic") != std::string::npos)
245 target =
new flopoco::Virtex5();
261 setRecoverEnvironment(&recover);
262 extern int recoverEnvironmentReady;
263 recoverEnvironmentReady = 1;
272 const std::string& FU_name,
const std::string& pipe_parameter)
275 unsigned int n_mant_in, n_exp_in;
276 unsigned int n_mant_out, n_exp_out;
283 "Creating FloPoCo operator for unit " + FU_type +
"(" +
STR(FU_prec_in) +
"-" +
STR(FU_prec_out) +
284 "-" + pipe_parameter +
")");
286 if(pipe_parameter !=
"" && pipe_parameter !=
"0")
289 freq = std::stod(pipe_parameter);
293 target->setNotPipelined();
298 target->setFrequency(1e6 * freq);
300 flopoco::Operator* op =
nullptr;
301 THROW_ASSERT(n_mant_in > 0 && n_exp_in > 0,
"Unsupported significand and exponent values.");
302 THROW_ASSERT(n_mant_out > 0 && n_exp_out > 0,
"Unsupported significand and exponent values.");
305 type = flopoco_wrapper::UT_UNKNOWN;
306 if(
"FPAdder" == FU_type)
308 type = flopoco_wrapper::UT_ADD;
309 op =
new flopoco::FPAdderSinglePath(
target, static_cast<int>(n_exp_in), static_cast<int>(n_mant_in),
310 static_cast<int>(n_exp_in), static_cast<int>(n_mant_in),
311 static_cast<int>(n_exp_out), static_cast<int>(n_mant_out));
313 else if(
"FPSub" == FU_type)
315 type = flopoco_wrapper::UT_SUB;
316 op =
new flopoco::FPAdderSinglePath(
target, static_cast<int>(n_exp_in), static_cast<int>(n_mant_in),
317 static_cast<int>(n_exp_in), static_cast<int>(n_mant_in),
318 static_cast<int>(n_exp_out), static_cast<int>(n_mant_out));
320 else if(
"FPAddSub" == FU_type)
322 type = flopoco_wrapper::UT_ADDSUB;
323 op =
new flopoco::FPAdderSinglePath(
target, static_cast<int>(n_exp_in), static_cast<int>(n_mant_in),
324 static_cast<int>(n_exp_in), static_cast<int>(n_mant_in),
325 static_cast<int>(n_exp_out), static_cast<int>(n_mant_out));
327 else if(
"FPMultiplier" == FU_type)
329 type = flopoco_wrapper::UT_MULT;
330 op =
new flopoco::FPMultiplier(
target, static_cast<int>(n_exp_in), static_cast<int>(n_mant_in),
331 static_cast<int>(n_exp_in), static_cast<int>(n_mant_in),
332 static_cast<int>(n_exp_out), static_cast<int>(n_mant_out));
334 else if(
"FPDiv" == FU_type)
336 type = flopoco_wrapper::UT_DIV;
337 op =
new flopoco::FPDiv(
target, static_cast<int>(n_exp_in), static_cast<int>(n_mant_in));
339 else if(
"FPExp" == FU_type)
341 type = flopoco_wrapper::UT_EXP;
342 op =
new flopoco::FPExp(
target, static_cast<int>(n_exp_in), static_cast<int>(n_mant_in), 0, 0, -1,
false, 0.7f);
344 else if(
"FPSqrtPoly" == FU_type)
346 type = flopoco_wrapper::UT_SQRT;
348 new flopoco::FPSqrtPoly(
target, static_cast<int>(n_exp_in), static_cast<int>(n_mant_in),
false, 3 );
350 else if(
"FPSqrt" == FU_type)
352 type = flopoco_wrapper::UT_SQRT;
353 op =
new flopoco::FPSqrt(
target, static_cast<int>(n_exp_in), static_cast<int>(n_mant_in));
355 else if(
"Fix2FP_32_32" == FU_type)
358 type = flopoco_wrapper::UT_IFIX2FP;
361 op =
new flopoco::Fix2FP(
target, 0, static_cast<int>(FU_prec_in) - 1, 1, static_cast<int>(n_exp_out),
362 static_cast<int>(n_mant_out));
364 else if(
"Fix2FP_32_64" == FU_type)
367 type = flopoco_wrapper::UT_IFIX2FP;
370 op =
new flopoco::Fix2FP(
target, 0, static_cast<int>(FU_prec_in) - 1, 1, static_cast<int>(n_exp_out),
371 static_cast<int>(n_mant_out));
373 else if(
"Fix2FP_64_32" == FU_type)
377 type = flopoco_wrapper::UT_IFIX2FP;
379 op =
new flopoco::Fix2FP(
target, 0, static_cast<int>(FU_prec_in) - 1, 1, static_cast<int>(n_exp_out),
380 static_cast<int>(n_mant_out));
382 else if(
"Fix2FP_64_64" == FU_type)
385 type = flopoco_wrapper::UT_IFIX2FP;
388 op =
new flopoco::Fix2FP(
target, 0, static_cast<int>(FU_prec_in) - 1, 1, static_cast<int>(n_exp_out),
389 static_cast<int>(n_mant_out));
391 else if(
"UFix2FP_32_32" == FU_type)
393 type = flopoco_wrapper::UT_UFIX2FP;
396 op =
new flopoco::Fix2FP(
target, 0, static_cast<int>(FU_prec_in) - 1, 0, static_cast<int>(n_exp_out),
397 static_cast<int>(n_mant_out));
399 else if(
"UFix2FP_32_64" == FU_type)
401 type = flopoco_wrapper::UT_UFIX2FP;
404 op =
new flopoco::Fix2FP(
target, 0, static_cast<int>(FU_prec_in) - 1, 0, static_cast<int>(n_exp_out),
405 static_cast<int>(n_mant_out));
407 else if(
"UFix2FP_64_32" == FU_type)
409 type = flopoco_wrapper::UT_UFIX2FP;
412 op =
new flopoco::Fix2FP(
target, 0, static_cast<int>(FU_prec_in) - 1, 0, static_cast<int>(n_exp_out),
413 static_cast<int>(n_mant_out));
415 else if(
"UFix2FP_64_64" == FU_type)
417 type = flopoco_wrapper::UT_UFIX2FP;
420 op =
new flopoco::Fix2FP(
target, 0, static_cast<int>(FU_prec_in) - 1, 0, static_cast<int>(n_exp_out),
421 static_cast<int>(n_mant_out));
423 else if(
"FP2Fix_32_32" == FU_type)
425 type = flopoco_wrapper::UT_FP2IFIX;
428 op =
new flopoco::FP2Fix(
target, 0, static_cast<int>(FU_prec_out) - 1, 1, static_cast<int>(n_exp_in),
429 static_cast<int>(n_mant_in),
true);
431 else if(
"FP2Fix_32_u32" == FU_type)
433 type = flopoco_wrapper::UT_FP2UFIX;
436 op =
new flopoco::FP2Fix(
target, 0, static_cast<int>(FU_prec_out) - 1, 0, static_cast<int>(n_exp_in),
437 static_cast<int>(n_mant_in),
true);
439 else if(
"FP2Fix_32_64" == FU_type)
441 type = flopoco_wrapper::UT_FP2IFIX;
444 op =
new flopoco::FP2Fix(
target, 0, static_cast<int>(FU_prec_out) - 1, 1, static_cast<int>(n_exp_in),
445 static_cast<int>(n_mant_in),
true);
447 else if(
"FP2Fix_32_u64" == FU_type)
449 type = flopoco_wrapper::UT_FP2UFIX;
452 op =
new flopoco::FP2Fix(
target, 0, static_cast<int>(FU_prec_out) - 1, 0, static_cast<int>(n_exp_in),
453 static_cast<int>(n_mant_in),
true);
455 else if(
"FP2Fix_64_32" == FU_type)
457 type = flopoco_wrapper::UT_FP2IFIX;
460 op =
new flopoco::FP2Fix(
target, 0, static_cast<int>(FU_prec_out) - 1, 1, static_cast<int>(n_exp_in),
461 static_cast<int>(n_mant_in),
true);
463 else if(
"FP2Fix_64_u32" == FU_type)
465 type = flopoco_wrapper::UT_FP2UFIX;
468 op =
new flopoco::FP2Fix(
target, 0, static_cast<int>(FU_prec_out) - 1, 0, static_cast<int>(n_exp_in),
469 static_cast<int>(n_mant_in),
true);
471 else if(
"FP2Fix_64_64" == FU_type)
473 type = flopoco_wrapper::UT_FP2IFIX;
476 op =
new flopoco::FP2Fix(
target, 0, static_cast<int>(FU_prec_out) - 1, 1, static_cast<int>(n_exp_in),
477 static_cast<int>(n_mant_in),
true);
479 else if(
"FP2Fix_64_u64" == FU_type)
481 type = flopoco_wrapper::UT_FP2UFIX;
484 op =
new flopoco::FP2Fix(
target, 0, static_cast<int>(FU_prec_out) - 1, 0, static_cast<int>(n_exp_in),
485 static_cast<int>(n_mant_in),
true);
487 else if(
"FF_CONV" == FU_type)
489 type = flopoco_wrapper::UT_FF_CONV;
492 else if(
"FPgt_expr" == FU_type)
494 type = flopoco_wrapper::UT_compare_expr;
497 else if(
"FPlt_expr" == FU_type)
499 type = flopoco_wrapper::UT_compare_expr;
502 else if(
"FPge_expr" == FU_type)
504 type = flopoco_wrapper::UT_compare_expr;
507 else if(
"FPle_expr" == FU_type)
509 type = flopoco_wrapper::UT_compare_expr;
512 else if(
"FPLog" == FU_type)
514 type = flopoco_wrapper::UT_LOG;
515 op =
new flopoco::FPLog(
target, static_cast<int>(n_exp_in), static_cast<int>(n_mant_in), 0);
517 else if(
"FPPow" == FU_type)
519 type = flopoco_wrapper::UT_POW;
520 op =
new flopoco::FPPow(
target, static_cast<int>(n_exp_in), static_cast<int>(n_mant_in), 0);
527 std::string FU_name_stored;
528 FU_name_stored =
ENCODE_NAME(FU_name, FU_prec_in, FU_prec_out, pipe_parameter);
531 FU_to_prec.insert(make_pair(FU_name_stored, std::pair<unsigned int, unsigned int>(FU_prec_in, FU_prec_out)));
535 if(
type != flopoco_wrapper::UT_IFIX2FP and
type != flopoco_wrapper::UT_UFIX2FP)
537 if(
type == flopoco_wrapper::UT_FF_CONV)
539 op =
new flopoco::InputIEEE(
target, static_cast<int>(n_exp_in), static_cast<int>(n_mant_in),
540 static_cast<int>(n_exp_out), static_cast<int>(n_mant_out));
544 op =
new flopoco::InputIEEE(
target, static_cast<int>(n_exp_in), static_cast<int>(n_mant_in),
545 static_cast<int>(n_exp_in), static_cast<int>(n_mant_in));
551 if(
type != flopoco_wrapper::UT_FP2UFIX and
type != flopoco_wrapper::UT_FP2IFIX and
552 type != flopoco_wrapper::UT_compare_expr)
554 op =
new flopoco::OutputIEEE(
target, static_cast<int>(n_exp_out), static_cast<int>(n_mant_out),
555 static_cast<int>(n_exp_out), static_cast<int>(n_mant_out),
true);
563 const unsigned int FU_prec_out,
564 const std::string& pipe_parameter)
const 566 std::string FU_name_stored =
ENCODE_NAME(FU_name, FU_prec_in, FU_prec_out, pipe_parameter);
567 unsigned int fu_pipe_depth =
static_cast<unsigned int>(
get_FU(
WRAPPED_PREFIX + FU_name_stored)->getPipelineDepth());
568 if(
type != flopoco_wrapper::UT_IFIX2FP and
type != flopoco_wrapper::UT_UFIX2FP)
570 fu_pipe_depth +=
static_cast<unsigned int>(
get_FU(
IN_WRAP_PREFIX + FU_name_stored)->getPipelineDepth());
572 if(
type != flopoco_wrapper::UT_FP2UFIX and
type != flopoco_wrapper::UT_FP2IFIX and
573 type != flopoco_wrapper::UT_compare_expr)
575 fu_pipe_depth +=
static_cast<unsigned int>(
get_FU(
OUT_WRAP_PREFIX + FU_name_stored)->getPipelineDepth());
577 return fu_pipe_depth;
582 auto op_found =
FUs.find(FU_name_stored);
583 THROW_ASSERT(op_found !=
FUs.end(),
"Functional unit " + FU_name_stored +
" not found (maybe not yet generated)");
584 return op_found->second;
588 const std::string& pipe_parameter)
592 PP(os,
"library ieee;\n");
593 PP(os,
"use ieee.std_logic_1164.all;\n");
594 PP(os,
"use ieee.numeric_std.all;\n");
596 PP(os,
"entity " + FU_name_stored +
" is\n");
603 for(
const auto& p_in_it : p_in)
605 PP(os,
"BITSIZE_" + p_in_it +
": integer := " +
STR(FU_to_prec_it->second.first) +
"; ");
609 for(
auto p_out_it = p_out.begin(); p_out_it != p_out.end(); ++p_out_it)
611 if(p_out_it + 1 != p_out.end())
613 PP(os,
"BITSIZE_" + *p_out_it +
": integer := " +
STR(FU_to_prec_it->second.second) +
";");
617 PP(os,
"BITSIZE_" + *p_out_it +
": integer := " +
STR(FU_to_prec_it->second.second));
629 PP(os,
"end entity;\n");
631 PP(os,
"architecture arch of " + FU_name_stored +
" is\n");
635 for(
const auto& prefixe : prefixes)
637 if(!(((
type == flopoco_wrapper::UT_UFIX2FP or
type == flopoco_wrapper::UT_IFIX2FP) &&
639 (((
type == flopoco_wrapper::UT_FP2UFIX or
type == flopoco_wrapper::UT_FP2IFIX) ||
640 type == flopoco_wrapper::UT_compare_expr) &&
641 prefixe == OUT_WRAP_PREFIX)))
643 PP(os,
"component " + prefixe + FU_name_stored +
"\n");
655 else if(OUT_WRAP_PREFIX == prefixe)
666 PP(os,
"end component;\n");
675 if(
type == flopoco_wrapper::UT_FP2UFIX)
677 PP(os,
"O <= unsigned(wireOut1);\n");
679 else if(
type == flopoco_wrapper::UT_FP2IFIX)
681 PP(os,
"O <= signed(wireOut1);\n");
687 PP(os,
"end architecture;\n");
692 const std::string& pipe_parameter)
697 std::vector<std::string> p_in_wrap_in;
698 std::vector<std::string> p_in_wrap_out;
699 if(
type != flopoco_wrapper::UT_IFIX2FP and
type != flopoco_wrapper::UT_UFIX2FP)
704 std::vector<std::string> p_out_wrap_in;
705 std::vector<std::string> p_out_wrap_out;
706 if(
type != flopoco_wrapper::UT_FP2UFIX and
type != flopoco_wrapper::UT_FP2IFIX and
707 type != flopoco_wrapper::UT_compare_expr)
715 unsigned int n_bits_in ;
716 unsigned int prec_in ;
717 prec_in = FU_to_prec_it->second.first;
724 for(
unsigned int i = 0; i < p_wrapped_in.size(); i++)
726 if(
type == flopoco_wrapper::UT_ADDSUB && i == 1)
728 mapping += p_wrapped_in.at(i) +
" => wire_ADDSUB, ";
730 else if(
type == flopoco_wrapper::UT_SUB && i == 1)
732 mapping += p_wrapped_in.at(i) +
" => wire_SUB, ";
734 else if(
type == flopoco_wrapper::UT_IFIX2FP)
736 mapping += p_wrapped_in.at(i) +
" => std_logic_vector(" + p_wrapped_in.at(i) +
"), ";
738 else if(
type == flopoco_wrapper::UT_UFIX2FP)
740 mapping += p_wrapped_in.at(i) +
" => std_logic_vector(" + p_wrapped_in.at(i) +
"), ";
744 mapping += p_wrapped_in.at(i) +
" => wireIn" +
STR(i + 1) +
", ";
747 for(
unsigned int j = 0; j < p_wrapped_out.size(); j++)
749 if(
type == flopoco_wrapper::UT_compare_expr)
751 mapping += p_wrapped_out.at(j) +
" => " + p_wrapped_out.at(j) +
"(0 downto 0)";
755 mapping += p_wrapped_out.at(j) +
" => wireOut" +
STR(j + 1);
758 if(pipe_parameter !=
"" && pipe_parameter !=
"0")
760 const std::string p_clock =
get_port(clk);
761 const std::string p_reset =
get_port(rst);
766 if(
type == flopoco_wrapper::UT_ADDSUB)
768 PP(os,
"wire_ADDSUB <= wireIn2(" +
STR(n_bits_in + 1) +
" downto " +
STR(n_bits_in) +
") & (wireIn2(" +
769 STR(n_bits_in - 1) +
") xor sel_minus_expr) & wireIn2(" +
STR(n_bits_in - 2) +
" downto 0);\n");
771 else if(
type == flopoco_wrapper::UT_SUB)
773 PP(os,
"wire_SUB <= wireIn2(" +
STR(n_bits_in + 1) +
" downto " +
STR(n_bits_in) +
") & (wireIn2(" +
774 STR(n_bits_in - 1) +
") xor '1') & wireIn2(" +
STR(n_bits_in - 2) +
" downto 0);\n");
776 else if(
type == flopoco_wrapper::UT_EXP ||
type == flopoco_wrapper::UT_SQRT ||
type == flopoco_wrapper::UT_LOG ||
777 type == flopoco_wrapper::UT_POW)
783 if(
type != flopoco_wrapper::UT_IFIX2FP and
type != flopoco_wrapper::UT_UFIX2FP)
785 for(
unsigned int i = 0; i < p_wrapped_in.size(); i++)
788 mapping += p_in_wrap_in.at(0) +
"=>" + p_wrapped_in.at(i) +
", ";
789 mapping += p_in_wrap_out.at(0) +
"=>wireIn" +
STR(i + 1);
790 if(pipe_parameter !=
"" && pipe_parameter !=
"0")
792 const std::string p_clock =
get_port(clk);
793 const std::string p_reset =
get_port(rst);
794 mapping +=
", " + p_clock +
"=> " + std::string(
CLOCK_PORT_NAME) +
", " + p_reset +
"=> " +
797 PP(os,
"in" +
STR(i + 1) +
" : " +
STR(
IN_WRAP_PREFIX + FU_name_stored) +
" port map (" + mapping +
");\n");
801 if(
type != flopoco_wrapper::UT_FP2UFIX and
type != flopoco_wrapper::UT_FP2IFIX and
802 type != flopoco_wrapper::UT_compare_expr)
804 for(
unsigned int i = 0; i < p_wrapped_out.size(); i++)
807 mapping += p_out_wrap_in.at(0) +
"=>wireOut" +
STR(i + 1) +
", ";
808 mapping += p_out_wrap_out.at(0) +
"=>" + p_wrapped_out.at(i);
809 if(pipe_parameter !=
"" && pipe_parameter !=
"0")
811 const std::string p_clock =
get_port(clk);
812 const std::string p_reset =
get_port(rst);
813 mapping +=
", " + p_clock +
"=> " + std::string(
CLOCK_PORT_NAME) +
", " + p_reset +
"=> " +
823 std::string Signals =
"";
828 unsigned int n_bits_in, n_bits_out;
829 unsigned int prec_in, prec_out;
830 prec_in = FU_to_prec_it->second.first;
831 prec_out = FU_to_prec_it->second.second;
833 n_bits_out = prec_out;
835 if(
type == flopoco_wrapper::UT_ADDSUB)
837 Signals +=
"wire_ADDSUB, ";
839 else if(
type == flopoco_wrapper::UT_SUB)
841 Signals +=
"wire_SUB, ";
843 else if(
type == flopoco_wrapper::UT_FF_CONV)
845 n_bits_in = prec_out;
848 if(
type == flopoco_wrapper::UT_IFIX2FP or
type == flopoco_wrapper::UT_UFIX2FP)
850 if(prec_in != prec_out)
852 PP(os,
"signal I_temp : std_logic_vector(" +
STR(
std::max(prec_in, prec_out) - 1) +
" downto 0);\n");
857 size_t n_in_elements = p_in.size();
858 for(
unsigned int i = 0; i < n_in_elements; i++)
860 Signals +=
"wireIn" +
STR(i + 1) + (i + 1 != n_in_elements ?
", " :
"");
862 PP(os,
"signal " + Signals +
" : std_logic_vector(" +
STR(n_bits_in + 1) +
" downto 0);\n");
864 if(
type == flopoco_wrapper::UT_FP2UFIX or
type == flopoco_wrapper::UT_FP2IFIX)
867 for(
unsigned int j = 0; j < p_out.size(); j++)
869 Signals +=
"wireOut" +
STR(j + 1) + (j + 1 != p_out.size() ?
", " :
"");
871 PP(os,
"signal " + Signals +
" : std_logic_vector(" +
STR(n_bits_out - 1) +
" downto 0);\n");
873 else if(
type != flopoco_wrapper::UT_compare_expr)
876 for(
unsigned int j = 0; j < p_out.size(); j++)
878 Signals +=
"wireOut" +
STR(j + 1) + (j + 1 != p_out.size() ?
", " :
"");
880 PP(os,
"signal " + Signals +
" : std_logic_vector(" +
STR(n_bits_out + 1) +
" downto 0);\n");
885 std::ostream& os,
component_type c_type,
const std::string& pipe_parameter)
888 int in_offset, out_offset;
889 unsigned int n_bits_in, n_bits_out;
890 unsigned int prec_in, prec_out;
893 in_offset = out_offset = -1;
894 n_bits_in = n_bits_out = 0;
895 prec_in = FU_to_prec_it->second.first;
896 prec_out = FU_to_prec_it->second.second;
897 if(wrapped == c_type)
899 if(
type != flopoco_wrapper::UT_IFIX2FP and
type != flopoco_wrapper::UT_UFIX2FP)
903 if(
type != flopoco_wrapper::UT_FP2UFIX and
type != flopoco_wrapper::UT_FP2IFIX and
904 type != flopoco_wrapper::UT_compare_expr)
908 if(
type == flopoco_wrapper::UT_FF_CONV)
910 n_bits_in = n_bits_out = prec_out;
912 else if(
type == flopoco_wrapper::UT_compare_expr)
920 n_bits_out = prec_out;
923 else if(in_wrap == c_type)
926 if(
type == flopoco_wrapper::UT_FF_CONV)
929 n_bits_out = prec_out;
933 n_bits_in = n_bits_out = prec_in;
936 else if(out_wrap == c_type)
939 n_bits_in = n_bits_out = prec_out;
941 if(pipe_parameter !=
"" && pipe_parameter !=
"0")
943 if(wrapped == c_type || in_wrap == c_type || out_wrap == c_type)
949 const std::vector<std::string> p_in =
get_ports(FU_prefix + FU_name_stored, 0, port_in,
false);
950 for(
const auto& p_in_it : p_in)
954 if(
type == flopoco_wrapper::UT_IFIX2FP)
956 PP(os, p_in_it +
" : in signed(BITSIZE_" + p_in_it +
"-1 downto 0);\n");
958 else if(
type == flopoco_wrapper::UT_UFIX2FP)
960 PP(os, p_in_it +
" : in unsigned(BITSIZE_" + p_in_it +
"-1 downto 0);\n");
964 PP(os, p_in_it +
" : in std_logic_vector(BITSIZE_" + p_in_it +
"-1 downto 0);\n");
967 else if(static_cast<int>(n_bits_in) + in_offset > 0)
969 PP(os, p_in_it +
" : in std_logic_vector(" +
STR(static_cast<int>(n_bits_in) + in_offset) +
" downto 0);\n");
973 PP(os, p_in_it +
" : in std_logic;\n");
982 if(
type == flopoco_wrapper::UT_ADDSUB)
984 PP(os, std::string(
"sel_plus_expr") +
" : in std_logic;\n");
985 PP(os, std::string(
"sel_minus_expr") +
" : in std_logic;\n");
987 else if(
type == flopoco_wrapper::UT_EXP ||
type == flopoco_wrapper::UT_SQRT ||
type == flopoco_wrapper::UT_LOG ||
988 type == flopoco_wrapper::UT_POW)
995 const std::vector<std::string> p_out =
get_ports(FU_prefix + FU_name_stored, 0, port_out,
false);
996 for(
auto p_out_it = p_out.begin(); p_out_it != p_out.end(); ++p_out_it)
1000 if(
type == flopoco_wrapper::UT_FP2IFIX)
1002 PP(os, *p_out_it +
" : out signed(BITSIZE_" + *p_out_it +
"-1 downto 0)\n");
1004 else if(
type == flopoco_wrapper::UT_FP2UFIX)
1006 PP(os, *p_out_it +
" : out unsigned(BITSIZE_" + *p_out_it +
"-1 downto 0)\n");
1010 PP(os, *p_out_it +
" : out std_logic_vector(BITSIZE_" + *p_out_it +
"-1 downto 0)\n");
1016 *p_out_it +
" : out std_logic_vector(" +
STR(static_cast<int>(n_bits_out) + out_offset) +
" downto 0)\n");
1018 if(p_out_it + 1 != p_out.end())
1031 os <<
"--------------------------------------------------------------------------------" << endl;
1032 os <<
"-- " << FU_name_stored << endl;
1033 os <<
"-- Operator automatically generated by " << PACKAGE_NAME <<
" framework version " << PACKAGE_VERSION << endl;
1034 os <<
"-- assemblying operators generated by the Infinite Virtual Library FloPoCoLib" << endl;
1035 os <<
"-- Send any bug to: " << PACKAGE_BUGREPORT << endl;
1036 os <<
"--------------------------------------------------------------------------------" << endl;
1040 const unsigned int FU_prec_out,
const std::string&
filename,
1041 const std::string& pipe_parameter)
1043 std::string FU_name_stored =
ENCODE_NAME(FU_name, FU_prec_in, FU_prec_out, pipe_parameter);
1045 "Writing VHDL code for unit " + FU_name_stored +
" to file " + filename);
1051 std::ofstream
file(filename.c_str());
1061 flopoco::Operator::outputVHDLToFile(
OPLIST,
file);
1063 catch(
const std::string& s)
1065 cerr <<
"Exception while generating '" << s << endl;
1080 const unsigned int FU_prec_out, std::string pipe_parameter, std::string&
filename)
1083 return this->
InternalWriteVHDL(FU_name, FU_prec_in, FU_prec_out, filename, pipe_parameter);
1088 std::vector<flopoco::Operator*>* common_oplist =
target->getGlobalOpListRef();
1089 if(!common_oplist || common_oplist->empty())
1094 std::ofstream
file(filename.c_str());
1104 flopoco::Operator::outputVHDLToFile(*common_oplist,
file);
1106 catch(
const std::string& s)
1120 std::vector<std::string> ports;
1121 flopoco::Operator* op =
get_FU(FU_name_stored);
1122 for(
int i = 0; i < op->getIOListSize(); i++)
1124 flopoco::Signal* sig = op->getIOListSignal(i);
1125 if(local_type == port_in && sig->type() == flopoco::Signal::in)
1127 ports.push_back(sig->getName());
1129 else if(local_type == port_out && sig->type() == flopoco::Signal::out)
1131 ports.push_back(sig->getName());
1134 THROW_ASSERT(!check_ports || expected_ports == ports.size(),
1135 "Expected a different number of " +
1136 (local_type == port_in ? std::string(
"input") : std::string(
"output")) +
" ports");
1142 if(local_type == rst)
1146 else if(local_type == clk)
1178 THROW_ERROR(
"Intel Extended Precision not currently supported");
1191 n_exp = 8 + (3u * (FU_prec - 32) / 32);
1192 n_mant = FU_prec - n_exp - 1;
Forward declarations of FloPoCo classes.
vector< pair< string, int > > theUseTable
const std::string get_port(port_type type) const
Returns the name of a port, according to the needed port type (clock or reset)
int InternalWriteVHDL(const std::string &FU_name, const unsigned int FU_prec_in, const unsigned int FU_prec_out, const std::string &filename, const std::string &pipe_parameter)
Writes the VHDL for a Functional Unit to the desired file name Returns -1 if some problem occurred...
void * top(node_stack *head)
FPge_expr module for flopoco.
File containing functions and utilities to support the printing of debug messagges.
#define PRINT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
int writeVHDL(const std::string &FU_name, const unsigned int FU_prec_in, const unsigned int FU_prec_out, std::string pipe_parameter, std::string &filename)
Writes the VHDL for a Functional Unit to the default file name, which is "FU_name.vhdl" Returns -1 if some problem occurred, 0 if the file was successfully written, 1 if the FU was already written to a file.
#define DEBUG_LEVEL_PEDANTIC
very verbose debugging print is performed.
simple_indent PP
Pretty print functor object used to indent the generated code.
exceptions managed by PandA
enum { port_in, port_out, clk, rst } port_type
Port types.
#define IN_WRAP_PREFIX
Prefix for the wrapper to the inputs.
void outputWrapVHDL(const std::string &FU_name_stored, std::ostream &os, const std::string &pipe_parameter)
#define ENCODE_NAME(FU_name, FU_prec_in, FU_prec_out, pipe_parameter)
Name of the stored Functional Unit.
FPlt_expr module for flopoco.
redefinition of map to manage ordered/unordered structures
int debug_level
Current debug level.
#define STR(s)
Macro which performs a lexical_cast to a string.
void deindent()
Manually reduce the indenting of the code.
#define WRAPPED_PREFIX
Suffix appended to the internal (wrapped) Functional Unit.
FPgt_expr module for flopoco.
std::string writeVHDLcommon()
write the common components
#define CLOCK_PORT_NAME
standard name for ports
CustomUnorderedSet< std::string > FU_files
Set of Functional Units written to a .vhdl file.
CustomUnorderedMap< std::string, std::pair< unsigned int, unsigned int > > FU_to_prec
Maps a Functional Unit to its precision.
#define ASSERT_PARAMETER(parameter)
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
void indent()
Manually increase the indenting of the code.
CustomUnorderedMap< std::string, flopoco::Operator * > FUs
Generated Functional Units.
#define FILE_EXT
Default extension for generated files.
absl::flat_hash_map< T, U, Hash, Eq, Alloc > CustomUnorderedMap
static void DECODE_BITS(unsigned int FU_prec, unsigned int &n_mant, unsigned int &n_exp)
Retrieve mantissa and exponent for a given precision.
FPAssign module for flopoco.
redefinition of set to manage ordered/unordered structures
utility function used to read files.
#define FLOPOCO_ADDITIONAL_BITS
Additional bits in FloPoCo encoding with reference to IEEE-754 standard.
void add_FU(const std::string &FU_type, unsigned int FU_prec_in, unsigned int FU_prec_out, const std::string &FU_name, const std::string &pipe_parameter)
Adds a Functional Unit to the wrapper.
This file collects some utility functions and macros.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
#define STD_OPENING_CHAR
STD include.
void outputPortMap(const std::string &FU_name_stored, std::ostream &os, const std::string &pipe_parameter)
const std::vector< std::string > get_ports(const std::string &FU_name_stored, unsigned int expected_ports, port_type type, bool check_ports=true) const
Returns the names of ports, according to the needed port type (port_in or port_out) ...
bool combinatorialOperator
#define STD_CLOSING_CHAR
Special closing character used to close the current nested level.
This class describes all classes used to represent a structural object.
std::string GetPath(std::filesystem::path path)
void outputPortDeclaration(const std::string &FU_prefix, const std::string &FU_name_stored, std::ostream &os, component_type type, const std::string &pipe_parameter)
flopoco_wrapper(int _debug_level, const std::string &FU_target)
Constructor.
#define OPLIST
Autoheader include.
static constexpr double DEFAULT_TARGET_FREQUENCY
enum { top, wrapped, in_wrap, out_wrap } component_type
Component types.
Wrapper to FloPoCo for VHDL code generation.
~flopoco_wrapper()
Destructor.
void outputHeaderVHDL(const std::string &FU_name_stored, std::ostream &os) const
Helper methods for automatic VHDL code generation:
FPle_expr module for flopoco.
#define OUT_WRAP_PREFIX
Prefix for the wrapper to the inputs.
unsigned int get_FUPipelineDepth(const std::string &FU_name, const unsigned int FU_prec_in, const unsigned int FU_prec_out, const std::string &pipe_parameter) const
Returns the Functional Unit's Pipeline Depth.
void outputSignals(const std::string &FU_name_stored, std::ostream &os)
flopoco::Operator * get_FU(std::string FU_name_stored) const
Returns one of the generated Functional Units.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...