HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
ff_function.cpp
Go to the documentation of this file.
10 #include "hal_core/utilities/log.h"
11 #include "verilator/verilator.h"
12 
13 #include <filesystem>
14 #include <sstream>
15 #include <vector>
16 
17 namespace hal
18 {
19  namespace verilator
20  {
21  namespace converter
22  {
23  std::string get_function_for_ff(const GateType* gt)
24  {
25  std::stringstream function;
26 
27  if (FFComponent* ff_component = gt->get_component_as<FFComponent>([](const GateTypeComponent* c) { return FFComponent::is_class_of(c); }); ff_component != nullptr)
28  {
29  StateComponent* state_component;
30  if (state_component = ff_component->get_component_as<StateComponent>([](const GateTypeComponent* c) { return StateComponent::is_class_of(c); }); state_component == nullptr)
31  {
32  log_error("verilator", "gate: {} has no state information in gate_library. you need to set one! aborting...", gt->get_name());
33  return std::string();
34  }
35 
36  std::vector<GatePin*> output_pins = gt->get_output_pins();
37  std::string internal_state = state_component->get_state_identifier();
38  std::string internal_negated_state = state_component->get_neg_state_identifier();
39 
40  function << "reg " << internal_state << ";" << std::endl;
41  function << "reg " << internal_negated_state << ";" << std::endl;
42  function << std::endl;
43  function << "wire clock___internal___;" << std::endl;
44  function << std::endl;
45 
46  if (InitComponent* init_component = ff_component->get_component_as<InitComponent>([](const GateTypeComponent* c) { return InitComponent::is_class_of(c); });
47  init_component != nullptr)
48  {
49  function << "initial begin" << std::endl;
50  function << "\t" << internal_state << " = INIT;" << std::endl;
51  function << "\t" << internal_negated_state << " = !(INIT);" << std::endl;
52  function << "end" << std::endl;
53  }
54 
55  function << std::endl;
56 
57  std::vector<GatePin*> clock_pins = gt->get_pins([](const GatePin* p) { return p->get_type() == PinType::clock; });
58  if (clock_pins.size() != 1)
59  {
60  log_error("verilator", "unsupported reached: currently only supporting FFs with one clock! aborting...");
61  return std::string();
62  }
63  BooleanFunction clock_function = ff_component->get_clock_function();
64  BooleanFunction async_reset_function = ff_component->get_async_reset_function();
65  BooleanFunction async_set_function = ff_component->get_async_set_function();
66 
67  bool reset_async = false;
68  bool set_async = false;
69 
70  if (clock_function.is_empty())
71  {
72  log_error("verilator", "gate: {} has no clock function in gate_library. you need to set one! aborting...", gt->get_name());
73  return std::string();
74  }
75 
76  // create new signals for clock, async reset/set that already have function in them
77  function << "assign clock___internal___ = " << clock_function << ";" << std::endl;
78  if (!async_reset_function.is_empty())
79  {
80  reset_async = true;
81  function << "wire async_reset___internal___;" << std::endl;
82  function << "assign async_reset___internal___ = " << async_reset_function.to_string(verilog_function_printer) << ";" << std::endl;
83  function << std::endl;
84  }
85  if (!async_set_function.is_empty())
86  {
87  set_async = true;
88  function << "wire async_set___internal___;" << std::endl;
89  function << "assign async_set___internal___ = " << async_set_function.to_string(verilog_function_printer) << ";" << std::endl;
90  function << std::endl;
91  }
92 
93  function << std::endl;
94 
95  // begin process
96  function << "always @(posedge clock___internal___";
97  if (reset_async)
98  {
99  function << " or posedge async_reset___internal___";
100  }
101 
102  if (set_async)
103  {
104  function << " or posedge async_set___internal___";
105  }
106  function << ")" << std::endl;
107  function << "begin" << std::endl;
108 
109  bool if_used = false;
110 
111  if (reset_async && set_async)
112  {
113  auto [behav_state, behave_neg_state] = ff_component->get_async_set_reset_behavior();
114 
115  function << (if_used ? "\telse if (" : "\tif (") << async_reset_function.to_string(verilog_function_printer) << " & " << async_set_function << ") begin" << std::endl;
116 
117  switch (behav_state)
118  {
120  function << "\t\t" << internal_state << " <= 1'b0;" << std::endl;
121  break;
123  function << "\t\t" << internal_state << " <= 1'b1;" << std::endl;
124  break;
126  function << "\t\t" << internal_state << " <= !(" << internal_state << ");" << std::endl;
127  break;
129  function << "\t\t" << internal_state << " <= " << internal_state << ";" << std::endl;
130  break;
132  function << "\t\t" << internal_state << " <= 1'bX;" << std::endl;
133  break;
134 
135  default:
136  log_error("verilator", "unimplemented reached: found weird AsyncSetResetBehaviour for gate: {}", gt->get_name());
137  return std::string();
138  break;
139  }
140 
141  switch (behave_neg_state)
142  {
144  function << "\t\t" << internal_negated_state << " <= 1'b0;" << std::endl;
145  break;
147  function << "\t\t" << internal_negated_state << " <= 1'b1;" << std::endl;
148  break;
150  function << "\t\t" << internal_negated_state << " <= !(" << internal_negated_state << ");" << std::endl;
151  break;
153  function << "\t\t" << internal_negated_state << " <= " << internal_negated_state << ";" << std::endl;
154  break;
156  function << "\t\t" << internal_negated_state << " <= 1'bX;" << std::endl;
157  break;
158 
159  default:
160  log_error("verilator", "unimplemented reached: found weird AsyncSetResetBehaviour for gate: {}", gt->get_name());
161  return std::string();
162  break;
163  }
164  function << "\tend" << std::endl;
165 
166  if_used = true;
167  }
168  if (reset_async)
169  {
170  function << (if_used ? "\telse if (" : "\tif (") << async_reset_function.to_string(verilog_function_printer) << ") begin" << std::endl;
171  function << "\t\t" << internal_state << " <= 1'b0;" << std::endl;
172  function << "\t\t" << internal_negated_state << " <= 1'b1;" << std::endl;
173  function << "\tend" << std::endl;
174  if_used = true;
175  }
176  if (set_async)
177  {
178  function << (if_used ? "\telse if (" : "\tif (") << async_set_function.to_string(verilog_function_printer) << ") begin" << std::endl;
179  function << "\t\t" << internal_state << " <= 1'b1;" << std::endl;
180  function << "\t\t" << internal_negated_state << " <= 1'b0;" << std::endl;
181  function << "\tend" << std::endl;
182 
183  if_used = true;
184  }
185 
186  // else case of normal case if DFF
187  function << (if_used ? "\telse begin\n" : "");
188  function << (if_used ? "\t" : "") << "\t" << internal_state << " <= " << ff_component->get_next_state_function() << ";" << std::endl;
189  function << (if_used ? "\t" : "") << "\t" << internal_negated_state << " <= !(" << ff_component->get_next_state_function() << ");" << std::endl;
190  function << (if_used ? "\tend\n" : "");
191  function << "end" << std::endl;
192 
193  // set output wires
194  for (const GatePin* output_pin : output_pins)
195  {
196  function << "assign " << output_pin->get_name() << " = " << gt->get_boolean_function(output_pin) << ";" << std::endl;
197  }
198  }
199  else
200  {
201  log_error("verilator", "cannot get FFComponent, aborting...");
202  return function.str();
203  }
204 
205  return function.str();
206  }
207  } // namespace converter
208  } // namespace verilator
209 } // namespace hal
PinType get_type() const
Definition: base_pin.h:150
static std::string to_string(Value value)
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
std::vector< GatePin * > get_pins(const std::function< bool(GatePin *)> &filter=nullptr) const
Definition: gate_type.cpp:210
const std::string & get_state_identifier() const
const std::string & get_neg_state_identifier() const
#define log_error(channel,...)
Definition: log.h:78
std::string get_function_for_ff(const GateType *gt)
Definition: ff_function.cpp:23
Result< std::string > verilog_function_printer(const BooleanFunction::Node &node, std::vector< std::string > &&operands)
Definition: converter.cpp:304
Definition: defines.h:45