@@ -575,39 +575,42 @@ bool TimingGraph::validate_values() const {
575575
576576 for (NodeId node_id : nodes ()) {
577577 if (!valid_node_id (node_id)) {
578- throw tatum::Error (" Invalid node id" );
578+ throw tatum::Error (" Invalid node id" , node_id );
579579 }
580580
581581 for (EdgeId edge_id : node_in_edges_[node_id]) {
582582 if (!valid_edge_id (edge_id)) {
583- throw tatum::Error (" Invalid node-in-edge reference" );
583+ throw tatum::Error (" Invalid node-in-edge reference" , node_id, edge_id );
584584 }
585585
586586 // Check that the references are consistent
587587 if (edge_sink_nodes_[edge_id] != node_id) {
588- throw tatum::Error (" Mismatched edge-sink/node-in-edge reference" );
588+ throw tatum::Error (" Mismatched edge-sink/node-in-edge reference" , node_id, edge_id );
589589 }
590590 }
591591 for (EdgeId edge_id : node_out_edges_[node_id]) {
592592 if (!valid_edge_id (edge_id)) {
593- throw tatum::Error (" Invalid node-out-edge reference" );
593+ throw tatum::Error (" Invalid node-out-edge reference" , node_id, edge_id );
594594 }
595595
596596 // Check that the references are consistent
597597 if (edge_src_nodes_[edge_id] != node_id) {
598- throw tatum::Error (" Mismatched edge-src/node-out-edge reference" );
598+ throw tatum::Error (" Mismatched edge-src/node-out-edge reference" , node_id, edge_id );
599599 }
600600 }
601601 }
602602 for (EdgeId edge_id : edges ()) {
603603 if (!valid_edge_id (edge_id)) {
604- throw tatum::Error (" Invalid edge id" );
604+ throw tatum::Error (" Invalid edge id" , edge_id );
605605 }
606- if (!valid_node_id (edge_src_nodes_[edge_id])) {
607- throw tatum::Error (" Invalid edge source node" );
606+ NodeId src_node = edge_src_nodes_[edge_id];
607+ if (!valid_node_id (src_node)) {
608+ throw tatum::Error (" Invalid edge source node" , src_node, edge_id);
608609 }
609- if (!valid_node_id (edge_sink_nodes_[edge_id])) {
610- throw tatum::Error (" Invalid edge sink node" );
610+
611+ NodeId sink_node = edge_sink_nodes_[edge_id];
612+ if (!valid_node_id (sink_node)) {
613+ throw tatum::Error (" Invalid edge sink node" , sink_node, edge_id);
611614 }
612615 }
613616
@@ -633,29 +636,29 @@ bool TimingGraph::validate_structure() const {
633636 // Check expected number of fan-in/fan-out edges
634637 if (src_type == NodeType::SOURCE) {
635638 if (in_edges.size () > 1 ) {
636- throw tatum::Error (" SOURCE node has more than one active incoming edge (expected 0 if primary input, or 1 if clocked)" );
639+ throw tatum::Error (" SOURCE node has more than one active incoming edge (expected 0 if primary input, or 1 if clocked)" , src_node );
637640 }
638641 } else if (src_type == NodeType::SINK) {
639642 if (out_edges.size () > 0 ) {
640- throw tatum::Error (" SINK node has out-going edges" );
643+ throw tatum::Error (" SINK node has out-going edges" , src_node );
641644 }
642645 } else if (src_type == NodeType::IPIN) {
643646 if (in_edges.size () == 0 && !allow_dangling_combinational_nodes_) {
644- throw tatum::Error (" IPIN has no in-coming edges" );
647+ throw tatum::Error (" IPIN has no in-coming edges" , src_node );
645648 }
646649 if (out_edges.size () == 0 && !allow_dangling_combinational_nodes_) {
647- throw tatum::Error (" IPIN has no out-going edges" );
650+ throw tatum::Error (" IPIN has no out-going edges" , src_node );
648651 }
649652 } else if (src_type == NodeType::OPIN) {
650653 // May have no incoming edges if a constant generator, so don't check that case
651654
652655 if (out_edges.size () == 0 && !allow_dangling_combinational_nodes_) {
653- throw tatum::Error (" OPIN has no out-going edges" );
656+ throw tatum::Error (" OPIN has no out-going edges" , src_node );
654657 }
655658 } else {
656659 TATUM_ASSERT (src_type == NodeType::CPIN);
657660 if (in_edges.size () == 0 ) {
658- throw tatum::Error (" CPIN has no in-coming edges" );
661+ throw tatum::Error (" CPIN has no in-coming edges" , src_node );
659662 }
660663 // We do not check for out-going cpin edges, since there is no reason that
661664 // a clock pin must be used
@@ -675,61 +678,61 @@ bool TimingGraph::validate_structure() const {
675678 && sink_type != NodeType::OPIN
676679 && sink_type != NodeType::CPIN
677680 && sink_type != NodeType::SINK) {
678- throw tatum::Error (" SOURCE nodes should only drive IPIN, OPIN, CPIN or SINK nodes" );
681+ throw tatum::Error (" SOURCE nodes should only drive IPIN, OPIN, CPIN or SINK nodes" , src_node, out_edge );
679682 }
680683
681684 if (sink_type == NodeType::SINK) {
682685 if ( out_edge_type != EdgeType::INTERCONNECT
683686 && out_edge_type != EdgeType::PRIMITIVE_COMBINATIONAL) {
684- throw tatum::Error (" SOURCE to SINK edges should always be either INTERCONNECT or PRIMTIIVE_COMBINATIONAL type edges" );
687+ throw tatum::Error (" SOURCE to SINK edges should always be either INTERCONNECT or PRIMTIIVE_COMBINATIONAL type edges" , src_node, out_edge );
685688 }
686689
687690 } else if (sink_type == NodeType::OPIN) {
688691 if (out_edge_type != EdgeType::PRIMITIVE_COMBINATIONAL) {
689- throw tatum::Error (" SOURCE to OPIN edges should always be PRIMITIVE_COMBINATIONAL type edges" );
692+ throw tatum::Error (" SOURCE to OPIN edges should always be PRIMITIVE_COMBINATIONAL type edges" , src_node, out_edge );
690693 }
691694 } else {
692695 TATUM_ASSERT (sink_type == NodeType::IPIN || sink_type == NodeType::CPIN);
693696 if (out_edge_type != EdgeType::INTERCONNECT) {
694- throw tatum::Error (" SOURCE to IPIN/CPIN edges should always be INTERCONNECT type edges" );
697+ throw tatum::Error (" SOURCE to IPIN/CPIN edges should always be INTERCONNECT type edges" , src_node, out_edge );
695698 }
696699 }
697700
698701 } else if (src_type == NodeType::SINK) {
699- throw tatum::Error (" SINK nodes should not have out-going edges" );
702+ throw tatum::Error (" SINK nodes should not have out-going edges" , sink_node );
700703 } else if (src_type == NodeType::IPIN) {
701704 if (sink_type != NodeType::OPIN && sink_type != NodeType::SINK) {
702- throw tatum::Error (" IPIN nodes should only drive OPIN or SINK nodes" );
705+ throw tatum::Error (" IPIN nodes should only drive OPIN or SINK nodes" , src_node, out_edge );
703706 }
704707
705708 if (out_edge_type != EdgeType::PRIMITIVE_COMBINATIONAL) {
706- throw tatum::Error (" IPIN to OPIN/SINK edges should always be PRIMITIVE_COMBINATIONAL type edges" );
709+ throw tatum::Error (" IPIN to OPIN/SINK edges should always be PRIMITIVE_COMBINATIONAL type edges" , src_node, out_edge );
707710 }
708711
709712 } else if (src_type == NodeType::OPIN) {
710713 if ( sink_type != NodeType::IPIN
711714 && sink_type != NodeType::CPIN
712715 && sink_type != NodeType::SINK) {
713- throw tatum::Error (" OPIN nodes should only drive IPIN, CPIN or SINK nodes" );
716+ throw tatum::Error (" OPIN nodes should only drive IPIN, CPIN or SINK nodes" , src_node, out_edge );
714717 }
715718
716719 if (out_edge_type != EdgeType::INTERCONNECT) {
717- throw tatum::Error (" OPIN out edges should always be INTERCONNECT type edges" );
720+ throw tatum::Error (" OPIN out edges should always be INTERCONNECT type edges" , src_node, out_edge );
718721 }
719722
720723 } else if (src_type == NodeType::CPIN) {
721724 if ( sink_type != NodeType::SOURCE
722725 && sink_type != NodeType::SINK) {
723- throw tatum::Error (" CPIN nodes should only drive SOURCE or SINK nodes" );
726+ throw tatum::Error (" CPIN nodes should only drive SOURCE or SINK nodes" , src_node, out_edge );
724727 }
725728
726729 if (sink_type == NodeType::SOURCE && out_edge_type != EdgeType::PRIMITIVE_CLOCK_LAUNCH) {
727- throw tatum::Error (" CPIN to SOURCE edges should always be PRIMITIVE_CLOCK_LAUNCH type edges" );
730+ throw tatum::Error (" CPIN to SOURCE edges should always be PRIMITIVE_CLOCK_LAUNCH type edges" , src_node, out_edge );
728731 } else if (sink_type == NodeType::SINK && out_edge_type != EdgeType::PRIMITIVE_CLOCK_CAPTURE) {
729- throw tatum::Error (" CPIN to SINK edges should always be PRIMITIVE_CLOCK_CAPTURE type edges" );
732+ throw tatum::Error (" CPIN to SINK edges should always be PRIMITIVE_CLOCK_CAPTURE type edges" , src_node, out_edge );
730733 }
731734 } else {
732- throw tatum::Error (" Unrecognized node type" );
735+ throw tatum::Error (" Unrecognized node type" , src_node, out_edge );
733736 }
734737 }
735738 }
@@ -757,27 +760,27 @@ bool TimingGraph::validate_structure() const {
757760 for (EdgeId edge : edge_ids) {
758761 ss << edge << " " ;
759762 }
760- throw tatum::Error (ss.str ());
763+ throw tatum::Error (ss.str (), src_node );
761764 }
762765 }
763766
764767 for (NodeId node : primary_inputs ()) {
765768 if (!node_in_edges (node).empty ()) {
766- throw tatum::Error (" Primary input nodes should have no incoming edges" );
769+ throw tatum::Error (" Primary input nodes should have no incoming edges" , node );
767770 }
768771
769772 if (node_type (node) != NodeType::SOURCE) {
770- throw tatum::Error (" Primary inputs should be only SOURCE nodes" );
773+ throw tatum::Error (" Primary inputs should be only SOURCE nodes" , node );
771774 }
772775 }
773776
774777 for (NodeId node : logical_outputs ()) {
775778 if (!node_out_edges (node).empty ()) {
776- throw tatum::Error (" Logical output node should have no outgoing edges" );
779+ throw tatum::Error (" Logical output node should have no outgoing edges" , node );
777780 }
778781
779782 if (node_type (node) != NodeType::SINK) {
780- throw tatum::Error (" Logical outputs should be only SINK nodes" );
783+ throw tatum::Error (" Logical outputs should be only SINK nodes" , node );
781784 }
782785 }
783786
@@ -912,10 +915,10 @@ EdgeType infer_edge_type(const TimingGraph& tg, EdgeId edge) {
912915 } else if (sink_node_type == NodeType::SINK) {
913916 return EdgeType::PRIMITIVE_CLOCK_CAPTURE;
914917 } else {
915- throw tatum::Error (" Invalid edge sink node (CPIN source node must connect to SOURCE or SINK sink node)" );
918+ throw tatum::Error (" Invalid edge sink node (CPIN source node must connect to SOURCE or SINK sink node)" , sink_node, edge );
916919 }
917920 } else {
918- throw tatum::Error (" Invalid edge sink/source nodes" );
921+ throw tatum::Error (" Invalid edge sink/source nodes" , edge );
919922 }
920923}
921924
0 commit comments