diff options
| author | Chick Markley | 2017-05-04 14:52:57 -0700 |
|---|---|---|
| committer | Jack Koenig | 2017-05-04 14:52:57 -0700 |
| commit | 9ad6c747ddcedb831dbfbcd970a46966f986b800 (patch) | |
| tree | 76b76f4ff947af4d08404705e2af1cc30390875b | |
| parent | 7d085287640e76fa10903e4be9ffdd1cfed8acdb (diff) | |
Connecting basic types wrong should error in chisel (#497)
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala | 34 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/ConnectSpec.scala | 85 |
2 files changed, 110 insertions, 9 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala b/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala index 0cf035f4..80e96ce7 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala @@ -55,15 +55,31 @@ object MonoConnect { * during the recursive decent and then rethrow them with extra information added. * This gives the user a 'path' to where in the connections things went wrong. */ - def connect(sourceInfo: SourceInfo, connectCompileOptions: CompileOptions, sink: Data, source: Data, context_mod: UserModule): Unit = + //scalastyle:off cyclomatic.complexity method.length + def connect( + sourceInfo: SourceInfo, + connectCompileOptions: CompileOptions, + sink: Data, + source: Data, + context_mod: UserModule): Unit = (sink, source) match { - // Handle element case (root case) - case (sink_e: Element, source_e: Element) => { + + // Handle legal element cases, note (Bool, Bool) is caught by the first two, as Bool is a UInt + case (sink_e: Bool, source_e: UInt) => elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod) - // TODO(twigg): Verify the element-level classes are connectable - } + case (sink_e: UInt, source_e: Bool) => + elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod) + case (sink_e: UInt, source_e: UInt) => + elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod) + case (sink_e: SInt, source_e: SInt) => + elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod) + case (sink_e: FixedPoint, source_e: FixedPoint) => + elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod) + case (sink_e: Clock, source_e: Clock) => + elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod) + // Handle Vec case - case (sink_v: Vec[Data @unchecked], source_v: Vec[Data @unchecked]) => { + case (sink_v: Vec[Data @unchecked], source_v: Vec[Data @unchecked]) => if(sink_v.length != source_v.length) { throw MismatchedVecException } for(idx <- 0 until sink_v.length) { try { @@ -73,9 +89,9 @@ object MonoConnect { case MonoConnectException(message) => throw MonoConnectException(s"($idx)$message") } } - } + // Handle Record case - case (sink_r: Record, source_r: Record) => { + case (sink_r: Record, source_r: Record) => // For each field, descend with right for((field, sink_sub) <- sink_r.elements) { try { @@ -91,7 +107,7 @@ object MonoConnect { case MonoConnectException(message) => throw MonoConnectException(s".$field$message") } } - } + // Sink and source are different subtypes of data so fail case (sink, source) => throw MismatchedException(sink.toString, source.toString) } diff --git a/src/test/scala/chiselTests/ConnectSpec.scala b/src/test/scala/chiselTests/ConnectSpec.scala new file mode 100644 index 00000000..30e23f55 --- /dev/null +++ b/src/test/scala/chiselTests/ConnectSpec.scala @@ -0,0 +1,85 @@ +// See LICENSE for license details. + +package chiselTests + +import chisel3._ +import chisel3.experimental.{FixedPoint, Analog} +import chisel3.testers.BasicTester + +abstract class CrossCheck extends Bundle { + val in: Data + val out: Data +} + +class CrossConnects(inType: Data, outType: Data) extends Module { + val io = IO(new Bundle { + val in = Input(inType) + val out = Output(outType) + }) + io.out := io.in +} + +class CrossConnectTester(inType: Data, outType: Data) extends BasicTester { + val dut = Module(new CrossConnects(inType, outType)) + stop() +} + +class ConnectSpec extends ChiselPropSpec { + property("SInt := SInt should succeed") { + assertTesterPasses{ new CrossConnectTester(SInt(16.W), SInt(16.W)) } + } + property("SInt := UInt should fail") { + intercept[ChiselException]{ new CrossConnectTester(UInt(16.W), SInt(16.W)) } + } + property("SInt := FixedPoint should fail") { + intercept[ChiselException]{ new CrossConnectTester(FixedPoint(16.W, 8.BP), UInt(16.W)) } + } + property("UInt := UInt should succeed") { + assertTesterPasses{ new CrossConnectTester(UInt(16.W), UInt(16.W)) } + } + property("UInt := SInt should fail") { + intercept[ChiselException]{ new CrossConnectTester(SInt(16.W), UInt(16.W)) } + } + property("UInt := FixedPoint should fail") { + intercept[ChiselException]{ new CrossConnectTester(FixedPoint(16.W, 8.BP), UInt(16.W)) } + } + + property("Clock := Clock should succeed") { + assertTesterPasses{ new CrossConnectTester(Clock(), Clock()) } + } + property("Clock := UInt should fail") { + intercept[ChiselException]{ new CrossConnectTester(Clock(), UInt(16.W)) } + } + + property("FixedPoint := FixedPoint should succeed") { + assertTesterPasses{ new CrossConnectTester(FixedPoint(16.W, 8.BP), FixedPoint(16.W, 8.BP)) } + } + property("FixedPoint := SInt should fail") { + intercept[ChiselException]{ new CrossConnectTester(SInt(16.W), FixedPoint(16.W, 8.BP)) } + } + property("FixedPoint := UInt should fail") { + intercept[ChiselException]{ new CrossConnectTester(UInt(16.W), FixedPoint(16.W, 8.BP)) } + } + + property("Analog := Analog should fail") { + intercept[ChiselException]{ new CrossConnectTester(Analog(16.W), Analog(16.W)) } + } + property("Analog := FixedPoint should fail") { + intercept[ChiselException]{ new CrossConnectTester(Analog(16.W), FixedPoint(16.W, 8.BP)) } + } + property("FixedPoint := Analog should fail") { + intercept[ChiselException]{ new CrossConnectTester(FixedPoint(16.W, 8.BP), Analog(16.W)) } + } + property("Analog := UInt should fail") { + intercept[ChiselException]{ new CrossConnectTester(Analog(16.W), UInt(16.W)) } + } + property("Analog := SInt should fail") { + intercept[ChiselException]{ new CrossConnectTester(Analog(16.W), SInt(16.W)) } + } + property("UInt := Analog should fail") { + intercept[ChiselException]{ new CrossConnectTester(UInt(16.W), Analog(16.W)) } + } + property("SInt := Analog should fail") { + intercept[ChiselException]{ new CrossConnectTester(SInt(16.W), Analog(16.W)) } + } +} |
