From 156435b80e32175883be21c7ab53784dd94f5c53 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Sun, 6 Aug 2017 16:37:31 -0700 Subject: Don't assign default direction to Analog in Chisel._ --- .../src/main/scala/chisel3/core/Data.scala | 9 +- src/test/scala/chiselTests/CompatibilitySpec.scala | 252 +++++++++++++++++++++ src/test/scala/chiselTests/CompatibiltySpec.scala | 244 -------------------- 3 files changed, 257 insertions(+), 248 deletions(-) create mode 100644 src/test/scala/chiselTests/CompatibilitySpec.scala delete mode 100644 src/test/scala/chiselTests/CompatibiltySpec.scala diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index 74e41895..66f16294 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -202,10 +202,11 @@ abstract class Data extends HasId { * DO NOT USE OUTSIDE THIS PURPOSE. THIS OPERATION IS DANGEROUS! */ private[core] def _assignCompatibilityExplicitDirection: Unit = { - _userDirection match { - case UserDirection.Unspecified => _userDirection = UserDirection.Output - case UserDirection.Flip => _userDirection = UserDirection.Input - case UserDirection.Input | UserDirection.Output => // nothing to do + (this, _userDirection) match { + case (_: Analog, _) => // nothing to do + case (_, UserDirection.Unspecified) => _userDirection = UserDirection.Output + case (_, UserDirection.Flip) => _userDirection = UserDirection.Input + case (_, UserDirection.Input | UserDirection.Output) => // nothing to do } } diff --git a/src/test/scala/chiselTests/CompatibilitySpec.scala b/src/test/scala/chiselTests/CompatibilitySpec.scala new file mode 100644 index 00000000..f3934f76 --- /dev/null +++ b/src/test/scala/chiselTests/CompatibilitySpec.scala @@ -0,0 +1,252 @@ +// See LICENSE for license details. + +package chiselTests + +import org.scalacheck.Gen +import org.scalatest.prop.GeneratorDrivenPropertyChecks + +class CompatibiltySpec extends ChiselFlatSpec with GeneratorDrivenPropertyChecks { + import Chisel._ + + behavior of "Chisel compatibility layer" + + it should "accept direction arguments" in { + val directionArgument: Direction = Gen.oneOf(INPUT, OUTPUT, NODIR).sample.get + val b = Bool(directionArgument) + b shouldBe a [Bool] + b.getWidth shouldEqual 1 + b.dir shouldEqual(directionArgument) + // Choose a random width + val width = Gen.choose(1, 2048).sample.get + val u = UInt(directionArgument, width) + u shouldBe a [UInt] + u.getWidth shouldEqual width + u.dir shouldEqual(directionArgument) + } + + it should "accept single argument U/SInt factory methods" in { + // Choose a random value + val value: Int = Gen.choose(0, Int.MaxValue).sample.get + val l = UInt(value) + l shouldBe a [UInt] + l shouldBe 'lit + l.getWidth shouldEqual BigInt(value).bitLength + l.litValue() shouldEqual value + } + + it should "map utility objects into the package object" in { + val value: Int = Gen.choose(2, 2048).sample.get + log2Up(value) shouldBe (1 max BigInt(value - 1).bitLength) + log2Ceil(value) shouldBe (BigInt(value - 1).bitLength) + log2Down(value) shouldBe ((1 max BigInt(value - 1).bitLength) - (if (value > 0 && ((value & (value - 1)) == 0)) 0 else 1)) + log2Floor(value) shouldBe (BigInt(value - 1).bitLength - (if (value > 0 && ((value & (value - 1)) == 0)) 0 else 1)) + isPow2(BigInt(1) << value) shouldBe true + isPow2((BigInt(1) << value) - 1) shouldBe false + } + + it should "make BitPats available" in { + val value: Int = Gen.choose(1, Int.MaxValue).sample.get + val binaryString = value.toBinaryString + val maskPosition = Gen.choose(0, binaryString.length - 1).sample.get + val bs = new StringBuilder(binaryString) + bs(maskPosition) = '?' + val bitPatString = bs.toString + val bp = BitPat("b" + bitPatString) + bp shouldBe a [BitPat] + bp.getWidth shouldEqual binaryString.length + + } + + it should "successfully compile a complete module" in { + class Dummy extends Module { + // The following just checks that we can create objects with nothing more than the Chisel compatibility package. + val io = new Bundle + val data = UInt(width = 3) + new ArbiterIO(data, 2) shouldBe a [ArbiterIO[_]] + new LockingRRArbiter(data, 2, 2, None) shouldBe a [LockingRRArbiter[_]] + new RRArbiter(data, 2) shouldBe a [RRArbiter[_]] + new Arbiter(data, 2) shouldBe a [Arbiter[_]] + new Counter(2) shouldBe a [Counter] + new ValidIO(data) shouldBe a [ValidIO[_]] + new DecoupledIO(data) shouldBe a [DecoupledIO[_]] + new QueueIO(data, 2) shouldBe a [QueueIO[_]] + new Pipe(data, 2) shouldBe a [Pipe[_]] + + FillInterleaved(2, data) shouldBe a [UInt] + PopCount(data) shouldBe a [UInt] + Fill(2, data) shouldBe a [UInt] + Reverse(data) shouldBe a [UInt] + Cat(data, data) shouldBe a [UInt] + Log2(data) shouldBe a [UInt] + unless(Bool(false)) {} + // 'switch' and 'is' are tested below in Risc + Counter(2) shouldBe a [Counter] + DecoupledIO(data) shouldBe a [DecoupledIO[_]] + val dcd = Decoupled(data) + dcd shouldBe a [DecoupledIO[_]] + Queue(dcd) shouldBe a [Queue[_]] + Enum(data, 2) shouldBe a [List[_]] + val lfsr16 = LFSR16() + lfsr16 shouldBe a [UInt] + lfsr16.getWidth shouldBe (16) + ListLookup(data, List(data), Array((BitPat("b1"), List(data)))) shouldBe a [List[_]] + Lookup(data, data, Seq((BitPat("b1"), data))) shouldBe a [List[_]] + Mux1H(data, Seq(data)) shouldBe a [UInt] + PriorityMux(Seq(Bool(false)), Seq(data)) shouldBe a [UInt] + MuxLookup(data, data, Seq((data, data))) shouldBe a [UInt] + MuxCase(data, Seq((Bool(), data))) shouldBe a [UInt] + OHToUInt(data) shouldBe a [UInt] + PriorityEncoder(data) shouldBe a [UInt] + UIntToOH(data) shouldBe a [UInt] + PriorityEncoderOH(data) shouldBe a [UInt] + RegNext(data) shouldBe a [UInt] + RegInit(data) shouldBe a [UInt] + RegEnable(data, Bool()) shouldBe a [UInt] + ShiftRegister(data, 2) shouldBe a [UInt] + Valid(data) shouldBe a [ValidIO[_]] + Pipe(Valid(data), 2) shouldBe a [ValidIO[_]] + } + + } + // Verify we can elaborate a design expressed in Chisel2 + class Chisel2CompatibleRisc extends Module { + val io = new Bundle { + val isWr = Bool(INPUT) + val wrAddr = UInt(INPUT, 8) + val wrData = Bits(INPUT, 32) + val boot = Bool(INPUT) + val valid = Bool(OUTPUT) + val out = Bits(OUTPUT, 32) + } + val file = Mem(256, Bits(width = 32)) + val code = Mem(256, Bits(width = 32)) + val pc = Reg(init=UInt(0, 8)) + + val add_op :: imm_op :: Nil = Enum(2) + + val inst = code(pc) + val op = inst(31,24) + val rci = inst(23,16) + val rai = inst(15, 8) + val rbi = inst( 7, 0) + + val ra = Mux(rai === Bits(0), Bits(0), file(rai)) + val rb = Mux(rbi === Bits(0), Bits(0), file(rbi)) + val rc = Wire(Bits(width = 32)) + + io.valid := Bool(false) + io.out := Bits(0) + rc := Bits(0) + + when (io.isWr) { + code(io.wrAddr) := io.wrData + } .elsewhen (io.boot) { + pc := UInt(0) + } .otherwise { + switch(op) { + is(add_op) { rc := ra +% rb } + is(imm_op) { rc := (rai << 8) | rbi } + } + io.out := rc + when (rci === UInt(255)) { + io.valid := Bool(true) + } .otherwise { + file(rci) := rc + } + pc := pc +% UInt(1) + } + } + + it should "Chisel2CompatibleRisc should elaborate" in { + elaborate { new Chisel2CompatibleRisc } + } + + it should "not try to assign directions to Analog" in { + elaborate(new Module { + val io = new Bundle { + val port = chisel3.experimental.Analog(32.W) + } + }) + } + + + class SmallBundle extends Bundle { + val f1 = UInt(width = 4) + val f2 = UInt(width = 5) + override def cloneType: this.type = (new SmallBundle).asInstanceOf[this.type] + } + class BigBundle extends SmallBundle { + val f3 = UInt(width = 6) + override def cloneType: this.type = (new BigBundle).asInstanceOf[this.type] + } + + "A Module with missing bundle fields when compiled with the Chisel compatibility package" should "not throw an exception" in { + + class ConnectFieldMismatchModule extends Module { + val io = new Bundle { + val in = (new SmallBundle).asInput + val out = (new BigBundle).asOutput + } + io.out := io.in + } + elaborate { new ConnectFieldMismatchModule() } + } + + "A Module in which a Reg is created with a bound type when compiled with the Chisel compatibility package" should "not throw an exception" in { + + class CreateRegFromBoundTypeModule extends Module { + val io = new Bundle { + val in = (new SmallBundle).asInput + val out = (new BigBundle).asOutput + } + val badReg = Reg(UInt(7, width=4)) + } + elaborate { new CreateRegFromBoundTypeModule() } + } + + "A Module with unwrapped IO when compiled with the Chisel compatibility package" should "not throw an exception" in { + + class RequireIOWrapModule extends Module { + val io = new Bundle { + val in = UInt(width = 32).asInput + val out = Bool().asOutput + } + io.out := io.in(1) + } + elaborate { new RequireIOWrapModule() } + } + + "A Module connecting output as source to input as sink when compiled with the Chisel compatibility package" should "not throw an exception" in { + + class SimpleModule extends Module { + val io = new Bundle { + val in = (UInt(width = 3)).asInput + val out = (UInt(width = 4)).asOutput + } + } + class SwappedConnectionModule extends SimpleModule { + val child = Module(new SimpleModule) + io.in := child.io.out + } + elaborate { new SwappedConnectionModule() } + } + + "A Module with directionless connections when compiled with the Chisel compatibility package" should "not throw an exception" in { + + class SimpleModule extends Module { + val io = new Bundle { + val in = (UInt(width = 3)).asInput + val out = (UInt(width = 4)).asOutput + } + val noDir = Wire(UInt(width = 3)) + } + + class DirectionLessConnectionModule extends SimpleModule { + val a = UInt(0, width = 3) + val b = Wire(UInt(width = 3)) + val child = Module(new SimpleModule) + b := child.noDir + } + elaborate { new DirectionLessConnectionModule() } + } +} diff --git a/src/test/scala/chiselTests/CompatibiltySpec.scala b/src/test/scala/chiselTests/CompatibiltySpec.scala deleted file mode 100644 index cc14be5e..00000000 --- a/src/test/scala/chiselTests/CompatibiltySpec.scala +++ /dev/null @@ -1,244 +0,0 @@ -// See LICENSE for license details. - -package chiselTests - -import org.scalacheck.Gen -import org.scalatest.prop.GeneratorDrivenPropertyChecks - -class CompatibiltySpec extends ChiselFlatSpec with GeneratorDrivenPropertyChecks { - import Chisel._ - - behavior of "Chisel compatibility layer" - - it should "accept direction arguments" in { - val directionArgument: Direction = Gen.oneOf(INPUT, OUTPUT, NODIR).sample.get - val b = Bool(directionArgument) - b shouldBe a [Bool] - b.getWidth shouldEqual 1 - b.dir shouldEqual(directionArgument) - // Choose a random width - val width = Gen.choose(1, 2048).sample.get - val u = UInt(directionArgument, width) - u shouldBe a [UInt] - u.getWidth shouldEqual width - u.dir shouldEqual(directionArgument) - } - - it should "accept single argument U/SInt factory methods" in { - // Choose a random value - val value: Int = Gen.choose(0, Int.MaxValue).sample.get - val l = UInt(value) - l shouldBe a [UInt] - l shouldBe 'lit - l.getWidth shouldEqual BigInt(value).bitLength - l.litValue() shouldEqual value - } - - it should "map utility objects into the package object" in { - val value: Int = Gen.choose(2, 2048).sample.get - log2Up(value) shouldBe (1 max BigInt(value - 1).bitLength) - log2Ceil(value) shouldBe (BigInt(value - 1).bitLength) - log2Down(value) shouldBe ((1 max BigInt(value - 1).bitLength) - (if (value > 0 && ((value & (value - 1)) == 0)) 0 else 1)) - log2Floor(value) shouldBe (BigInt(value - 1).bitLength - (if (value > 0 && ((value & (value - 1)) == 0)) 0 else 1)) - isPow2(BigInt(1) << value) shouldBe true - isPow2((BigInt(1) << value) - 1) shouldBe false - } - - it should "make BitPats available" in { - val value: Int = Gen.choose(1, Int.MaxValue).sample.get - val binaryString = value.toBinaryString - val maskPosition = Gen.choose(0, binaryString.length - 1).sample.get - val bs = new StringBuilder(binaryString) - bs(maskPosition) = '?' - val bitPatString = bs.toString - val bp = BitPat("b" + bitPatString) - bp shouldBe a [BitPat] - bp.getWidth shouldEqual binaryString.length - - } - - it should "successfully compile a complete module" in { - class Dummy extends Module { - // The following just checks that we can create objects with nothing more than the Chisel compatibility package. - val io = new Bundle - val data = UInt(width = 3) - new ArbiterIO(data, 2) shouldBe a [ArbiterIO[_]] - new LockingRRArbiter(data, 2, 2, None) shouldBe a [LockingRRArbiter[_]] - new RRArbiter(data, 2) shouldBe a [RRArbiter[_]] - new Arbiter(data, 2) shouldBe a [Arbiter[_]] - new Counter(2) shouldBe a [Counter] - new ValidIO(data) shouldBe a [ValidIO[_]] - new DecoupledIO(data) shouldBe a [DecoupledIO[_]] - new QueueIO(data, 2) shouldBe a [QueueIO[_]] - new Pipe(data, 2) shouldBe a [Pipe[_]] - - FillInterleaved(2, data) shouldBe a [UInt] - PopCount(data) shouldBe a [UInt] - Fill(2, data) shouldBe a [UInt] - Reverse(data) shouldBe a [UInt] - Cat(data, data) shouldBe a [UInt] - Log2(data) shouldBe a [UInt] - unless(Bool(false)) {} - // 'switch' and 'is' are tested below in Risc - Counter(2) shouldBe a [Counter] - DecoupledIO(data) shouldBe a [DecoupledIO[_]] - val dcd = Decoupled(data) - dcd shouldBe a [DecoupledIO[_]] - Queue(dcd) shouldBe a [Queue[_]] - Enum(data, 2) shouldBe a [List[_]] - val lfsr16 = LFSR16() - lfsr16 shouldBe a [UInt] - lfsr16.getWidth shouldBe (16) - ListLookup(data, List(data), Array((BitPat("b1"), List(data)))) shouldBe a [List[_]] - Lookup(data, data, Seq((BitPat("b1"), data))) shouldBe a [List[_]] - Mux1H(data, Seq(data)) shouldBe a [UInt] - PriorityMux(Seq(Bool(false)), Seq(data)) shouldBe a [UInt] - MuxLookup(data, data, Seq((data, data))) shouldBe a [UInt] - MuxCase(data, Seq((Bool(), data))) shouldBe a [UInt] - OHToUInt(data) shouldBe a [UInt] - PriorityEncoder(data) shouldBe a [UInt] - UIntToOH(data) shouldBe a [UInt] - PriorityEncoderOH(data) shouldBe a [UInt] - RegNext(data) shouldBe a [UInt] - RegInit(data) shouldBe a [UInt] - RegEnable(data, Bool()) shouldBe a [UInt] - ShiftRegister(data, 2) shouldBe a [UInt] - Valid(data) shouldBe a [ValidIO[_]] - Pipe(Valid(data), 2) shouldBe a [ValidIO[_]] - } - - } - // Verify we can elaborate a design expressed in Chisel2 - class Chisel2CompatibleRisc extends Module { - val io = new Bundle { - val isWr = Bool(INPUT) - val wrAddr = UInt(INPUT, 8) - val wrData = Bits(INPUT, 32) - val boot = Bool(INPUT) - val valid = Bool(OUTPUT) - val out = Bits(OUTPUT, 32) - } - val file = Mem(256, Bits(width = 32)) - val code = Mem(256, Bits(width = 32)) - val pc = Reg(init=UInt(0, 8)) - - val add_op :: imm_op :: Nil = Enum(2) - - val inst = code(pc) - val op = inst(31,24) - val rci = inst(23,16) - val rai = inst(15, 8) - val rbi = inst( 7, 0) - - val ra = Mux(rai === Bits(0), Bits(0), file(rai)) - val rb = Mux(rbi === Bits(0), Bits(0), file(rbi)) - val rc = Wire(Bits(width = 32)) - - io.valid := Bool(false) - io.out := Bits(0) - rc := Bits(0) - - when (io.isWr) { - code(io.wrAddr) := io.wrData - } .elsewhen (io.boot) { - pc := UInt(0) - } .otherwise { - switch(op) { - is(add_op) { rc := ra +% rb } - is(imm_op) { rc := (rai << 8) | rbi } - } - io.out := rc - when (rci === UInt(255)) { - io.valid := Bool(true) - } .otherwise { - file(rci) := rc - } - pc := pc +% UInt(1) - } - } - - it should "Chisel2CompatibleRisc should elaborate" in { - elaborate { new Chisel2CompatibleRisc } - } - - - class SmallBundle extends Bundle { - val f1 = UInt(width = 4) - val f2 = UInt(width = 5) - override def cloneType: this.type = (new SmallBundle).asInstanceOf[this.type] - } - class BigBundle extends SmallBundle { - val f3 = UInt(width = 6) - override def cloneType: this.type = (new BigBundle).asInstanceOf[this.type] - } - - "A Module with missing bundle fields when compiled with the Chisel compatibility package" should "not throw an exception" in { - - class ConnectFieldMismatchModule extends Module { - val io = new Bundle { - val in = (new SmallBundle).asInput - val out = (new BigBundle).asOutput - } - io.out := io.in - } - elaborate { new ConnectFieldMismatchModule() } - } - - "A Module in which a Reg is created with a bound type when compiled with the Chisel compatibility package" should "not throw an exception" in { - - class CreateRegFromBoundTypeModule extends Module { - val io = new Bundle { - val in = (new SmallBundle).asInput - val out = (new BigBundle).asOutput - } - val badReg = Reg(UInt(7, width=4)) - } - elaborate { new CreateRegFromBoundTypeModule() } - } - - "A Module with unwrapped IO when compiled with the Chisel compatibility package" should "not throw an exception" in { - - class RequireIOWrapModule extends Module { - val io = new Bundle { - val in = UInt(width = 32).asInput - val out = Bool().asOutput - } - io.out := io.in(1) - } - elaborate { new RequireIOWrapModule() } - } - - "A Module connecting output as source to input as sink when compiled with the Chisel compatibility package" should "not throw an exception" in { - - class SimpleModule extends Module { - val io = new Bundle { - val in = (UInt(width = 3)).asInput - val out = (UInt(width = 4)).asOutput - } - } - class SwappedConnectionModule extends SimpleModule { - val child = Module(new SimpleModule) - io.in := child.io.out - } - elaborate { new SwappedConnectionModule() } - } - - "A Module with directionless connections when compiled with the Chisel compatibility package" should "not throw an exception" in { - - class SimpleModule extends Module { - val io = new Bundle { - val in = (UInt(width = 3)).asInput - val out = (UInt(width = 4)).asOutput - } - val noDir = Wire(UInt(width = 3)) - } - - class DirectionLessConnectionModule extends SimpleModule { - val a = UInt(0, width = 3) - val b = Wire(UInt(width = 3)) - val child = Module(new SimpleModule) - b := child.noDir - } - elaborate { new DirectionLessConnectionModule() } - } -} -- cgit v1.2.3