blob: d30b64b35a5e9d37d48ec0a15dd6afb45d6a673d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
// See LICENSE for license details.
package chiselTests
import chisel3._
import chisel3.core.IgnoreSeqInBundle
import chisel3.testers.BasicTester
trait BundleSpecUtils {
class BundleFooBar extends Bundle {
val foo = UInt(16.W)
val bar = UInt(16.W)
override def cloneType: this.type = (new BundleFooBar).asInstanceOf[this.type]
}
class BundleBarFoo extends Bundle {
val bar = UInt(16.W)
val foo = UInt(16.W)
override def cloneType: this.type = (new BundleBarFoo).asInstanceOf[this.type]
}
class BundleFoo extends Bundle {
val foo = UInt(16.W)
override def cloneType: this.type = (new BundleFoo).asInstanceOf[this.type]
}
class BundleBar extends Bundle {
val bar = UInt(16.W)
override def cloneType: this.type = (new BundleBar).asInstanceOf[this.type]
}
class BadSeqBundle extends Bundle {
val bar = Seq(UInt(16.W), UInt(8.W), UInt(4.W))
override def cloneType: this.type = (new BadSeqBundle).asInstanceOf[this.type]
}
class MyModule(output: Bundle, input: Bundle) extends Module {
val io = IO(new Bundle {
val in = Input(input)
val out = Output(output)
})
io.out <> io.in
}
class BundleSerializationTest extends BasicTester {
// Note that foo is higher order because its defined earlier in the Bundle
val bundle = Wire(new BundleFooBar)
bundle.foo := 0x1234.U
bundle.bar := 0x5678.U
// To UInt
val uint = bundle.asUInt
assert(uint.getWidth == 32) // elaboration time
assert(uint === "h12345678".asUInt(32.W))
// Back to Bundle
val bundle2 = uint.asTypeOf(new BundleFooBar)
assert(0x1234.U === bundle2.foo)
assert(0x5678.U === bundle2.bar)
stop()
}
}
class BundleSpec extends ChiselFlatSpec with BundleSpecUtils {
"Bundles with the same fields but in different orders" should "bulk connect" in {
elaborate { new MyModule(new BundleFooBar, new BundleBarFoo) }
}
"Bundles" should "follow UInt serialization/deserialization API" in {
assertTesterPasses { new BundleSerializationTest }
}
"Bulk connect on Bundles" should "check that the fields match" in {
(the [ChiselException] thrownBy {
elaborate { new MyModule(new BundleFooBar, new BundleFoo) }
}).getMessage should include ("Right Record missing field")
(the [ChiselException] thrownBy {
elaborate { new MyModule(new BundleFoo, new BundleFooBar) }
}).getMessage should include ("Left Record missing field")
}
"Bundles" should "not be able to use Seq for constructing hardware" in {
(the[ChiselException] thrownBy {
elaborate {
new Module {
val io = IO(new Bundle {
val b = new BadSeqBundle
})
}
}
}).getMessage should include("Public Seq members cannot be used to define Bundle elements")
}
"Bundles" should "be allowed to have Seq if need be" in {
assertTesterPasses {
new BasicTester {
val m = Module(new Module {
val io = IO(new Bundle {
val b = new BadSeqBundle with IgnoreSeqInBundle
})
})
stop()
}
}
}
"Bundles" should "be allowed to have non-Chisel Seqs" in {
assertTesterPasses {
new BasicTester {
val m = Module(new Module {
val io = IO(new Bundle {
val f = Output(UInt(8.W))
val unrelated = (0 to 10).toSeq
val unrelated2 = Seq("Hello", "World", "Chisel")
})
io.f := 0.U
})
stop()
}
}
}
"Bundles" should "not have aliased fields" in {
(the[ChiselException] thrownBy {
elaborate { new Module {
val io = IO(Output(new Bundle {
val a = UInt(8.W)
val b = a
}))
io.a := 0.U
io.b := 1.U
} }
}).getMessage should include("aliased fields")
}
}
|