Hog Hog2025.1-6
post-synthesis.tcl
Go to the documentation of this file.
1 #!/usr/bin/env tclsh
2 # Copyright 2018-2025 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 set tcl_path [file normalize "[file dirname [info script]]/.."]
24 source $tcl_path/hog.tcl
25 
26 if {[IsISE]} {
27  # Vivado + PlanAhead
28  set old_path [file normalize "../../Projects/$project/$project.runs/synth_1"]
29  file mkdir $old_path
30 } else {
31  set old_path [pwd]
32 }
33 
34 if {[IsXilinx]} {
35  # Vivado + PlanAhead
36  if {[IsISE]} {
37  set proj_dir [get_property DIRECTORY [current_project]]
38  set project [file tail $proj_dir]
39  set proj_file $proj_dir/$project.prr
40  } else {
41  set proj_file [get_property parent.project_path [current_project]]
42  }
43  set proj_dir [file normalize [file dirname $proj_file]]
44  set proj_name [file rootname [file tail $proj_file]]
45  set top_name [get_property top [current_fileset]]
46 } elseif {[IsQuartus]} {
47  # Quartus
48  set proj_name [lindex $quartus(args) 1]
49  #set proj_dir [file normalize "$repo_path/Projects/$proj_name"]
50  set proj_dir [pwd]
51  set proj_file [file normalize "$proj_dir/$proj_name.qpf"]
52  # Test generated files
53  set hogQsysFileName [file normalize "$proj_dir/.hog/.hogQsys.md5"]
54  if { [file exists $hogQsysFileName] != 0} {
55  set hogQsysFile [open $hogQsysFileName r]
56  set hogQsysFileLines [split [read $hogQsysFile] "\n"]
57  foreach line $hogQsysFileLines {
58  set fileEntry [split $line "\t"]
59  set fileEntryName [lindex $fileEntry 0]
60  if {$fileEntryName != ""} {
61  if {[file exists $fileEntryName]} {
62  set newMd5Sum [Md5Sum $fileEntryName]
63  set oldMd5Sum [lindex $fileEntry 1]
64  if { $newMd5Sum != $oldMd5Sum } {
65  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!"
66  }
67  } else {
68  Msg Warning "File $fileEntryName not found... Will not check Md5Sum!"
69  }
70  }
71  }
72 
73  }
74 } elseif {[IsDiamond]} {
75  # Import tcllib
76  if {[info exists env(HOG_TCLLIB_PATH)]} {
77  lappend auto_path $env(HOG_TCLLIB_PATH)
78  } else {
79  puts "ERROR: To run Hog with Microsemi Libero SoC, you need to define the HOG_TCLLIB_PATH variable."
80  return
81  }
82  set proj_dir [file normalize "[pwd]/.."]
83  set proj_name [file tail $proj_dir]
84  set project $proj_name
85 } else {
86  #Tclssh
87  set proj_file $old_path/[file tail $old_path].xpr
88  set proj_dir [file normalize [file dirname $proj_file]]
89  set proj_name [file rootname [file tail $proj_file]]
90  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/"
91 }
92 
93 if {[catch {package require struct::matrix} ERROR]} {
94  puts "$ERROR\n If you are running this script on tclsh, you can fix this by installing 'tcllib'"
95  return
96 }
97 
98 # Go to repository path
99 set repo_path [file normalize "$tcl_path/../.."]
100 set bin_dir [file normalize "$repo_path/bin"]
101 
102 cd $repo_path
103 
104 set group_name [GetGroupName $proj_dir "$tcl_path/../.."]
105 
106 Msg Info "Evaluating Git sha for $proj_name..."
107 lassign [GetRepoVersions [file normalize ./Top/$group_name/$proj_name] $repo_path] sha
108 
109 set describe [GetHogDescribe $sha $repo_path]
110 Msg Info "Git describe set to: $describe"
111 set dst_dir [file normalize "$bin_dir/$group_name/$proj_name\-$describe"]
112 
113 Msg Info "Creating $dst_dir..."
114 file mkdir $dst_dir
115 # Reports
116 file mkdir $dst_dir/reports
117 
118 
119 
120 # Vivado
121 if {[IsXilinx]} {
122 
123  # Vivado + PlanAhead
124  if {[IsISE]} {
125  # planAhead
126  set work_path [get_property DIRECTORY [get_runs synth_1]]
127  } else {
128  # Vivado
129  set work_path $old_path
130  }
131  set run_dir [file normalize "$work_path/.."]
132 
133  if {[IsISE]} {
134  set reps [glob -nocomplain "$run_dir/*/*{.syr,.srp,.mrp,.map,.twr,.drc,.bgn,_routed.par,_routed_pad.txt,_routed.unroutes}"]
135  } else {
136  set reps [glob -nocomplain "$run_dir/*/*.rpt"]
137  }
138  if {[file exists [lindex $reps 0]]} {
139  file copy -force {*}$reps $dst_dir/reports
140  if {[file exists [glob -nocomplain "$dst_dir/reports/${top_name}_utilization_synth.rpt"] ]} {
141  set utilization_file [file normalize $dst_dir/utilization.txt]
142  set report_file [glob -nocomplain "$dst_dir/reports/${top_name}_utilization_synth.rpt"]
143  if {$group_name != ""} {
144  WriteUtilizationSummary $report_file $utilization_file $group_name/$proj_name "Synthesis"
145  } else {
146  WriteUtilizationSummary $report_file $utilization_file $proj_name "Synthesis"
147  }
148  }
149  } else {
150  Msg Warning "No reports found in $run_dir subfolders"
151  }
152 
153 
154  # Handle IPs
155  if {[IsVivado]} {
156  if {[info exists env(HOG_IP_PATH)]} {
157  set ip_repo $env(HOG_IP_PATH)
158  set ips [get_ips *]
159  set run_paths [glob -nocomplain "$run_dir/*"]
160  set runs {}
161  foreach r $run_paths {
162  if {[regexp -all {^(.+)_synth_1} $r whole_match run]} {
163  lappend runs [file tail $run]
164  }
165  }
166 
167  foreach ip $ips {
168  if {$ip in $runs} {
169  set force 1
170  } else {
171  set force 0
172  }
173  Msg Info "Copying synthesised IP $ip to $ip_repo..."
174  HandleIP push [get_property IP_FILE $ip] $ip_repo $repo_path [get_property IP_OUTPUT_DIR $ip] $force
175  }
176  }
177 
178  # Copy DCP to artifacts, if HOG_SAVE_DCP is set
179  if {[info exists env(HOG_SAVE_DCP)] && ($env(HOG_SAVE_DCP) == 1 || $env(HOG_SAVE_DCP) == 2)} {
180  set dcp_dir [file normalize "$repo_path/DCPs/$group_name/$proj_name/synth_dcp"]
181  file mkdir $dcp_dir
182  set dcps [glob -nocomplain "$run_dir/synth*/*.dcp"]
183  if {[file exists [lindex $dcps 0]]} {
184  file copy -force {*}$dcps $dcp_dir/
185  }
186  }
187 
188 
189  }
190 
191 
192  # Log files
193  set logs [glob -nocomplain "$run_dir/*/runme.log"]
194  foreach log $logs {
195  set run_name [file tail [file dirname $log]]
196  file copy -force $log $dst_dir/reports/$run_name.log
197  }
198 } elseif {[IsQuartus]} {
199  #Reports
200  set reps [glob -nocomplain "$proj_dir/output_files/*.rpt"]
201 
202  if {[file exists [lindex $reps 0]]} {
203  file copy -force {*}$reps $dst_dir/reports
204  } else {
205  Msg Warning "No reports found in $proj_dir/output_files subfolders"
206  }
207 } elseif {[IsDiamond]} {
208  #Logs
209  set logs [glob -nocomplain "$proj_dir/Implementation0/*.log"]
210 
211  if {[file exists [lindex $logs 0]]} {
212  file copy -force {*}$logs $dst_dir/reports
213  } else {
214  Msg Warning "No .log reports found in $proj_dir/Implementation0 subfolders"
215  }
216 
217  # Arearep
218  set areas [glob -nocomplain "$proj_dir/Implementation0/*.arearep"]
219 
220  if {[file exists [lindex $areas 0]]} {
221  file copy -force {*}$areas $dst_dir/reports
222  } else {
223  Msg Warning "No .arearep reports found in $proj_dir/Implementation0 subfolders"
224  }
225 
226  # Timing (TWR)
227  set t_reps [glob -nocomplain "$proj_dir/Implementation0/*.twr"]
228 
229  if {[file exists [lindex $t_reps 0]]} {
230  file copy -force {*}$t_reps $dst_dir/reports
231  } else {
232  Msg Warning "No .twr reports found in $proj_dir/Implementation0 subfolders"
233  }
234 
235 }
236 
237 # Run user post-synthesis file
238 set user_post_synthesis_file "./Top/$group_name/$proj_name/post-synthesis.tcl"
239 if {[file exists $user_post_synthesis_file]} {
240  Msg Info "Sourcing user post-synthesis file $user_post_synthesis_file"
241  source $user_post_synthesis_file
242 }
243 
244 cd $old_path
245 Msg Info "All done."