From 2f40920b6d13d0ea573a3c6eebee3ffedfa83ddc Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Tue, 20 Nov 2018 13:00:35 -0800 Subject: Make Vec cloneType keep directions of elements (#945) Fixes #893--- .../src/main/scala/chisel3/core/Aggregate.scala | 2 +- src/test/scala/chiselTests/Direction.scala | 79 ++++++++++++++++++++-- 2 files changed, 76 insertions(+), 5 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index b5c63c44..9a2e9a38 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -240,7 +240,7 @@ sealed class Vec[T <: Data] private[core] (gen: => T, val length: Int) def apply(idx: Int): T = self(idx) override def cloneType: this.type = { - new Vec(gen.cloneType, length).asInstanceOf[this.type] + new Vec(gen.cloneTypeFull, length).asInstanceOf[this.type] } override def getElements: Seq[Data] = diff --git a/src/test/scala/chiselTests/Direction.scala b/src/test/scala/chiselTests/Direction.scala index 49d0ab77..5f8c4f9b 100644 --- a/src/test/scala/chiselTests/Direction.scala +++ b/src/test/scala/chiselTests/Direction.scala @@ -2,11 +2,9 @@ package chiselTests -import chisel3._ import org.scalatest._ -import org.scalatest.matchers._ -import org.scalatest.prop._ -import chisel3.testers.BasicTester +import chisel3._ +import chisel3.util.Decoupled class DirectionedBundle extends Bundle { val in = Input(UInt(32.W)) @@ -62,4 +60,77 @@ class DirectionSpec extends ChiselPropSpec with Matchers { property("Top-level forced outputs should be assignable") { elaborate(new TopDirectionOutput) } + + import chisel3.experimental.{MultiIOModule, DataMirror, Direction} + import chisel3.core.SpecifiedDirection + + property("Directions should be preserved through cloning and binding of Bundles") { + elaborate(new MultiIOModule { + class MyBundle extends Bundle { + val foo = Input(UInt(8.W)) + val bar = Output(UInt(8.W)) + } + class MyOuterBundle extends Bundle { + val fizz = new MyBundle + val buzz = Flipped(new MyBundle) + } + val a = new MyOuterBundle + val b = IO(a) + val specifiedDirs = Seq( + a.fizz.foo -> SpecifiedDirection.Input, + a.fizz.bar -> SpecifiedDirection.Output, + a.fizz -> SpecifiedDirection.Unspecified, + a.buzz.foo -> SpecifiedDirection.Input, + a.buzz.bar -> SpecifiedDirection.Output, + a.buzz -> SpecifiedDirection.Flip + ) + val actualDirs = Seq( + b.fizz.foo -> Direction.Input, + b.fizz.bar -> Direction.Output, + b.fizz -> Direction.Bidirectional(Direction.Default), + b.buzz.foo -> Direction.Output, + b.buzz.bar -> Direction.Input, + b.buzz -> Direction.Bidirectional(Direction.Flipped) + ) + for ((data, dir) <- specifiedDirs) { + DataMirror.specifiedDirectionOf(data) shouldBe (dir) + } + for ((data, dir) <- actualDirs) { + DataMirror.directionOf(data) shouldBe (dir) + } + }.asInstanceOf[MultiIOModule]) // The cast works around weird reflection behavior (bug?) + } + + property("Directions should be preserved through cloning and binding of Vecs") { + elaborate(new MultiIOModule { + val a = Vec(1, Input(UInt(8.W))) + val b = Vec(1, a) + val c = Vec(1, Flipped(a)) + val io0 = IO(b) + val io1 = IO(c) + val specifiedDirs = Seq( + a(0) -> SpecifiedDirection.Input, + b(0)(0) -> SpecifiedDirection.Input, + a -> SpecifiedDirection.Unspecified, + b -> SpecifiedDirection.Unspecified, + c(0) -> SpecifiedDirection.Flip, + c(0)(0) -> SpecifiedDirection.Input, + c -> SpecifiedDirection.Unspecified + ) + val actualDirs = Seq( + io0(0)(0) -> Direction.Input, + io0(0) -> Direction.Input, + io0 -> Direction.Input, + io1(0)(0) -> Direction.Output, + io1(0) -> Direction.Output, + io1 -> Direction.Output + ) + for ((data, dir) <- specifiedDirs) { + DataMirror.specifiedDirectionOf(data) shouldBe (dir) + } + for ((data, dir) <- actualDirs) { + DataMirror.directionOf(data) shouldBe (dir) + } + }.asInstanceOf[MultiIOModule]) // The cast works around weird reflection behavior (bug?) + } } -- cgit v1.2.3