72
72
#include < vector>
73
73
#include " atom_netlist.h"
74
74
#include " atom_netlist_utils.h"
75
+ #include " clock_modeling.h"
75
76
#include " globals.h"
76
77
#include " logic_vec.h"
77
78
#include " netlist_walker.h"
@@ -2644,22 +2645,145 @@ std::string join_identifier(std::string lhs, std::string rhs) {
2644
2645
return lhs + ' _' + rhs;
2645
2646
}
2646
2647
2648
+ /* *
2649
+ * @brief Add the original SDC constraints that VPR used during its flow to the
2650
+ * given SDC file.
2651
+ */
2652
+ void add_original_sdc_to_post_implemented_sdc_file (std::ofstream& sdc_os,
2653
+ const t_timing_inf& timing_info) {
2654
+ // Open the original SDC file provided to VPR.
2655
+ std::ifstream original_sdc_file;
2656
+ original_sdc_file.open (timing_info.SDCFile );
2657
+ if (!original_sdc_file.is_open ()) {
2658
+ // TODO: VPR automatically creates SDC constraints by default if no SDC
2659
+ // file is provided. These can be replicated here if needed.
2660
+ VPR_FATAL_ERROR (VPR_ERROR_IMPL_NETLIST_WRITER,
2661
+ " No SDC files provided to VPR, currently cannot generate "
2662
+ " post-implementation SDC file without it" );
2663
+ }
2664
+
2665
+ // Write a header to declare where these commands came from.
2666
+ sdc_os << " \n " ;
2667
+ sdc_os << " #******************************************************************************#\n " ;
2668
+ sdc_os << " # The following SDC commands were provided to VPR from the given SDC file:\n " ;
2669
+ sdc_os << " # \t " << timing_info.SDCFile << " \n " ;
2670
+ sdc_os << " #******************************************************************************#\n " ;
2671
+
2672
+ // Append the original SDC file to the post-implementation SDC file.
2673
+ sdc_os << original_sdc_file.rdbuf ();
2674
+ }
2675
+
2676
+ /* *
2677
+ * @brief Add propagated clock commands to the given SDC file based on the set
2678
+ * clock modeling.
2679
+ *
2680
+ * This is necessary since VPR decides if clocks are routed or not, which has
2681
+ * affects on how timing analysis is performed on the clocks.
2682
+ */
2683
+ void add_propagated_clocks_to_sdc_file (std::ofstream& sdc_os,
2684
+ e_clock_modeling clock_modeling) {
2685
+
2686
+ // Ideal and routed clocks are handled by the code below. Other clock models
2687
+ // like dedicated routing are not supported yet.
2688
+ if (clock_modeling != e_clock_modeling::ROUTED_CLOCK && clock_modeling != e_clock_modeling::IDEAL_CLOCK) {
2689
+ VPR_FATAL_ERROR (VPR_ERROR_IMPL_NETLIST_WRITER,
2690
+ " Only ideal and routed clock modeling are currentlt "
2691
+ " supported for post-implementation SDC file generation" );
2692
+ }
2693
+
2694
+ // The timing constraints contain information on all the clocks in the circuit
2695
+ // (provided by the user-provided SDC file).
2696
+ const auto timing_constraints = g_vpr_ctx.timing ().constraints ;
2697
+
2698
+ // Collect the non-virtual clocks. Virtual clocks are not routed and
2699
+ // do not get propageted.
2700
+ std::vector<tatum::DomainId> non_virtual_clocks;
2701
+ for (tatum::DomainId clock_domain_id : timing_constraints->clock_domains ()) {
2702
+ if (!timing_constraints->is_virtual_clock (clock_domain_id)) {
2703
+ non_virtual_clocks.push_back (clock_domain_id);
2704
+ }
2705
+ }
2706
+
2707
+ // If there are no non-virtual clocks, no extra commands needed, any other
2708
+ // clocks will be set to be ideal.
2709
+ if (non_virtual_clocks.empty ()) {
2710
+ return ;
2711
+ }
2712
+
2713
+ // Append a header to explain why these commands are added.
2714
+ sdc_os << " \n " ;
2715
+ sdc_os << " #******************************************************************************#\n " ;
2716
+ sdc_os << " # The following are clock domains in VPR which have delays on their edges.\n " ;
2717
+ sdc_os << " #\n " ;
2718
+ sdc_os << " # Clocks that have been routed or whose input signal have been placed to an\n " ;
2719
+ sdc_os << " # input pad have delays on their signals. Thus, they should be treated as\n " ;
2720
+ sdc_os << " # propageted (non-ideal) clocks.\n " ;
2721
+ sdc_os << " #\n " ;
2722
+ sdc_os << " # Note: Virtual clocks do not get routed and are treated as ideal.\n " ;
2723
+ sdc_os << " #******************************************************************************#\n " ;
2724
+
2725
+ // Add the SDC commands to set the non-virtual clocks as propagated (non-ideal);
2726
+ // Note: It was decided that "ideal" clock modeling in VPR should still
2727
+ // set the clocks as propagated to allow for the input pad delays of
2728
+ // clocks to be included. The SDF delay annotations on clock signals
2729
+ // should make this safe to do.
2730
+ for (tatum::DomainId clock_domain_id : non_virtual_clocks) {
2731
+ sdc_os << " set_propagated_clock " ;
2732
+ sdc_os << timing_constraints->clock_domain_name (clock_domain_id);
2733
+ sdc_os << " \n " ;
2734
+ }
2735
+ }
2736
+
2737
+ /* *
2738
+ * @brief Generates a post-implementation SDC file with the given file name
2739
+ * based on the timing info and clock modeling set for VPR.
2740
+ */
2741
+ void generate_post_implementation_sdc (const std::string& sdc_filename,
2742
+ const t_timing_inf& timing_info,
2743
+ e_clock_modeling clock_modeling) {
2744
+ if (!timing_info.timing_analysis_enabled ) {
2745
+ VTR_LOG_WARN (" Timing analysis is disabled. Post-implementation SDC file "
2746
+ " will not be generated.\n " );
2747
+ return ;
2748
+ }
2749
+
2750
+ // Begin writing the post-implementation SDC file.
2751
+ std::ofstream sdc_os (sdc_filename);
2752
+
2753
+ // Print a header declaring that this file is auto-generated and what version
2754
+ // of VTR produced it.
2755
+ sdc_os << " #******************************************************************************#\n " ;
2756
+ sdc_os << " # SDC automatically generated by VPR from a post-place-and-route implementation.\n " ;
2757
+ sdc_os << " #\t Version: " << vtr::VERSION << " \n " ;
2758
+ sdc_os << " #******************************************************************************#\n " ;
2759
+
2760
+ // Add the original SDC that VPR used during its flow.
2761
+ add_original_sdc_to_post_implemented_sdc_file (sdc_os, timing_info);
2762
+
2763
+ // Add propagated clocks to SDC file if needed.
2764
+ add_propagated_clocks_to_sdc_file (sdc_os, clock_modeling);
2765
+ }
2766
+
2647
2767
} // namespace
2648
2768
2649
2769
//
2650
2770
// Externally Accessible Functions
2651
2771
//
2652
2772
2653
2773
// /@brief Main routine for this file. See netlist_writer.h for details.
2654
- void netlist_writer (const std::string basename, std::shared_ptr<const AnalysisDelayCalculator> delay_calc, const LogicalModels& models, t_analysis_opts opts) {
2774
+ void netlist_writer (const std::string basename,
2775
+ std::shared_ptr<const AnalysisDelayCalculator> delay_calc,
2776
+ const LogicalModels& models,
2777
+ const t_timing_inf& timing_info,
2778
+ e_clock_modeling clock_modeling,
2779
+ t_analysis_opts opts) {
2655
2780
std::string verilog_filename = basename + " _post_synthesis.v" ;
2656
2781
std::string blif_filename = basename + " _post_synthesis.blif" ;
2657
2782
std::string sdf_filename = basename + " _post_synthesis.sdf" ;
2658
2783
2659
2784
VTR_LOG (" Writing Implementation Netlist: %s\n " , verilog_filename.c_str ());
2660
2785
VTR_LOG (" Writing Implementation Netlist: %s\n " , blif_filename.c_str ());
2661
2786
VTR_LOG (" Writing Implementation SDF : %s\n " , sdf_filename.c_str ());
2662
-
2663
2787
std::ofstream verilog_os (verilog_filename);
2664
2788
std::ofstream blif_os (blif_filename);
2665
2789
std::ofstream sdf_os (sdf_filename);
@@ -2669,6 +2793,16 @@ void netlist_writer(const std::string basename, std::shared_ptr<const AnalysisDe
2669
2793
NetlistWalker nl_walker (visitor);
2670
2794
2671
2795
nl_walker.walk ();
2796
+
2797
+ if (opts.gen_post_implementation_sdc ) {
2798
+ std::string sdc_filename = basename + " _post_synthesis.sdc" ;
2799
+
2800
+ VTR_LOG (" Writing Implementation SDC : %s\n " , sdc_filename.c_str ());
2801
+
2802
+ generate_post_implementation_sdc (sdc_filename,
2803
+ timing_info,
2804
+ clock_modeling);
2805
+ }
2672
2806
}
2673
2807
2674
2808
// /@brief Main routine for this file. See netlist_writer.h for details.
0 commit comments