Commit 15b9811a authored by Jens Korinth's avatar Jens Korinth

Produce pre-synthesized netlists in EvaluateIP

* synthesis can be accelerated by dumping an EDIF netlist during IP
  evaluation and only using the netlist in the IP-XACT core
* no need to re-synthesize IP, especially useful in case of many
  instances
* replaced old links to original zip files by new zip that contains only
  the component.xml and the netlist
parent 325315a8
......@@ -34,8 +34,12 @@ add_files @@SRC_FILES@@
# add_files -fileset constrs_1 @@XDC_FILES@@
foreach script [list @@TCL_FILES@@] { source $script }
# find top
set top [lindex [find_top] 0]
# synthesize and optimize netlist
synth_design -part @@PART@@ -top [lindex [find_top] 0] -no_iobuf -mode out_of_context
#synth_design -part @@PART@@ -top $top -no_iobuf -mode out_of_context -retiming
synth_design -part @@PART@@ -top $top -mode out_of_context -retiming
# read switching activity files (if any)
foreach saif [glob -nocomplain *.saif] {
......@@ -74,5 +78,9 @@ if {$wns < 0} {
# report power
report_power -quiet -file @@REPORT_POWER@@
# write netlist file
set netlist "@@NETLIST@@"
write_edif $netlist
# done!
exit
set name [lindex $argv 0]
set version [lindex $argv 1]
ipx::infer_core -vendor de.tu-darmstadt.cs.esa.tapasco -library tapasco -name $name -version $version .
set_property taxonomy "TaPaSCo" [ipx::current_core]
set_property display_name $name [ipx::current_core]
set_property supported_families [list zynq Pre-Production \
virtex7 Pre-Production \
artix7 Pre-Production \
kintex7 Pre-Production] [ipx::current_core]
ipx::create_xgui_files -logo_file $::env(TAPASCO_HOME)/icon/tapasco_icon_small.png [ipx::current_core]
ipx::save_core
exit
......@@ -27,7 +27,7 @@ import de.tu_darmstadt.cs.esa.tapasco.reports._
import de.tu_darmstadt.cs.esa.tapasco.util._
import de.tu_darmstadt.cs.esa.tapasco.util.ZipUtils._
import Logging._
import java.nio.file.{Files, Path}
import java.nio.file.{Files, Path, Paths}
import scala.sys.process._
import scala.xml.XML
......@@ -97,6 +97,9 @@ object EvaluateIP {
java.nio.file.Paths.get((f \ "name").text).getFileName
}
}
lazy val netlist = catchAllDefault[Path](Paths.get("netlist.edn"), "could not parse component.xml: ") {
reportFile.resolveSibling("%s.edn".format((XML.loadFile(ipxact.get.toString) \\ "component" \\ "name").head.text))
}
}
/** Perform the evaluation.
......@@ -165,7 +168,8 @@ object EvaluateIP {
"REPORT_UTILIZATION" -> files.rpt_util.toString,
"REPORT_POWER" -> files.rpt_power.toString,
"SYNTH_CHECKPOINT" -> files.s_dcp.toString,
"IMPL_CHECKPOINT" -> files.i_dcp.toString
"IMPL_CHECKPOINT" -> files.i_dcp.toString,
"NETLIST" -> files.netlist.toString
)
// write Tcl script
......
......@@ -30,6 +30,7 @@ import de.tu_darmstadt.cs.esa.tapasco.base._
import de.tu_darmstadt.cs.esa.tapasco.base.json._
import de.tu_darmstadt.cs.esa.tapasco.util._
import de.tu_darmstadt.cs.esa.tapasco.filemgmt.FileAssetManager
import scala.sys.process._
import java.nio.file._
/**
......@@ -83,26 +84,7 @@ object Import {
Files.createDirectories(p.getParent)
logger.trace("created output directories: {}", p.getParent.toString)
// add link to original .zip in the 'ipcore' subdir
val linkp = cfg.outputDir(c, t).resolve("ipcore").resolve(c.zipPath.getFileName.toString)
if (! linkp.toFile.equals(c.zipPath.toAbsolutePath.toFile)) {
Files.createDirectories(linkp.getParent)
logger.trace("created directories: {}", linkp.getParent.toString)
if (linkp.toFile.exists) {
logger.debug("file {} already exists, skipping copy/link step")
} else {
logger.trace("creating symbolic link {} -> {}", linkp: Any, c.zipPath.toAbsolutePath)
try { java.nio.file.Files.createSymbolicLink(linkp, c.zipPath.toAbsolutePath) }
catch { case ex: java.nio.file.FileSystemException => {
logger.warn("cannot create link {} -> {}, copying data", linkp: Any, c.zipPath)
java.nio.file.Files.copy(c.zipPath, linkp, java.nio.file.StandardCopyOption.REPLACE_EXISTING)
}}
}
} else {
logger.debug("{} is the same as {}, no copy/link required", linkp: Any, c.zipPath.toAbsolutePath)
}
// finally, evaluate the ip core and store the report with the link
// evaluate the ip core and store the report with the link
val res = evaluateCore(c, t)
// write core.json
......@@ -113,7 +95,7 @@ object Import {
/**
* Searches for an existing synthesis report, otherwise performs out-of-context synthesis and
* place-and-route to produce area and Fmax estimates
* place-and-route to produce area and Fmax estimates and the netlist.
* @param c Core description.
* @param t Target Architecture + Platform combination.
* @param cfg Implicit [[Configuration]].
......@@ -131,6 +113,34 @@ object Import {
} getOrElse {
logger.info("SynthesisReport for {} not found, starting evaluation ...", c.name)
EvaluateIP(c.zipPath, period, t.pd.part, report)
} && repack(c, t)
}
private def repack(c: Core, t: Target)(implicit cfg: Configuration): Boolean = {
logger.debug("repacking {} for {} ...", c: Any, t)
val out = cfg.outputDir(c, t).resolve("ipcore")
val vivadoCmd: Seq[String] = Seq("vivado",
"-mode", "batch",
"-source", FileAssetManager.TAPASCO_HOME.resolve("common").resolve("repack-edn.tcl").toString,
c.name,
c.version,
"-nolog", "-notrace", "-nojournal")
// execute Vivado (max runtime: 1h)
val r = InterruptibleProcess(Process(vivadoCmd, out.toFile),
waitMillis = Some(60 * 60 * 1000)).!(InterruptibleProcess.io)
r match {
case InterruptibleProcess.TIMEOUT_RETCODE =>
logger.error("repack-edn.tcl: Vivado timeout error")
case 0 =>
logger.info("repack-edn.tcl: Vivado finished successfully")
val zip = cfg.outputDir(c, t).resolve("ipcore").resolve("%s.zip".format(c.name))
val edn = zip.resolveSibling("%s.edn".format(c.name))
val xml = zip.resolveSibling("component.xml")
xml.toFile.deleteOnExit()
ZipUtils.zipFile(zip, Seq(xml, edn))
case _ =>
logger.error("repack-edn.tcl: Vivado exited with non-zero exit-code ({})", r)
}
r == 0
}
}
......@@ -61,4 +61,10 @@ private[tapasco] final case class InterruptibleProcess(p: ProcessBuilder, waitMi
object InterruptibleProcess {
final val TIMEOUT_RETCODE = 124 // matches 'timeout' command
// custom ProcessIO: ignore everything
val io = new ProcessIO(
stdin => {stdin.close()},
stdout => {stdout.close()},
stderr => {stderr.close()}
)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment