Hog v9.9.0
post-synthesis.tcl
Go to the documentation of this file.
1 #!/usr/bin/env tclsh
2 # Copyright 2018-2024 The University of Birmingham
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 # @file
17 # The post synthesis script copies the synthesis reports and other files to the bin.
18 # This script is automatically integrated into the Vivado/Quartus workflow by the Create Project script.
19 
20 ##nagelfar variable quartus
21 ##nagelfar variable project
22 
23 if {[catch {package require struct::matrix} ERROR]} {
24  puts "$ERROR\n If you are running this script on tclsh, you can fix this by installing 'tcllib'"
25  return
26 }
27 
28 set tcl_path [file normalize "[file dirname [info script]]/.."]
29 source $tcl_path/hog.tcl
30 
31 if {[IsISE]} {
32  # Vivado + PlanAhead
33  set old_path [file normalize "../../Projects/$project/$project.runs/synth_1"]
34  file mkdir $old_path
35 } else {
36  set old_path [pwd]
37 }
38 
39 if {[IsXilinx]} {
40  # Vivado + PlanAhead
41  if {[IsISE]} {
42  set proj_file [get_property DIRECTORY [current_project]]
43  } else {
44  set proj_file [get_property parent.project_path [current_project]]
45  }
46  set proj_dir [file normalize [file dirname $proj_file]]
47  set proj_name [file rootname [file tail $proj_file]]
48  set top_name [get_property top [current_fileset]]
49 } elseif {[IsQuartus]} {
50  # Quartus
51  set proj_name [lindex $quartus(args) 1]
52  #set proj_dir [file normalize "$repo_path/Projects/$proj_name"]
53  set proj_dir [pwd]
54  set proj_file [file normalize "$proj_dir/$proj_name.qpf"]
55  # Test generated files
56  set hogQsysFileName [file normalize "$proj_dir/.hog/.hogQsys.md5"]
57  if { [file exists $hogQsysFileName] != 0} {
58  set hogQsysFile [open $hogQsysFileName r]
59  set hogQsysFileLines [split [read $hogQsysFile] "\n"]
60  foreach line $hogQsysFileLines {
61  set fileEntry [split $line "\t"]
62  set fileEntryName [lindex $fileEntry 0]
63  if {$fileEntryName != ""} {
64  if {[file exists $fileEntryName]} {
65  set newMd5Sum [Md5Sum $fileEntryName]
66  set oldMd5Sum [lindex $fileEntry 1]
67  if { $newMd5Sum != $oldMd5Sum } {
68  Msg Warning "The checksum for file $fileEntryName not equal to the one saved in $hogQsysFileName: new checksum $newMd5Sum, old checksum $oldMd5Sum. Please check the any changes in the file are correctly propagated to git!"
69  }
70  } else {
71  Msg Warning "File $fileEntryName not found... Will not check Md5Sum!"
72  }
73  }
74  }
75 
76  }
77 } else {
78  #Tclssh
79  set proj_file $old_path/[file tail $old_path].xpr
80  set proj_dir [file normalize [file dirname $proj_file]]
81  set proj_name [file rootname [file tail $proj_file]]
82  Msg CriticalWarning "You seem to be running locally on tclsh, so this is a debug, the project file will be set to $proj_file and was derived from the path you launched this script from: $old_path. If you want this script to work properly in debug mode, please launch it from the top folder of one project, for example Repo/Projects/fpga1/ or Repo/Top/fpga1/"
83 }
84 
85 # Go to repository path
86 set repo_path [file normalize "$tcl_path/../.."]
87 set bin_dir [file normalize "$repo_path/bin"]
88 
89 cd $repo_path
90 
91 set group_name [GetGroupName $proj_dir "$tcl_path/../.."]
92 
93 Msg Info "Evaluating Git sha for $proj_name..."
94 lassign [GetRepoVersions [file normalize ./Top/$group_name/$proj_name] $repo_path] sha
95 
96 set describe [GetHogDescribe $sha $repo_path]
97 Msg Info "Git describe set to: $describe"
98 set dst_dir [file normalize "$bin_dir/$group_name/$proj_name\-$describe"]
99 
100 Msg Info "Creating $dst_dir..."
101 file mkdir $dst_dir
102 # Reports
103 file mkdir $dst_dir/reports
104 
105 
106 
107 # Vivado
108 if {[IsXilinx]} {
109 
110  # Vivado + PlanAhead
111  if {[IsISE]} {
112  # planAhead
113  set work_path [get_property DIRECTORY [get_runs synth_1]]
114  } else {
115  # Vivado
116  set work_path $old_path
117  }
118  set run_dir [file normalize "$work_path/.."]
119 
120  if {[IsISE]} {
121  set reps [glob -nocomplain "$run_dir/*/*{.syr,.srp,.mrp,.map,.twr,.drc,.bgn,_routed.par,_routed_pad.txt,_routed.unroutes}"]
122  } else {
123  set reps [glob -nocomplain "$run_dir/*/*.rpt"]
124  }
125  if {[file exists [lindex $reps 0]]} {
126  file copy -force {*}$reps $dst_dir/reports
127  if {[file exists [glob -nocomplain "$dst_dir/reports/${top_name}_utilization_synth.rpt"] ]} {
128  set utilization_file [file normalize $dst_dir/utilization.txt]
129  set report_file [glob -nocomplain "$dst_dir/reports/${top_name}_utilization_synth.rpt"]
130  if {$group_name != ""} {
131  WriteUtilizationSummary $report_file $utilization_file $group_name/$proj_name "Synthesis"
132  } else {
133  WriteUtilizationSummary $report_file $utilization_file $proj_name "Synthesis"
134  }
135  }
136  } else {
137  Msg Warning "No reports found in $run_dir subfolders"
138  }
139 
140 
141  # Handle IPs
142  if {[IsVivado]} {
143  if {[info exists env(HOG_IP_PATH)]} {
144  set ip_repo $env(HOG_IP_PATH)
145  set ips [get_ips *]
146  set run_paths [glob -nocomplain "$run_dir/*"]
147  set runs {}
148  foreach r $run_paths {
149  if {[regexp -all {^(.+)_synth_1} $r whole_match run]} {
150  lappend runs [file tail $run]
151  }
152  }
153 
154  foreach ip $ips {
155  if {$ip in $runs} {
156  set force 1
157  } else {
158  set force 0
159  }
160  Msg Info "Copying synthesised IP $ip to $ip_repo..."
161  HandleIP push [get_property IP_FILE $ip] $ip_repo $repo_path [get_property IP_OUTPUT_DIR $ip] $force
162  }
163  }
164 
165  # Copy DCP to artifacts, if HOG_SAVE_DCP is set
166  if {[info exists env(HOG_SAVE_DCP)] && ($env(HOG_SAVE_DCP) == 1 || $env(HOG_SAVE_DCP) == 2)} {
167  set dcp_dir [file normalize "$repo_path/DCPs/$group_name/$proj_name/synth_dcp"]
168  file mkdir $dcp_dir
169  set dcps [glob -nocomplain "$run_dir/synth*/*.dcp"]
170  if {[file exists [lindex $dcps 0]]} {
171  file copy -force {*}$dcps $dcp_dir/
172  }
173  }
174 
175 
176  }
177 
178 
179  # Log files
180  set logs [glob -nocomplain "$run_dir/*/runme.log"]
181  foreach log $logs {
182  set run_name [file tail [file dirname $log]]
183  file copy -force $log $dst_dir/reports/$run_name.log
184  }
185 } elseif {[IsQuartus]} {
186  #Reports
187  set reps [glob -nocomplain "$proj_dir/output_files/*.rpt"]
188 
189  if {[file exists [lindex $reps 0]]} {
190  file copy -force {*}$reps $dst_dir/reports
191  } else {
192  Msg Warning "No reports found in $proj_dir/output_files subfolders"
193  }
194 }
195 
196 # Run user post-synthesis file
197 set user_post_synthesis_file "./Top/$group_name/$proj_name/post-synthesis.tcl"
198 if {[file exists $user_post_synthesis_file]} {
199  Msg Info "Sourcing user post-synthesis file $user_post_synthesis_file"
200  source $user_post_synthesis_file
201 }
202 
203 cd $old_path
204 Msg Info "All done."