HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
pin_event.cpp
Go to the documentation of this file.
4 #include <algorithm>
5 #include <assert.h>
6 
7 namespace hal {
8 
9  template<>
10  std::map<PinEvent, std::string> EnumStrings<PinEvent>::data = {
11  {PinEvent::unknown, "unknown"},
12  {PinEvent::GroupCreate, "GroupCreate"},
13  {PinEvent::GroupReorder, "GroupReorder"},
14  {PinEvent::GroupRename, "GroupRename"},
15  {PinEvent::GroupTypeChange, "GroupTypeChange"},
16  {PinEvent::GroupDirChange, "GroupDirChange"},
17  {PinEvent::GroupDelete, "GroupDelete"},
18  {PinEvent::PinCreate, "PinCreate"},
19  {PinEvent::PinReorder, "PinReorder"},
20  {PinEvent::PinAssignToGroup, "PinAssignToGroup"},
21  {PinEvent::PinRename, "PinRename"},
22  {PinEvent::PinTypeChange, "PinTypeChange"},
23  {PinEvent::PinDirChange, "PinDirChange"},
24  {PinEvent::PinDelete, "PinDelete"},
25  {PinEvent::PinsReload, "PinsReload"}
26  };
27 
28  std::unordered_map<Module*,PinChangedEvent::EventStack*> PinChangedEvent::s_event_stack;
29  u64 PinChangedEvent::s_order = 0;
30  int PinChangedEvent::s_bulk_depth = 0;
31 
33  : m_module(m), m_event(pev), m_id(id), m_order(++s_order)
34  {;}
35 
37  {
38  auto it = s_event_stack.find(m_module);
39  if (it == s_event_stack.end())
40  {
41  if (s_bulk_depth <= 0)
42  {
43  // not stacked, send event immediately
45  return;
46  }
47 
48  // within a bulk scope every module collects its events, the bulk scope owns the stack
49  it = s_event_stack.emplace(m_module, new EventStack).first;
50  it->second->m_sticky = true;
51  }
52 
53  // put event on stack to emit it later
54  it->second->push_back(*this);
55  }
56 
58  {
59  auto it = s_event_stack.find(m);
60  if (it == s_event_stack.end())
61  return;
62  delete it->second;
63  s_event_stack.erase(it);
64  }
65 
67  {
68  return m_module;
69  }
70 
72  {
73  return (m_id << 4) | (((u32)m_event)&0xF);
74  }
75 
77  {
78  if (a.m_event < b.m_event) return true;
79  if (a.m_event > b.m_event) return false;
80  if (a.m_event == PinEvent::PinAssignToGroup)
81  return a.m_order > b.m_order; // revert order for descending pin groups
82  return a.m_id<b.m_id;
83  }
84 
85  void PinChangedEvent::EventStack::send_events(Module* m)
86  {
87  std::sort(begin(),end(),pin_event_order);
88  for (auto it=begin(); it != end(); ++it)
89  m->get_event_handler()->notify(ModuleEvent::event::pin_changed, m, it->associated_data());
90  }
91 
93  : m_module(m)
94  {
95  auto it = PinChangedEvent::s_event_stack.find(m);
96  if (it == PinChangedEvent::s_event_stack.end())
97  {
98  auto* stack = new PinChangedEvent::EventStack;
99  stack->m_sticky = (PinChangedEvent::s_bulk_depth > 0);
100  PinChangedEvent::s_event_stack[m] = stack;
101  }
102  else
103  ++it->second->m_count;
104  }
105 
107  {
108  auto it = PinChangedEvent::s_event_stack.find(m_module);
109  if (it == PinChangedEvent::s_event_stack.end())
110  return; // module got destroyed within the scope, stack has been discarded
111  if (it->second->m_count > 0)
112  --it->second->m_count;
113  else if (!it->second->m_sticky) // sticky stacks are owned by the enclosing bulk scope
114  {
115  delete it->second;
116  PinChangedEvent::s_event_stack.erase(it);
117  }
118  }
119 
121  {
122  auto it = PinChangedEvent::s_event_stack.find(m_module);
123  if (it == PinChangedEvent::s_event_stack.end())
124  return; // module got destroyed within the scope, stack has been discarded
125  if (it->second->m_count > 0) // do not send yet
126  return;
127  if (it->second->m_sticky) // coalesced and sent by the enclosing bulk scope
128  return;
129  it->second->send_events(m_module);
130  }
131 
133  {
134  ++PinChangedEvent::s_bulk_depth;
135  }
136 
138  {
139  if (--PinChangedEvent::s_bulk_depth > 0)
140  return;
141 
142  // hand the stacks over before sending, listeners are free to change pins from within their handler
143  std::unordered_map<Module*,PinChangedEvent::EventStack*> stacks;
144  stacks.swap(PinChangedEvent::s_event_stack);
145 
146  for (auto& [module, stack] : stacks)
147  {
148  if (!stack->empty())
150  delete stack;
151  }
152  }
153 }
void notify(NetlistEvent::event ev, Netlist *netlist, u32 associated_data=0xFFFFFFFF)
@ pin_changed
associated_data = [4LSB: type of action] [28HSB: id of pin group or pin]
EventHandler * get_event_handler() const
Definition: module.cpp:1910
static void discard(Module *m)
Definition: pin_event.cpp:57
PinChangedEvent(Module *m, PinEvent pev, u32 id)
Definition: pin_event.cpp:32
Module * get_module() const
Definition: pin_event.cpp:66
PinChangedEventScope(Module *m)
Definition: pin_event.cpp:92
uint64_t u64
Definition: defines.h:42
uint32_t u32
Definition: defines.h:41
const Module * module(const Gate *g, const NodeBoxes &boxes)
Definition: defines.h:45
PinEvent
Definition: pin_event.h:42
@ PinsReload
group deleted
@ PinTypeChange
pin renamed
@ GroupReorder
changed PinDirection attribute of group (like input)
@ PinDirChange
changed PinType attribute of pin (like data)
@ PinCreate
moved group to a new position within containing module
@ GroupTypeChange
pin group renamed
@ PinRename
pin assigned to new group
@ PinAssignToGroup
new pin created
@ PinDelete
moved pin to a new position within containing group
@ GroupRename
new pin group created
@ GroupDelete
pin deleted
@ GroupDirChange
changed PinType attribute of group (like data)
@ PinReorder
changed PinDirection attribute of pin (like input)
bool pin_event_order(const PinChangedEvent &a, const PinChangedEvent &b)
Definition: pin_event.cpp:76
i32 id