@@ -70,7 +70,7 @@ private[chisel3] case object ColonLessGreaterEq extends Connection {
70
70
// when calling DirectionConnection.connect. Hence, we can just default to false to take the non-optimized emission path
71
71
case e : Throwable => false
72
72
}
73
- (typeEquivalent && consumer.notSpecial && producer.notSpecial )
73
+ (typeEquivalent && consumer.notWaivedOrSqueezedOrExcluded && producer.notWaivedOrSqueezedOrExcluded )
74
74
}
75
75
}
76
76
@@ -173,76 +173,84 @@ private[chisel3] object Connection {
173
173
import Alignment .deriveChildAlignment
174
174
175
175
def doConnection (
176
- consumerAlignment : Alignment ,
177
- producerAlignment : Alignment
176
+ conAlign : Alignment ,
177
+ proAlign : Alignment
178
178
)(
179
179
implicit sourceInfo : SourceInfo
180
180
): Unit = {
181
- (consumerAlignment, producerAlignment ) match {
181
+ (conAlign, proAlign ) match {
182
182
// Base Case 0: should probably never happen
183
183
case (_ : EmptyAlignment , _ : EmptyAlignment ) => ()
184
184
185
- // Base Case 1: early exit if dangling/unconnected is wavied
186
- case (consumerAlignment : NonEmptyAlignment , _ : EmptyAlignment ) if consumerAlignment.isWaived => ()
187
- case (_ : EmptyAlignment , producerAlignment : NonEmptyAlignment ) if producerAlignment.isWaived => ()
185
+ // Base Case 1: early exit if dangling/unconnected is excluded
186
+ case (conAlign : Alignment , proAlign : Alignment ) if conAlign.isExcluded && proAlign.isExcluded => ()
188
187
189
- // Base Case 2: early exit if operator requires matching orientations, but they don't align
190
- case (consumerAlignment : NonEmptyAlignment , producerAlignment : NonEmptyAlignment )
191
- if (! consumerAlignment.alignsWith(producerAlignment)) && (connectionOp.noWrongOrientations) =>
192
- errors = (s " inversely oriented fields ${consumerAlignment.member} and ${producerAlignment.member}" ) +: errors
188
+ // Base Case 2(A,B): early exit if dangling/unconnected is wavied or excluded
189
+ case (conAlign : NonEmptyAlignment , _ : EmptyAlignment ) if conAlign.isWaived || conAlign.isExcluded => ()
190
+ case (_ : EmptyAlignment , proAlign : NonEmptyAlignment ) if proAlign.isWaived || proAlign.isExcluded => ()
193
191
194
- // Base Case 3: early exit if operator requires matching widths, but they aren't the same
195
- case (consumerAlignment : NonEmptyAlignment , producerAlignment : NonEmptyAlignment )
196
- if (consumerAlignment
197
- .truncationRequired(producerAlignment, connectionOp)
198
- .nonEmpty) && (connectionOp.noMismatchedWidths) =>
199
- val mustBeTruncated = consumerAlignment.truncationRequired(producerAlignment, connectionOp).get
192
+ // Base Case 3: early exit if dangling/unconnected is wavied
193
+ case (conAlign : NonEmptyAlignment , proAlign : NonEmptyAlignment ) if conAlign.isExcluded || proAlign.isExcluded =>
194
+ val (excluded, included) =
195
+ if (conAlign.isExcluded) (conAlign, proAlign)
196
+ else (proAlign, conAlign)
197
+ errors = (s " excluded field ${excluded.member} has matching non-excluded field ${included.member}" ) +: errors
198
+
199
+ // Base Case 4: early exit if operator requires matching orientations, but they don't align
200
+ case (conAlign : NonEmptyAlignment , proAlign : NonEmptyAlignment )
201
+ if (! conAlign.alignsWith(proAlign)) && (connectionOp.noWrongOrientations) =>
202
+ errors = (s " inversely oriented fields ${conAlign.member} and ${proAlign.member}" ) +: errors
203
+
204
+ // Base Case 5: early exit if operator requires matching widths, but they aren't the same
205
+ case (conAlign : NonEmptyAlignment , proAlign : NonEmptyAlignment )
206
+ if (conAlign.truncationRequired(proAlign, connectionOp).nonEmpty) && (connectionOp.noMismatchedWidths) =>
207
+ val mustBeTruncated = conAlign.truncationRequired(proAlign, connectionOp).get
200
208
errors =
201
- (s " mismatched widths of ${consumerAlignment .member} and ${producerAlignment .member} might require truncation of $mustBeTruncated" ) +: errors
209
+ (s " mismatched widths of ${conAlign .member} and ${proAlign .member} might require truncation of $mustBeTruncated" ) +: errors
202
210
203
- // Base Case 3 : operator error on dangling/unconnected fields
211
+ // Base Case 6 : operator error on dangling/unconnected fields
204
212
case (consumer : NonEmptyAlignment , _ : EmptyAlignment ) =>
205
- errors = (s " ${consumer.errorWord(connectionOp)} consumer field ${consumerAlignment .member}" ) +: errors
213
+ errors = (s " ${consumer.errorWord(connectionOp)} consumer field ${conAlign .member}" ) +: errors
206
214
case (_ : EmptyAlignment , producer : NonEmptyAlignment ) =>
207
- errors = (s " ${producer.errorWord(connectionOp)} producer field ${producerAlignment .member}" ) +: errors
215
+ errors = (s " ${producer.errorWord(connectionOp)} producer field ${proAlign .member}" ) +: errors
208
216
209
217
// Recursive Case 4: non-empty orientations
210
- case (consumerAlignment : NonEmptyAlignment , producerAlignment : NonEmptyAlignment ) =>
211
- (consumerAlignment .member, producerAlignment .member) match {
218
+ case (conAlign : NonEmptyAlignment , proAlign : NonEmptyAlignment ) =>
219
+ (conAlign .member, proAlign .member) match {
212
220
case (consumer : Aggregate , producer : Aggregate ) =>
213
- matchingZipOfChildren(Some (consumerAlignment ), Some (producerAlignment )).foreach {
221
+ matchingZipOfChildren(Some (conAlign ), Some (proAlign )).foreach {
214
222
case (ceo, peo) =>
215
- doConnection(ceo.getOrElse(consumerAlignment .empty), peo.getOrElse(producerAlignment .empty))
223
+ doConnection(ceo.getOrElse(conAlign .empty), peo.getOrElse(proAlign .empty))
216
224
}
217
225
case (consumer : Aggregate , DontCare ) =>
218
226
consumer.getElements.foreach {
219
227
case f =>
220
228
doConnection(
221
- deriveChildAlignment(f, consumerAlignment ),
222
- deriveChildAlignment(f, consumerAlignment ).swap(DontCare )
229
+ deriveChildAlignment(f, conAlign ),
230
+ deriveChildAlignment(f, conAlign ).swap(DontCare )
223
231
)
224
232
}
225
233
case (DontCare , producer : Aggregate ) =>
226
234
producer.getElements.foreach {
227
235
case f =>
228
236
doConnection(
229
- deriveChildAlignment(f, producerAlignment ).swap(DontCare ),
230
- deriveChildAlignment(f, producerAlignment )
237
+ deriveChildAlignment(f, proAlign ).swap(DontCare ),
238
+ deriveChildAlignment(f, proAlign )
231
239
)
232
240
}
233
241
case (consumer, producer) =>
234
242
val alignment = (
235
- consumerAlignment .alignsWith(producerAlignment ),
236
- (! consumerAlignment .alignsWith(
237
- producerAlignment
243
+ conAlign .alignsWith(proAlign ),
244
+ (! conAlign .alignsWith(
245
+ proAlign
238
246
) && connectionOp.connectToConsumer && ! connectionOp.connectToProducer),
239
- (! consumerAlignment .alignsWith(
240
- producerAlignment
247
+ (! conAlign .alignsWith(
248
+ proAlign
241
249
) && ! connectionOp.connectToConsumer && connectionOp.connectToProducer)
242
250
) match {
243
- case (true , _, _) => consumerAlignment
244
- case (_, true , _) => consumerAlignment
245
- case (_, _, true ) => producerAlignment
251
+ case (true , _, _) => conAlign
252
+ case (_, true , _) => conAlign
253
+ case (_, _, true ) => proAlign
246
254
case other => throw new Exception (other.toString)
247
255
}
248
256
val lAndROpt = alignment.computeLandR(consumer, producer, connectionOp)
0 commit comments