Skip to content

Commit c8171fe

Browse files
committed
Added Incoming/Outgoing, and clarified scaladoc on Input/Output
1 parent d011b44 commit c8171fe

File tree

2 files changed

+108
-7
lines changed

2 files changed

+108
-7
lines changed

core/src/main/scala/chisel3/Data.scala

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@ object SpecifiedDirection {
4646
case Input => Output
4747
}
4848

49+
/** Returns true if specified direction manifests as a flipped field
50+
*
51+
* @param dir provided specified direction
52+
* @return
53+
*/
54+
private[chisel3] def isFlipped(dir: SpecifiedDirection): Boolean = dir match {
55+
case Unspecified => false
56+
case Flip => true
57+
case Output => false
58+
case Input => true
59+
}
60+
4961
/** Returns the effective SpecifiedDirection of this node given the parent's effective SpecifiedDirection
5062
* and the user-specified SpecifiedDirection of this node.
5163
*/
@@ -251,8 +263,17 @@ object chiselTypeOf {
251263
}
252264
}
253265

254-
/**
255-
* Input, Output, and Flipped are used to define the directions of Module IOs.
266+
/** Creates a field of a parent [[Aggregate]] which is
267+
* - flipped relative to that parent
268+
* - coerced all members of the field to be aligned
269+
*
270+
* E.g. The following will create a field `i` of `b` where all recursive sub-elements of `i` are aligned, and where `i` flipped relative to `b`
271+
*
272+
* ```scala
273+
* val b = new Bundle {
274+
* val i = Input(new Decoupled(UInt(32.W))
275+
* }
276+
* ```
256277
*
257278
* Note that they currently clone their source argument, including its bindings.
258279
*
@@ -263,12 +284,44 @@ object Input {
263284
SpecifiedDirection.specifiedDirection(source)(_ => SpecifiedDirection.Input)
264285
}
265286
}
287+
288+
/** Creates a field of a parent [[Aggregate]] which is
289+
* - aligned relative to that parent
290+
* - coerced all members of the field to be aligned
291+
*
292+
* E.g. The following will create a field `i` of `b` where all recursive sub-elements of `i` are aligned, and where `i` is also aligned relative to `b`
293+
*
294+
* ```scala
295+
* val b = new Bundle {
296+
* val i = Output(new Decoupled(UInt(32.W))
297+
* }
298+
* ```
299+
*
300+
* Note that they currently clone their source argument, including its bindings.
301+
*
302+
* Thus, an error will be thrown if these are used on bound Data
303+
*/
266304
object Output {
267305
def apply[T <: Data](source: => T): T = {
268306
SpecifiedDirection.specifiedDirection(source)(_ => SpecifiedDirection.Output)
269307
}
270308
}
271309

310+
/** Creates a field of a parent [[Aggregate]] which is
311+
* - flipped relative to that parent
312+
*
313+
* E.g. The following will create a field `i` of `b` where `i` is flipped relative to `b`
314+
*
315+
* ```scala
316+
* val b = new Bundle {
317+
* val i = Flipped(new Decoupled(UInt(32.W))
318+
* }
319+
* ```
320+
*
321+
* Note that they currently clone their source argument, including its bindings.
322+
*
323+
* Thus, an error will be thrown if these are used on bound Data
324+
*/
272325
object Flipped {
273326
def apply[T <: Data](source: => T): T = {
274327
SpecifiedDirection.specifiedDirection(source)(x => SpecifiedDirection.flip(x.specifiedDirection))

core/src/main/scala/chisel3/IO.scala

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,7 @@ object IO {
99

1010
/** Constructs a port for the current Module
1111
*
12-
* This must wrap the datatype used to set the io field of any Module.
13-
* i.e. All concrete modules must have defined io in this form:
14-
* [lazy] val io[: io type] = IO(...[: io type])
15-
*
16-
* Items in [] are optional.
12+
* This must wrap the datatype used to create an io port of any Module.
1713
*
1814
* The granted iodef must be a chisel type and not be bound to hardware.
1915
*
@@ -62,3 +58,55 @@ object IO {
6258
iodefClone
6359
}
6460
}
61+
62+
object Incoming {
63+
64+
/** Constructs an incoming port of the provided `iodef` chisel type for the current Module
65+
*
66+
* The following example creates a input (and mixed-alignment) aggregate port in the current module
67+
*
68+
* ```scala
69+
* val i = Incoming(new Decoupled(UInt(32.W)))
70+
* ```
71+
* In this example, the sub-elements of `i` are ports of the following direction:
72+
* * `i.bits` is an input port
73+
* * `i.valid` is an input port
74+
* * `i.ready` is an output port
75+
*
76+
* Note that `Incoming(foo)` is equivalent to `IO(Flipped(foo))`
77+
*
78+
* This must wrap the datatype used to create an io port of any Module.
79+
*
80+
* The granted iodef must be a non-flipped chisel type and not be bound to hardware.
81+
*/
82+
def apply[T <: Data](iodef: => T)(implicit sourceInfo: SourceInfo): T = {
83+
if (SpecifiedDirection.isFlipped(iodef.specifiedDirection)) Builder.error("Incoming(..) cannot accept a chisel typed which is flipped")
84+
IO(Flipped(iodef))
85+
}
86+
}
87+
88+
object Outgoing {
89+
90+
/** Constructs an outgoing port of the provided `iodef` chisel type for the current Module
91+
*
92+
* The following example creates a output (and mixed-alignment) aggregate port in the current module
93+
*
94+
* ```scala
95+
* val i = Outgoing(new Decoupled(UInt(32.W)))
96+
* ```
97+
* In this example, the sub-elements of `i` are ports of the following direction:
98+
* * `i.bits` is an output port
99+
* * `i.valid` is an output port
100+
* * `i.ready` is an input port
101+
*
102+
* Note that `Outgoing(foo)` is equivalent to `IO(foo)`
103+
*
104+
* This must wrap the datatype used to create an io port of any Module.
105+
*
106+
* The granted iodef must be a non-flipped chisel type and not be bound to hardware.
107+
*/
108+
def apply[T <: Data](iodef: => T)(implicit sourceInfo: SourceInfo): T = {
109+
if (SpecifiedDirection.isFlipped(iodef.specifiedDirection)) Builder.error("Outgoing(..) cannot accept a chisel typed which is flipped")
110+
IO(iodef)
111+
}
112+
}

0 commit comments

Comments
 (0)