Commit 56b77300 authored by Jens Korinth's avatar Jens Korinth
Browse files

Merge branch '2018.1' into pe-local-memories

parents a2ce13bb 76275656
# create a dictionary of compatible VLNVs # create a dictionary of compatible VLNVs
source $::env(TAPASCO_HOME)/common/common_ip.tcl #source $::env(TAPASCO_HOME)/common/common_ip.tcl
dict set stdcomps dualdma vlnv "esa.informatik.tu-darmstadt.de:user:dual_dma:1.10" dict set stdcomps dualdma vlnv "esa.informatik.tu-darmstadt.de:user:dual_dma:1.10"
# create a dictionary of compatible VLNVs # create a dictionary of compatible VLNVs
source $::env(TAPASCO_HOME)/common/common_ip.tcl #source $::env(TAPASCO_HOME)/common/common_ip.tcl
dict set stdcomps dualdma vlnv "esa.informatik.tu-darmstadt.de:user:dual_dma:1.11" dict set stdcomps dualdma vlnv "esa.informatik.tu-darmstadt.de:user:dual_dma:1.11"
...@@ -48,42 +48,147 @@ foreach script [list @@TCL_FILES@@] { source $script } ...@@ -48,42 +48,147 @@ foreach script [list @@TCL_FILES@@] { source $script }
# find top # find top
set top [lindex [find_top] 0] set top [lindex [find_top] 0]
# synthesize and optimize netlist # set parameters
synth_design \ set opt @@OPTIMIZATION@@
-part @@PART@@ \ set target_opt @@OPTIMIZATION@@
-top $top \ set period @@PERIOD@@
-mode out_of_context \ set target_period @@PERIOD@@
-directive AlternateRoutability \
-retiming \ if {@@OPTIMIZATION@@ == 42} {
-fanout_limit 400 \ # activate opt and period loops
-fsm_extraction one_hot \ set opt 3
-keep_equivalent_registers \ set target_opt 0
-resource_sharing off \ set period 0.5
-no_lc \ set target_period 10.0
-shreg_min_size 5
# read switching activity files (if any)
foreach saif [glob -nocomplain *.saif] {
read_saif $saif
} }
# write design checkpoint set results_file [open [file join [file dirname "@@REPORT_TIMING@@"] "synthesis_results.tsv"] "w+"]
write_checkpoint -force @@SYNTH_CHECKPOINT@@ puts $results_file "TT\tTF\t\O\tWNS\tOT\tOF"
set runtimes_file [open [file join [file dirname "@@REPORT_TIMING@@"] "synthesis_runtimes.tsv"] "w+"]
# set clock puts $runtimes_file "TT\tTF\tO\tP\tS\t\E\tD"
set clock_ports [get_ports -filter {DIRECTION == IN && (NAME =~ *clk* || NAME =~ *CLK* || NAME =~ clock)}]
puts "clock_ports = $clock_ports" #for {set period 0.5} {$period <= 5.0} {set period [expr $period + 0.125]} {
create_clock -name clk -period @@PERIOD@@ $clock_ports for {} {$period <= $target_period} {set period [expr $period + 0.25]} {
set_property HD.CLK_SRC BUFGCTRL_X0Y0 $clock_ports for {} {$opt >= $target_opt} {incr opt -1} {
set synth_start [clock seconds]
# place and route set synth_options [list @@SYNTH_OPTIONS@@]
opt_design lappend synth_options {-part} {@@PART@@} {-top} $top {-mode} {out_of_context}
place_design
phys_opt_design # synthesize and optimize netlist
route_design if {$opt >= 1} {
lappend synth_options {-retiming} {-fanout_limit} 400 {-shreg_min_size} 5
}
if {$opt >= 2} {
lappend synth_options {-fsm_extraction} {one_hot} {-flatten_hierarchy} {full}
}
if {$opt >= 3} {
lappend synth_options {-keep_equivalent_registers} {-resource_sharing} {off} {-no_lc}
}
synth_design {*}$synth_options
set opt_start [clock seconds]
opt_design -propconst -sweep -remap
set synth_finish [clock seconds]
set ur [file join [file dirname "@@REPORT_UTILIZATION@@"] "synth_utilization_period${period}_opt${opt}.rpt"]
puts "writing utilization report $ur ..."
report_utilization -quiet -file $ur
set tr [file join [file dirname "@@REPORT_TIMING@@"] "synth_timing_period${period}_opt${opt}.rpt"]
puts "writing timing report summary $tr ..."
report_timing_summary -quiet -file $tr
puts "synth_design for O$opt took [expr $synth_finish - $opt_start] sec, opt_design took [expr $opt_start - $synth_finish] sec."
puts $runtimes_file "$period\t[expr 1000.0/$period]\t$opt\tsynth_design\t$synth_start\t$opt_start\t[expr $opt_start - $synth_start]"
puts $runtimes_file "$period\t[expr 1000.0/$period]\t$opt\topt_design\t$opt_start\t$synth_finish\t[expr $synth_finish - $opt_start]"
puts $runtimes_file "$period\t[expr 1000.0/$period]\t$opt\ttotal_synth\t$synth_start\t$synth_finish\t[expr $synth_finish - $synth_start]"
# read switching activity files (if any)
foreach saif [glob -nocomplain *.saif] {
read_saif $saif
}
# write design checkpoint
#write_checkpoint -force "@@SYNTH_CHECKPOINT@@.O${opt}_P${period}.dcp"
# set clock
set clock_ports [get_ports -filter {DIRECTION == IN && (NAME =~ *clk* || NAME =~ *CLK* || NAME =~ clock)}]
puts "clock_ports = $clock_ports"
create_clock -name clk -period $period $clock_ports
set pnr_start [clock seconds]
# place and route
set opt_directive "RuntimeOptimized"
if {$opt >= 1} { set opt_directive "Default" }
if {$opt >= 2} { set opt_directive "Explore" }
if {$opt >= 3} { set opt_directive "ExploreWithRemap" }
puts "running opt_design -directive $opt_directive ..."
opt_design -directive $opt_directive
set opt_design_finish [clock seconds]
set place_directive "RuntimeOptimized"
if {$opt >= 1} { set place_directive "Default" }
if {$opt >= 2} { set place_directive "Explore" }
if {$opt >= 3} { set place_directive "ExtraTimingOpt" }
puts "running place_design -directive $place_directive ..."
place_design -directive $place_directive
set place_design_finish [clock seconds]
set physopt1_directive "RuntimeOptimized"
if {$opt >= 1} { set physopt1_directive "Explore" }
if {$opt >= 2} { set physopt1_directive "AggressiveExplore" }
if {$opt >= 3} { set physopt1_directive "AlternateFlowWithRetiming" }
puts "running phys_opt_design -directive $physopt1_directive ..."
phys_opt_design -directive $physopt1_directive
set physopt1_finish [clock seconds]
set route_directive "RuntimeOptimized"
if {$opt >= 1} { set route_directive "Default" }
if {$opt >= 2} { set route_directive "Explore" }
if {$opt >= 3} { set route_directive "MoreGlobalIterations" }
puts "running route_design -directive $route_directive ..."
route_design -directive $route_directive
set route_design_finish [clock seconds]
set physopt2_directive "Explore"
if {$opt >= 2} { set physopt2_directive "AggressiveExplore" }
if {$opt >= 3} { set physopt1_directive "AlternateFlowWithRetiming" }
if {$opt >= 2} {
puts "phys_opt_design -directive $physopt2_directive ..."
phys_opt_design -directive $physopt2_directive
set physopt2_finish [clock seconds]
}
set pnr_finish [clock seconds]
# report timing
set tr [file join [file dirname "@@REPORT_TIMING@@"] "pnr_timing_period${period}_opt${opt}.rpt"]
report_timing_summary -quiet -datasheet -file $tr
# report utilization
report_utilization -quiet -file [file join [file dirname "@@REPORT_UTILIZATION@@"] "pnr_utilization_period${period}_opt${opt}.rpt"]
set wns [tapasco::get_wns_from_timing_report $tr]
set clk [expr "$period - $wns"]
# write design checkpoint
#write_checkpoint -force "@@IMPL_CHECKPOINT@@.O${opt}_P${period}.dcp"
puts "O$opt RESULT: WNS = $wns PERIOD = $clk F = [expr 1000.0 / $clk]"
puts $results_file "$period\t[expr 1000.0/$period]\t$opt\t$wns\t$clk\t[expr 1000.0/$clk]"
puts $runtimes_file "$period\t[expr 1000.0/$period]\t$opt\tpnr_opt_design\t$pnr_start\t$opt_design_finish\t[expr $opt_design_finish - $pnr_start]"
puts $runtimes_file "$period\t[expr 1000.0/$period]\t$opt\tplace_design\t$opt_design_finish\t$place_design_finish\t[expr $place_design_finish - $opt_design_finish]"
puts $runtimes_file "$period\t[expr 1000.0/$period]\t$opt\tphys_opt_design\t$place_design_finish\t$physopt1_finish\t[expr $physopt1_finish - $place_design_finish]"
puts $runtimes_file "$period\t[expr 1000.0/$period]\t$opt\troute_design\t$physopt1_finish\t$route_design_finish\t[expr $route_design_finish - $physopt1_finish]"
if {$opt >= 2} {
puts $runtimes_file "$period\t[expr 1000.0/$period]\t$opt\tphys_opt_design2\t$route_design_finish\t$physopt2_finish\t[expr $physopt2_finish - $route_design_finish]"
}
puts $runtimes_file "$period\t[expr 1000.0/$period]\t$opt\ttotal_pnr\t$pnr_start\t$pnr_finish\t[expr $pnr_finish - $pnr_start]"
flush $runtimes_file
flush $results_file
}
if {$opt < 0} { set opt 3 }
}
# write design checkpoint close $runtimes_file
write_checkpoint -force @@IMPL_CHECKPOINT@@ close $results_file
# report timing # report timing
report_timing_summary -quiet -datasheet -file @@REPORT_TIMING@@ report_timing_summary -quiet -datasheet -file @@REPORT_TIMING@@
...@@ -93,7 +198,7 @@ report_utilization -quiet -file @@REPORT_UTILIZATION@@ ...@@ -93,7 +198,7 @@ report_utilization -quiet -file @@REPORT_UTILIZATION@@
# recalculate achieved frequency and set new period (for realistic power values) # recalculate achieved frequency and set new period (for realistic power values)
set wns [tapasco::get_wns_from_timing_report @@REPORT_TIMING@@] set wns [tapasco::get_wns_from_timing_report @@REPORT_TIMING@@]
if {$wns < 0} { if {$wns < 0} {
create_clock -name clk -period [expr "@@PERIOD@@ - $wns"] $clock_ports create_clock -name clk -period [expr "$period - $wns"] $clock_ports
} }
# report power # report power
......
...@@ -113,7 +113,13 @@ object EvaluateIP { ...@@ -113,7 +113,13 @@ object EvaluateIP {
/** Perform the evaluation. /** Perform the evaluation.
* @return true if successful **/ * @return true if successful **/
def apply(zipFile: Path, targetPeriod: Double, targetPart: String, reportFile: Path)(implicit cfg: Configuration): Boolean = { def apply(zipFile: Path,
targetPeriod: Double,
targetPart: String,
reportFile: Path,
optimization: Int,
synthOptions: Option[String] = None)
(implicit cfg: Configuration): Boolean = {
def deleteOnExit(f: java.io.File) = f.deleteOnExit def deleteOnExit(f: java.io.File) = f.deleteOnExit
//def deleteOnExit(f: java.io.File) = f // keep files? //def deleteOnExit(f: java.io.File) = f // keep files?
...@@ -123,7 +129,7 @@ object EvaluateIP { ...@@ -123,7 +129,7 @@ object EvaluateIP {
// define report filenames // define report filenames
Files.createDirectories(reportFile.getParent) Files.createDirectories(reportFile.getParent)
val files = new Files(zipFile, reportFile) val files = new Files(zipFile, reportFile)
writeTclScript(files, targetPart, targetPeriod) writeTclScript(files, targetPart, targetPeriod, optimization, synthOptions)
val lt = new LogTrackingFileWatcher(Some(logger)) val lt = new LogTrackingFileWatcher(Some(logger))
cfg.verbose foreach { _ => lt += files.logFile } cfg.verbose foreach { _ => lt += files.logFile }
...@@ -139,7 +145,7 @@ object EvaluateIP { ...@@ -139,7 +145,7 @@ object EvaluateIP {
// execute Vivado (max runtime: 1d) // execute Vivado (max runtime: 1d)
val r = InterruptibleProcess(Process(vivadoCmd, files.baseDir.toFile), val r = InterruptibleProcess(Process(vivadoCmd, files.baseDir.toFile),
waitMillis = Some(24 * 60 * 60 * 1000)).!(io) waitMillis = Some((if (optimization == 42) 14 else 1) * 24 * 60 * 60 * 1000)).!(io)
cfg.verbose foreach { _ => lt.closeAll } cfg.verbose foreach { _ => lt.closeAll }
...@@ -171,7 +177,11 @@ object EvaluateIP { ...@@ -171,7 +177,11 @@ object EvaluateIP {
* @param targetPart Part identifier of the target FPGA. * @param targetPart Part identifier of the target FPGA.
* @param targetPeriod Target operating period. * @param targetPeriod Target operating period.
**/ **/
private def writeTclScript(files: Files, targetPart: String, targetPeriod: Double): Unit = { private def writeTclScript(files: Files,
targetPart: String,
targetPeriod: Double,
optimization: Int,
synthOptions: Option[String]): Unit = {
val needles: scala.collection.mutable.Map[String, String] = scala.collection.mutable.Map( val needles: scala.collection.mutable.Map[String, String] = scala.collection.mutable.Map(
"SRC_FILES" -> (files.hdl_files map (_.toString) mkString " "), "SRC_FILES" -> (files.hdl_files map (_.toString) mkString " "),
"TCL_FILES" -> (files.tcl_files mkString " "), "TCL_FILES" -> (files.tcl_files mkString " "),
...@@ -184,7 +194,9 @@ object EvaluateIP { ...@@ -184,7 +194,9 @@ object EvaluateIP {
"REPORT_POWER" -> files.rpt_power.toString, "REPORT_POWER" -> files.rpt_power.toString,
"SYNTH_CHECKPOINT" -> files.s_dcp.toString, "SYNTH_CHECKPOINT" -> files.s_dcp.toString,
"IMPL_CHECKPOINT" -> files.i_dcp.toString, "IMPL_CHECKPOINT" -> files.i_dcp.toString,
"NETLIST" -> files.netlist.toString "NETLIST" -> files.netlist.toString,
"OPTIMIZATION" -> optimization.toString,
"SYNTH_OPTIONS" -> (synthOptions getOrElse "")
) )
// write Tcl script // write Tcl script
......
...@@ -52,7 +52,8 @@ object Import { ...@@ -52,7 +52,8 @@ object Import {
* @param skipEval Do not perform out-of-context synthesis for resource estimation (optional). * @param skipEval Do not perform out-of-context synthesis for resource estimation (optional).
* @param cfg Implicit [[base.Configuration]]. * @param cfg Implicit [[base.Configuration]].
**/ **/
def apply(zip: Path, id: Kernel.Id, t: Target, acc: Option[Int], skipEval: Option[Boolean]) def apply(zip: Path, id: Kernel.Id, t: Target, acc: Option[Int], skipEval: Option[Boolean],
optimization: Int, synthOptions: Option[String] = None)
(implicit cfg: Configuration): Boolean = { (implicit cfg: Configuration): Boolean = {
// get VLNV from the file // get VLNV from the file
val vlnv = VLNV.fromZip(zip) val vlnv = VLNV.fromZip(zip)
...@@ -70,7 +71,7 @@ object Import { ...@@ -70,7 +71,7 @@ object Import {
// write core.json to output directory (as per config) // write core.json to output directory (as per config)
val p = cfg.outputDir(c, t).resolve("ipcore").resolve("core.json") val p = cfg.outputDir(c, t).resolve("ipcore").resolve("core.json")
importCore(c, t, p, vlnv, skipEval) importCore(c, t, p, vlnv, skipEval, optimization, synthOptions)
} }
/** /**
...@@ -82,7 +83,8 @@ object Import { ...@@ -82,7 +83,8 @@ object Import {
* @param skipEval Skip out-of-context synthesis step (optional). * @param skipEval Skip out-of-context synthesis step (optional).
* @param cfg Implicit [[Configuration]]. * @param cfg Implicit [[Configuration]].
**/ **/
private def importCore(c: Core, t: Target, p: Path, vlnv: VLNV, skipEval: Option[Boolean]) private def importCore(c: Core, t: Target, p: Path, vlnv: VLNV, skipEval: Option[Boolean], optimization: Int,
synthOptions: Option[String])
(implicit cfg: Configuration): Boolean = { (implicit cfg: Configuration): Boolean = {
Files.createDirectories(p.getParent) Files.createDirectories(p.getParent)
logger.trace("created output directories: {}", p.getParent.toString) logger.trace("created output directories: {}", p.getParent.toString)
...@@ -107,7 +109,7 @@ object Import { ...@@ -107,7 +109,7 @@ object Import {
} }
// evaluate the ip core and store the report with the link // evaluate the ip core and store the report with the link
val res = skipEval.getOrElse(false) || evaluateCore(c, t) val res = skipEval.getOrElse(false) || evaluateCore(c, t, optimization = optimization, synthOptions = synthOptions)
// write core.json // write core.json
logger.debug("writing core description: {}", p.toString) logger.debug("writing core description: {}", p.toString)
...@@ -120,11 +122,14 @@ object Import { ...@@ -120,11 +122,14 @@ object Import {
* place-and-route to produce area and Fmax estimates and the netlist. * place-and-route to produce area and Fmax estimates and the netlist.
* @param c Core description. * @param c Core description.
* @param t Target Architecture + Platform combination. * @param t Target Architecture + Platform combination.
* @param optimization Positive integer optimization level.
* @param synthOptions Optional arguments for synth_design.
* @param cfg Implicit [[Configuration]]. * @param cfg Implicit [[Configuration]].
**/ **/
private def evaluateCore(c: Core, t: Target)(implicit cfg: Configuration): Boolean = { private def evaluateCore(c: Core, t: Target, optimization: Int, synthOptions: Option[String] = None)
(implicit cfg: Configuration): Boolean = {
logger.trace("looking for SynthesisReport ...") logger.trace("looking for SynthesisReport ...")
val period = 0.5 val period = 1.0
val report = cfg.outputDir(c, t).resolve("ipcore").resolve("%s_export.xml".format(c.name)) val report = cfg.outputDir(c, t).resolve("ipcore").resolve("%s_export.xml".format(c.name))
FileAssetManager.reports.synthReport(c.name, t) map { hls_report => FileAssetManager.reports.synthReport(c.name, t) map { hls_report =>
logger.trace("found existing synthesis report: " + hls_report) logger.trace("found existing synthesis report: " + hls_report)
...@@ -134,7 +139,7 @@ object Import { ...@@ -134,7 +139,7 @@ object Import {
true true
} getOrElse { } getOrElse {
logger.info("SynthesisReport for {} not found, starting evaluation ...", c.name) logger.info("SynthesisReport for {} not found, starting evaluation ...", c.name)
EvaluateIP(c.zipPath, period, t.pd.part, report) EvaluateIP(c.zipPath, period, t.pd.part, report, optimization, synthOptions)
} }
} }
} }
...@@ -90,9 +90,10 @@ class MultiFileWatcher(pollInterval: Int = MultiFileWatcher.POLL_INTERVAL) exten ...@@ -90,9 +90,10 @@ class MultiFileWatcher(pollInterval: Int = MultiFileWatcher.POLL_INTERVAL) exten
_waitingFor.synchronized { _waitingFor -= p } _waitingFor.synchronized { _waitingFor -= p }
} }
@scala.annotation.tailrec
private def readFrom(br: BufferedReader, ls: Seq[String] = Seq()): Seq[String] = { private def readFrom(br: BufferedReader, ls: Seq[String] = Seq()): Seq[String] = {
val line = Option(br.readLine()) val line = scala.util.Try(Option(br.readLine())).toOption.flatten
if (line.nonEmpty) readFrom(br, ls :+ line.get) else ls if (line.isEmpty) ls else readFrom(br, ls :+ line.get)
} }
private def startWatchThread: Unit = { private def startWatchThread: Unit = {
......
...@@ -68,7 +68,7 @@ class CorePanelController extends { ...@@ -68,7 +68,7 @@ class CorePanelController extends {
val path = java.nio.file.Paths.get(ImportFileChooser.selectedFile.toString) val path = java.nio.file.Paths.get(ImportFileChooser.selectedFile.toString)
val tasks = for { val tasks = for {
t <- Job.job.targets t <- Job.job.targets
} yield new ImportTask(path, t, 1, b => cores.update())(Config.configuration) // FIXME missing ID, clock cycles, skip eval } yield new ImportTask(path, t, 1, b => cores.update(), None, None, None, 2)(Config.configuration) // FIXME missing ID, clock cycles, skip eval
tasks foreach (TaskScheduler.apply _) tasks foreach (TaskScheduler.apply _)
} }
} }
......
...@@ -64,8 +64,10 @@ object JobExamples { ...@@ -64,8 +64,10 @@ object JobExamples {
Some("Optional description of the core."), Some("Optional description of the core."),
Some(13124425), Some(13124425),
Some(true), Some(true),
Some("-retiming"),
Some(Seq("axi4mm")), Some(Seq("axi4mm")),
Some(Seq("zedboard", "zc706"))) Some(Seq("zedboard", "zc706")),
Some(3))
val jobs: Seq[Job] = Seq(bulkImportJob, composeJob, coreStatisticsJob, dseJob, hlsJob, importJob) val jobs: Seq[Job] = Seq(bulkImportJob, composeJob, coreStatisticsJob, dseJob, hlsJob, importJob)
......
...@@ -226,8 +226,10 @@ final case class HighLevelSynthesisJob( ...@@ -226,8 +226,10 @@ final case class HighLevelSynthesisJob(
* @param description Description of the core (optional). * @param description Description of the core (optional).
* @param averageClockCycles Clock cycles in an average job (optional). * @param averageClockCycles Clock cycles in an average job (optional).
* @param skipEvaluation Do not perform evaluation (optional). * @param skipEvaluation Do not perform evaluation (optional).
* @param synthOptions Optional parameters for synth_design.
* @param _architectures Name list of [[base.Architecture]] instances. * @param _architectures Name list of [[base.Architecture]] instances.
* @param _platforms Name list of [[base.Platform]] instances. * @param _platforms Name list of [[base.Platform]] instances.
* @param _optimization Positive integer optimization level.
**/ **/
final case class ImportJob( final case class ImportJob(
zipFile: Path, zipFile: Path,
...@@ -235,8 +237,10 @@ final case class ImportJob( ...@@ -235,8 +237,10 @@ final case class ImportJob(
description: Option[String] = None, description: Option[String] = None,
averageClockCycles: Option[Int] = None, averageClockCycles: Option[Int] = None,
skipEvaluation: Option[Boolean] = None, skipEvaluation: Option[Boolean] = None,
synthOptions: Option[String] = None,
private val _architectures: Option[Seq[String]] = None, private val _architectures: Option[Seq[String]] = None,
private val _platforms: Option[Seq[String]] = None) extends Job("import") { private val _platforms: Option[Seq[String]] = None,
private val _optimization: Option[Int] = None) extends Job("import") {
/** Returns the list of [[base.Architecture]] instances selected in this job. */ /** Returns the list of [[base.Architecture]] instances selected in this job. */
def architectures: Set[Architecture] = def architectures: Set[Architecture] =
FileAssetManager.entities.architectures filter (a => _architectures map (_.contains(a.name)) getOrElse true) FileAssetManager.entities.architectures filter (a => _architectures map (_.contains(a.name)) getOrElse true)
...@@ -244,6 +248,9 @@ final case class ImportJob( ...@@ -244,6 +248,9 @@ final case class ImportJob(
/** Returns the list of [[base.Platform]] instances selected in this job. */ /** Returns the list of [[base.Platform]] instances selected in this job. */
def platforms: Set[Platform] = def platforms: Set[Platform] =
FileAssetManager.entities.platforms filter (p => _platforms map (_.contains(p.name)) getOrElse true) FileAssetManager.entities.platforms filter (p => _platforms map (_.contains(p.name)) getOrElse true)
/** Returns the optimization level. */
def optimization: Int = _optimization getOrElse 0
} }
object BulkImportJob extends Builds[BulkImportJob] object BulkImportJob extends Builds[BulkImportJob]
......
...@@ -52,7 +52,7 @@ private object BulkImport extends Executor[BulkImportJob] { ...@@ -52,7 +52,7 @@ private object BulkImport extends Executor[BulkImportJob] {
a <- j.architectures a <- j.architectures
p <- j.platforms p <- j.platforms
t = Target(a, p) t = Target(a, p)
} yield new ImportTask(j.zipFile, t, j.id, _ => signal.release(), j.averageClockCycles)(cfg) } yield new ImportTask(j.zipFile, t, j.id, _ => signal.release(), j.averageClockCycles, None, None, 2)(cfg)
importTasks foreach { tsk.apply _ } importTasks foreach { tsk.apply _ }
......
...@@ -70,7 +70,7 @@ protected object HighLevelSynthesis extends Executor[HighLevelSynthesisJob] { ...@@ -70,7 +70,7 @@ protected object HighLevelSynthesis extends Executor[HighLevelSynthesisJob] {
if (avgCC.isEmpty && k.testbenchFiles.length > 0) { if (avgCC.isEmpty && k.testbenchFiles.length > 0) {
logger.warn("executed HLS with co-sim for {}, but no co-simulation report was found", k) logger.warn("executed HLS with co-sim for {}, but no co-simulation report was found", k)
} }
Some(new ImportTask(zip, t, k.id, _ => signal.release(), avgCC)(cfg)) Some(new ImportTask(zip, t, k.id, _ => signal.release(), avgCC, None, None, 2)(cfg))
} }
case _ => None case _ => None
} }
......
...@@ -51,7 +51,7 @@ object Import extends Executor[ImportJob] { ...@@ -51,7 +51,7 @@ object Import extends Executor[ImportJob] {
val tasks = jobs map { case (j, t) => val tasks = jobs map { case (j, t) =>
val avgCC = FileAssetManager.reports.cosimReport(VLNV.fromZip(j.zipFile).name, t) map (_.latency.avg) val avgCC = FileAssetManager.reports.cosimReport(VLNV.fromZip(j.zipFile).name, t) map (_.latency.avg)
new ImportTask(j.zipFile, t, j.id, _ => signal.release(), avgCC, j.skipEvaluation)(cfg) new ImportTask(j.zipFile, t, j.id, _ => signal.release(), avgCC, j.skipEvaluation, None, j.optimization)(cfg)
} }
tasks foreach { tsk.apply _ } tasks foreach { tsk.apply _ }
......
...@@ -55,8 +55,10 @@ package object json { ...@@ -55,8 +55,10 @@ package object json {
(JsPath \ "Description").readNullable[String] ~ (JsPath \ "Description").readNullable[String] ~
(JsPath \ "Average Clock Cycles").readNullable[Int] (verifying[Int](_ > 0)) ~ (JsPath \ "Average Clock Cycles").readNullable[Int] (verifying[Int](_ > 0)) ~
(JsPath \ "Skip Evaluation").readNullable[Boolean] ~ (JsPath \ "Skip Evaluation").readNullable[Boolean] ~
(JsPath \ "Synth Options").readNullable[String] ~
(JsPath \ "Architectures").readNullable[Seq[String]] ~ (JsPath \ "Architectures").readNullable[Seq[String]] ~
(JsPath \ "Platforms").readNullable[Seq[String]] (JsPath \ "Platforms").readNullable[Seq[String]] ~
(JsPath \ "Optimization").readNullable[Int] (verifying[Int](_ >= 0))
) (ImportJob.apply _) ) (ImportJob.apply _)
implicit val importJobWrites: Writes[ImportJob] = ( implicit val importJobWrites: Writes[ImportJob] = (
...@@ -66,8 +68,10 @@ package object json { ...@@ -66,8 +68,10 @@ package object json {
(JsPath \ "Description").writeNullable[String] ~ (JsPath \ "Description").writeNullable[String] ~
(JsPath \ "Average Clock Cycles").writeNullable[Int] ~ (JsPath \ "Average Clock Cycles").writeNullable[Int] ~
(JsPath \ "Skip Evaluation").writeNullable[Boolean] ~ (JsPath \ "Skip Evaluation").writeNullable[Boolean] ~
(JsPath \ "Synth Options").writeNullable[String] ~
(JsPath \ "Architectures").writeNullable[Seq[String]] ~ (JsPath \ "Architectures").writeNullable[Seq[String]] ~
(JsPath \ "Platforms").writeNullable[Seq[String]] (JsPath \ "Platforms").writeNullable[Seq[String]] ~
(JsPath \ "Optimization").writeNullable[Int]
) (unlift(ImportJob.unapply _ andThen (_ map ("Import" +: _)))) ) (unlift(ImportJob.unapply _ andThen (_ map ("Import" +: _))))
/* ImportJob @} */ /* ImportJob @} */
......
...@@ -37,7 +37,7 @@ private object ImportParser { ...@@ -37,7 +37,7 @@ private object ImportParser {
private val jobid = identity[ImportJob] _ private val jobid = identity[ImportJob] _
private def options: Parser[ImportJob => ImportJob] = private def options: Parser[ImportJob => ImportJob] =
(description | avgClockCycles | skipEval | architectures | platforms).rep map (opts => (description | avgClockCycles | skipEval | architectures | platforms | synthOptions | optimization).rep map (opts =>
(opts map (applyOption _) fold jobid) (_ andThen _)) (opts map (applyOption _) fold jobid) (_ andThen _))
private def description: Parser[(String, String)] = private def description: Parser[(String, String)] =
...@@ -50,12 +50,20 @@ private object ImportParser { ...@@ -50,12 +50,20 @@ private object ImportParser {
private def skipEval: Parser[(String, Boolean)] = private def skipEval: Parser[(String, Boolean)] =
(longOption("skipEvaluation", "SkipEval") ~ ws) map { case s => (s, true) } (longOption("skipEvaluation", "SkipEval") ~ ws) map { case s => (s, true) }
private def synthOptions: Parser[(String, String)] =
longOption("synthOptions", "SynthOptions") ~ ws ~/ qstring.opaque("additional synth_design options as string") ~ ws
private def optimization: Parser[(String, Int)] =
longOption("optimization", "Optimization") ~ ws ~/ posint.opaque("positive integer optimization level") ~ ws