Hog Hog2025.2-3
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 is not equal to the one saved in $hogQsysFileName.\n\
66  New checksum $newMd5Sum, old checksum $oldMd5Sum. \
67  Please check the any changes in the file are correctly propagated to git!"
68  }
69  } else {
70  Msg Warning "File $fileEntryName not found... Will not check Md5Sum!"
71  }
72  }
73  }
74  }
75 } elseif {[IsDiamond]} {
76  # Import tcllib
77  if {[info exists env(HOG_TCLLIB_PATH)]} {
78  lappend auto_path $env(HOG_TCLLIB_PATH)
79  } else {
80  puts "ERROR: To run Hog with Microsemi Libero SoC, you need to define the HOG_TCLLIB_PATH variable."
81  return
82  }
83  set proj_dir [file normalize "[pwd]/.."]
84  set proj_name [file tail $proj_dir]
85  set project $proj_name
86 } else {
87  #Tclssh
88  set proj_file $old_path/[file tail $old_path].xpr
89  set proj_dir [file normalize [file dirname $proj_file]]
90  set proj_name [file rootname [file tail $proj_file]]
91  Msg CriticalWarning "You seem to be running locally on tclsh, so this is a debug message. \
92  The project file will be set to $proj_file and was derived from the path you launched this script from: $old_path. \
93  If you want this script to work properly in debug mode, please launch it from the top folder of one project, \
94  for example Repo/Projects/fpga1/ or Repo/Top/fpga1/"
95 }
96 
97 if {[catch {package require struct::matrix} ERROR]} {
98  puts "$ERROR\n If you are running this script on tclsh, you can fix this by installing 'tcllib'"
99  return
100 }
101 
102 # Go to repository path
103 set repo_path [file normalize "$tcl_path/../.."]
104 set bin_dir [file normalize "$repo_path/bin"]
105 
106 cd $repo_path
107 
108 set group_name [GetGroupName $proj_dir "$tcl_path/../.."]
109 
110 Msg Info "Evaluating Git sha for $proj_name..."
111 lassign [GetRepoVersions [file normalize ./Top/$group_name/$proj_name] $repo_path] sha
112 
113 set describe [GetHogDescribe $sha $repo_path]
114 Msg Info "Git describe set to: $describe"
115 set dst_dir [file normalize "$bin_dir/$group_name/$proj_name\-$describe"]
116 
117 Msg Info "Creating $dst_dir..."
118 file mkdir $dst_dir
119 # Reports
120 file mkdir $dst_dir/reports
121 
122 
123 # Vivado
124 if {[IsXilinx]} {
125  # Vivado + PlanAhead
126  if {[IsISE]} {
127  # planAhead
128  set work_path [get_property DIRECTORY [get_runs synth_1]]
129  } else {
130  # Vivado
131  set work_path $old_path
132  }
133  set run_dir [file normalize "$work_path/.."]
134 
135  if {[IsISE]} {
136  set reps [glob -nocomplain "$run_dir/*/*{.syr,.srp,.mrp,.map,.twr,.drc,.bgn,_routed.par,_routed_pad.txt,_routed.unroutes}"]
137  } else {
138  set reps [glob -nocomplain "$run_dir/*/*.rpt"]
139  }
140  if {[file exists [lindex $reps 0]]} {
141  file copy -force {*}$reps $dst_dir/reports
142  if {[file exists [glob -nocomplain "$dst_dir/reports/${top_name}_utilization_synth.rpt"]]} {
143  set utilization_file [file normalize $dst_dir/utilization.txt]
144  set report_file [glob -nocomplain "$dst_dir/reports/${top_name}_utilization_synth.rpt"]
145  if {$group_name != ""} {
146  WriteUtilizationSummary $report_file $utilization_file $group_name/$proj_name "Synthesis"
147  } else {
148  WriteUtilizationSummary $report_file $utilization_file $proj_name "Synthesis"
149  }
150  }
151  } else {
152  Msg Warning "No reports found in $run_dir subfolders"
153  }
154 
155 
156  # Handle IPs
157  if {[IsVivado]} {
158  if {[info exists env(HOG_IP_PATH)]} {
159  set ip_repo $env(HOG_IP_PATH)
160  set ips [get_ips *]
161  set run_paths [glob -nocomplain "$run_dir/*"]
162  set runs {}
163  foreach r $run_paths {
164  if {[regexp -all {^(.+)_synth_1} $r whole_match run]} {
165  lappend runs [file tail $run]
166  }
167  }
168 
169  foreach ip $ips {
170  if {$ip in $runs} {
171  set force 1
172  } else {
173  set force 0
174  }
175  Msg Info "Copying synthesised IP $ip to $ip_repo..."
176  HandleIP push [get_property IP_FILE $ip] $ip_repo $repo_path [get_property IP_OUTPUT_DIR $ip] $force
177  }
178  }
179 
180  # Copy DCP to artifacts, if HOG_SAVE_DCP is set
181  if {[info exists env(HOG_SAVE_DCP)] && ($env(HOG_SAVE_DCP) == 1 || $env(HOG_SAVE_DCP) == 2)} {
182  set dcp_dir [file normalize "$repo_path/DCPs/$group_name/$proj_name/synth_dcp"]
183  file mkdir $dcp_dir
184  set dcps [glob -nocomplain "$run_dir/synth*/*.dcp"]
185  if {[file exists [lindex $dcps 0]]} {
186  file copy -force {*}$dcps $dcp_dir/
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 # Run user post-synthesis file
237 set user_post_synthesis_file "./Top/$group_name/$proj_name/post-synthesis.tcl"
238 if {[file exists $user_post_synthesis_file]} {
239  Msg Info "Sourcing user post-synthesis file $user_post_synthesis_file"
240  source $user_post_synthesis_file
241 }
242 
243 cd $old_path
244 Msg Info "All done."