Commit 0ec5077d authored by Jens Korinth's avatar Jens Korinth
Browse files

Add 'packaging/' from commit '134b2f62'

git-subtree-dir: packaging
git-subtree-mainline: 1846cfbe
git-subtree-split: 134b2f62
parents 1846cfbe 134b2f62
### Project Specific stuff
test_run_dir/*
### XilinxISE template
# intermediate build files
*.bgn
*.bit
*.bld
*.cmd_log
*.drc
*.ll
*.lso
*.msd
*.msk
*.ncd
*.ngc
*.ngd
*.ngr
*.pad
*.par
*.pcf
*.prj
*.ptwx
*.rbb
*.rbd
*.stx
*.syr
*.twr
*.twx
*.unroutes
*.ut
*.xpi
*.xst
*_bitgen.xwbt
*_envsettings.html
*_map.map
*_map.mrp
*_map.ngm
*_map.xrpt
*_ngdbuild.xrpt
*_pad.csv
*_pad.txt
*_par.xrpt
*_summary.html
*_summary.xml
*_usage.xml
*_xst.xrpt
# project-wide generated files
*.gise
par_usage_statistics.html
usage_statistics_webtalk.html
webtalk.log
webtalk_pn.xml
# generated folders
iseconfig/
xlnx_auto_0_xdb/
xst/
_ngo/
_xmsgs/
### Eclipse template
*.pydevproject
.metadata
.gradle
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
# Eclipse Core
.project
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# JDT-specific (Eclipse Java Development Tools)
.classpath
# Java annotation processor (APT)
.factorypath
# PDT-specific
.buildpath
# sbteclipse plugin
.target
# TeXlipse plugin
.texlipse
### C template
# Object files
*.o
*.ko
*.obj
*.elf
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
### SBT template
# Simple Build Tool
# http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html#configuring-version-control
target/
lib_managed/
src_managed/
project/boot/
.history
.cache
### Emacs template
# -*- mode: gitignore; -*-
*~
\#*\#
/.emacs.desktop
/.emacs.desktop.lock
*.elc
auto-save-list
tramp
.\#*
# Org-mode
.org-id-locations
*_archive
# flymake-mode
*_flymake.*
# eshell files
/eshell/history
/eshell/lastdir
# elpa packages
/elpa/
# reftex files
*.rel
# AUCTeX auto folder
/auto/
# cask packages
.cask/
### Vim template
[._]*.s[a-w][a-z]
[._]s[a-w][a-z]
*.un~
Session.vim
.netrwhist
*~
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
*.iml
## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### C++ template
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
### OSX template
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Xcode template
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Build generated
build/
DerivedData
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
## Other
*.xccheckout
*.moved-aside
*.xcuserstate
### Scala template
*.class
*.log
# sbt specific
.cache
.history
.lib/
dist/*
target/
lib_managed/
src_managed/
project/boot/
project/plugins/project/
# Scala-IDE specific
.scala_dependencies
.worksheet
### Java template
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
package chisel.packaging
import scala.io.Source
import play.api.libs.json._
import play.api.libs.functional.syntax._
import chisel3.Module
/** Abstraction for known bus interfaces / pin groups. */
final case class Interface(name: String, kind: String)
/**
* Basic definition of a core for IP-XACT packaging.
**/
class CoreDefinition(val name: String, val vendor: String, val library: String, val version: String,
val root: String, val postBuildActions: Seq[Option[Any] => Unit] = Seq(),
val interfaces: Seq[Interface] = Seq()) {
import CoreDefinition._
def write(filename: String) : Boolean = try {
val fw = new java.io.FileWriter(filename)
fw.append(Json.toJson(this).toString)
fw.flush()
fw.close()
true
} catch { case ex: Exception => println("ERROR: " + ex); false }
}
/**
* Contains methods for reading a core definition from Json.
**/
object CoreDefinition {
def apply(name: String, vendor: String, library: String, version: String, root: String,
interfaces: Seq[Interface] = Seq()): CoreDefinition =
new CoreDefinition(name, vendor, library, version, root, interfaces = interfaces)
def withActions(name: String, vendor: String, library: String, version: String, root: String,
postBuildActions: Seq[Option[Any] => Unit], interfaces: Seq[Interface] = Seq()): CoreDefinition =
new CoreDefinition(name, vendor, library, version, root, postBuildActions, interfaces)
def unapply(cd: CoreDefinition): Option[Tuple6[String, String, String, String, String, Seq[Interface]]] =
Some((cd.name, cd.vendor, cd.library, cd.version, cd.root, cd.interfaces))
/** Provide automatic IP directory for given name. **/
def root(name: String): String =
java.nio.file.Paths.get(".").toAbsolutePath.resolveSibling("ip").resolve(name).toString
implicit val interfaceFormat: Format[Interface] = (
(JsPath \ "name").format[String] ~
(JsPath \ "kind").format[String]
) (Interface.apply _, unlift(Interface.unapply _))
implicit val coreDefinitionWrites: Writes[CoreDefinition] = (
(JsPath \ "name").write[String] ~
(JsPath \ "vendor").write[String] ~
(JsPath \ "library").write[String] ~
(JsPath \ "version").write[String] ~
(JsPath \ "root").write[String] ~
(JsPath \ "interfaces").write[Seq[Interface]]
)(unlift(CoreDefinition.unapply _))
implicit val coreDefinitionReads: Reads[CoreDefinition] = (
(JsPath \ "name").read[String] ~
(JsPath \ "vendor").read[String] ~
(JsPath \ "library").read[String] ~
(JsPath \ "version").read[String] ~
(JsPath \ "root").read[String] ~
(JsPath \ "interfaces").readNullable[Seq[Interface]].map(_ getOrElse Seq[Interface]())
)(apply _)
/**
* Read CoreDefinition from file containing Json format.
* @param filename Name (and path) of file.
**/
def read(filename: String) : Option[CoreDefinition] = try {
val contents = Source.fromFile(filename).getLines.mkString("\n")
val json = Json.parse(contents)
json.validate[CoreDefinition] match {
case s: JsSuccess[CoreDefinition] => Some(s.get)
case e: JsError => { println("ERROR: " + e); None }
}
} catch { case ex: Exception => println("ERROR: " + ex); None }
}
package chisel.packaging
import chisel3._
import scala.sys.process._
/** Module definition.
* @param config Optional, arbitrary configuration object, passed to post build actions.
* @param constr Module constructor function.
* @param core Core definition.
**/
final case class ModuleDef(config: Option[Any], constr: () => Module, core: CoreDefinition)
/**
* Abstract IP-XACT builder class:
* Objects can inherit from ModuleBuilder to automate the building
* and packaging process. Provides main method that can be run
* automatically via sbt run, takes arguments which cores to build.
* @param packagingDir Base directory of packaging submodule
* (default: ./packaging)
**/
abstract class ModuleBuilder(packagingDir: String = "packaging") {
val chiselArgs = Array[String]()
/** List of modules to build. */
val modules: Seq[ModuleDef]
def main(args: Array[String]) {
assert ((modules map (_.core.name.toLowerCase)).toSet.size == modules.length, "module names must be unique")
val fm = modules filter (m => args.length == 0 || args.map(_.toLowerCase).contains(m.core.name.toLowerCase))
assert (fm.length > 0, "no matching cores found for: " + args.mkString(", "))
fm foreach { m =>
Driver.execute(chiselArgs ++ Array("--target-dir", m.core.root, "--top-name", m.core.name), m.constr)
m.core.postBuildActions map (fn => fn.apply(m.config))
val json = "%s/%s.json".format(m.core.root, m.core.name)
m.core.write(json)
"%s/package.py %s".format(packagingDir, json).!
}
}
}
Chisel IP-XACT packaging for Xilinx Vivado Design Suite
=======================================================
Helper scripts and Scala classes to simplify the generation of IP-XACT IP cores from Chisel.
Uses [*Xilinx Vivado Design Suite*] [2] to infer most of the interfaces automatically.
The resulting `component.xml` files can be edited manually or with Vivado, if the automagic
did not fit your needs.
Requirements
----------------------
* Vivado 2016.x+
* Chisel 3.x *(currently using `3.0-SNAPSHOT`)*
* *optional*: sbt
Basic Usage
-----------
Class `ModuleBuilder` provides an abstract base class for an executable object with a `main`
method. You'll only need to provide a list of Chisel cores you'd like to wrap into IP-XACT.
A full example can be found in `example`; test it as follows:
1. Source the Vivado settings scripts, make sure `vivado` is in the `PATH`.
2. In the `chisel-packaging` base dir, do:
cp example/* .
3. Execute via:
sbt run
4. This should create a new directory `ip`, which contains subdirectories for each core.
The subdirectories contain the Verilog sources and the IP-XACT `component.xml`.
You can use the `ip` directory as a base directory for user IP in Vivado, the cores should
automatically appear in Vivado and IP-Integrator.
Usage in Chisel Projects (*sbt*)
--------------------------------
The easiest way to setup `chisel-packaging` for your Chisel project with `sbt` is using
**git subtree** ([this article] [1] has an excellent intro to subtrees) as follows:
1. In your the base directory of your project, add a new remote *chisel-packaging*:
git remote add chisel-packaging https://bitbucket.org/jkorinth/chisel-packaging.git
2. Setup a subtree in `packaging`:
git subtree add --prefix packaging chisel-packaging master --squash
This will clone the `chisel-packaging` into the `packaging` folder.
3. Add a project dependency in your `build.sbt`, add lines:
lazy val packaging = project.in(file("packaging"))
lazy val root = (project in file(".")).dependsOn(packaging)
*Note that the empty lines are **not optional** - a quirk of sbt.*
4. Implement `chisel.packaging.ModuleBuilder` in your own code; if you've chosen
a different directory than `packaging` for the subtree, you can pass it to the
baseclass constructor -- see [example/ModuleBuilderTest.scala][3]
5. Build the IP-XACT cores via `sbt run`.
Gotchas
-------
* The python script requires `vivado` to be in `PATH`, so you need to source the Vivado
settings scripts first.
* The repo is setup for Chisel 3.x; it can be used for Chisel 2.x, but that requires
manual changes - open an issue in the issue tracker if you need it.
* If you're using the `sbt` approach outlined above, make sure your `build.sbt` contains
the empty lines; they are required by `sbt`.
[1]: https://www.atlassian.com/blog/git/alternatives-to-git-submodule-git-subtree
[2]: https://www.xilinx.com/products/design-tools/vivado.html
[3]: example/ModuleBuilderTest.scala
__port_map = {
'AWID' : 'io_{0}_writeAddr_bits_id',
'AWADDR' : 'io_{0}_writeAddr_bits_addr',
'AWLEN' : 'io_{0}_writeAddr_bits_burst_len',
'AWSIZE' : 'io_{0}_writeAddr_bits_burst_size',
'AWBURST' : 'io_{0}_writeAddr_bits_burst_burst',
'AWLOCK' : 'io_{0}_writeAddr_bits_lock_lock',
'AWCACHE' : 'io_{0}_writeAddr_bits_cache_cache',
'AWPROT' : 'io_{0}_writeAddr_bits_prot_prot',
'AWQOS' : 'io_{0}_writeAddr_bits_qos',
'AWREGION' : 'io_{0}_writeAddr_bits_region',
'AWUSER' : 'io_{0}_writeAddr_bits_user',
'AWVALID' : 'io_{0}_writeAddr_valid',
'AWREADY' : 'io_{0}_writeAddr_ready',
'WID' : 'io_{0}_writeData_bits_id',
'WDATA' : 'io_{0}_writeData_bits_data',
'WSTRB' : 'io_{0}_writeData_bits_strb_strb',
'WLAST' : 'io_{0}_writeData_bits_last',
'WUSER' : 'io_{0}_writeData_bits_user',
'WVALID' : 'io_{0}_writeData_valid',
'WREADY' : 'io_{0}_writeData_ready',
'BID' : 'io_{0}_writeResp_bits_bid',
'BRESP' : 'io_{0}_writeResp_bits_bresp',
'BUSER' : 'io_{0}_writeResp_bits_buser',
'BVALID' : 'io_{0}_writeResp_valid',
'BREADY' : 'io_{0}_writeResp_ready',
'ARID' : 'io_{0}_readAddr_bits_id',
'ARADDR' : 'io_{0}_readAddr_bits_addr',
'ARLEN' : 'io_{0}_readAddr_bits_burst_len',
'ARSIZE' : 'io_{0}_readAddr_bits_burst_size',
'ARBURST' : 'io_{0}_readAddr_bits_burst_burst',
'ARLOCK' : 'io_{0}_readAddr_bits_lock_lock',
'ARCACHE' : 'io_{0}_readAddr_bits_cache_cache',
'ARPROT' : 'io_{0}_readAddr_bits_prot_prot',
'ARQOS' : 'io_{0}_readAddr_bits_qos',
'ARREGION' : 'io_{0}_readAddr_bits_region',
'ARUSER' : 'io_{0}_readAddr_bits_user',
'ARVALID' : 'io_{0}_readAddr_valid',
'ARREADY' : 'io_{0}_readAddr_ready',
'RID' : 'io_{0}_readData_bits_id',
'RDATA' : 'io_{0}_readData_bits_data',
'RRESP' : 'io_{0}_readData_bits_resp',
'RLAST' : 'io_{0}_readData_bits_last',
'RUSER' : 'io_{0}_readData_bits_user',
'RVALID' : 'io_{0}_readData_valid',
'RREADY' : 'io_{0}_readData_ready'
}
def get_port_dict(name):
return {k: v.format(name) for k, v in __port_map.items()}
name := "chisel-packaging"
organization := "esa.cs.tu-darmstadt.de"
version := "0.3-SNAPSHOT"
scalaVersion := "2.11.11"
resolvers ++= Seq(
Resolver.sonatypeRepo("snapshots"),
Resolver.sonatypeRepo("releases")
)
// Provide a managed dependency on X if -DXVersion="" is supplied on the command line.
val defaultVersions = Map("chisel3" -> "3.0-SNAPSHOT",
"chisel-iotesters" -> "1.1-SNAPSHOT")
libraryDependencies ++= (Seq("chisel3","chisel-iotesters").map {
dep: String => "edu.berkeley.cs" %% dep % sys.props.getOrElse(dep + "Version", defaultVersions(dep)) })
libraryDependencies ++= Seq(
"com.typesafe.play" %% "play-json" % "2.6.3"
)
scalacOptions += "-feature"
package chisel.packaging
import chisel3._
import CoreDefinition._
object ModuleBuilderTest extends ModuleBuilder(".") {
private object TestModule extends Module { val io = IO(new Bundle) }
val modules: List[(() => Module, CoreDefinition)] = List(
( // test module
() => TestModule,
CoreDefinition(
name = "TestModule",
vendor = "esa.cs.tu-darmstadt.de",
library = "chisel",
version = "1.0",
root("TestModule")
)
)