Add ice40 synthesis results

This commit is contained in:
Dolu1990 2018-04-26 13:14:37 +02:00
parent bdcf3f6234
commit 558af595a1
3 changed files with 185 additions and 3 deletions

View File

@ -67,21 +67,25 @@ VexRiscv smallest (RV32I, 0.52 DMIPS/Mhz, no datapath bypass, no interrupt) ->
Artix 7 -> 346 Mhz 481 LUT 539 FF Artix 7 -> 346 Mhz 481 LUT 539 FF
Cyclone V -> 201 Mhz 347 ALMs Cyclone V -> 201 Mhz 347 ALMs
Cyclone IV -> 190 Mhz 673 LUT 529 FF Cyclone IV -> 190 Mhz 673 LUT 529 FF
iCE40 -> 81 Mhz 1130 LC
VexRiscv smallest (RV32I, 0.52 DMIPS/Mhz, no datapath bypass) -> VexRiscv smallest (RV32I, 0.52 DMIPS/Mhz, no datapath bypass) ->
Artix 7 -> 340 Mhz 562 LUT 589 FF Artix 7 -> 340 Mhz 562 LUT 589 FF
Cyclone V -> 202 Mhz 387 ALMs Cyclone V -> 202 Mhz 387 ALMs
Cyclone IV -> 180 Mhz 780 LUT 579 FF Cyclone IV -> 180 Mhz 780 LUT 579 FF
iCE40 -> 71 Mhz 1278 LC
VexRiscv small and productive (RV32I, 0.82 DMIPS/Mhz) -> VexRiscv small and productive (RV32I, 0.82 DMIPS/Mhz) ->
Artix 7 -> 327 Mhz 698 LUT 558 FF Artix 7 -> 327 Mhz 698 LUT 558 FF
Cyclone V -> 158 Mhz 524 ALMs Cyclone V -> 158 Mhz 524 ALMs
Cyclone IV -> 146 Mhz 1,061 LUT 552 FF Cyclone IV -> 146 Mhz 1,061 LUT 552 FF
iCE40 -> 55 Mhz 1541 LC
VexRiscv small and productive with I$ (RV32I, 0.72 DMIPS/Mhz, 4KB-I$) -> VexRiscv small and productive with I$ (RV32I, 0.72 DMIPS/Mhz, 4KB-I$) ->
Artix 7 -> 331 Mhz 727 LUT 600 FF Artix 7 -> 331 Mhz 727 LUT 600 FF
Cyclone V -> 152 Mhz 536 ALMs Cyclone V -> 152 Mhz 536 ALMs
Cyclone IV -> 156 Mhz 1,075 LUT 565 FF Cyclone IV -> 156 Mhz 1,075 LUT 565 FF
iCE40 -> 54 Mhz 1686 LC
VexRiscv full no cache (RV32IM, 1.22 DMIPS/Mhz, single cycle barrel shifter, debug module, catch exceptions, static branch) -> VexRiscv full no cache (RV32IM, 1.22 DMIPS/Mhz, single cycle barrel shifter, debug module, catch exceptions, static branch) ->
Artix 7 -> 295 Mhz 1399 LUT 971 FF Artix 7 -> 295 Mhz 1399 LUT 971 FF

View File

