@@ -7,15 +7,8 @@ import chisel3.util._
7
7
// 1. use lower-bits of set to select bank
8
8
// 2. split ways and parallel access
9
9
// 3. split data and parallel access
10
+ // * a simple graph is shown below
10
11
11
- // * an example of "setSplit 2, waySplit 2, dataSplit 4"
12
- // ==================================================================
13
- // |- way 0 -- [data 0] [data 1] [data 2] [data 3]
14
- // set[0] == 0.U -> |- way 1 -- [data 0] [data 1] [data 2] [data 3]
15
- // ------------------------------------------------------------------
16
- // set[0] == 1.U -> |- way 0 -- [data 0] [data 1] [data 2] [data 3]
17
- // |- way 1 -- [data 0] [data 1] [data 2] [data 3]
18
- // ==================================================================
19
12
class SplittedSRAM [T <: Data ]
20
13
(
21
14
gen : T , sets : Int , ways : Int ,
@@ -69,7 +62,8 @@ class SplittedSRAM[T <: Data]
69
62
array(i)(j)(k).io.r.req.bits.apply(r_setIdx)
70
63
array(i)(j)(k).io.w.req.valid := io.w.req.valid && wen // && needWrite
71
64
array(i)(j)(k).io.w.req.bits.apply(
72
- io.w.req.bits.data.asUInt(innerWidth * (k+ 1 ) - 1 , innerWidth * k), w_setIdx, waymask
65
+ VecInit (io.w.req.bits.data.slice(innerWays * j, innerWays * (j+ 1 )).map(_.asUInt(innerWidth * (k+ 1 ) - 1 , innerWidth * k))),
66
+ w_setIdx, waymask
73
67
)
74
68
}
75
69
}
@@ -86,21 +80,36 @@ class SplittedSRAM[T <: Data]
86
80
87
81
// TODO: we should consider the readys of all sram to be accessed, and orR them
88
82
// but since waySplitted and dataSplitted smaller srams should have the same behavior
89
- // we can just use one of them for ready, for better timing
83
+ // we just use one of them for ready, for better timing
90
84
io.r.req.ready := VecInit ((0 until setSplit).map(i => array(i).head.head.io.r.req.ready))(r_bankSel)
91
85
io.w.req.ready := VecInit ((0 until setSplit).map(i => array(i).head.head.io.w.req.ready))(w_bankSel)
92
86
93
87
94
- // aggregate data first, then way, finally use set to select
95
- val rdata = Mux1H (ren_vec,
96
- (0 until setSplit).map(i =>
97
- (0 until waySplit).map(j =>
98
- (0 until innerWays).map(w =>
99
- Cat ((0 until dataSplit).map(k => array(i)(j)(k).io.r.resp.data(w)).reverse)
100
- )
101
- ).flatten
102
- ).flatten
88
+ // * an example of "setSplit 2, waySplit 2, dataSplit 4" of an SRAM with way 2 *
89
+ // =========================================================================================
90
+ // / way 0 -- [data 3] | [data 2] | [data 1] | [data 0]
91
+ // set[0] == 0.U -> waySplit 0 |- way 1 -- [data 3] | [data 2] | [data 1] | [data 0]
92
+ // -----------------------------------------------------------------------------------------
93
+ // waySplit 1 |- way 0 -- [data 3] | [data 2] | [data 1] | [data 0]
94
+ // \ way 1 -- [data 3] | [data 2] | [data 1] | [data 0]
95
+ // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
96
+ // / way 0 -- [data 3] | [data 2] | [data 1] | [data 0]
97
+ // set[0] == 0.U -> waySplit 0 |- way 1 -- [data 3] | [data 2] | [data 1] | [data 0]
98
+ // -----------------------------------------------------------------------------------------
99
+ // waySplit 1 |- way 0 -- [data 3] | [data 2] | [data 1] | [data 0]
100
+ // \ way 1 -- [data 3] | [data 2] | [data 1] | [data 0]
101
+ // =========================================================================================
102
+ // 1. aggregate data of the same line first
103
+ // 2. collect all data lines in the same `WaySplit`
104
+ // 3. use flatMap to collect all `WaySplit`, and we can get the targetData (Vec[T])
105
+ // 4. use ren_vec to select the certain set
106
+ val allData = (0 until setSplit).map(i =>
107
+ VecInit ((0 until waySplit).flatMap(j =>
108
+ (0 until innerWays).map(w =>
109
+ Cat ((0 until dataSplit).map(k => array(i)(j)(k).io.r.resp.data(w)).reverse)
110
+ )
111
+ ))
103
112
)
104
113
105
- io.r.resp.data := VecInit ( Seq .fill(ways)(rdata .asTypeOf(gen) ))
114
+ io.r.resp.data := Mux1H (ren_vec, allData) .asTypeOf(Vec (ways, gen))
106
115
}
0 commit comments