HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
verilog_converter.cpp
Go to the documentation of this file.
2 
4 
5 namespace hal
6 {
7  namespace z3_utils
8  {
9  void VerilogConverter::set_control_mapping(const std::map<std::string, bool>& control_mapping)
10  {
11  m_control_mapping = control_mapping;
12  }
13 
14  std::string VerilogConverter::build_operand(const std::string& operand) const
15  {
16  if (operand.find("?") != std::string::npos)
17  {
18  return operand.substr(1);
19  }
20 
21  return operand;
22  }
23 
24  std::string VerilogConverter::build_operation(const Converter::Operation& operation, const std::vector<std::string>& operands) const
25  {
26  std::string op;
27 
28  switch (operation)
29  {
30  case Converter::bvand:
31  for (const auto& o : operands)
32  {
33  op += (build_operand(o) + " & ");
34  }
35  op.erase(op.size() - 3);
36  break;
37  case Converter::bvnot:
38  if (operands.size() > 1)
39  {
40  log_error("z3_utils", "unhandled amount of operands for operation");
41  return "NOT IMPLEMENTED REACHED";
42  }
43  op = "~" + build_operand(operands.front());
44  break;
45  case Converter::bvor:
46  for (const auto& o : operands)
47  {
48  op += (build_operand(o) + " | ");
49  }
50  op.erase(op.size() - 3);
51  break;
52  case Converter::bvxor:
53  for (const auto& o : operands)
54  {
55  op += (build_operand(o) + " ^ ");
56  }
57  op.erase(op.size() - 3);
58  break;
59  default:
60  log_error("verifiaction", "unkown operation for operation building ({})", operation_to_string(operation));
61  return "NOT IMPLEMENTED REACHED";
62  }
63 
64  op = '(' + op + ')';
65  return op;
66  }
67 
68  std::string VerilogConverter::generate_assignment(const std::string& l) const
69  {
70  // stores variable the is being declared
71  std::string lhs = extract_lhs(l);
72 
73  auto sub_expressions_start = l.find(lhs) + lhs.size() + 1; // hardcoded + 1 for the space between (just for my ocd)
74  auto sub_expressions_size = l.size() - sub_expressions_start - 2; // hardcoded -2 for the last two closing brackest (just for my ocd)
75  auto sub_expressions_string = l.substr(sub_expressions_start, sub_expressions_size);
76 
77  auto sub_expressions = extract_sub_exrepssions(sub_expressions_string);
78 
79  log_debug("z3_utils", "Found {} sub_expressions.", sub_expressions.size());
80 
81  auto translated_sub_expressions = translate_sub_expressions(sub_expressions);
82 
83  log_debug("z3_utils", "Translated {} sub_expressions.", translated_sub_expressions.size());
84 
85  auto rhs = merge_sub_expressions(translated_sub_expressions);
86 
87  return "\twire " + lhs + ";\n" + "\tassign " + lhs + " = " + rhs + ";\n";
88  }
89 
90  std::string VerilogConverter::generate_initialization(const std::vector<std::string>& input_vars) const
91  {
92  std::string init = "module func ( ";
93  int counter = 0;
94  for (const auto& in : input_vars)
95  {
96  counter++;
97  if (m_control_mapping.find(in) == m_control_mapping.end())
98  {
99  init = init + in + ", ";
100  }
101  }
102  init += "out );\n";
103 
104  for (const auto& in : input_vars)
105  {
106  if (m_control_mapping.find(in) == m_control_mapping.end())
107  {
108  init += "\tinput " + in + ";\n";
109  }
110  }
111 
112  init += "\toutput out;\n";
113 
114  init += "\n\n";
115 
116  for (const auto& [control_var, value] : m_control_mapping)
117  {
118  init += "\twire " + control_var + ";\n";
119  init += "\tassign " + control_var + " = " + std::to_string(value) + "; // control bit\n";
120  }
121 
122  init += "\n\n";
123  return init;
124  }
125 
126  std::string VerilogConverter::construct_function(const std::string& assignments, const std::string& initialization, const std::vector<std::string>& input_vars) const
127  {
128  // NOTE the inputs are unused because they are included in the initialization for the verilog converter
129  UNUSED(input_vars);
130  std::string return_var;
131  if (assignments.empty())
132  {
133  const auto begin = initialization.find("i");
134  const auto end = initialization.find(",");
135  return_var = initialization.substr(begin, end - begin);
136  }
137  else
138  {
139  const auto last_assigment_pos = assignments.rfind("assign") + 7; // length of "assign" + one space
140  const auto last_line = assignments.substr(last_assigment_pos);
141  return_var = extract_lhs(last_line);
142  }
143 
144  std::string final_words = "\tassign out = " + return_var + ";\n";
145  final_words += "endmodule";
146  return (initialization + assignments + final_words);
147  }
148  } // namespace z3_utils
149 } // namespace hal
std::map< std::string, std::string > extract_sub_exrepssions(const std::string &l) const
Definition: converter.cpp:147
std::string extract_lhs(const std::string &l) const
Definition: converter.cpp:75
std::map< std::string, std::string > translate_sub_expressions(const std::map< std::string, std::string > &se) const
Definition: converter.cpp:256
std::string merge_sub_expressions(const std::map< std::string, std::string > &translated_sub_expressions) const
Definition: converter.cpp:271
std::string operation_to_string(const Operation &op) const
Definition: converter.cpp:43
void set_control_mapping(const std::map< std::string, bool > &control_mapping)
#define UNUSED(expr)
Definition: defines.h:49
#define log_error(channel,...)
Definition: log.h:78
#define log_debug(channel,...)
Definition: log.h:74
Definition: defines.h:45