diff options
| author | ducky | 2015-11-03 12:57:58 -0800 |
|---|---|---|
| committer | ducky | 2015-11-03 12:59:27 -0800 |
| commit | 2ceb98ee2a203e2cb394f3f4b9cf0628e7485f6f (patch) | |
| tree | 5b5e9add278eb34f3aa08b484f37062a50532262 /src/main | |
| parent | f9fe5da6f9ff79c17e57ef46dd9d885d51895535 (diff) | |
Add documentation on some non-intuitive parts
Diffstat (limited to 'src/main')
| -rw-r--r-- | src/main/scala/Chisel/Aggregate.scala | 2 | ||||
| -rw-r--r-- | src/main/scala/Chisel/Mem.scala | 6 | ||||
| -rw-r--r-- | src/main/scala/Chisel/Reg.scala | 14 |
3 files changed, 20 insertions, 2 deletions
diff --git a/src/main/scala/Chisel/Aggregate.scala b/src/main/scala/Chisel/Aggregate.scala index de77a7e7..07362b9b 100644 --- a/src/main/scala/Chisel/Aggregate.scala +++ b/src/main/scala/Chisel/Aggregate.scala @@ -86,6 +86,8 @@ object Vec { * collection transformation functions found in software array implementations. * * @tparam T type of elements + * @note when multiple conflicting assignments are performed on a Vec element, + * the last one takes effect (unlike Mem, where the result is undefined) */ sealed class Vec[T <: Data] private (gen: => T, val length: Int) extends Aggregate(gen.dir) with VecLike[T] { diff --git a/src/main/scala/Chisel/Mem.scala b/src/main/scala/Chisel/Mem.scala index 87f717b6..f4003c25 100644 --- a/src/main/scala/Chisel/Mem.scala +++ b/src/main/scala/Chisel/Mem.scala @@ -66,6 +66,9 @@ sealed abstract class MemBase[T <: Data](t: T, val length: Int) extends HasId wi * Writes take effect on the rising clock edge after the request. Reads are * combinational (requests will return data on the same cycle). * Read-after-write hazards are not an issue. + * + * @note when multiple conflicting writes are performed on a Mem element, the + * result is undefined (unlike Vec, where the last assignment wins) */ sealed class Mem[T <: Data](t: T, length: Int) extends MemBase(t, length) @@ -92,6 +95,9 @@ object SeqMem { * data on the rising edge after the request. Read-after-write behavior (when * a read and write to the same address are requested on the same cycle) is * undefined. + * + * @note when multiple conflicting writes are performed on a Mem element, the + * result is undefined (unlike Vec, where the last assignment wins) */ sealed class SeqMem[T <: Data](t: T, n: Int) extends MemBase[T](t, n) { def read(addr: UInt, enable: Bool): T = diff --git a/src/main/scala/Chisel/Reg.scala b/src/main/scala/Chisel/Reg.scala index f870f544..098f3922 100644 --- a/src/main/scala/Chisel/Reg.scala +++ b/src/main/scala/Chisel/Reg.scala @@ -27,10 +27,20 @@ object Reg { * empty to not update unless assigned to using the := operator) * @param init: initialization value on reset (or empty for uninitialized, * where the register value persists across a reset) + * + * @note this may result in a type error if called from a type parameterized + * function, since the Scala compiler isn't smart enough to know that null + * is a valid value. In those cases, you can either use the outType only Reg + * constructor or pass in `null.asInstanceOf[T]`. */ def apply[T <: Data](t: T = null, next: T = null, init: T = null): T = { - // REVIEW TODO: rewrite this in a less brittle way, perhaps also in a way - // that doesn't need two implementations of apply() + // TODO: write this in a way that doesn't need nulls (bad Scala style), + // null.asInstanceOf[T], and two constructors. Using Option types are an + // option, but introduces cumbersome syntax (wrap everything in a Some()). + // Implicit conversions to Option (or similar) types were also considered, + // but Scala's type inferencer and implicit insertion isn't smart enough + // to resolve all use cases. If the type inferencer / implicit resolution + // system improves, this may be changed. val x = makeType(t, next, init) pushCommand(DefRegister(x, Node(x._parent.get.clock), Node(x._parent.get.reset))) // TODO multi-clock if (init != null) { |
