46 #include "config_HAVE_FROM_C_BUILT.hpp" 63 #include <boost/algorithm/string.hpp> 64 #include <boost/tokenizer.hpp> 71 #define VERILOG_2001_SUPPORTED 80 "abs",
"abstol",
"access",
"acos",
"acosh",
"always",
"analog",
"and",
"asin",
"asinh",
"assign",
"atan",
"atan2",
81 "atanh",
"automatic",
"begin",
"bool",
"buf",
"bufif0",
"bufif1",
"case",
"casex",
"casez",
"ceil",
"cell",
"cmos",
82 "config",
"continuous",
"cos",
"cosh",
"ddt_nature",
"deassign",
"default",
"defparam",
"design",
"disable",
83 "discipline",
"discrete",
"domain",
"edge",
"else",
"end",
"endcase",
"endconfig",
"enddiscipline",
"endfunction",
84 "endgenerate",
"endmodule",
"endnature",
"endprimitive",
"endspecify",
"endtable",
"endtask",
"event",
"exclude",
85 "exp",
"floor",
"flow",
"for",
"force",
"forever",
"fork",
"from",
"function",
"generate",
"genvar",
"ground",
86 "highz0",
"highz1",
"hypot",
"idt_nature",
"if",
"ifnone",
"incdir",
"include",
"inf",
"initial",
"inout",
"input",
87 "instance",
"integer",
"join",
"large",
"liblist",
"library",
"ln",
"localparam",
"log",
"macromodule",
"max",
88 "medium",
"min",
"module",
"nand",
"nature",
"negedge",
"nmos",
"nor",
"noshowcancelled",
"not",
"notif0",
"notif1",
89 "or",
"output",
"parameter",
"pmos",
"posedge",
"potential",
"pow",
"primitive",
"pull0",
"pull1",
"pulldown",
90 "pullup",
"pulsestyle_onevent",
"pulsestyle_ondetect",
"rcmos",
"real",
"realtime",
"reg",
"release",
"repeat",
91 "rnmos",
"rpmos",
"rtran",
"rtranif0",
"rtranif1",
"scalared",
"showcancelled",
"signed",
"sin",
"sinh",
"small",
92 "specify",
"specparam",
"sqrt",
"strong0",
"strong1",
"supply0",
"supply1",
"table",
"tan",
"tanh",
"task",
"time",
93 "tran",
"tranif0",
"tranif1",
"tri",
"tri0",
"tri1",
"triand",
"trior",
"trireg",
"units",
"unsigned",
"use",
94 "uwire",
"vectored",
"wait",
"wand",
"weak0",
"weak1",
"while",
"wire",
"wone",
"wor",
"xnor",
"xor",
96 "alias",
"always_comb",
"always_ff",
"always_latch",
"assert",
"assume",
"before",
"bind",
"bins",
"binsof",
"bit",
97 "break",
"byte",
"chandle",
"class",
"clocking",
"const",
"constraint",
"context",
"continue",
"cover",
98 "covergroup",
"coverpoint",
"cross",
"dist",
"do",
"endclass",
"endgroup",
"endsequence",
"endclocking",
99 "endpackage",
"endinterface",
"endprogram",
"endproperty",
"enum",
"expect",
"export",
"extends",
"extern",
"final",
100 "first_match",
"foreach",
"forkjoin",
"iff",
"ignore_bins",
"illegal_bins",
"import",
"intersect",
"inside",
101 "interface",
"int",
"join_any",
"join_none",
"local",
"logic",
"longint",
"matches",
"modport",
"new",
"null",
102 "package",
"packed",
"priority",
"program",
"property",
"protected",
"pure",
"rand",
"randc",
"randcase",
103 "randomize",
"randsequence",
"ref",
"return",
"sequence",
"shortint",
"shortreal",
"solve",
"static",
"string",
104 "struct",
"super",
"tagged",
"this",
"throughout",
"timeprecision",
"timeunit",
"type",
"typedef",
"unique",
"var",
105 "virtual",
"void",
"wait_order",
"wildcard",
"with",
"within",
107 "accept_on",
"checker",
"endchecker",
"eventually",
"global",
"implies",
"let",
"nexttime",
"reject_on",
"restrict",
108 "s_always",
"s_eventually",
"s_nexttime",
"s_until",
"s_until_with",
"strong",
"sync_accept_on",
"sync_reject_on",
109 "unique0",
"until",
"until_with",
"untyped",
"weak",
111 "implements",
"interconnect",
"nettype",
"soft"};
179 auto*
mod = GetPointer<module>(Owner);
180 std::string port_name = cir->
get_id();
181 bool specialization_string =
false;
187 std::vector<std::pair<std::string, structural_objectRef>> library_parameters;
188 mod->get_NP_library_parameters(Owner, library_parameters);
189 for(
auto const& library_parameter : library_parameters)
191 if(port_name == library_parameter.first)
193 specialization_string =
true;
204 if(specialization_string)
210 return "[" +
STR(GetPointer<port_o>(cir)->get_ports_size() - 1) +
":0] ";
215 const auto owner_vector = GetPointer<const port_o>(cir->
get_owner());
216 for(
unsigned int vector_index = 0; vector_index < owner_vector->get_ports_size(); vector_index++)
218 if(owner_vector->get_port(vector_index) == cir)
220 return "[" +
STR(vector_index) +
":" +
STR(vector_index) +
"]";
233 Type->
print(std::cerr);
242 if(specialization_string)
246 auto lsb = GetPointer<port_o>(cir)->get_lsb();
248 STR(static_cast<int>(lsb) - 1) +
"):" +
STR(lsb) +
"] ";
265 auto n_sign = GetPointer<signal_o>(cir)->get_signals_size();
267 auto lsb = GetPointer<signal_o>(cir)->get_lsb();
268 auto msb = size_fs * n_sign + lsb;
270 return "[" +
STR(static_cast<int>(msb) - 1) +
":" +
STR(lsb) +
"] ";
274 auto lsb = GetPointer<port_o>(cir)->get_lsb();
275 auto n_ports = GetPointer<port_o>(cir)->get_ports_size();
278 auto size_fp = Type_fp->
vector_size > 0 ? Type_fp->size * Type_fp->vector_size : Type_fp->size;
279 auto msb = size_fp * n_ports + lsb;
280 return "[" +
STR(static_cast<int>(msb) - 1) +
":" +
STR(lsb) +
"] ";
284 const auto owner_vector = GetPointer<const port_o>(cir->
get_owner());
285 auto lsb = owner_vector->get_lsb();
286 for(
unsigned int vector_index = 0; vector_index < owner_vector->get_ports_size(); vector_index++)
288 if(owner_vector->get_port(vector_index) == cir)
292 return "[" +
STR(((vector_index + 1) * single_size_port) - 1 + lsb) +
":" +
293 STR(vector_index * single_size_port + lsb) +
"]";
300 return "[" +
STR(static_cast<int>(Type->
vector_size) - 1) +
":0] ";
308 return "[" +
STR(static_cast<int>(Type->
size) - 1) +
":0] ";
312 THROW_ERROR(
"Not completely specified: " + port_name);
321 if(specialization_string)
354 auto*
mod = GetPointer<module>(Owner);
355 std::string port_name = cir->
get_id();
356 bool specialization_string =
false;
362 std::vector<std::pair<std::string, structural_objectRef>> library_parameters;
363 mod->get_NP_library_parameters(Owner, library_parameters);
364 for(
const auto& library_parameter : library_parameters)
366 if(port_name == library_parameter.first)
368 specialization_string =
true;
379 return "[" + GetPointer<port_o>(cir)->get_id() +
"]";
388 Type->
print(std::cerr);
397 if(specialization_string)
401 auto lsb = GetPointer<port_o>(Owner)->get_lsb();
402 return "[((" +
STR(GetPointer<port_o>(cir)->get_id()) +
"+1)*" + (
BITSIZE_PREFIX + port_name) +
")+(" +
403 STR(static_cast<int>(lsb) - 1) +
"):(" +
STR(GetPointer<port_o>(cir)->get_id()) +
"*" +
417 auto lsb = GetPointer<port_o>(Owner)->get_lsb();
419 STR((1 + std::stoi(GetPointer<port_o>(cir)->get_id())) * static_cast<int>(size_fp) +
420 static_cast<int>(lsb) - 1) +
422 STR((std::stoi(GetPointer<port_o>(cir)->get_id())) * static_cast<int>(size_fp) +
423 static_cast<int>(lsb)) +
437 if(specialization_string)
441 auto lsb = GetPointer<port_o>(Owner)->get_lsb();
442 return "[((" +
STR(GetPointer<port_o>(cir)->get_id()) +
"+1)*" + (
BITSIZE_PREFIX + port_name) +
"*" +
444 STR(GetPointer<port_o>(cir)->get_id()) +
"*" + (
BITSIZE_PREFIX + port_name) +
"*" +
458 auto lsb = GetPointer<port_o>(Owner)->get_lsb();
460 STR((1 + std::stoi(GetPointer<port_o>(cir)->get_id())) * static_cast<int>(size_fp) +
461 static_cast<int>(lsb) - 1) +
463 STR((std::stoi(GetPointer<port_o>(cir)->get_id())) * static_cast<int>(size_fp) +
464 static_cast<int>(lsb)) +
490 "Expected a component or a channel got something of different");
495 const auto IP_includes_list = string_to_container<std::vector<std::string>>(IP_includes,
";");
496 for(
const auto& inc : IP_includes_list)
505 auto*
mod = GetPointer<module>(cir);
508 if(
mod->get_keep_hierarchy())
513 bool first_obj =
false;
516 for(
unsigned int i = 0; i <
mod->get_num_ports(); i++)
557 "Expected a port got something of different " + cir->
get_id());
559 dir = GetPointer<port_o>(cir)->get_port_direction();
583 case port_o::TLM_INOUT:
584 case port_o::TLM_OUT:
585 case port_o::UNKNOWN:
601 "Expected a signal or a signal vector got something of different");
607 auto n_sign = GetPointer<signal_o>(cir)->get_signals_size();
609 auto lsb = GetPointer<signal_o>(cir)->get_lsb();
610 auto msb = size_fs * n_sign + lsb;
623 const auto mod = GetPointer<const module>(component);
625 THROW_ASSERT(GetPointer<const port_o>(
mod->get_out_port(0)),
"does not have an output port");
626 THROW_ASSERT(component->get_owner(),
"does not have an owner");
627 THROW_ASSERT(GetPointer<const port_o>(
mod->get_out_port(0))->find_bounded_object(component->get_owner()),
628 component->get_path() +
" does not have a bounded object");
629 const auto object_bounded =
630 GetPointer<const port_o>(
mod->get_out_port(0))->find_bounded_object(component->get_owner());
633 "Verilog keyword corresponding to " + component_name +
" not found");
638 component->get_path() +
" has " +
STR(
mod->get_out_port_size()) +
" output ports");
640 for(
unsigned int i = 0; i <
mod->get_in_port_size(); i++)
644 THROW_ASSERT(GetPointer<port_o>(
mod->get_in_port(i))->find_bounded_object(component->get_owner()),
645 "does not have a structural object connected to the input");
646 const auto in_object_bounded =
647 GetPointer<port_o>(
mod->get_in_port(i))->find_bounded_object(component->get_owner());
652 const auto port = GetPointer<port_o>(
mod->get_in_port(i));
653 const auto in_object_bounded = port->find_bounded_object(component);
654 if(in_object_bounded)
660 auto n_ports = port->get_ports_size();
661 for(decltype(n_ports) port_index = 0; port_index < n_ports; port_index++)
663 if(i != 0 or port_index != 0)
667 const auto vec_in_object_bounded = GetPointer<port_o>(port->get_port(port_index))->find_bounded_object();
668 THROW_ASSERT(vec_in_object_bounded, port->get_port(port_index)->get_path());
683 bool write_parametrization)
686 "Expected a component or a channel got something of different");
688 if(module_name.find(
"widen_mult_expr") != std::string::npos)
696 if(write_parametrization)
723 if(first_port_analyzed)
747 "-->Port binding for " + port->
get_path() +
" not found - looking for single port binding");
748 std::string port_binding;
749 auto* pv = GetPointer<port_o>(port);
750 bool local_first_port_analyzed =
false;
751 unsigned long long msb, lsb;
756 auto n_ports = pv->get_ports_size();
757 for(
unsigned int j = 0; j < n_ports; ++j)
759 auto index = n_ports - j - 1;
770 auto vector_position =
static_cast<unsigned>(std::stoul(object_bounded->
get_id()));
773 if(local_first_port_analyzed)
775 port_binding +=
",\n";
778 unsigned int max = 0;
779 auto* pvs = GetPointer<port_o>(slice);
782 max = pvs->get_ports_size();
786 auto* sv = GetPointer<signal_o>(slice);
789 max = sv->get_signals_size();
792 if(lsb != 0 || msb != (max - 1))
794 port_binding +=
"[" +
STR(msb);
797 port_binding +=
":" +
STR(lsb);
801 local_first_port_analyzed =
true;
805 if(!slice || (slice->
get_id() == object_bounded->
get_owner()->get_id() and
806 (((vector_position + 1) *
GET_TYPE_SIZE(object_bounded)) - 1) == lsb - 1))
811 msb = (vector_position + 1) *
GET_TYPE_SIZE(object_bounded) - 1;
819 if(local_first_port_analyzed)
821 port_binding +=
",\n";
826 unsigned int max = 0;
827 auto* pvs = GetPointer<port_o>(slice);
830 max = pvs->get_ports_size();
834 auto* sv = GetPointer<signal_o>(slice);
837 max = sv->get_signals_size();
840 if(lsb != 0 || msb != (max - 1))
842 port_binding +=
"[" +
STR(msb);
845 port_binding +=
":" +
STR(lsb);
847 port_binding +=
"], ";
849 else if(local_first_port_analyzed)
851 port_binding +=
",\n";
856 auto* con = GetPointer<constant_o>(object_bounded);
857 std::string trimmed_value =
"";
858 auto long_value = std::stoull(con->get_value());
861 trimmed_value = trimmed_value + (((1LLU << (
GET_TYPE_SIZE(con) - ind - 1)) & long_value) ?
'1' :
'0');
867 if(local_first_port_analyzed)
869 port_binding +=
",\n";
874 unsigned int max = 0;
875 auto* pvs = GetPointer<port_o>(slice);
878 max = pvs->get_ports_size();
882 auto* sv = GetPointer<signal_o>(slice);
885 max = sv->get_signals_size();
888 if(lsb != 0 || msb != (max - 1))
890 port_binding +=
"[" +
STR(msb);
893 port_binding +=
":" +
STR(lsb);
895 port_binding +=
"], ";
897 else if(local_first_port_analyzed)
899 port_binding +=
",\n";
906 local_first_port_analyzed =
true;
910 if(local_first_port_analyzed)
912 port_binding +=
",\n";
915 unsigned int max = 0;
916 auto* pvs = GetPointer<port_o>(slice);
919 max = pvs->get_ports_size();
923 auto* sv = GetPointer<signal_o>(slice);
926 max = sv->get_signals_size();
929 if(lsb != 0 || msb != (max - 1))
931 port_binding +=
"[" +
STR(msb);
934 port_binding +=
":" +
STR(lsb);
940 if(port_binding.size() == 0)
945 if(first_port_analyzed)
957 "<--Port binding for " + port->
get_path() +
" not found - looking for single port binding");
962 bool first_port_analyzed)
973 "A port has to have always an owner");
974 if(first_port_analyzed)
1002 auto* con = GetPointer<constant_o>(object_bounded);
1003 std::string trimmed_value =
"";
1004 auto long_value = std::stoull(con->get_value());
1007 trimmed_value = trimmed_value + (((1LLU << (
GET_TYPE_SIZE(con) - ind - 1)) & long_value) ?
'1' :
'0');
1023 "Expected a signal or a constant, got something of different");
1024 std::string port_string;
1025 std::string signal_string;
1028 auto* con = GetPointer<constant_o>(sig);
1029 std::string trimmed_value =
"";
1030 auto long_value = std::stoull(con->get_value());
1033 trimmed_value = trimmed_value + (((1LLU << (
GET_TYPE_SIZE(con) - ind - 1)) & long_value) ?
'1' :
'0');
1056 if(GetPointer<port_o>(port)->get_port_direction() == port_o::IN)
1058 std::swap(port_string, signal_string);
1060 if(port_string != signal_string)
1071 std::string port_string;
1072 std::string signal_string;
1075 if(GetPointer<port_o>(port)->get_port_direction() == port_o::IN)
1077 std::swap(port_string, signal_string);
1079 if(port_string != signal_string)
1089 "Expected a component or a channel got something of different");
1090 auto*
mod = GetPointer<module>(cir);
1091 bool first_it =
true;
1099 std::vector<std::string> mem_tag = string_to_container<std::vector<std::string>>(memory_str,
";");
1100 for(
const auto& i : mem_tag)
1102 std::vector<std::string> mem_add = string_to_container<std::vector<std::string>>(i,
"=");
1103 THROW_ASSERT(mem_add.size() == 2,
"malformed address");
1114 std::string name = mem_add[0];
1116 if(mod->get_owner() && GetPointer<module>(mod->get_owner()) &&
1135 std::vector<std::pair<std::string, structural_objectRef>> library_parameters;
1136 mod->get_NP_library_parameters(cir, library_parameters);
1137 for(
const auto& library_parameter : library_parameters)
1149 const std::string& name = library_parameter.first;
1152 if(!mod->ExistsParameter(std::string(
BITSIZE_PREFIX) + name) && obj)
1171 auto ports_size = GetPointer<port_o>(obj)->get_ports_size();
1179 std::string param_value, param_name;
1180 if(mod->ExistsParameter(name))
1182 param_value = mod->GetParameter(name);
1185 else if(mod->ExistsParameter(std::string(
BITSIZE_PREFIX) + name))
1187 param_value = mod->GetParameter(std::string(
BITSIZE_PREFIX) + name);
1192 cir->
print(std::cerr);
1195 if(param_value.find(
"\"\"") != std::string::npos)
1197 boost::replace_all(param_value,
"\"\"",
"\"");
1199 else if(param_value.find(
'\"') != std::string::npos)
1201 boost::replace_all(param_value,
"\"",
"");
1202 param_value =
STR(param_value.size()) +
"'b" + param_value;
1205 "---Written ." + param_name +
"(" + param_value +
")");
1221 const std::list<std::string>& list_of_states,
const std::string&,
1222 const std::string& reset_state,
bool one_hot)
1226 auto it_end = list_of_states.end();
1227 auto n_states =
static_cast<unsigned int>(list_of_states.size());
1228 unsigned int count = 0;
1231 unsigned max_value = 0;
1232 for(
auto it = list_of_states.begin(); it != it_end; ++it)
1236 if(max_value != n_states - 1)
1248 for(
auto it = list_of_states.begin(); it != it_end; ++it)
1253 *it +
" = " +
STR(max_value + 1) +
"'b" +
1262 if(count == n_states)
1282 auto*
mod = GetPointer<module>(cir);
1289 STR(
parameters->getOption<
unsigned int>(OPT_context_switch) - 1) +
":0];\n");
1295 " for (i=0; i<" +
STR(
parameters->getOption<
unsigned int>(OPT_context_switch)) +
"; i=i+1) begin\n");
1303 STR(
parameters->getOption<
unsigned int>(OPT_context_switch) - 1) +
":0];\n");
1309 " for (i=0; i<" +
STR(
parameters->getOption<
unsigned int>(OPT_context_switch)) +
"; i=i+1) begin\n");
1320 ", _next_state;\n");
1325 ", _next_state;\n");
1329 THROW_ASSERT(
mod->get_out_port_size(),
"Expected a FSM with at least one output");
1331 std::string port_name;
1334 for(
unsigned int i = 0; i <
mod->get_out_port_size(); i++)
1352 const std::string& reset_port,
const std::string& clock_port,
1353 const std::string& reset_type,
bool connect_present_next_state_signals)
1355 if(reset_type ==
"no" || reset_type ==
"sync")
1359 else if(!
parameters->getOption<
bool>(OPT_reset_level))
1369 auto*
mod = GetPointer<module>(cir);
1373 if(!
parameters->getOption<
bool>(OPT_reset_level))
1387 if(!
parameters->getOption<
bool>(OPT_reset_level))
1398 if(connect_present_next_state_signals)
1401 "= _next_state;\n");
1406 bool single_proc,
unsigned int output_index,
const structural_objectRef& cir,
const std::string& reset_state,
1407 const std::string& reset_port,
const std::string& start_port,
const std::string& clock_port,
1408 std::vector<std::string>::const_iterator& first, std::vector<std::string>::const_iterator& end,
bool is_yosys,
1409 const std::map<
unsigned int,
std::map<std::string, std::set<unsigned int>>>& bypass_signals)
1411 using tokenizer = boost::tokenizer<boost::char_separator<char>>;
1417 boost::char_separator<char> state_sep(
":",
nullptr);
1418 boost::char_separator<char> sep(
" ",
nullptr);
1420 auto*
mod = GetPointer<module>(cir);
1422 THROW_ASSERT(
mod->get_out_port_size(),
"Expected a FSM with at least one output");
1423 std::string port_name;
1426 unsigned int numInputIgnored;
1429 numInputIgnored = 4;
1433 numInputIgnored = 3;
1436 #ifdef VERILOG_2001_SUPPORTED 1443 if(
mod->get_in_port_size())
1445 for(
unsigned int i = 0; i <
mod->get_in_port_size(); i++)
1448 if(port_name != reset_port && port_name != clock_port)
1457 if(!single_proc && output_index ==
mod->get_out_port_size())
1463 std::string default_output;
1464 for(
unsigned int i = 0; i <
mod->get_out_port_size(); i++)
1474 default_output +=
"0";
1475 if(!single_proc && output_index != i)
1493 for(
auto first_it = first; first_it != end; ++first_it)
1495 tokenizer state_tokens_first(*first_it, state_sep);
1497 tokenizer::const_iterator it = state_tokens_first.begin();
1499 std::string state_description = *it;
1502 std::vector<std::string> state_transitions;
1503 for(; it != state_tokens_first.end(); ++it)
1505 state_transitions.push_back(*it);
1508 tokenizer tokens_curr(state_description, sep);
1511 it = tokens_curr.begin();
1515 std::string current_output = *it;
1518 bool skip_state = !single_proc && output_index !=
mod->get_out_port_size() &&
1519 default_output[output_index] == current_output[output_index];
1520 bool skip_state_transition = !single_proc && output_index !=
mod->get_out_port_size();
1521 if(!single_proc && output_index !=
mod->get_out_port_size())
1523 for(
const auto& current_transition : state_transitions)
1525 tokenizer transition_tokens(current_transition, sep);
1526 tokenizer::const_iterator itt = transition_tokens.begin();
1528 tokenizer::const_iterator current_input_it;
1529 std::string input_string = *itt;
1530 if(
mod->get_in_port_size() - numInputIgnored)
1532 boost::char_separator<char> comma_sep(
",",
nullptr);
1533 tokenizer current_input_tokens(input_string, comma_sep);
1534 current_input_it = current_input_tokens.begin();
1538 std::string transition_outputs = *itt;
1540 THROW_ASSERT(itt == transition_tokens.end(),
"Bad transition format");
1541 if(transition_outputs[output_index] !=
'-')
1544 skip_state_transition =
false;
1556 if(reset_state == present_state)
1564 bool unique_transition = (state_transitions.size() == 1);
1565 if(current_output != default_output && (single_proc || !unique_transition || skip_state_transition))
1567 for(
unsigned int i = 0; i <
mod->get_out_port_size(); i++)
1578 if(default_output[i] != current_output[i])
1580 if(single_proc || output_index == i)
1582 switch(current_output[i])
1586 if(bypass_signals.find(i) == bypass_signals.end() ||
1587 bypass_signals.find(i)->second.find(present_state) == bypass_signals.find(i)->second.end())
1594 for(
const auto& stateIns : bypass_signals.find(i)->second)
1596 if(stateIns.first != present_state)
1600 bool first_i =
true;
1601 for(
const auto& in : stateIns.second)
1625 THROW_ERROR(
"Unsupported value in current output");
1633 if(!skip_state_transition)
1636 bool unique_case_condition =
true;
1637 std::string guard_casez_port;
1638 auto n_bits_guard_casez_port = 0ULL;
1639 if(!unique_transition)
1641 for(
unsigned int i = 0; i < state_transitions.size(); i++)
1643 tokenizer transition_tokens(state_transitions[i], sep);
1644 tokenizer::const_iterator itt = transition_tokens.begin();
1646 tokenizer::const_iterator current_input_it;
1647 std::string input_string = *itt;
1648 if(
mod->get_in_port_size() - numInputIgnored)
1650 boost::char_separator<char> comma_sep(
",",
nullptr);
1651 tokenizer current_input_tokens(input_string, comma_sep);
1652 current_input_it = current_input_tokens.begin();
1655 std::string next_state = *itt;
1657 std::string transition_outputs = *itt;
1659 THROW_ASSERT(itt == transition_tokens.end(),
"Bad transition format");
1660 if((i + 1) < state_transitions.size())
1662 bool first_test =
true;
1663 for(
unsigned int ind = 0; ind <
mod->get_in_port_size() && unique_case_condition; ind++)
1666 auto port_size =
mod->get_in_port(ind)->get_typeRef()->size;
1667 auto vec_size =
mod->get_in_port(ind)->get_typeRef()->vector_size;
1668 if(port_name != reset_port && port_name != clock_port && port_name != start_port &&
1671 std::string in_or_conditions = *current_input_it;
1672 boost::char_separator<char> pipe_sep(
"|",
nullptr);
1673 tokenizer in_or_conditions_tokens(in_or_conditions, pipe_sep);
1675 if((*in_or_conditions_tokens.begin()) !=
"-")
1677 if(guard_casez_port.empty())
1679 guard_casez_port = port_name;
1681 else if(guard_casez_port != port_name)
1683 unique_case_condition =
false;
1687 unique_case_condition =
false;
1693 bool first_test_or =
true;
1694 for(tokenizer::const_iterator in_or_conditions_tokens_it = in_or_conditions_tokens.begin();
1695 in_or_conditions_tokens_it != in_or_conditions_tokens.end() && unique_case_condition;
1696 ++in_or_conditions_tokens_it)
1698 THROW_ASSERT((*in_or_conditions_tokens_it) !=
"-",
"wrong conditions structure");
1701 unique_case_condition =
false;
1705 first_test_or =
false;
1708 if((*in_or_conditions_tokens_it)[0] !=
'&')
1710 unique_case_condition =
false;
1714 if(n_bits_guard_casez_port == 0)
1716 n_bits_guard_casez_port = vec_size == 0 ? port_size : vec_size;
1728 if(!unique_transition)
1730 if(unique_case_condition)
1736 for(
unsigned int i = 0; i < state_transitions.size(); i++)
1739 tokenizer transition_tokens(state_transitions[i], sep);
1740 tokenizer::const_iterator itt = transition_tokens.begin();
1742 tokenizer::const_iterator current_input_it;
1743 std::string input_string = *itt;
1744 if(
mod->get_in_port_size() - numInputIgnored)
1746 boost::char_separator<char> comma_sep(
",",
nullptr);
1747 tokenizer current_input_tokens(input_string, comma_sep);
1748 current_input_it = current_input_tokens.begin();
1751 std::string next_state = *itt;
1753 std::string transition_outputs = *itt;
1755 THROW_ASSERT(itt == transition_tokens.end(),
"Bad transition format");
1757 if(!unique_transition)
1761 if(unique_case_condition)
1770 else if((i + 1) == state_transitions.size())
1772 if(unique_case_condition)
1783 if(unique_case_condition)
1792 if((i + 1) < state_transitions.size())
1794 bool first_test =
true;
1795 for(
unsigned int ind = 0; ind <
mod->get_in_port_size(); ind++)
1798 auto port_size =
mod->get_in_port(ind)->get_typeRef()->size;
1799 auto vec_size =
mod->get_in_port(ind)->get_typeRef()->vector_size;
1800 if(port_name != reset_port && port_name != clock_port && port_name != start_port &&
1803 std::string in_or_conditions = *current_input_it;
1804 boost::char_separator<char> pipe_sep(
"|",
nullptr);
1805 tokenizer in_or_conditions_tokens(in_or_conditions, pipe_sep);
1807 if((*in_or_conditions_tokens.begin()) !=
"-")
1817 bool first_test_or =
true;
1818 bool need_parenthesis =
false;
1819 std::string res_or_conditions;
1820 for(tokenizer::const_iterator in_or_conditions_tokens_it = in_or_conditions_tokens.begin();
1821 in_or_conditions_tokens_it != in_or_conditions_tokens.end();
1822 ++in_or_conditions_tokens_it)
1824 THROW_ASSERT((*in_or_conditions_tokens_it) !=
"-",
"wrong conditions structure");
1827 res_or_conditions +=
" || ";
1828 need_parenthesis =
true;
1832 first_test_or =
false;
1835 res_or_conditions += port_name;
1836 if((*in_or_conditions_tokens_it)[0] ==
'&')
1838 auto n_bits = vec_size == 0 ? port_size : vec_size;
1839 auto pos =
static_cast<unsigned>(std::stoul((*in_or_conditions_tokens_it).substr(1)));
1840 if(unique_case_condition)
1842 res_or_conditions =
"";
1843 for(
unsigned int guard_ind = 0; guard_ind < n_bits; ++guard_ind)
1846 (guard_ind == pos ?
"1" : (guard_ind < pos ?
"0" : (is_yosys ?
"0" :
"?"))) +
1852 res_or_conditions +=
1853 (n_bits > 1 ? std::string(
"[") +
STR(pos) +
"]" :
"") +
" == 1'b1";
1858 res_or_conditions += std::string(
" == ") +
1859 ((*in_or_conditions_tokens_it)[0] ==
'-' ?
"-" :
"") +
1860 (vec_size == 0 ?
STR(port_size) :
STR(vec_size));
1861 if(port_size > 1 || (port_size == 1 && vec_size > 0))
1863 res_or_conditions +=
"'d" + (((*in_or_conditions_tokens_it)[0] ==
'-') ?
1864 ((*in_or_conditions_tokens_it).substr(1)) :
1865 *in_or_conditions_tokens_it);
1869 res_or_conditions +=
"'b" + *in_or_conditions_tokens_it;
1873 if(need_parenthesis)
1875 res_or_conditions =
"(" + res_or_conditions +
")";
1882 if(unique_case_condition)
1895 if(single_proc || output_index ==
mod->get_out_port_size())
1899 for(
unsigned int ind = 0; ind <
mod->get_out_port_size(); ind++)
1910 if(transition_outputs[ind] !=
'-')
1912 if(single_proc || output_index == ind)
1914 if(transition_outputs[ind] ==
'2')
1920 if(bypass_signals.find(ind) == bypass_signals.end() ||
1921 bypass_signals.find(ind)->second.find(present_state) ==
1922 bypass_signals.find(ind)->second.end())
1929 for(
const auto& stateIns : bypass_signals.find(ind)->second)
1931 if(stateIns.first != present_state)
1935 bool first_i =
true;
1936 for(
const auto& in : stateIns.second)
1957 if(!unique_transition)
1964 if(!unique_transition)
1966 if(unique_case_condition)
1977 if(reset_state == present_state)
1983 for(
unsigned int i = 0; i <
mod->get_out_port_size(); i++)
1993 if(
starts_with(
mod->get_out_port(i)->get_id(),
"selector_MUX") ||
1997 if((single_proc || output_index == i) &&
2004 if(single_proc || output_index ==
mod->get_out_port_size())
2021 for(
unsigned int i = 0; i <
mod->get_out_port_size(); i++)
2031 if(
starts_with(
mod->get_out_port(i)->get_id(),
"selector_MUX") ||
2035 if((single_proc || output_index == i) &&
2058 auto*
mod = GetPointer<module>(cir);
2061 THROW_ASSERT(np,
"NP Behavioral description is missing for module: " +
2064 THROW_ASSERT(beh_desc !=
"",
"VERILOG behavioral description is missing for module: " +
2067 if(!
parameters->getOption<
bool>(OPT_reset_level))
2069 boost::replace_all(beh_desc,
"1RESET_EDGE_FORCE",
"or negedge " + std::string(
RESET_PORT_NAME));
2070 if(
parameters->getOption<std::string>(OPT_reset_type) ==
"async")
2072 boost::replace_all(beh_desc,
"1RESET_EDGE",
"or negedge " + std::string(
RESET_PORT_NAME));
2076 boost::replace_all(beh_desc,
"1RESET_EDGE",
"");
2078 boost::replace_all(beh_desc,
"1RESET_VALUE", std::string(
RESET_PORT_NAME) +
" == 1'b0");
2082 boost::replace_all(beh_desc,
"1RESET_EDGE_FORCE",
"or posedge " + std::string(
RESET_PORT_NAME));
2083 if(
parameters->getOption<std::string>(OPT_reset_type) ==
"async")
2085 boost::replace_all(beh_desc,
"1RESET_EDGE",
"or posedge " + std::string(
RESET_PORT_NAME));
2089 boost::replace_all(beh_desc,
"1RESET_EDGE",
"");
2091 boost::replace_all(beh_desc,
"1RESET_VALUE", std::string(
RESET_PORT_NAME) +
" == 1'b1");
2093 if(
parameters->getOption<
bool>(OPT_reg_init_value))
2095 boost::replace_all(beh_desc,
"1INIT_ZERO_VALUE",
"=0");
2099 boost::replace_all(beh_desc,
"1INIT_ZERO_VALUE",
"");
2117 "Expected a component or a channel got something of different");
2118 auto*
mod = GetPointer<module>(cir);
2120 bool first_it =
true;
2128 std::vector<std::string> mem_tag = string_to_container<std::vector<std::string>>(memory_str,
";");
2129 for(
const auto& i : mem_tag)
2131 std::vector<std::string> mem_add = string_to_container<std::vector<std::string>>(i,
"=");
2132 THROW_ASSERT(mem_add.size() == 2,
"malformed address");
2143 std::string name = mem_add[0];
2144 std::string
value = mem_add[1];
2145 if(value.find(
"\"\"") != std::string::npos)
2147 boost::replace_all(value,
"\"\"",
"\"");
2149 else if(value.find(
'\"') != std::string::npos)
2151 boost::replace_all(value,
"\"",
"");
2152 value =
STR(value.size()) +
"'b" + value;
2161 std::vector<std::pair<std::string, structural_objectRef>> library_parameters;
2162 mod->get_NP_library_parameters(cir, library_parameters);
2163 for(
const auto& library_parameter : library_parameters)
2175 const auto& name = library_parameter.first;
2176 const auto obj = library_parameter.second;
2193 auto ports_size = GetPointer<port_o>(obj)->get_ports_size();
2204 std::string
param = mod->GetDefaultParameter(name);
2206 " parameter = #" << name <<
"#; value = #" << param <<
"#");
2207 if(param.find(
"\"\"") != std::string::npos)
2209 boost::replace_all(param,
"\"\"",
"\"");
2211 else if(param.find(
'\"') != std::string::npos)
2213 boost::replace_all(param,
"\"",
"");
2214 param =
STR(param.size()) +
"'b" + param;
2251 `define _SIM_HAVE_CLOG2 2254 `define _SIM_HAVE_CLOG2 2257 `define _SIM_HAVE_CLOG2 2260 `define _SIM_HAVE_CLOG2 2263 `define _SIM_HAVE_CLOG2 2265 `ifdef XILINX_SIMULATOR 2266 `define _SIM_HAVE_CLOG2 2269 `define _SIM_HAVE_CLOG2 #define register_AR_NORETIME_INT
#define PRESENT_STATE_PORT_NAME
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
void write_port_decl_header() override
Write the header for port_decl.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
static std::string convert_to_identifier(const language_writer *writer, const std::string &id)
Converts a generic string to a language compliant identifier.
File containing functions and utilities to support the printing of debug messagges.
#define register_AR_NORETIME_UINT
#define PRINT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
#define NEXT_STATE_PORT_NAME
void write_port_binding(const structural_objectRef &port, const structural_objectRef &object_bounded, bool first_port_analyzed) override
Write the binding of a port.
void write_signal_declaration(const structural_objectRef &cir) override
Write the declaration of a signal.
This file contains the structures needed to manage a graph that will represent the state transition g...
const std::string & get_id() const
Return the identifier associated with the structural_object.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
int debug_level
debugging level of the class
void write_assign(const std::string &op0, const std::string &op1) override
void WriteBuiltin(const structural_objectConstRef component) override
Write a builtin component.
std::string get_NP_functionality(NP_functionaly_type type) const
Return the description provided the type.
std::string type_converter(structural_type_descriptorRef Type) override
Return a language based type string given a structural_type_descriptor.
void Indent()
Manually increase the indenting of the code.
void write_io_signal_post_fix_vector(const structural_objectRef &port, const structural_objectRef &sig) override
void write_vector_port_binding(const structural_objectRef &port, bool first_port_analyzed) override
exceptions managed by PandA
Collect information about resource performance.
Class to print indented code.
void write_present_state_update(const structural_objectRef cir, const std::string &reset_state, const std::string &reset_port, const std::string &clock_port, const std::string &reset_type, bool connect_present_next_state_signals) override
write the present_state update process
const IndentedOutputStreamRef indented_output_stream
Represents the stream we are currently writing to.
Class specification of the manager of the technology library data structures.
void write_module_internal_declaration(const structural_objectRef &cir) override
Write the declaration of internal objects of the module.
#define GET_TYPE_NAME(structural_obj)
Macro returning the string name of a type.
bool check_keyword(const std::string &id) const override
verilog_writer(const ParameterConstRef parameters)
Constructor.
void write_comment(const std::string &comment_string) override
Print a comment.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
void write_header() override
Writes the header part of the file.
s_type type
The type of the port or the signal.
port_direction
Enumerative type describing the direction of a port.
unsigned long long size
The size of the object (in bit). The objects having a size are: ports, signals, channels, data, and actions.
void write_module_parametrization(const structural_objectRef &cir) override
Module can be parameterized with respect different features.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
bool starts_with(const std::string &str, const std::string &pattern)
void write_transition_output_functions(bool single_proc, unsigned int output_index, const structural_objectRef &cir, const std::string &reset_state, const std::string &reset_port, const std::string &start_port, const std::string &clock_port, std::vector< std::string >::const_iterator &first, std::vector< std::string >::const_iterator &end, bool is_yosys, const std::map< unsigned int, std::map< std::string, std::set< unsigned int >>> &bypass_signals) override
Write the transition and output functions.
void write_NP_functionalities(const structural_objectRef &cir) override
Write in the proper language the behavioral description of the module described in "Not Parsed" form...
s_type
Define the possible type of a structural object.
Class for system verilog writing.
unsigned map[NUM_VERTICES]
void Append(const std::string &str)
Append a string to the output.
Class specification of the data structures used to manage technology information. ...
const std::string get_path() const
Return a unique identifier of the structural object.
void write_module_definition_begin(const structural_objectRef &cir) override
Write the top constructor declaration.
virtual void print(std::ostream &os) const
Print the structural_object (for debug purpose)
void write_state_declaration(const structural_objectRef &cir, const std::list< std::string > &list_of_states, const std::string &reset_port, const std::string &reset_state, bool one_hot) override
write the declaration of all the states of the finite state machine.
void write_module_instance_end(const structural_objectRef &cir) override
Write the ending part of the instance of a module.
#define register_AR_NORETIME
register with asynchronous reset no retime
virtual enum so_kind get_kind() const =0
Virtual function used to find the real type of a structural_object instance.
void write_io_signal_post_fix(const structural_objectRef &port, const structural_objectRef &sig) override
Write some code managing primary ports to signals connections.
static const std::map< std::string, std::string > builtin_to_verilog_keyword
map putting into relation standard gates with the corresponding built-in Verilog statements.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
#define STD_OPENING_CHAR
STD include.
constants used in testbench generation
void write_module_definition_end(const structural_objectRef &cir) override
Write the end part in a module declaration.
void write_module_parametrization_decl(const structural_objectRef &cir) override
Write the declaration of the module parameters.
void write_port_decl_tail() override
Write the tail for port_decl.
#define GET_TYPE_SIZE(structural_obj)
Macro returning the size of the type of a structural object.
std::string id_type
Original type id of the structural object.
#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.
const structural_type_descriptorRef & get_typeRef() const
Return the type descriptor of the structural_object.
std::string encode_one_hot(unsigned int n_states, unsigned int val) const
#define register_AR_NORETIME_REAL
void write_component_declaration(const structural_objectRef &cir) override
Write the declaration of a component.
void write_module_declaration(const structural_objectRef &cir) override
Write the declaration of the module.
#define STATE_NAME_PREFIX
state name prefix
const structural_objectRef get_owner() const
Return the owner.
void write_module_instance_begin(const structural_objectRef &cir, const std::string &module_name, bool write_parametrization) override
Write the initial part of the instance of a module.
~verilog_writer() override
Destructor.
void write_library_declaration(const structural_objectRef &cir) override
Write the #include for each used library.
static unsigned int bitnumber(unsigned long long n)
Counts the number of bits in an unsigned int.
std::string type_converter_size(const structural_objectRef &cir) override
Return a language based type string given a structural_type_descriptor for the range of the array...
const ParameterConstRef parameters
the set of input parameters
static bool check_keyword_verilog(const std::string &word)
HDL writer base class used to specify the interface of the different language writers.
this class is used to manage the command-line or XML options.
#define SELECTOR_REGISTER_FILE
Not parsed functionality manager.
void Deindent()
Manually reduce the indenting of the code.
std::string may_slice_string(const structural_objectRef &cir)
return the slice in case of a port owned by a port vector
This class writes different HDL based descriptions (VHDL, Verilog, SystemC) starting from a structura...
void print(std::ostream &os) const
function that prints the class.
bool exist_NP_functionality(NP_functionaly_type type) const
Return true in case there exist a functionaly of the given type.
#define DEBUG_LEVEL_VERBOSE
verbose debugging print is performed.
static const std::set< std::string > keywords
void write_port_declaration(const structural_objectRef &cir, bool last_port_to_analyze) override
Write the port declaration starting from a port object.
unsigned long long vector_size
The number of the elements of a vector.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...