@ -0,0 +1,171 @@
package spinal.lib.eda.icestorm
import spinal.lib.eda._
import spinal.lib.eda.bench.{Report, Rtl, Target}
import scala.collection.mutable.ArrayBuffer
import java.io.File
import java.nio.file.Paths
import org.apache.commons.io.FileUtils
import spinal.core._
import spinal.lib.StreamFifo
import spinal.lib.eda.bench.Report
import scala.sys.process._
object IcestormFlow {
def doCmd(cmd : Seq[String], path : String): String ={
println(cmd)
val str = new StringBuilder()
val log = new ProcessLogger {
override def err(s: => String): Unit = {
str ++= s
stderr.println(s)
}
override def out(s: => String): Unit = {
str ++= s
stdout.println(s)
}
override def buffer[T](f: => T) = f
}
if(isWindows)
Process("cmd /C " + cmd, new java.io.File(path)) !(log)
else
Process.apply(cmd, new java.io.File(path)) !(log)
return str.toString()
}
val isWindows = System.getProperty("os.name").toLowerCase().contains("win")
def apply(workspacePath : String,toplevelPath : String,family : String,device : String, pack : String) : Report = {
val projectName = toplevelPath.split("/").last.split("[.]").head
val workspacePathFile = new File(workspacePath)
FileUtils.deleteDirectory(workspacePathFile)
workspacePathFile.mkdir()
FileUtils.copyFileToDirectory(new File(toplevelPath), workspacePathFile)
doCmd(List("yosys", "-v3", "-p", s"synth_ice40 -top $projectName -blif ${projectName}.blif", s"$projectName.v" ), workspacePath)
val arachne = doCmd(List("arachne-pnr", "-d", device.replace("hx",""), "--max-passes", "600", "-P", pack, s"$projectName.blif" ,"-o", s"$projectName.asc"), workspacePath)
doCmd(List("icepack", s"$projectName.asc", s"$projectName.bin"), workspacePath)
val icetime = doCmd(List("icetime", "-tmd", device, s"${projectName}.asc"), workspacePath)
new Report{
val intFind = "(\\d+,?)+".r
val fMaxReg = """[-+]?(\d*[.])?\d+""".r
override def getFMax() = {
try {
fMaxReg.findAllMatchIn("Total path delay: [^\\n]* MHz".r.findFirstIn(icetime).get).drop(1).next.toString().toDouble * 1e6
} catch {
case e : Throwable => -1
}
}
override def getArea() = {
try {
intFind.findFirstIn("LCs[^\\n]*\\/".r.findFirstIn(arachne).get).get.toString() + " LC"
} catch {
case e : Throwable => "error"
}
}
}
// mkdir -p bin
// rm -f Murax.v*.bin
// cp ../../../Murax.v*.bin . | true
// yosys -v3 -p "synth_ice40 -top toplevel -blif bin/toplevel.blif" ${VERILOG}
//
// val isVhdl = toplevelPath.endsWith(".vhd") || toplevelPath.endsWith(".vhdl")
//
// val tcl = new java.io.FileWriter(Paths.get(workspacePath,"doit.tcl").toFile)
// tcl.write(
// s"""read_${if(isVhdl) "vhdl" else "verilog"} $toplevelPath
//read_xdc doit.xdc
//
//synth_design -part $device -top ${toplevelPath.split("\\.").head}
//opt_design
//place_design
//route_design
//
//report_utilization
//report_timing"""
// )
//
// tcl.flush();
// tcl.close();
//
//
// val xdc = new java.io.FileWriter(Paths.get(workspacePath,"doit.xdc").toFile)
// xdc.write(s"""create_clock -period ${(targetPeriod*1e9) toBigDecimal} [get_ports clk]""")
//
// xdc.flush();
// xdc.close();
//
// doCmd(s"$vivadoPath/vivado -nojournal -log doit.log -mode batch -source doit.tcl", workspacePath)
//
// new Report{
// override def getFMax(): Double = {
// import scala.io.Source
// val report = Source.fromFile(Paths.get(workspacePath,"doit.log").toFile).getLines.mkString
// val intFind = "-?(\\d+\\.?)+".r
// val slack = try {
// (family match {
// case "Artix 7" =>
// intFind.findFirstIn("-?(\\d+.?)+ns \\(required time - arrival time\\)".r.findFirstIn(report).get).get
// }).toDouble
// }catch{
// case e : Exception => -1.0
// }
// return 1.0/(targetPeriod.toDouble-slack*1e-9)
// }
// override def getArea(): String = {
// import scala.io.Source
// val report = Source.fromFile(Paths.get(workspacePath,"doit.log").toFile).getLines.mkString
// val intFind = "(\\d+,?)+".r
// val leArea = try {
// family match {
// case "Artix 7" =>
// intFind.findFirstIn("Slice LUTs[ ]*\\|[ ]*(\\d+,?)+".r.findFirstIn(report).get).get + " LUT " +
// intFind.findFirstIn("Slice Registers[ ]*\\|[ ]*(\\d+,?)+".r.findFirstIn(report).get).get + " FF "
// }
// }catch{
// case e : Exception => "???"
// }
// return leArea
// }
// }
}
def main(args: Array[String]) {
SpinalVerilog(StreamFifo(Bits(8 bits), 64))
val report = IcestormFlow(
workspacePath="/home/spinalvm/tmp",
toplevelPath="VexRiscv.v",
family="iCE40",
device="hx8k",
pack = "ct256"
)
println(report.getArea())
println(report.getFMax())
}
}
object IcestormStdTargets {
def apply(): Seq[Target] = {
val targets = ArrayBuffer[Target]()
targets += new Target {
override def getFamilyName(): String = "iCE40"
override def synthesise(rtl: Rtl, workspace: String): Report = {
IcestormFlow(
workspacePath=workspace,
toplevelPath=rtl.getRtlPath(),
family=getFamilyName(),
device="hx8k",
pack = "ct256"
)
}
}
targets
}
}

View File

@ -2,8 +2,9 @@ package vexriscv.demo
import spinal.core._ import spinal.core._
import spinal.lib.eda.bench._ import spinal.lib.eda.bench._
import spinal.lib.eda.icestorm.IcestormStdTargets
import vexriscv.VexRiscv import vexriscv.VexRiscv
import vexriscv.plugin.DecoderSimplePlugin import vexriscv.plugin.{DecoderSimplePlugin, KeepAttribute}
import scala.collection.mutable.ArrayBuffer import scala.collection.mutable.ArrayBuffer
@ -14,6 +15,11 @@ object VexRiscvSynthesisBench {
def main(args: Array[String]) { def main(args: Array[String]) {
def wrap(that : => Component) : Component = that def wrap(that : => Component) : Component = that
// def wrap(that : => Component) : Component = {
// val c = that
// c.getAllIo.foreach(io => KeepAttribute(io.asDirectionLess()))
// c
// }
// Wrap with input/output registers // Wrap with input/output registers
// def wrap(that : => Component) : Component = { // def wrap(that : => Component) : Component = {
// //new WrapWithReg.Wrapper(that) // //new WrapWithReg.Wrapper(that)
@ -105,8 +111,9 @@ object VexRiscvSynthesisBench {
) ++ AlteraStdTargets( ) ++ AlteraStdTargets(
quartusCycloneIVPath = "/eda/intelFPGA_lite/17.0/quartus/bin", quartusCycloneIVPath = "/eda/intelFPGA_lite/17.0/quartus/bin",
quartusCycloneVPath = "/eda/intelFPGA_lite/17.0/quartus/bin" quartusCycloneVPath = "/eda/intelFPGA_lite/17.0/quartus/bin"
) ) ++ IcestormStdTargets()
// val targets = IcestormStdTargets()
Bench(rtls, targets, "/eda/tmp/") Bench(rtls, targets, "/eda/tmp/")
} }
} }