Skip to content

Commit da5d4b7

Browse files
committed
Merge branch 'master' into release
2 parents 6e162ea + 794812f commit da5d4b7

33 files changed

+715
-732
lines changed

README.md

Lines changed: 68 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ The ScalaDoc for Chisel3 is available at the [API tab on the Chisel web site.](h
1010
## Overview
1111
Chisel3 is much more modular than Chisel2, and the compilation pipeline looks
1212
like:
13-
- Chisel3 (Scala) to Firrtl (this is your "Chisel RTL").
14-
- [Firrtl](https://github.com/ucb-bar/firrtl) to Verilog (which then be passed
15-
into FPGA or ASIC tools).
16-
- Verilog to C++ for simulation and testing using
17-
[Verilator](http://www.veripool.org/wiki/verilator).
13+
- Chisel3 (Scala) to Firrtl (this is your "Chisel RTL").
14+
- [Firrtl](https://github.com/ucb-bar/firrtl) to Verilog (which then be passed
15+
into FPGA or ASIC tools).
16+
- Verilog to C++ for simulation and testing using
17+
[Verilator](http://www.veripool.org/wiki/verilator).
1818

1919
## Installation
2020
This will walk you through installing Chisel and its dependencies:
@@ -29,47 +29,47 @@ This will walk you through installing Chisel and its dependencies:
2929
### (Ubuntu-like) Linux
3030

3131
1. [Install sbt](http://www.scala-sbt.org/release/docs/Installing-sbt-on-Linux.html),
32-
which isn't available by default in the system package manager:
33-
34-
```
35-
echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list
36-
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 642AC823
37-
sudo apt-get update
38-
sudo apt-get install sbt
39-
```
40-
1. Install Verilator. As of November 2016, the version of Verilator included by
41-
in Ubuntu's default package repositories is too out of date, so it must be
42-
compiled from source.
43-
1. Install prerequisites (if not installed already):
44-
45-
```
46-
sudo apt-get install git make autoconf g++ flex bison
47-
```
48-
1. Clone the Verilator repository:
49-
50-
```
51-
git clone http://git.veripool.org/git/verilator
32+
which isn't available by default in the system package manager:
5233
```
53-
1. In the Verilator repository directory, check out a known good version:
54-
55-
```
56-
git pull
57-
git checkout verilator_3_886
58-
```
59-
1. In the Verilator repository directory, build and install:
60-
61-
```
62-
unset VERILATOR_ROOT # For bash, unsetenv for csh
63-
autoconf # Create ./configure script
64-
./configure
65-
make
66-
sudo make install
34+
echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list
35+
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 642AC823
36+
sudo apt-get update
37+
sudo apt-get install sbt
6738
```
39+
1. Install Verilator. As of November 2016, the version of Verilator included by
40+
in Ubuntu's default package repositories is too out of date, so it must be
41+
compiled from source.
42+
43+
1. Install prerequisites (if not installed already):
44+
```
45+
sudo apt-get install git make autoconf g++ flex bison
46+
```
47+
48+
2. Clone the Verilator repository:
49+
```
50+
git clone http://git.veripool.org/git/verilator
51+
```
52+
53+
3. In the Verilator repository directory, check out a known good version:
54+
```
55+
git pull
56+
git checkout verilator_3_886
57+
```
58+
59+
4. In the Verilator repository directory, build and install:
60+
```
61+
unset VERILATOR_ROOT # For bash, unsetenv for csh
62+
autoconf # Create ./configure script
63+
./configure
64+
make
65+
sudo make install
66+
```
6867
6968
### Arch Linux
70-
```
71-
yaourt -S firrtl-git verilator sbt
72-
```
69+
70+
```
71+
yaourt -S firrtl-git verilator sbt
72+
```
7373
7474
### Windows
7575
@@ -79,14 +79,15 @@ This will walk you through installing Chisel and its dependencies:
7979
8080
1. Install sbt:
8181
82-
```
83-
brew install sbt
84-
```
82+
```
83+
brew install sbt
84+
```
85+
8586
1. Install Verilator:
8687
87-
```
88-
brew install verilator
89-
```
88+
```
89+
brew install verilator
90+
```
9091
9192
## Getting Started
9293
If you are migrating to Chisel3 from Chisel2, please visit
@@ -171,7 +172,7 @@ You will need to build from source and `publish-local`.
171172
The repo version can be found in the build.sbt file.
172173
At last check it was:
173174
174-
version := "3.1-SNAPSHOT",
175+
version := "3.1-SNAPSHOT",
175176
176177
To publish your version of Chisel to the local Ivy (sbt's dependency manager)
177178
repository, run:
@@ -206,22 +207,23 @@ match the version string in your local copy of Chisel's build.sbt.
206207
### Chisel3 Architecture Overview
207208
208209
The Chisel3 compiler consists of these main parts:
209-
- **The frontend**, `chisel.*`, which is the publicly visible "API" of Chisel
210-
and what is used in Chisel RTL. These just add data to the...
211-
- **The Builder**, `chisel.internal.Builder`, which maintains global state
212-
(like the currently open Module) and contains commands, generating...
213-
- **The intermediate data structures**, `chisel.firrtl.*`, which are
214-
syntactically very similar to Firrtl. Once the entire circuit has been
215-
elaborated, the top-level object (a `Circuit`) is then passed to...
216-
- **The Firrtl emitter**, `chisel.firrtl.Emitter`, which turns the
217-
intermediate data structures into a string that can be written out into a
218-
Firrtl file for further processing.
210+
211+
- **The frontend**, `chisel.*`, which is the publicly visible "API" of Chisel
212+
and what is used in Chisel RTL. These just add data to the...
213+
- **The Builder**, `chisel.internal.Builder`, which maintains global state
214+
(like the currently open Module) and contains commands, generating...
215+
- **The intermediate data structures**, `chisel.firrtl.*`, which are
216+
syntactically very similar to Firrtl. Once the entire circuit has been
217+
elaborated, the top-level object (a `Circuit`) is then passed to...
218+
- **The Firrtl emitter**, `chisel.firrtl.Emitter`, which turns the
219+
intermediate data structures into a string that can be written out into a
220+
Firrtl file for further processing.
219221
220222
Also included is:
221-
- **The standard library** of circuit generators, `chisel.util.*`. These
222-
contain commonly used interfaces and constructors (like `Decoupled`, which
223-
wraps a signal with a ready-valid pair) as well as fully parameterizable
224-
circuit generators (like arbiters and muxes).
225-
- **Driver utilities**, `chisel.Driver`, which contains compilation and test
226-
functions that are invoked in the standard Verilog generation and simulation
227-
testing infrastructure. These can also be used as part of custom flows.
223+
- **The standard library** of circuit generators, `chisel.util.*`. These
224+
contain commonly used interfaces and constructors (like `Decoupled`, which
225+
wraps a signal with a ready-valid pair) as well as fully parameterizable
226+
circuit generators (like arbiters and muxes).
227+
- **Driver utilities**, `chisel.Driver`, which contains compilation and test
228+
functions that are invoked in the standard Verilog generation and simulation
229+
testing infrastructure. These can also be used as part of custom flows.

build.sbt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ lazy val customUnidocSettings = unidocSettings ++ Seq (
1515

1616
lazy val commonSettings = Seq (
1717
organization := "edu.berkeley.cs",
18-
version := "3.0-SNAPSHOT_2017-06-22",
18+
version := "3.0-SNAPSHOT_2017-07-17",
1919
git.remoteRepo := "git@github.com:ucb-bar/chisel3.git",
2020
autoAPIMappings := true,
2121
scalaVersion := "2.11.11",
@@ -76,7 +76,7 @@ lazy val publishSettings = Seq (
7676
}
7777
)
7878

79-
val defaultVersions = Map("firrtl" -> "1.0-SNAPSHOT_2017-06-22")
79+
val defaultVersions = Map("firrtl" -> "1.0-SNAPSHOT_2017-07-17")
8080

8181
lazy val chiselSettings = Seq (
8282
name := "chisel3",

chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala

Lines changed: 77 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,58 @@ import chisel3.internal.sourceinfo._
1515
* of) other Data objects.
1616
*/
1717
sealed abstract class Aggregate extends Data {
18+
private[chisel3] override def bind(target: Binding, parentDirection: UserDirection) {
19+
binding = target
20+
21+
val resolvedDirection = UserDirection.fromParent(parentDirection, userDirection)
22+
for (child <- getElements) {
23+
child.bind(ChildBinding(this), resolvedDirection)
24+
}
25+
26+
// Check that children obey the directionality rules.
27+
val childDirections = getElements.map(_.direction).toSet
28+
direction = if (childDirections == Set()) { // Sadly, Scala can't do set matching
29+
// If empty, use my assigned direction
30+
resolvedDirection match {
31+
case UserDirection.Unspecified | UserDirection.Flip => ActualDirection.Unspecified
32+
case UserDirection.Output => ActualDirection.Output
33+
case UserDirection.Input => ActualDirection.Input
34+
}
35+
} else if (childDirections == Set(ActualDirection.Unspecified)) {
36+
ActualDirection.Unspecified
37+
} else if (childDirections == Set(ActualDirection.Input)) {
38+
ActualDirection.Input
39+
} else if (childDirections == Set(ActualDirection.Output)) {
40+
ActualDirection.Output
41+
} else if (childDirections subsetOf
42+
Set(ActualDirection.Output, ActualDirection.Input,
43+
ActualDirection.Bidirectional(ActualDirection.Default),
44+
ActualDirection.Bidirectional(ActualDirection.Flipped))) {
45+
resolvedDirection match {
46+
case UserDirection.Unspecified => ActualDirection.Bidirectional(ActualDirection.Default)
47+
case UserDirection.Flip => ActualDirection.Bidirectional(ActualDirection.Flipped)
48+
case _ => throw new RuntimeException("Unexpected forced Input / Output")
49+
}
50+
} else {
51+
this match {
52+
// Anything flies in compatibility mode
53+
case t: Record if !t.compileOptions.dontAssumeDirectionality => resolvedDirection match {
54+
case UserDirection.Unspecified => ActualDirection.Bidirectional(ActualDirection.Default)
55+
case UserDirection.Flip => ActualDirection.Bidirectional(ActualDirection.Flipped)
56+
case _ => ActualDirection.Bidirectional(ActualDirection.Default)
57+
}
58+
case _ =>
59+
val childWithDirections = getElements zip getElements.map(_.direction)
60+
throw Binding.MixedDirectionAggregateException(s"Aggregate '$this' can't have elements that are both directioned and undirectioned: $childWithDirections")
61+
}
62+
}
63+
}
64+
1865
/** Returns a Seq of the immediate contents of this Aggregate, in order.
1966
*/
2067
def getElements: Seq[Data]
2168

22-
private[core] def width: Width = getElements.map(_.width).foldLeft(0.W)(_ + _)
69+
private[chisel3] def width: Width = getElements.map(_.width).foldLeft(0.W)(_ + _)
2370
private[core] def legacyConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit =
2471
pushCommand(BulkConnect(sourceInfo, this.lref, that.lref))
2572

@@ -68,25 +115,21 @@ object Vec {
68115

69116
// Check that types are homogeneous. Width mismatch for Elements is safe.
70117
require(!elts.isEmpty)
118+
elts.foreach(requireIsHardware(_, "vec element"))
71119

72120
val vec = Wire(new Vec(cloneSupertype(elts, "Vec"), elts.length))
73121

74-
def doConnect(sink: T, source: T) = {
75-
// TODO: this looks bad, and should feel bad. Replace with a better abstraction.
76-
// NOTE: Must use elts.head instead of vec.sample_element because vec.sample_element has
77-
// WireBinding which does not have a direction
78-
val hasDirectioned = elts.head match {
79-
case t: Aggregate => t.flatten.exists(_.dir != Direction.Unspecified)
80-
case t: Element => t.dir != Direction.Unspecified
81-
}
82-
if (hasDirectioned) {
83-
sink bulkConnect source
84-
} else {
85-
sink connect source
86-
}
87-
}
88-
for ((v, e) <- vec zip elts) {
89-
doConnect(v, e)
122+
// TODO: try to remove the logic for this mess
123+
elts.head.direction match {
124+
case ActualDirection.Input | ActualDirection.Output | ActualDirection.Unspecified =>
125+
// When internal wires are involved, driver / sink must be specified explicitly, otherwise
126+
// the system is unable to infer which is driver / sink
127+
(vec zip elts).foreach(x => x._1 := x._2)
128+
case ActualDirection.Bidirectional(_) =>
129+
// For bidirectional, must issue a bulk connect so subelements are resolved correctly.
130+
// Bulk connecting two wires may not succeed because Chisel frontend does not infer
131+
// directions.
132+
(vec zip elts).foreach(x => x._1 <> x._2)
90133
}
91134
vec
92135
}
@@ -186,7 +229,7 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int)
186229
*
187230
* Needed specifically for the case when the Vec is length 0.
188231
*/
189-
private[core] val sample_element: T = gen
232+
private[chisel3] val sample_element: T = gen
190233

191234
// allElements current includes sample_element
192235
// This is somewhat weird although I think the best course of action here is
@@ -226,16 +269,25 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int)
226269
override def apply(p: UInt): T = macro CompileOptionsTransform.pArg
227270

228271
def do_apply(p: UInt)(implicit compileOptions: CompileOptions): T = {
229-
Binding.checkSynthesizable(p ,s"'p' ($p)")
272+
requireIsHardware(p, "vec index")
230273
val port = gen
231-
val i = Vec.truncateIndex(p, length)(UnlocatableSourceInfo, compileOptions)
232-
port.setRef(this, i)
233274

234-
// Bind each element of port to being whatever the base type is
235-
// Using the head element as the sample_element
236-
for((port_elem, model_elem) <- port.allElements zip sample_element.allElements) {
237-
port_elem.binding = model_elem.binding
275+
// Reconstruct the resolvedDirection (in Aggregate.bind), since it's not stored.
276+
// It may not be exactly equal to that value, but the results are the same.
277+
val reconstructedResolvedDirection = direction match {
278+
case ActualDirection.Input => UserDirection.Input
279+
case ActualDirection.Output => UserDirection.Output
280+
case ActualDirection.Bidirectional(ActualDirection.Default) | ActualDirection.Unspecified =>
281+
UserDirection.Unspecified
282+
case ActualDirection.Bidirectional(ActualDirection.Flipped) => UserDirection.Flip
238283
}
284+
// TODO port technically isn't directly child of this data structure, but the result of some
285+
// muxes / demuxes. However, this does make access consistent with the top-level bindings.
286+
// Perhaps there's a cleaner way of accomplishing this...
287+
port.bind(ChildBinding(this), reconstructedResolvedDirection)
288+
289+
val i = Vec.truncateIndex(p, length)(UnlocatableSourceInfo, compileOptions)
290+
port.setRef(this, i)
239291

240292
port
241293
}
@@ -256,7 +308,6 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int)
256308
new Vec(gen.cloneType, length).asInstanceOf[this.type]
257309
}
258310

259-
private[chisel3] def toType: String = s"${sample_element.toType}[$length]"
260311
override def getElements: Seq[Data] =
261312
(0 until length).map(apply(_))
262313

@@ -384,14 +435,6 @@ abstract class Record(private[chisel3] implicit val compileOptions: CompileOptio
384435
/** Name for Pretty Printing */
385436
def className: String = this.getClass.getSimpleName
386437

387-
private[chisel3] def toType = {
388-
def eltPort(elt: Data): String = {
389-
val flipStr: String = if(Data.isFirrtlFlipped(elt)) "flip " else ""
390-
s"${flipStr}${elt.getRef.name} : ${elt.toType}"
391-
}
392-
elements.toIndexedSeq.reverse.map(e => eltPort(e._2)).mkString("{", ", ", "}")
393-
}
394-
395438
private[core] override def typeEquivalent(that: Data): Boolean = that match {
396439
case that: Record =>
397440
this.getClass == that.getClass &&

0 commit comments

Comments
 (0)