HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
latch_function.cpp
Go to the documentation of this file.
10 #include "verilator/verilator.h"
11 
12 #include <filesystem>
13 #include <sstream>
14 #include <vector>
15 
16 namespace hal
17 {
18  namespace verilator
19  {
20  namespace converter
21  {
22  std::string get_function_for_latch(const GateType* gt)
23  {
24  std::stringstream function;
25 
26  if (LatchComponent* latch_component = gt->get_component_as<LatchComponent>([](const GateTypeComponent* c) { return LatchComponent::is_class_of(c); }); latch_component != nullptr)
27  {
28  std::vector<GatePin*> output_pins = gt->get_output_pins();
29  // TODO: JULIAN
30  // std::string internal_state = latch_component->get_state_identifier();
31  // std::string internal_negated_state = latch_component->get_neg_state_identifier();
32  std::string internal_state = "IQ";
33  std::string internal_negated_state = "IQN";
34 
35  function << "reg " << internal_state << ";" << std::endl;
36  function << "reg " << internal_negated_state << ";" << std::endl;
37  function << std::endl;
38 
39  if (InitComponent* init_component = latch_component->get_component_as<InitComponent>([](const GateTypeComponent* c) { return InitComponent::is_class_of(c); });
40  init_component != nullptr)
41  {
42  function << "initial begin" << std::endl;
43  function << "\t" << internal_state << " = INIT;" << std::endl;
44  function << "\t" << internal_negated_state << " = !(INIT);" << std::endl;
45  function << "end" << std::endl;
46  }
47  function << std::endl;
48 
49  auto async_reset_function = latch_component->get_async_reset_function();
50  auto async_set_function = latch_component->get_async_set_function();
51  auto enable_function = latch_component->get_enable_function();
52  auto data_function = latch_component->get_data_in_function();
53 
54  bool reset_async = false;
55  bool set_async = false;
56  bool enable = false;
57 
58  // create new signals for clock, async reset/set that already have function in them
59  if (!enable_function.is_empty())
60  {
61  enable = true;
62  function << "wire new_enable;" << std::endl;
63  function << "assign new_enable = " << enable_function.to_string(verilog_function_printer) << ";" << std::endl;
64  function << std::endl;
65  }
66  if (!async_reset_function.is_empty())
67  {
68  reset_async = true;
69  function << "wire new_async_reset;" << std::endl;
70  function << "assign new_async_reset = " << async_reset_function.to_string(verilog_function_printer) << ";" << std::endl;
71  function << std::endl;
72  }
73  if (!async_set_function.is_empty())
74  {
75  set_async = true;
76  function << "wire new_async_set;" << std::endl;
77  function << "assign new_async_set = " << async_set_function.to_string(verilog_function_printer) << ";" << std::endl;
78  function << std::endl;
79  }
80 
81  function << std::endl;
82 
83  // begin process
84  if (enable)
85  {
86  function << "always @(new_enable";
87 
88  if (reset_async)
89  {
90  function << " or new_async_reset";
91  }
92 
93  if (set_async)
94  {
95  function << " or new_async_set";
96  }
97  }
98  else if (reset_async)
99  {
100  function << "always @(new_async_set";
101 
102  if (set_async)
103  {
104  function << " or new_async_set";
105  }
106  }
107  else if (set_async)
108  {
109  function << "always @(new_async_set";
110  }
111  else
112  {
113  log_error("verilator", "gate '{}' has no signals in process, please check gate lib, aborting...", gt->get_name());
114  return std::string();
115  }
116 
117  function << ")" << std::endl;
118  function << "begin" << std::endl;
119 
120  bool if_used = false;
121 
122  if (reset_async && set_async)
123  {
124  auto [behav_state, behave_neg_state] = latch_component->get_async_set_reset_behavior();
125 
126  function << (if_used ? "\telse if (" : "\tif (") << async_reset_function.to_string(verilog_function_printer) << " & " << async_set_function << ") begin" << std::endl;
127 
128  switch (behav_state)
129  {
131  function << "\t\t" << internal_state << " <= 1'b0;" << std::endl;
132  break;
134  function << "\t\t" << internal_state << " <= 1'b1;" << std::endl;
135  break;
137  function << "\t\t" << internal_state << " <= !(" << internal_state << ");" << std::endl;
138  break;
140  function << "\t\t" << internal_state << " <= " << internal_state << ";" << std::endl;
141  break;
143  function << "\t\t" << internal_state << " <= 1'bX;" << std::endl;
144  break;
145 
146  default:
147  log_error("verilator", "unimplemented reached: found weird AsyncSetResetBehaviour for gate: {}", gt->get_name());
148  return std::string();
149  break;
150  }
151 
152  switch (behave_neg_state)
153  {
155  function << "\t\t" << internal_negated_state << " <= 1'b0;" << std::endl;
156  break;
158  function << "\t\t" << internal_negated_state << " <= 1'b1;" << std::endl;
159  break;
161  function << "\t\t" << internal_negated_state << " <= !(" << internal_negated_state << ");" << std::endl;
162  break;
164  function << "\t\t" << internal_negated_state << " <= " << internal_negated_state << ";" << std::endl;
165  break;
167  function << "\t\t" << internal_negated_state << " <= 1'bX;" << std::endl;
168  break;
169 
170  default:
171  log_error("verilator", "unimplemented reached: found weird AsyncSetResetBehaviour for gate: {}", gt->get_name());
172  return std::string();
173  break;
174  }
175  function << "\tend" << std::endl;
176 
177  if_used = true;
178  }
179  if (reset_async)
180  {
181  function << (if_used ? "\telse if (" : "\tif (") << async_reset_function.to_string(verilog_function_printer) << ") begin" << std::endl;
182  function << "\t\t" << internal_state << " <= 1'b0;" << std::endl;
183  function << "\t\t" << internal_negated_state << " <= 1'b1;" << std::endl;
184  function << "\tend" << std::endl;
185  if_used = true;
186  }
187  if (set_async)
188  {
189  function << (if_used ? "\telse if (" : "\tif (") << async_set_function.to_string(verilog_function_printer) << ") begin" << std::endl;
190  function << "\t\t" << internal_state << " <= 1'b1;" << std::endl;
191  function << "\t\t" << internal_negated_state << " <= 1'b0;" << std::endl;
192  function << "\tend" << std::endl;
193 
194  if_used = true;
195  }
196 
197  if (enable)
198  {
199  function << (if_used ? "\telse if (" : "\tif (") << enable_function.to_string(verilog_function_printer) << ") begin" << std::endl;
200  function << (if_used ? "\t" : "") << "\t" << internal_state << " <= " << data_function << ";" << std::endl;
201  function << (if_used ? "\t" : "") << "\t" << internal_negated_state << " <= !(" << data_function << ");" << std::endl;
202  function << "\tend" << std::endl;
203 
204  // unncessary but for completeness
205  function << "\telse begin" << std::endl;
206  function << (if_used ? "\t" : "") << "\t" << internal_state << " <= " << internal_state << ";" << std::endl;
207  function << (if_used ? "\t" : "") << "\t" << internal_negated_state << " <= " << internal_negated_state << ";" << std::endl;
208  function << "\tend" << std::endl;
209  if_used = true;
210  }
211  else
212  {
213  // else case if no enable for latch is present
214 
215  if (data_function.is_empty())
216  {
217  function << "\telse begin" << std::endl;
218  function << (if_used ? "\t" : "") << "\t" << internal_state << " <= " << internal_state << ";" << std::endl;
219  function << (if_used ? "\t" : "") << "\t" << internal_negated_state << " <= " << internal_negated_state << ";" << std::endl;
220  function << "\tend" << std::endl;
221  }
222  else
223  {
224  function << (if_used ? "\telse begin\n" : "");
225  function << (if_used ? "\t" : "") << "\t" << internal_state << " <= " << data_function << ";" << std::endl;
226  function << (if_used ? "\t" : "") << "\t" << internal_negated_state << " <= !(" << data_function << ");" << std::endl;
227  function << "\tend" << std::endl;
228  }
229  }
230 
231  function << "end" << std::endl;
232 
233  // set output wires
234  for (const GatePin* output_pin : output_pins)
235  {
236  function << "assign " << output_pin->get_name() << " = " << gt->get_boolean_function(output_pin) << ";" << std::endl;
237  }
238  }
239  else
240  {
241  log_error("verilator", "cannot get FFComponent, aborting...");
242  return function.str();
243  }
244 
245  return function.str();
246  }
247  } // namespace converter
248  } // namespace verilator
249 } // namespace hal
T * get_component_as(const std::function< bool(const GateTypeComponent *)> &filter=nullptr)
std::vector< GatePin * > get_output_pins() const
Definition: gate_type.cpp:285
const std::string & get_name() const
Definition: gate_type.cpp:64
T * get_component_as(const std::function< bool(const GateTypeComponent *)> &filter=nullptr) const
Definition: gate_type.h:89
BooleanFunction get_boolean_function(const std::string &name) const
Definition: gate_type.cpp:714
#define log_error(channel,...)
Definition: log.h:78
std::string get_function_for_latch(const GateType *gt)
Result< std::string > verilog_function_printer(const BooleanFunction::Node &node, std::vector< std::string > &&operands)
Definition: converter.cpp:304
Definition: defines.h:45