diff options
| -rw-r--r-- | README.md | 177 | ||||
| -rw-r--r-- | src/main/scala/Chisel/Bits.scala | 4 | ||||
| -rw-r--r-- | src/main/scala/Chisel/internal/firrtl/IR.scala | 6 | ||||
| -rw-r--r-- | src/main/scala/Chisel/util/Decoupled.scala | 41 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/VectorPacketIO.scala | 63 |
5 files changed, 256 insertions, 35 deletions
@@ -7,13 +7,13 @@ It is currently in ALPHA VERSION, so many Chisel features may change in the comi ## Chisel2 Migration For those moving from Chisel2, there were some backwards incompatible changes and your RTL needs to be modified to work with Chisel3. The required -modifications are: +modifications are: - - Wire declaration style: + - Wire declaration style: ``` val wire = Bits(width = 15) - ``` - becomes (in Chisel3): + ``` + becomes (in Chisel3): ``` val wire = Wire(Bits(width = 15)) ``` @@ -30,12 +30,11 @@ modifications are: val mem = SeqMem(1024, UInt(width=8)) val dout = mem.read(addr, enable) ``` + Notice the address register is now internal to the SeqMem(), but the data - will still return on the subsequent cycle. - -## Getting Started + will still return on the subsequent cycle. -### Overview +## Overview Chisel3 is much more modular than Chisel2, and the compilation pipeline looks like: - Chisel3 (Scala) to FIRRTL (this is your "Chisel RTL"). @@ -44,16 +43,148 @@ like: - Verilog to C++ for simulation and testing using [Verilator](http://www.veripool.org/wiki/verilator). -### Installation -To compile down to Verilog for either simulation or synthesis, you will need to -download and install [FIRRTL](https://github.com/ucb-bar/firrtl). Currently, -FIRRTL is written in Stanza, which means it only runs on Linux or OS X. A -future Scala rewrite is planned which should also allow Windows compatibility. +## Installation +This will walk you through installing Chisel and its dependencies: +- [sbt](http://www.scala-sbt.org/), which is the preferred Scala build system + and what Chisel uses. +- [FIRRTL](https://github.com/ucb-bar/firrtl), which compile Chisel's IR down + to Verilog. A alpha version of FIRRTL written in Scala is available. + - FIRRTL is currently a separate repository but may eventually be made + available as a standalone program through system package managers and/or + included in the Chisel source tree. + - FIRRTL has known issues compiling under JDK 8, which manifests as an + infinite recursion / stack overflow exception. Instructions for selecting + JDK 7 are included. +- [Verilator](http://www.veripool.org/wiki/verilator), which compiles Verilog + down to C++ for simulation. The included unit testing infrastructure uses + this. + +### (Ubuntu-like) Linux + +1. [Install sbt](http://www.scala-sbt.org/release/docs/Installing-sbt-on-Linux.html), + which isn't available by default in the system package manager: + + ``` + echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list + sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 642AC823 + sudo apt-get update + sudo apt-get install sbt + ``` +1. Install FIRRTL. + 1. Clone the FIRRTL repository: + + ``` + git clone git@github.com:ucb-bar/firrtl.git + ``` + 1. Build Scala-FIRRTL. In the cloned FIRRTL repository: + + ``` + make build-scala + ``` + * This compiles FIRRTL into a JAR and creates a wrapper script `firrtl` to + make the JAR executable. The generated files are in `firrtl/utils/bin`. + * If this fails with an infinite recursion / stack overflow exception, this + is a known bug with JDK 8. You can either increase the stack size by + invoking: + + ``` + JAVA_OPTS=-Xss256m make build-scala + ``` + * Or, revert to JDK 7: + 1. Install JDK 7 (if not installed already): + + ``` + sudo apt-get install openjdk-7-jdk + ``` + 2. Select JDK 7 as the default JDK: + + ``` + sudo update-alternatives --config java + ``` + 1. Add the FIRRTL executable to your PATH. One way is to add this line to your + `.bashrc`: + + ``` + export PATH=$PATH:<path-to-your-firrtl-repository>/utils/bin + ``` +1. Install Verilator. As of February 2016, the version of Verilator included by + in Ubuntu's default package repositories are too out of date, so it must be + compiled from source. + 1. Install prerequisites (if not installed already): + + ``` + sudo apt-get install git make autoconf g++ flex bison + ``` + 1. Clone the Verilator repository: + + ``` + git clone http://git.veripool.org/git/verilator + ``` + 1. In the Verilator repository directory, check out a known good version: + + ``` + git pull + git checkout verilator_3_880 + ``` + 1. In the Verilator repository directory, build and install: + + ``` + unset VERILATOR_ROOT # For bash, unsetenv for csh + autoconf # Create ./configure script + ./configure + make + sudo make install + ``` + +### Windows + +*TODO: write me. If you __really__ want to see this happen, let us know by filing a bug report!* + +### Mac OS X + +1. Install sbt: + + ``` + brew cask install sbt + ``` +1. Install FIRRTL: + 1. Clone the FIRRTL repository: + + ``` + git clone git@github.com:ucb-bar/firrtl.git + ``` + 1. Build Scala-FIRRTL. In the cloned FIRRTL repository: + + ``` + make build-scala + ``` + * This compiles FIRRTL into a JAR and creates a wrapper script `firrtl` to + make the JAR executable. The generated files are in `firrtl/utils/bin`. + * If this fails with an infinite recursion / stack overflow exception, this + is a known bug with JDK 8. You can either increase the stack size by + invoking + + ``` + JAVA_OPTS=-Xss256m make build-scala` + ``` + * Or, revert to JDK 7: + + ``` + brew install caskroom/versions/java7 + ``` + 1. Add the FIRRTL executable to your PATH. One way is to add this line to your + `.bashrc`: + + ``` + export PATH=$PATH:<path-to-your-firrtl-repository>/utils/bin + ``` +1. Install Verilator: + + ``` + brew install verilator + ``` -To compile Verilog down to C++ for simulation (like the included unit testing -infrastructure uses), you will need to have -[Verilator](http://www.veripool.org/wiki/verilator) installed and in your -PATH. Verilator is available via the package manager for some operating systems. +## Getting Started ### Data Types Overview These are the base data types for defining circuit wires (abstract types which @@ -69,7 +200,7 @@ This section describes how to get started using Chisel to create a new RTL design from scratch. ### Project Setup -*TODO: recommended sbt style, project structure* +*TODO: recommended sbt style, project structure* ### RTL *TODO: toy example* @@ -82,7 +213,7 @@ pretty bare-bones unittest which also somewhat verifies the testing system itself. Unit tests are written with the ScalaTest unit testing framework, optionally -with ScalaCheck generators to sweep the parameter space where desired. +with ScalaCheck generators to sweep the parameter space where desired. `BasicTester`-based tests run a single circuit in simulation until either the test finishes or times out after a set amount of cycles. After compilation, @@ -100,7 +231,7 @@ a class that extends either `ChiselFlatSpec` (BDD-style testing) or `ChiselPropSpec` (ScalaCheck generators). In the test content, use ``` assert(execute{ new MyTestModule }) -``` +``` where `MyTestModule` is your top-level test circuit that extends `BasicTester`. @@ -125,11 +256,11 @@ to compile the Chisel library. If the compilation succeeded, you can then run the included unit tests by invoking: ``` sbt test -``` +``` ### Running Projects Against Local Chisel To publish your version of Chisel to the local Ivy (sbt's dependency manager) -repository, run: +repository, run: ``` sbt publish-local ``` @@ -140,7 +271,7 @@ becomes `sbt ~publish-local`. [sbt's manual](http://www.scala-sbt.org/0.13/docs/Publishing.html#Publishing+Locally) recommends that you use a `SNAPSHOT` version suffix to ensure that the local -repository is checked for updates. +repository is checked for updates. The compiled version gets placed in `~/.ivy2/local/`. You can nuke the relevant subfolder to un-publish your local copy of Chisel. diff --git a/src/main/scala/Chisel/Bits.scala b/src/main/scala/Chisel/Bits.scala index b800644d..8f2e1b09 100644 --- a/src/main/scala/Chisel/Bits.scala +++ b/src/main/scala/Chisel/Bits.scala @@ -280,7 +280,7 @@ sealed class UInt private[Chisel] (dir: Direction, width: Width, lit: Option[ULi extends Bits(dir, width, lit) with Num[UInt] { private[Chisel] override def cloneTypeWidth(w: Width): this.type = new UInt(dir, w).asInstanceOf[this.type] - private[Chisel] def toType = s"UInt<$width>" + private[Chisel] def toType = s"UInt$width" override private[Chisel] def fromInt(value: BigInt): this.type = UInt(value).asInstanceOf[this.type] @@ -412,7 +412,7 @@ sealed class SInt private (dir: Direction, width: Width, lit: Option[SLit] = Non extends Bits(dir, width, lit) with Num[SInt] { private[Chisel] override def cloneTypeWidth(w: Width): this.type = new SInt(dir, w).asInstanceOf[this.type] - private[Chisel] def toType = s"SInt<$width>" + private[Chisel] def toType = s"SInt$width" override def := (that: Data): Unit = that match { case _: SInt => this connect that diff --git a/src/main/scala/Chisel/internal/firrtl/IR.scala b/src/main/scala/Chisel/internal/firrtl/IR.scala index 6946652f..60a38a08 100644 --- a/src/main/scala/Chisel/internal/firrtl/IR.scala +++ b/src/main/scala/Chisel/internal/firrtl/IR.scala @@ -66,7 +66,7 @@ case class ILit(n: BigInt) extends Arg { } case class ULit(n: BigInt, w: Width) extends LitArg(n, w) { - def name: String = "UInt<" + width + ">(\"h0" + num.toString(16) + "\")" + def name: String = "UInt" + width + "(\"h0" + num.toString(16) + "\")" def minWidth: Int = 1 max n.bitLength require(n >= 0, s"UInt literal ${n} is negative") @@ -117,7 +117,7 @@ sealed case class UnknownWidth() extends Width { def known: Boolean = false def get: Int = None.get def op(that: Width, f: (W, W) => W): Width = this - override def toString: String = "?" + override def toString: String = "" } sealed case class KnownWidth(value: Int) extends Width { @@ -128,7 +128,7 @@ sealed case class KnownWidth(value: Int) extends Width { case KnownWidth(x) => KnownWidth(f(value, x)) case _ => that } - override def toString: String = value.toString + override def toString: String = s"<${value.toString}>" } sealed abstract class MemPortDirection(name: String) { diff --git a/src/main/scala/Chisel/util/Decoupled.scala b/src/main/scala/Chisel/util/Decoupled.scala index 23a08d52..ba33e6c7 100644 --- a/src/main/scala/Chisel/util/Decoupled.scala +++ b/src/main/scala/Chisel/util/Decoupled.scala @@ -22,21 +22,48 @@ object Decoupled { def apply[T <: Data](gen: T): DecoupledIO[T] = new DecoupledIO(gen) } -/** An I/O bundle for enqueuing data with valid/ready handshaking */ +/** An I/O bundle for enqueuing data with valid/ready handshaking + * Initialization must be handled, if necessary, by the parent circuit + */ class EnqIO[T <: Data](gen: T) extends DecoupledIO(gen) { + /** push dat onto the output bits of this interface to let the consumer know it has happened. + * @param dat the values to assign to bits. + * @return dat. + */ def enq(dat: T): T = { valid := Bool(true); bits := dat; dat } - valid := Bool(false) - for (io <- bits.flatten) - io := UInt(0) + + /** Initialize this Bundle. Valid is set to false, and all bits are set to zero. + * NOTE: This method of initialization is still being discussed and could change in the + * future. + */ + def init(): Unit = { + valid := Bool(false) + for (io <- bits.flatten) + io := UInt(0) + } override def cloneType: this.type = { new EnqIO(gen).asInstanceOf[this.type]; } } -/** An I/O bundle for dequeuing data with valid/ready handshaking */ +/** An I/O bundle for dequeuing data with valid/ready handshaking. + * Initialization must be handled, if necessary, by the parent circuit + */ class DeqIO[T <: Data](gen: T) extends DecoupledIO(gen) with Flipped { - ready := Bool(false) + /** Assert ready on this port and return the associated data bits. + * This is typically used when valid has been asserted by the producer side. + * @param b ignored + * @return the data for this device, + */ def deq(b: Boolean = false): T = { ready := Bool(true); bits } + + /** Initialize this Bundle. + * NOTE: This method of initialization is still being discussed and could change in the + * future. + */ + def init(): Unit = { + ready := Bool(false) + } override def cloneType: this.type = { new DeqIO(gen).asInstanceOf[this.type]; } } @@ -54,7 +81,7 @@ class DecoupledIOC[+T <: Data](gen: T) extends Bundle class QueueIO[T <: Data](gen: T, entries: Int) extends Bundle { /** I/O to enqueue data, is [[Chisel.DecoupledIO]] flipped */ - val enq = Decoupled(gen.cloneType).flip + val enq = Decoupled(gen.cloneType).flip() /** I/O to enqueue data, is [[Chisel.DecoupledIO]]*/ val deq = Decoupled(gen.cloneType) /** The current amount of data in the queue */ diff --git a/src/test/scala/chiselTests/VectorPacketIO.scala b/src/test/scala/chiselTests/VectorPacketIO.scala new file mode 100644 index 00000000..99ec66a6 --- /dev/null +++ b/src/test/scala/chiselTests/VectorPacketIO.scala @@ -0,0 +1,63 @@ +// See LICENSE for license details. + +package chiselTests + +import Chisel._ +import Chisel.testers.BasicTester + +/** + * This test used to fail when assignment statements were + * contained in DeqIO and EnqIO constructors. + * The symptom is creation of a firrtl file + * with missing declarations, the problem is exposed by + * the creation of the val outs in VectorPacketIO + * + * NOTE: The problem does not exist now because the initialization + * code has been removed from DeqIO and EnqIO + * + * IMPORTANT: The canonical way to initialize a decoupled inteface is still being debated. + */ +class Packet extends Bundle { + val header = UInt(width = 1) +} + +/** + * The problem occurs with just the ins or the outs + * lines also. + * The problem does not occur if the Vec is taken out + */ +class VectorPacketIO(n: Int) extends Bundle { + val ins = Vec(n, new DeqIO(new Packet())) + val outs = Vec(n, new EnqIO(new Packet())) +} + +/** + * a module uses the vector based IO bundle + * the value of n does not affect the error + */ +class BrokenVectorPacketModule extends Module { + val n = 4 + val io = new VectorPacketIO(n) + + /* the following method of initializing the circuit may change in the future */ + io.outs.foreach(_.init()) +} + +class VectorPacketIOUnitTester extends BasicTester { + val device_under_test = Module(new BrokenVectorPacketModule) + + // This counter just makes the test end quicker + val c = Counter(1) + when(c.inc()) { + stop() + } +} + +class VectorPacketIOUnitTesterSpec extends ChiselFlatSpec { + "a circuit using an io containing a vector of EnqIO wrapped packets" should + "compile and run" in { + assertTesterPasses { + new VectorPacketIOUnitTester + } + } +} |
