@@ -26,23 +26,6 @@ namespace hal
2626 {
2727 namespace
2828 {
29- struct VoidPtrHash
30- {
31- std::size_t operator ()( const std::pair<const void *, const void *> &pair ) const
32- {
33- return std::hash<const void *>()( pair.first ) ^ ( std::hash<const void *>()( pair.second ) << 1 );
34- }
35- };
36-
37- struct PairPtrEq
38- {
39- bool operator ()( const std::pair<void *, void *> &p1,
40- const std::pair<void *, void *> &p2 ) const noexcept
41- {
42- return p1.first == p2.first && p1.second == p2.second ;
43- }
44- };
45-
4629 inline bool is_ff ( const Gate *gate )
4730 {
4831 return gate->get_type ()->has_property ( GateTypeProperty::ff );
@@ -154,10 +137,13 @@ namespace hal
154137 std::unordered_set<std::pair<void *, void *>, VoidPtrHash> edges;
155138 std::unordered_map<const void *, PtrType> ptrs_to_type;
156139
157- std::queue<std::pair <const Gate *, const Gate *>> queue;
140+ std::queue<std::tuple <const Gate *, const Gate *, std::vector< const Gate *> >> queue;
158141 NetlistTraversalDecorator ntd = NetlistTraversalDecorator ( *netlist );
159142 std::unordered_set<std::pair<const Gate *, const Gate *>, VoidPtrHash> visited;
160143
144+ std::unordered_map<std::pair<const void *, const void *>, std::vector<const Gate *>, VoidPtrHash, PairPtrEq>
145+ paths;
146+
161147 for ( const Gate *ff : netlist->get_gates ( is_ff ) )
162148 {
163149 const std::vector<hal::GatePin *> clock_pins = ff->get_type ()->get_pins ( []( const auto &p ) {
@@ -201,7 +187,7 @@ namespace hal
201187 continue ;
202188 }
203189
204- queue.push ( { ff, clk->get_sources ().front ()->get_gate () } );
190+ queue.push ( { ff, clk->get_sources ().front ()->get_gate (), std::vector< const Gate *>{} } );
205191
206192 vertices.insert ( (void *) ff );
207193 ptrs_to_type[(void *) ff] = PtrType::GATE;
@@ -211,11 +197,14 @@ namespace hal
211197
212198 while ( !queue.empty () )
213199 {
214- const std::pair <const Gate *, const Gate *> pair = queue.front ();
200+ const std::tuple <const Gate *, const Gate *, std::vector< const Gate *>> tuple = queue.front ();
215201 queue.pop ();
216202
217- Gate *source = (Gate *) pair.second ;
218- Gate *reference = (Gate *) pair.first ;
203+ Gate *source = (Gate *) std::get<1 >( tuple );
204+ Gate *reference = (Gate *) std::get<0 >( tuple );
205+ std::vector<const Gate *> path = std::get<2 >( tuple );
206+
207+ path.push_back ( source );
219208
220209 if ( is_latch ( source ) )
221210 {
@@ -237,6 +226,9 @@ namespace hal
237226 ptrs_to_type[(void *) reference] = PtrType::GATE;
238227
239228 edges.insert ( { (void *) source, (void *) reference } );
229+ path.push_back ( reference );
230+ paths[{ (void *) source, (void *) reference }] = path;
231+ path.clear ();
240232
241233 if ( is_ff ( source ) )
242234 {
@@ -246,7 +238,7 @@ namespace hal
246238 reference = (Gate *) source;
247239 }
248240
249- visited.insert ( pair );
241+ visited.insert ( std::make_pair ( reference, source ) );
250242
251243 for ( const Endpoint *ep : source->get_fan_in_endpoints () )
252244 {
@@ -272,6 +264,10 @@ namespace hal
272264 ptrs_to_type[(void *) reference] = PtrType::GATE;
273265
274266 edges.insert ( { (void *) net, (void *) reference } );
267+
268+ // paths[{ (void *) net, (void *) reference }] = path;
269+ // path.clear();
270+
275271 continue ;
276272 }
277273
@@ -293,7 +289,7 @@ namespace hal
293289 const Gate *new_source = net->get_sources ().front ()->get_gate ();
294290 if ( visited.find ( { reference, new_source } ) == visited.end () )
295291 {
296- queue.push ( { reference, new_source } );
292+ queue.push ( { reference, new_source, path } );
297293 }
298294 }
299295 }
@@ -310,6 +306,7 @@ namespace hal
310306 }
311307
312308 clock_tree->m_ptrs_to_types = ptrs_to_type;
309+ clock_tree->m_paths = std::move ( paths );
313310
314311 igraph_error_t ierror;
315312 igraph_vector_int_t iedges;
@@ -710,5 +707,47 @@ namespace hal
710707 {
711708 return m_igraph_ptr;
712709 }
710+
711+ const std::
712+ unordered_map<std::pair<const void *, const void *>, std::vector<const Gate *>, VoidPtrHash, PairPtrEq>
713+ ClockTree::get_paths () const
714+ {
715+ return m_paths;
716+ }
717+
718+ Result<std::vector<std::pair<const void *, PtrType>>>
719+ ClockTree::get_neighbors ( const void *ptr, igraph_neimode_t direction ) const
720+ {
721+ auto it = m_ptrs_to_vertices.find ( ptr );
722+ if ( it == m_ptrs_to_vertices.end () )
723+ {
724+ return ERR ( " object is not part of clock tree" );
725+ }
726+
727+ igraph_error_t ierror;
728+ igraph_vector_int_t neighbors;
729+
730+ if ( ( ierror = igraph_vector_int_init ( &neighbors, 0 ) ) != IGRAPH_SUCCESS )
731+ {
732+ return ERR ( igraph_strerror ( ierror ) );
733+ }
734+
735+ if ( ( ierror = igraph_neighbors ( m_igraph_ptr, &neighbors, it->second , direction ) ) != IGRAPH_SUCCESS )
736+ {
737+ igraph_vector_int_destroy ( &neighbors );
738+ return ERR ( igraph_strerror ( ierror ) );
739+ }
740+
741+ std::vector<std::pair<const void *, PtrType>> result;
742+ for ( igraph_integer_t idx = 0 ; idx < igraph_vector_int_size ( &neighbors ); idx++ )
743+ {
744+ const void *n_ptr = m_vertices_to_ptrs.at ( VECTOR ( neighbors )[idx] );
745+ result.push_back ( std::make_pair ( n_ptr, m_ptrs_to_types.at ( n_ptr ) ) );
746+ }
747+
748+ igraph_vector_int_destroy ( &neighbors );
749+
750+ return OK ( result );
751+ }
713752 } // namespace cte
714753} // namespace hal
0 commit comments