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