SynthesisReport.scala 4.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//
// Copyright (C) 2014 Jens Korinth, TU Darmstadt
//
// This file is part of Tapasco (TPC).
//
// Tapasco is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Tapasco is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Tapasco.  If not, see <http://www.gnu.org/licenses/>.
//
/**
 * @file     SynthesisReport.scala
 * @brief    Model for parsing and evaluating synthesis reports in XML format
 *           (see common/ip_report.xml.template for an example).
 * @authors  J. Korinth, TU Darmstadt (jk@esa.cs.tu-darmstadt.de)
 **/
package de.tu_darmstadt.cs.esa.tapasco.reports
import  de.tu_darmstadt.cs.esa.tapasco.util._
import  java.nio.file.Path

/** Synthesis Report model. **/
final case class SynthesisReport(
    override val file: Path,
    area: Option[AreaEstimate],
33
    timing: Option[TimingEstimate],
34
35
    masters : Option[Int],
    slaves : Option[Int]) extends Report(file) {
36
  require(file.toFile.exists, "file %s does not exist".format(file.toString))
37
  require(area.nonEmpty || timing.nonEmpty || masters.nonEmpty || slaves.nonEmpty, "no synthesis results found in %s".format(file.toString))
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
}

object SynthesisReport {
  private[this] implicit val logger = de.tu_darmstadt.cs.esa.tapasco.Logging.logger(this.getClass)
  import de.tu_darmstadt.cs.esa.tapasco.Logging._

  /** Extracts the area estimation from the given synthesis report file.
    * @param sr Path to file
    * @return AreaEstimate if successful, None otherwise **/
  def extractArea(sr: Path): Option[AreaEstimate] = try {
      val xml = scala.xml.XML.loadFile(sr.toAbsolutePath.toString)
      (for (e <- List("Resources", "AvailableResources")) yield {
        val slice: Integer = ((xml \\ "AreaReport" \\ e \\ "SLICE") text).toInt
        val lut: Integer = ((xml \\ "AreaReport" \\ e \\ "LUT") text).toInt
        val ff: Integer = ((xml \\ "AreaReport" \\ e \\ "FF") text).toInt
        val dsp: Integer = ((xml \\ "AreaReport" \\ e \\ "DSP") text).toInt
        val bram: Integer = ((xml \\ "AreaReport" \\ e \\ "BRAM") text).toInt
55
56
        ResourcesEstimate(slice, lut, ff, dsp, bram)
      }).grouped(2).map(x => AreaEstimate(x.head, x.tail.head)).toList.headOption
57
58
59
60
61
62
63
64
65
66
67
68
    } catch { case e: Exception => logger.warn("parsing utilization report failed: " + e); None }

  /** Extracts the timing estimation from the given synthesis report file.
    * @param sr Path to file
    * @return TimingEstimate if successful, None otherwise **/
  def extractTiming(sr: Path): Option[TimingEstimate] = try {
      val xml = scala.xml.XML.loadFile(sr.toAbsolutePath.toString)
      Some(TimingEstimate(
        ((xml \\ "TimingReport" \\ "AchievedClockPeriod") text).toDouble,
        ((xml \\ "TimingReport" \\ "TargetClockPeriod") text).toDouble))
    } catch { case e: Exception => logger.warn("parsing timing report failed: " + e); None }

69
70
71
72
73
  def extractMasterPorts(sr : Path) : Option[Int] = try {
    val xml = scala.xml.XML.loadFile(sr.toAbsolutePath.toString)
    Some(((xml \\ "PortReport" \\ "NumMasters") text).toInt)
  } catch { case e : Exception => logger.warn("parsing port report failed: %s".format(e)); None}

74
75
76
77
78
  def extractSlavePorts(sr : Path) : Option[Int] = try {
    val xml = scala.xml.XML.loadFile(sr.toAbsolutePath.toString)
    Some(((xml \\ "PortReport" \\ "NumSlaves") text).toInt)
  } catch { case e : Exception => logger.warn("parsing port report failed: %s".format(e)); None}

79
80
81
  /** Produce SynthesisReport instance from file. **/
  def apply(sr: Path): Option[SynthesisReport] = catchAllDefault(None: Option[SynthesisReport],
      "failed to read synthesis report %s: ".format(sr.toString)) {
82
    Some(SynthesisReport(sr, extractArea(sr), extractTiming(sr), extractMasterPorts(sr), extractSlavePorts(sr)))
83
84
  }
}