@@ -139,7 +139,7 @@ class SRAMTemplate[T <: Data](
139
139
gen : T , set : Int , way : Int = 1 , singlePort : Boolean = false ,
140
140
shouldReset : Boolean = false , extraReset : Boolean = false ,
141
141
holdRead : Boolean = false , bypassWrite : Boolean = false ,
142
- useBitmask : Boolean = false ,
142
+ useBitmask : Boolean = false , withClockGate : Boolean = false ,
143
143
) extends Module {
144
144
val io = IO (new Bundle {
145
145
val r = Flipped (new SRAMReadBus (gen, set, way))
@@ -171,6 +171,19 @@ class SRAMTemplate[T <: Data](
171
171
val (ren, wen) = (io.r.req.valid, io.w.req.valid || resetState)
172
172
val realRen = (if (singlePort) ren && ! wen else ren)
173
173
174
+ val maskedRClock = Wire (Clock ())
175
+ val maskedWClock = Wire (Clock ())
176
+
177
+ if (singlePort) {
178
+ // To ensure the generation of single-port SRAM, the RCLK and WCLK must be the same.
179
+ val maskedClock = ClockGate (false .B , ren || wen, clock)
180
+ maskedRClock := maskedClock
181
+ maskedWClock := maskedClock
182
+ } else {
183
+ maskedRClock := ClockGate (false .B , ren, clock)
184
+ maskedWClock := ClockGate (false .B , wen, clock)
185
+ }
186
+
174
187
val setIdx = Mux (resetState, resetSet, io.w.req.bits.setIdx)
175
188
val wdata = Mux (resetState, 0 .U .asTypeOf(Vec (way, gen)), io.w.req.bits.data).
176
189
asTypeOf(Vec (arrayPortSize, arrayType))
@@ -179,17 +192,29 @@ class SRAMTemplate[T <: Data](
179
192
if (! useBitmask) {
180
193
val waymask = Mux (resetState, Fill (way, " b1" .U ), io.w.req.bits.waymask.getOrElse(" b1" .U ))
181
194
when(wen) {
182
- array.write(setIdx, wdata, waymask.asBools)
195
+ if (withClockGate) {
196
+ array.write(setIdx, wdata, waymask.asBools, maskedWClock)
197
+ } else {
198
+ array.write(setIdx, wdata, waymask.asBools)
199
+ }
183
200
}
184
201
} else {
185
202
val bitmask = Mux (resetState, Fill (way * gen.getWidth, " b1" .U ), io.w.req.bits.flattened_bitmask.getOrElse(" b1" .U ))
186
203
when(wen) {
187
- array.write(setIdx, wdata, bitmask.asBools)
204
+ if (withClockGate) {
205
+ array.write(setIdx, wdata, bitmask.asBools, maskedWClock)
206
+ } else {
207
+ array.write(setIdx, wdata, bitmask.asBools)
208
+ }
188
209
}
189
210
}
190
211
191
212
// Memory read
192
- val raw_rdata = array.read(io.r.req.bits.setIdx, realRen).asTypeOf(Vec (way, wordType))
213
+ val raw_rdata = if (withClockGate) {
214
+ array.read(io.r.req.bits.setIdx, realRen, maskedRClock).asTypeOf(Vec (way, wordType))
215
+ } else {
216
+ array.read(io.r.req.bits.setIdx, realRen).asTypeOf(Vec (way, wordType))
217
+ }
193
218
require(wdata.getWidth == raw_rdata.getWidth)
194
219
195
220
// bypass for dual-port SRAMs
@@ -229,6 +254,7 @@ class FoldedSRAMTemplate[T <: Data](
229
254
shouldReset : Boolean = false , extraReset : Boolean = false ,
230
255
holdRead : Boolean = false , singlePort : Boolean = false ,
231
256
bypassWrite : Boolean = false , useBitmask : Boolean = false ,
257
+ withClockGate : Boolean = false ,
232
258
) extends Module {
233
259
val io = IO (new Bundle {
234
260
val r = Flipped (new SRAMReadBus (gen, set, way))
@@ -246,7 +272,8 @@ class FoldedSRAMTemplate[T <: Data](
246
272
247
273
val array = Module (new SRAMTemplate (gen, set= nRows, way= width* way,
248
274
shouldReset= shouldReset, extraReset= extraReset, holdRead= holdRead,
249
- singlePort= singlePort, bypassWrite= bypassWrite, useBitmask= useBitmask))
275
+ singlePort= singlePort, bypassWrite= bypassWrite, useBitmask= useBitmask,
276
+ withClockGate= withClockGate))
250
277
if (array.extra_reset.isDefined) {
251
278
array.extra_reset.get := extra_reset.get
252
279
}
0 commit comments