1
+ package edu .berkeley .cs .ucie .digital
2
+ package sideband
3
+
4
+ import chisel3 ._
5
+ import chisel3 .util ._
6
+ import chiseltest ._
7
+ import org .scalatest .flatspec .AnyFlatSpec
8
+
9
+ import interfaces ._
10
+
11
+ class ChannelTest extends AnyFlatSpec with ChiselScalatestTester {
12
+ val fdiParams = new FdiParams (width = 8 , dllpWidth = 8 , sbWidth = 32 )
13
+ behavior of " sideband channel"
14
+ it should " instantiate d2d channel" in {
15
+ test(new D2DSidebandChannel (BigInt (1 ), new SidebandParams (), fdiParams)){ c =>
16
+ c.clock.step()
17
+ println(" welp" )
18
+ }
19
+ }
20
+
21
+ it should " instantiate phy channel" in {
22
+ test(new PHYSidebandChannel (BigInt (2 ), new SidebandParams (), fdiParams)){ c =>
23
+ c.clock.step()
24
+ println(" welp" )
25
+ }
26
+ }
27
+
28
+ it should " instantiate test" in {
29
+ test(new channel_wrapper()){ c =>
30
+ c.clock.step()
31
+ println(" welp" )
32
+ }
33
+ }
34
+
35
+ it should " send something for you" in {
36
+ test (new channel_wrapper()) { c =>
37
+ // init
38
+ c.io.channel.to_upper_layer.rx.valid.poke(false .B )
39
+ c.io.channel.to_upper_layer.tx.credit.poke(false .B )
40
+
41
+ c.io.channel.to_lower_layer.rx.valid.poke(false .B )
42
+ c.io.channel.to_lower_layer.tx.credit.poke(false .B )
43
+
44
+ c.io.channel.inner.node_to_layer_above.ready.poke(false .B )
45
+
46
+ c.clock.step()
47
+ // send something for you
48
+ c.io.channel.to_upper_layer.rx.valid.poke(true .B )
49
+ val packet = c.io.dummy_foryou.peek()
50
+
51
+ // send this in MSG_Width/NC_width cycles
52
+ for (i <- 0 until (c.sbParams.sbNodeMsgWidth / c.fdiParams.sbWidth)){
53
+ c.io.channel.to_upper_layer.rx.bits.poke(packet((i+ 1 )* c.fdiParams.sbWidth- 1 , i* c.fdiParams.sbWidth))
54
+ println(" subpacket: " + packet((i+ 1 )* c.fdiParams.sbWidth- 1 , i* c.fdiParams.sbWidth).litValue)
55
+ c.clock.step()
56
+ }
57
+
58
+ // wait for inner.node_to_layer_above.valid to be true
59
+ while (! c.io.channel.inner.node_to_layer_above.valid.peek().litToBoolean){
60
+ c.clock.step()
61
+ }
62
+
63
+ // check that the packet has arrived
64
+ c.io.channel.inner.node_to_layer_above.bits.expect(packet)
65
+ c.io.channel.inner.node_to_layer_above.valid.expect(true .B )
66
+ // assert the ready signal
67
+ c.io.channel.inner.node_to_layer_above.ready.poke(true .B )
68
+ println(" waiting for credit" )
69
+ // wait for a credit return
70
+ while (! c.io.channel.to_upper_layer.rx.credit.peek().litToBoolean){
71
+ c.clock.step()
72
+ }
73
+ }
74
+ }
75
+
76
+ it should " send something not for you" in {
77
+ test (new channel_wrapper()) { c =>
78
+ // init
79
+ c.io.channel.to_upper_layer.rx.valid.poke(false .B )
80
+ c.io.channel.to_upper_layer.tx.credit.poke(false .B )
81
+
82
+ c.io.channel.to_lower_layer.rx.valid.poke(false .B )
83
+ c.io.channel.to_lower_layer.tx.credit.poke(false .B )
84
+
85
+ c.io.channel.inner.node_to_layer_above.ready.poke(false .B )
86
+
87
+ c.clock.step()
88
+ // send something for you
89
+ c.io.channel.to_upper_layer.rx.valid.poke(true .B )
90
+ val packet = c.io.dummy_notforyou.peek()
91
+
92
+ // send this in MSG_Width/NC_width cycles
93
+ for (i <- 0 until (c.sbParams.sbNodeMsgWidth / c.fdiParams.sbWidth)){
94
+ c.io.channel.to_upper_layer.rx.bits.poke(packet((i+ 1 )* c.fdiParams.sbWidth- 1 , i* c.fdiParams.sbWidth))
95
+ println(" subpacket: " + packet((i+ 1 )* c.fdiParams.sbWidth- 1 , i* c.fdiParams.sbWidth).litValue)
96
+ c.clock.step()
97
+ }
98
+
99
+ // wait for the otherside tx valid to be high
100
+ while (! c.io.channel.to_lower_layer.tx.valid.peek().litToBoolean){
101
+ c.clock.step()
102
+ }
103
+
104
+ // check that the packet has arrived, MSG_Width/NC_width cycles
105
+ for (i <- 0 until (c.sbParams.sbNodeMsgWidth / c.fdiParams.sbWidth)){
106
+ c.io.channel.to_lower_layer.tx.bits.expect(packet((i+ 1 )* c.fdiParams.sbWidth- 1 , i* c.fdiParams.sbWidth))
107
+ println(" subpacket: " + packet((i+ 1 )* c.fdiParams.sbWidth- 1 , i* c.fdiParams.sbWidth).litValue)
108
+ c.clock.step()
109
+ }
110
+
111
+ // check the credit
112
+ c.io.channel.to_upper_layer.rx.credit.expect(true .B )
113
+ }
114
+ }
115
+
116
+ it should " send channel pair" in {
117
+ test(new channel_pair_wrapper()){ c =>
118
+ c.clock.step()
119
+ println(" welp" )
120
+
121
+ // initialize
122
+ c.reset.poke(true .B )
123
+ c.clock.step()
124
+ c.reset.poke(false .B )
125
+ c.clock.step()
126
+ c.io.to_D2D.layer_to_node_below.valid.poke(true .B )
127
+ val dtop_packet = c.io.dtop.peek()
128
+ c.io.to_D2D.layer_to_node_below.bits.poke(dtop_packet)
129
+
130
+
131
+ c.io.to_PHY.layer_to_node_above.valid.poke(true .B )
132
+ val ptod_packet = c.io.ptod.peek()
133
+ c.io.to_PHY.layer_to_node_above.bits.poke(ptod_packet)
134
+
135
+ c.clock.step()
136
+ c.io.to_D2D.layer_to_node_below.valid.poke(false .B )
137
+ c.io.to_PHY.layer_to_node_above.valid.poke(false .B )
138
+
139
+ // wait for the packet to arrive
140
+ while (! c.io.to_PHY.node_to_layer_above.valid.peek().litToBoolean){
141
+ c.clock.step()
142
+ }
143
+
144
+ c.io.to_PHY.node_to_layer_above.bits.expect(dtop_packet)
145
+
146
+ // wait for the other packet to arrive
147
+ while (! c.io.to_D2D.node_to_layer_below.valid.peek().litToBoolean){
148
+ c.clock.step()
149
+ }
150
+
151
+ c.io.to_D2D.node_to_layer_below.bits.expect(ptod_packet)
152
+
153
+ // verify credit is zero
154
+ c.io.to_D2D.layer_to_node_below.ready.expect(false .B )
155
+ c.io.to_PHY.layer_to_node_above.ready.expect(false .B )
156
+
157
+ // send complete over
158
+ c.io.to_D2D.layer_to_node_below.valid.poke(true .B )
159
+ val dtop_complete = c.io.dtop_cmp.peek()
160
+ c.io.to_D2D.layer_to_node_below.bits.poke(dtop_complete)
161
+
162
+ c.io.to_D2D.layer_to_node_below.ready.expect(true .B )
163
+
164
+ c.clock.step()
165
+
166
+ // change the input to something that is not complete, and shut valid
167
+ c.io.to_D2D.layer_to_node_below.valid.poke(false .B )
168
+ c.io.to_D2D.layer_to_node_below.bits.poke(dtop_packet)
169
+
170
+
171
+ // wait for arbitrary time: 20 cycles
172
+ for (i <- 0 until 20 ){
173
+ c.clock.step()
174
+ }
175
+
176
+ // verify the other side now sees the complete packet
177
+ c.io.to_PHY.node_to_layer_above.valid.expect(true .B )
178
+ c.io.to_PHY.node_to_layer_above.bits.expect(dtop_complete)
179
+
180
+ // dequeue the complete packet
181
+ c.io.to_PHY.node_to_layer_above.ready.poke(true .B )
182
+
183
+ c.clock.step()
184
+
185
+ c.io.to_PHY.node_to_layer_above.ready.poke(false .B )
186
+ // see the dtop packet there
187
+ c.io.to_PHY.node_to_layer_above.bits.expect(dtop_packet)
188
+ // see the ready is still false
189
+ for (i <- 0 until 10 ){
190
+ c.clock.step()
191
+ }
192
+
193
+ c.io.to_D2D.layer_to_node_below.ready.expect(false .B )
194
+
195
+ // now dequeue the other packet
196
+ c.io.to_PHY.node_to_layer_above.ready.poke(true .B )
197
+ for (i <- 0 until 10 ){
198
+ c.clock.step()
199
+ }
200
+ // see credit return
201
+ c.io.to_D2D.layer_to_node_below.ready.expect(true .B )
202
+ }
203
+ }
204
+ }
205
+
206
+ class channel_wrapper extends Module {
207
+ val sbParams = new SidebandParams ()
208
+ val fdiParams = new FdiParams (width = 8 , dllpWidth = 8 , sbWidth = 32 )
209
+ val io = IO ( new Bundle {
210
+ val channel = new D2DSidebandChannelIO (sbParams, fdiParams)
211
+ val dummy_foryou = Output (UInt (128 .W ))
212
+ val dummy_notforyou = Output (UInt (128 .W ))
213
+ })
214
+ val s = Module (new D2DSidebandChannel (BigInt (1 ),sbParams, fdiParams))
215
+ val d = Module (new dummyfactory())
216
+
217
+ s.io <> io.channel
218
+
219
+ io.dummy_foryou := d.io.output_foryou
220
+ io.dummy_notforyou := d.io.output_notforyou
221
+ }
222
+
223
+ class channel_pair_wrapper extends Module {
224
+ val sbParams = new SidebandParams (maxCrd = 1 )
225
+ val fdiParams = new FdiParams (width = 8 , dllpWidth = 8 , sbWidth = 32 )
226
+ val io = IO ( new Bundle {
227
+ val to_D2D = Flipped (new SidebandSwitcherbundle (sbParams))
228
+ val to_PHY = Flipped (new SidebandSwitcherbundle (sbParams))
229
+ val to_upper = new SidebandNodeOuterIO (sbParams, fdiParams)
230
+ val to_lower = new SidebandLinkNodeOuterIO (sbParams, fdiParams)
231
+ val dtop = Output (UInt (128 .W ))
232
+ val ptod = Output (UInt (128 .W ))
233
+ val dtop_cmp = Output (UInt (128 .W ))
234
+ })
235
+ val dietodie_channel = Module (new D2DSidebandChannel (BigInt (1 ),sbParams,fdiParams))
236
+ val phy_channel = Module (new PHYSidebandChannel (BigInt (2 ),sbParams, fdiParams))
237
+ val d = Module (new channelmsgfactory())
238
+
239
+ io.to_D2D <> dietodie_channel.io.inner
240
+ io.to_PHY <> phy_channel.io.inner
241
+
242
+ io.to_upper <> dietodie_channel.io.to_upper_layer
243
+ io.to_lower <> phy_channel.io.to_lower_layer
244
+
245
+ dietodie_channel.io.to_lower_layer.tx <> phy_channel.io.to_upper_layer.rx
246
+ dietodie_channel.io.to_lower_layer.rx <> phy_channel.io.to_upper_layer.tx
247
+
248
+ io.dtop := d.io.dtop
249
+ io.ptod := d.io.ptod
250
+ io.dtop_cmp := d.io.dtop_cmp
251
+ }
252
+
253
+ class channelmsgfactory extends Module {
254
+ val io = IO (new Bundle {
255
+ val dtop = Output (UInt (128 .W ))
256
+ val ptod = Output (UInt (128 .W ))
257
+ val dtop_cmp = Output (UInt (128 .W ))
258
+ })
259
+ io.dtop := SBMessage_factory (SBM .LINK_MGMT_ADAPTER0_REQ_DISABLE , src= " D2D" , remote= false , dst= " PHY" )
260
+ io.ptod := SBMessage_factory (SBM .MBINIT_REVERSALMB_CLEAR_ERROR_REQ , src= " PHY" , remote= false , dst= " D2D" )
261
+ io.dtop_cmp := SBMessage_factory (SBM .COMP_0 , src = " D2D" , remote = false , dst = " PHY" )
262
+ }
0 commit comments