@@ -16,7 +16,6 @@ class AsyncDequeueIO[T <: Data](gen: T) extends Bundle {
16
16
val sink : DecoupledIO [T ] = Decoupled (gen)
17
17
}
18
18
19
-
20
19
/** Memory used for queue.
21
20
* In ASIC, it will be synthesised to Flip-Flop
22
21
*
@@ -53,32 +52,29 @@ class DataMemory[T <: Data](gen: T, depth: Int, narrow: Boolean) extends RawModu
53
52
}
54
53
}
55
54
56
-
57
55
/** Sink of [[AsyncQueue ]] constructor.
58
56
*
59
57
* @tparam T Hardware type to be converted.
60
58
* @note SRAM-based clock-domain-crossing source.
61
59
*/
62
- class AsyncQueueSink [T <: Data ](gen : T , depth : Int , sync : Int , safe : Boolean = true , narrow : Boolean = true ) extends MultiIOModule {
60
+ class AsyncQueueSink [T <: Data ](gen : T , depth : Int , sync : Int , narrow : Boolean = true ) extends MultiIOModule {
63
61
require(depth > 0 && isPow2(depth), " todo" )
64
62
require(sync >= 2 , " todo" )
65
63
private val depthWidth : Int = log2Ceil(depth)
66
64
/** Dequeue Decoupled IO. */
67
65
val dequeue : DecoupledIO [T ] = IO (Decoupled (gen))
68
66
69
- val sourceReady : Option [Bool ] = if (safe) Some (IO (Input (Bool ()))) else None
70
-
71
- val readIndexGray : UInt = withReset(reset.asAsyncReset())(grayCounter(depthWidth + 1 , dequeue.fire(), ! sourceReady.getOrElse(true .B ), " readIndex" ))
67
+ val readIndexGray : UInt = withReset(reset.asAsyncReset())(grayCounter(depthWidth + 1 , dequeue.fire(), false .B , " readIndex" ))
72
68
val readIndexGrayReg : UInt = withReset(reset.asAsyncReset())(RegNext (next = readIndexGray, init = 0 .U ).suggestName(" readIndexReg" ))
73
69
val writeIndexGray : UInt = IO (Input (UInt ((depthWidth + 1 ).W )))
74
70
75
71
/** ready signal to indicate [[DecoupledIO ]] this queue is not empty, can still dequeue new data. */
76
72
val empty : Bool = readIndexGray === writeIndexGray
77
- val valid : Bool = sourceReady.getOrElse( true . B ) && ! empty
73
+ val valid : Bool = ! empty
78
74
val validReg : Bool = withReset(reset.asAsyncReset())(RegNext (next = valid, init = false .B ).suggestName(" validReg" ))
79
75
80
76
// dequeue to [[DecoupledIO]]
81
- dequeue.valid := validReg && sourceReady.getOrElse( true . B )
77
+ dequeue.valid := validReg
82
78
83
79
// port to access memory
84
80
val readEnable : Bool = IO (Output (Bool ()))
@@ -109,26 +105,24 @@ class AsyncQueueSink[T <: Data](gen: T, depth: Int, sync: Int, safe: Boolean = t
109
105
* @todo make sync optional, if None use async logic.
110
106
* add some verification codes.
111
107
*/
112
- class AsyncQueueSource [T <: Data ](gen : T , depth : Int , sync : Int , safe : Boolean , narrow : Boolean ) extends MultiIOModule {
108
+ class AsyncQueueSource [T <: Data ](gen : T , depth : Int , sync : Int ) extends MultiIOModule {
113
109
require(depth > 0 && isPow2(depth), " todo" )
114
110
require(sync >= 2 , " todo" )
115
111
private val depthWidth : Int = log2Ceil(depth)
116
112
/** Enqueue Decoupled IO. */
117
113
val enqueue : DecoupledIO [T ] = IO (Flipped (Decoupled (gen)))
118
114
119
- val sinkReady : Option [Bool ] = if (safe) Some (IO (Input (Bool ()))) else None
120
-
121
- val writeIndexGray : UInt = withReset(reset.asAsyncReset())(grayCounter(depthWidth + 1 , enqueue.fire(), ! sinkReady.getOrElse(true .B ), " writeIndex" ))
115
+ val writeIndexGray : UInt = withReset(reset.asAsyncReset())(grayCounter(depthWidth + 1 , enqueue.fire(), false .B , " writeIndex" ))
122
116
val writeIndexGrayReg : UInt = withReset(reset.asAsyncReset())(RegNext (next = writeIndexGray, init = 0 .U ).suggestName(" writeIndexReg" ))
123
117
val readIndexGray : UInt = IO (Input (UInt ((depthWidth + 1 ).W )))
124
118
125
119
/** ready signal to indicate [[DecoupledIO ]] this queue is not full, can still enqueue new data. */
126
120
val full : Bool = writeIndexGray === (readIndexGray ^ (depth | depth >> 1 ).U )
127
- val ready : Bool = sinkReady.getOrElse( true . B ) && ! full
121
+ val ready : Bool = ! full
128
122
val readyReg : Bool = withReset(reset.asAsyncReset())(RegNext (next = ready, init = false .B ).suggestName(" readyReg" ))
129
123
130
124
// enqueue from [[DecoupledIO]]
131
- enqueue.ready := readyReg && sinkReady.getOrElse( true . B )
125
+ enqueue.ready := readyReg
132
126
133
127
// port to access memory
134
128
val writeEnable : Bool = IO (Output (Bool ()))
@@ -139,7 +133,6 @@ class AsyncQueueSource[T <: Data](gen: T, depth: Int, sync: Int, safe: Boolean,
139
133
writeIndex := writeIndexGrayReg(depthWidth, 0 )
140
134
}
141
135
142
-
143
136
/** cross-clock-domain syncing asynchronous queue.
144
137
*
145
138
* @note [[AsyncQueueSource.writeIndexGray ]] and [[AsyncQueueSink.readIndexGray ]] will be synced to each other.
@@ -152,15 +145,15 @@ class AsyncQueueSource[T <: Data](gen: T, depth: Int, sync: Int, safe: Boolean,
152
145
* }}}
153
146
*
154
147
*/
155
- class AsyncQueue [T <: Data ](gen : T , depth : Int = 8 , sync : Int = 3 , narrow : Boolean = true , safe : Boolean = true ) extends MultiIOModule {
148
+ class AsyncQueue [T <: Data ](gen : T , depth : Int = 8 , sync : Int = 3 , narrow : Boolean = true ) extends MultiIOModule {
156
149
val enqueue : AsyncEnqueueIO [T ] = IO (new AsyncEnqueueIO (gen))
157
150
val sourceModule : AsyncQueueSource [T ] =
158
- withClockAndReset(enqueue.clock, enqueue.reset)(Module (new AsyncQueueSource (gen, depth, sync, safe, narrow )))
151
+ withClockAndReset(enqueue.clock, enqueue.reset)(Module (new AsyncQueueSource (gen, depth, sync)))
159
152
sourceModule.enqueue <> enqueue.source
160
153
161
154
val dequeue : AsyncDequeueIO [T ] = IO (new AsyncDequeueIO (gen))
162
155
val sinkModule : AsyncQueueSink [T ] =
163
- withClockAndReset(enqueue.clock, enqueue.reset)(Module (new AsyncQueueSink (gen, depth, sync, safe, narrow)))
156
+ withClockAndReset(enqueue.clock, enqueue.reset)(Module (new AsyncQueueSink (gen, depth, sync, narrow)))
164
157
dequeue.sink <> sinkModule.dequeue
165
158
166
159
// read/write index bidirectional sync
@@ -194,35 +187,4 @@ class AsyncQueue[T <: Data](gen: T, depth: Int = 8, sync: Int = 3, narrow: Boole
194
187
sinkFullData := withClock(dequeue.clock)(RegNext (memoryFullData))
195
188
case _ =>
196
189
}
197
-
198
- // reset sync to clear internal gray code index.
199
- private def resetSync (clock : Clock , desc : String )(in : Bool ): Bool = withClockAndReset(clock, (enqueue.reset || dequeue.reset).asAsyncReset()) {
200
- val shiftRegisters : Seq [Bool ] = ShiftRegisters (in, sync, false .B , true .B )
201
- group(shiftRegisters, s " ${desc}Module " , desc)
202
- shiftRegisters.last
203
- }
204
-
205
- sinkModule.sourceReady.foreach(_ :=
206
- resetSync(dequeue.clock, " sinkValid" )(
207
- resetSync(dequeue.clock, " sinkExtend" )(
208
- resetSync(enqueue.clock, " sinkValid1" )(
209
- resetSync(enqueue.clock, " sinkValid0" )(
210
- true .B
211
- )
212
- )
213
- )
214
- )
215
- )
216
-
217
- sourceModule.sinkReady.foreach(_ :=
218
- resetSync(enqueue.clock, " sourceValid" )(
219
- resetSync(enqueue.clock, " sourceExtend" )(
220
- resetSync(dequeue.clock, " sourceValid1" )(
221
- resetSync(dequeue.clock, " sourceValid0" )(
222
- true .B
223
- )
224
- )
225
- )
226
- )
227
- )
228
190
}
0 commit comments