HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
simulation_input.cpp
Go to the documentation of this file.
3 #include "hal_core/netlist/net.h"
6 #include <stdio.h>
7 
8 namespace hal {
9 
10  std::vector<const Net *> SimulationInput::NetGroup::get_nets() const
11  {
12  std::vector<const Net *> retval;
13  if (gate)
14  {
15  for (GatePin* gp : gate_pin_group->get_pins())
16  {
17  Net* n = nullptr;
18  if (gp->get_direction() == PinDirection::input || gp->get_direction() == PinDirection::inout)
19  n = gate->get_fan_in_net(gp);
20  else
21  n = gate->get_fan_out_net(gp);
22  if (n) retval.push_back(n);
23  }
24  }
25  else
26  {
27  for (ModulePin* mp : module_pin_group->get_pins())
28  retval.push_back(mp->get_net());
29  }
30  return retval;
31  }
32 
34  {
35  if (gate)
36  return gate_pin_group->get_name();
37  return module_pin_group->get_name();
38  }
39 
40  bool SimulationInput::contains_gate(const Gate* g) const
41  {
42  return (mSimulationSet.find(g) != mSimulationSet.end());
43  }
44 
45  void SimulationInput::add_gates(const std::vector<Gate*>& gates)
46  {
47  mSimulationSet.insert(gates.begin(), gates.end());
48 
49  compute_input_nets();
50  compute_output_nets();
51  compute_partial_nets();
52  }
53 
54  const std::unordered_set<const Gate*>& SimulationInput::get_gates() const
55  {
56  return mSimulationSet;
57  }
58 
59  bool SimulationInput::is_clock(const Net* n) const
60  {
61  for (const Clock& c: m_clocks)
62  if (c.clock_net == n) return true;
63  return false;
64  }
65 
67  {
68  m_clocks.push_back(clk);
69  }
70 
72  {
73  mSimulationSet.clear();
74  m_clocks.clear();
75  m_input_nets.clear();
76  m_output_nets.clear();
77  m_partial_nets.clear();
78  m_netgroups.clear();
79  }
80 
82  {
83  return has_gates() && (!m_clocks.empty() || mNoClockUsed) && !m_input_nets.empty();
84  }
85 
87  {
88  return !mSimulationSet.empty();
89  }
90 
91  const std::unordered_set<const Net *>& SimulationInput::get_input_nets() const
92  {
93  return m_input_nets;
94  }
95 
96  const std::vector<const Net*>& SimulationInput::get_output_nets() const
97  {
98  return m_output_nets;
99  }
100 
101  const std::vector<const Net*>& SimulationInput::get_partial_netlist_nets() const
102  {
103  return m_partial_nets;
104  }
105 
106  bool SimulationInput::is_input_net(const Net* n) const
107  {
108  return (m_input_nets.find(n) != m_input_nets.end());
109  }
110 
112  {
113  mNoClockUsed = true;
114  }
115 
117  {
118  return mNoClockUsed;
119  }
120 
121  void SimulationInput::dump(std::string filename) const
122  {
123  FILE* of = stderr;
124  if (!filename.empty())
125  if (!(of = fopen(filename.c_str(),"w")))
126  {
127  log_warning("SimulationInput", "cannot open simulation input dump file '{}'", filename);
128  return;
129  }
130 
131  fprintf(of, "Gates:______________________________________\n");
132  for (const Gate* g: mSimulationSet)
133  {
134  fprintf(of, " %4d <%s>\n", g->get_id(), g->get_name().c_str());
135  }
136  fprintf(of, "Clocks:_____________________________________\n");
137  for (const Clock& clk: m_clocks)
138  {
139  fprintf(of, " %4d <%s> \t period: %u \n", clk.clock_net->get_id(), clk.clock_net->get_name().c_str(), (unsigned int) clk.period());
140  }
141  fprintf(of, "Input nets:_________________________________\n");
142  for (const Net* n: m_input_nets)
143  {
144  fprintf(of, " %4d <%s>\n", n->get_id(), n->get_name().c_str());
145  }
146  fprintf(of, "Output nets:________________________________\n");
147  for (const Net* n: m_output_nets)
148  {
149  fprintf(of, " %4d <%s>\n", n->get_id(), n->get_name().c_str());
150  }
151  fprintf(of, "Partial netlist nets:________________________________\n");
152  for (const Net* n: m_partial_nets)
153  {
154  fprintf(of, " %4d <%s>\n", n->get_id(), n->get_name().c_str());
155  }
156  if (filename.empty())
157  fflush(of);
158  else
159  fclose(of);
160  }
161 
162  void SimulationInput::compute_input_nets()
163  {
164  m_input_nets.clear();
165  for (auto gate : mSimulationSet)
166  {
167  for (auto net : gate->get_fan_in_nets())
168  {
169  // "input net" is either a global input...
170  if (net->is_global_input_net())
171  {
172  m_input_nets.insert(net);
173  }
174  else // ... or has a source outside of the simulation set
175  {
176  int number_sources = 0;
177  for (auto src : net->get_sources())
178  {
179  ++number_sources;
180  if (!contains_gate(src->get_gate()))
181  {
182  m_input_nets.insert(net);
183  break;
184  }
185  }
186  if (!number_sources)
187  m_input_nets.insert(net);
188  }
189  }
190  }
191  }
192 
193  void SimulationInput::compute_output_nets()
194  {
195  m_output_nets.clear();
196  for (auto gate : mSimulationSet)
197  {
198  for (auto net : gate->get_fan_out_nets())
199  {
200  // "output net" is either a global output...
201  if (net->is_global_output_net())
202  {
203  m_output_nets.push_back(net);
204  }
205  else // ... or has a destination outside of the simulation set
206  {
207  int number_destinations = 0;
208  for (auto dst : net->get_destinations())
209  {
210  ++number_destinations;
211  if (!contains_gate(dst->get_gate()))
212  {
213  m_output_nets.push_back(net);
214  break;
215  }
216  }
217  if (!number_destinations)
218  m_output_nets.push_back(net);
219  }
220  }
221  }
222  }
223 
224  void SimulationInput::compute_partial_nets()
225  {
226  m_partial_nets.clear();
227  std::unordered_set<const Net*> found;
228  for (const Gate* g : mSimulationSet)
229  {
230  for (const Net* n : g->get_fan_in_nets())
231  {
232  if (found.find(n) == found.end())
233  {
234  found.insert(n);
235  m_partial_nets.push_back(n);
236  }
237  }
238  for (const Net* n : g->get_fan_out_nets())
239  {
240  if (found.find(n) == found.end())
241  {
242  found.insert(n);
243  m_partial_nets.push_back(n);
244  }
245  }
246  }
247  }
248 
250  {
251  std::unordered_set<const Module*> simulated_modules;
252 
253  // all nets that are part of the simulation
254  std::unordered_map<const Net*, DirectionType> ungrouped_nets;
255 
256  for (const Net* n : m_partial_nets) ungrouped_nets[n] = Undefined;
257  for (const Net* n : m_input_nets) ungrouped_nets[n] = InputOnly;
258  for (const Net* n : m_output_nets) ungrouped_nets[n] = OutputOnly;
259 
260  // all modules that contain at least one simulated gate
261  for (const Gate* g : mSimulationSet)
262  {
263  const Module *m = g->get_module();
264  while (m)
265  {
266  simulated_modules.insert(m);
267  m = m->get_parent_module();
268  }
269  }
270 
271  // check all pingroups from affected modules, working the module hierarchy top -> bottom
272  auto it = simulated_modules.begin();
273  for (int level = 0; ! simulated_modules.empty(); )
274  {
275  while ((*it)->get_submodule_depth() != level)
276  {
277  if (++it == simulated_modules.end())
278  {
279  ++level;
280  it = simulated_modules.begin();
281  }
282  }
283 
284  const Module*m = (*it);
285  for (PinGroup<ModulePin>* pg : m->get_pin_groups())
286  {
287  if (pg->size() < 2 || pg->size() > 31) continue;
288  bool pin_group_simulated = true;
289  DirectionType groupType = Undefined;
290 
291  for (ModulePin* mp : pg->get_pins())
292  {
293  Net* n = mp->get_net();
294  if (n)
295  {
296  auto itNet = ungrouped_nets.find(n);
297  if (itNet == ungrouped_nets.end())
298  {
299  // pin : net exists and is not part of the simulation, ignore pin group
300  pin_group_simulated = false;
301  break;
302  }
303  else
304  {
305  if (groupType == Undefined)
306  groupType = itNet->second;
307  else if (groupType != Mixed && groupType != itNet->second)
308  groupType = Mixed;
309  }
310  }
311  }
312  if (pin_group_simulated)
313  {
314  NetGroup group;
315  group.module_pin_group = pg;
316  group.direction = groupType;
317  group.ascending = pg->is_ascending();
318  for (ModulePin* mp : pg->get_pins())
319  {
320  Net* n = mp->get_net();
321  if (n)
322  {
323  ungrouped_nets.erase(n);
324  }
325  }
326  m_netgroups.push_back(group);
327  }
328  }
329 
330  simulated_modules.erase(it);
331  it = simulated_modules.begin();
332  }
333 
334  for (const Gate* g : mSimulationSet)
335  {
336  const GateType* gt = g->get_type();
337 
338  for (PinGroup<GatePin>* pg : gt->get_pin_groups())
339  {
340  if (pg->size() < 2 || pg->size() > 31) continue;
341  bool pin_group_simulated = true;
342  DirectionType groupType = Undefined;
343  std::unordered_set<const Net*> connectedNets;
344 
345  for (GatePin* gp : pg->get_pins())
346  {
347  Net* n = nullptr;
348  switch (gp->get_direction())
349  {
350  case PinDirection::inout:
351  n = g->get_fan_in_net(gp);
352  break;
354  n = g->get_fan_out_net(gp);
355  break;
356  default:
357  break;
358  }
359  if (n)
360  {
361  auto itNet = ungrouped_nets.find(n);
362  if (itNet == ungrouped_nets.end())
363  {
364  // pin : net already assigned to module pin group, ignore gate pin group
365  pin_group_simulated = false;
366  break;
367  }
368  else
369  {
370  connectedNets.insert(n);
371  if (groupType == Undefined)
372  groupType = itNet->second;
373  else if (groupType != Mixed && groupType != itNet->second)
374  groupType = Mixed;
375  }
376  }
377  else
378  pin_group_simulated = false;
379  }
380 
381  if (pin_group_simulated)
382  {
383  NetGroup group;
384  group.gate = g;
385  group.gate_pin_group = pg;
386  group.direction = groupType;
387  group.ascending = pg->is_ascending();
388  for (const Net* n : connectedNets)
389  ungrouped_nets.erase(n);
390  m_netgroups.push_back(group);
391  }
392  }
393  }
394  }
395 }
Definition: gate.h:58
Net * get_fan_in_net(const std::string &pin_name) const
Definition: gate.cpp:617
Net * get_fan_out_net(const std::string &pin_name) const
Definition: gate.cpp:761
std::vector< PinGroup< GatePin > * > get_pin_groups(const std::function< bool(PinGroup< GatePin > *)> &filter=nullptr) const
Definition: gate_type.cpp:548
Module * get_parent_module() const
Definition: module.cpp:125
std::vector< PinGroup< ModulePin > * > get_pin_groups(const std::function< bool(PinGroup< ModulePin > *)> &filter=nullptr) const
Definition: module.cpp:964
Definition: net.h:58
const std::vector< const Net * > & get_partial_netlist_nets() const
const std::vector< const Net * > & get_output_nets() const
void dump(std::string filename=std::string()) const
bool is_input_net(const Net *n) const
bool is_clock(const Net *n) const
const std::unordered_set< const Net * > & get_input_nets() const
void add_gates(const std::vector< Gate * > &gates)
bool contains_gate(const Gate *g) const
const std::unordered_set< const Gate * > & get_gates() const
void add_clock(const Clock &clk)
#define log_warning(channel,...)
Definition: log.h:76
Definition: defines.h:45
Net * net
PinGroup< GatePin > * gate_pin_group
PinGroup< ModulePin > * module_pin_group
std::vector< const Net * > get_nets() const