@@ -46,6 +46,11 @@ namespace hal
4646 return gate->get_type ()->has_property ( GateTypeProperty::c_inverter );
4747 }
4848
49+ inline bool is_delay ( const Gate *gate )
50+ {
51+ return gate->get_type ()->has_property ( GateTypeProperty::delay );
52+ }
53+
4954 inline bool is_control_pin ( const PinType &pin_type )
5055 {
5156 return pin_type == PinType::clock || pin_type == PinType::enable || pin_type == PinType::select
@@ -143,6 +148,9 @@ namespace hal
143148
144149 for ( const Gate *ff : netlist->get_gates ( is_ff ) )
145150 {
151+ vertices.insert ( (void *) ff );
152+ ptrs_to_type[(void *) ff] = PtrType::GATE ;
153+
146154 const std::vector<hal::GatePin *> clock_pins = ff->get_type ()->get_pins ( []( const auto &p ) {
147155 return ( p->get_direction () == PinDirection::input ) && ( p->get_type () == PinType::clock );
148156 } );
@@ -207,9 +215,6 @@ namespace hal
207215 const Gate *gate = source_ep->get_gate ();
208216 queue.push ( { ff, gate, std::vector<const Gate *>{ ff } } );
209217 }
210-
211- vertices.insert ( (void *) ff );
212- ptrs_to_type[(void *) ff] = PtrType::GATE ;
213218 }
214219
215220 const std::unordered_set<const Gate *> toggle_ffs = get_toggle_ffs ( netlist );
@@ -230,7 +235,7 @@ namespace hal
230235 // Ignore latches
231236 continue ;
232237 }
233- else if ( is_buffer ( source ) || is_inverter ( source ) || is_ff ( source ) )
238+ else if ( is_buffer ( source ) || is_inverter ( source ) || is_delay ( source ) || is_ff ( source ) )
234239 {
235240 if ( is_ff ( source ) && toggle_ffs.find ( source ) == toggle_ffs.end () )
236241 {
@@ -408,32 +413,52 @@ namespace hal
408413 continue ;
409414 }
410415
411- const i32 x = ( (Gate *) ptr )->get_location_x ();
412- const i32 y = ( (Gate *) ptr )->get_location_y ();
416+ const Gate *gate = (const Gate *) ptr;
417+
418+ std::string coords = " " ;
419+
420+ // Workaround for negative coordinates
413421
414- const std::string coords =
415- ( x < 0 || y < 0 ) ? " " : " x= " + std::to_string ( x ) + " y= " + std::to_string ( y );
422+ // const i32 x = gate->get_location_x();
423+ // const i32 y = gate->get_location_y( );
416424
417- if ( is_buffer ( (Gate *) ptr ) )
425+ try
418426 {
419- dot_fd << " " << std::to_string ( ( (Gate *) ptr )->get_id () ) << " [" << coords
420- << " shape=rectangle];\n " ;
427+ const i32 x = std::stoi ( std::get<1 >( gate->get_data ( " generic" , " X" ) ) );
428+ const i32 y = std::stoi ( std::get<1 >( gate->get_data ( " generic" , " Y" ) ) );
429+ coords = " x=" + std::to_string ( x ) + " y=" + std::to_string ( y );
430+ } catch ( const std::invalid_argument &err )
431+ {
432+ log_error ( " clock_tree_extractor" , " invalid coordinate format: {}" , err.what () );
433+ }
434+
435+ std::string shape = " shape=hexagon" ; // default (clock gates)
436+
437+ if ( is_buffer ( gate ) )
438+ {
439+ shape = " shape=rectangle" ;
421440 }
422- else if ( is_inverter ( (Gate *) ptr ) )
441+ else if ( is_inverter ( gate ) )
423442 {
424- dot_fd << " " << std::to_string ( ( (Gate *) ptr )->get_id () ) << " [" << coords
425- << " shape=triangle, orientation=180];\n " ;
443+ shape = " shape=triangle orientation=180" ;
426444 }
427- else if ( is_ff ( (Gate *) ptr ) )
445+ else if ( is_ff ( gate ) )
428446 {
429- dot_fd << " " << std::to_string ( ( (Gate *) ptr )->get_id () )
430- << ( coords.size () == 0 ? " ;\n " : " [" + coords + " ];\n " );
447+ shape = " " ; // no shape
431448 }
432- else
449+ else if ( is_delay ( gate ) )
433450 {
434- dot_fd << " " << std::to_string ( ( (Gate *) ptr )->get_id () ) << " [" << coords
435- << " shape=hexagon];\n " ;
451+ shape = " shape=square" ;
436452 }
453+
454+ dot_fd << " " << gate->get_id () << " [instance=\" " << gate->get_name () << " \" " << coords;
455+
456+ if ( !shape.empty () )
457+ {
458+ dot_fd << " " << shape;
459+ }
460+
461+ dot_fd << " ];\n " ;
437462 }
438463
439464 std::queue<std::pair<igraph_integer_t , std::string>> queue;
0 commit comments