@@ -38,15 +38,15 @@ class MEMRESPIO extends Bundle {
3838 val id = UInt (CacheConfig .IdLen .W )
3939}
4040
41- class WayIn (val tagWidth : Int , val idxWidth : Int , val offsetWidth : Int ) extends Bundle {
41+ class WAYINIO (val tagWidth : Int , val idxWidth : Int , val offsetWidth : Int ) extends Bundle {
4242 val wt = Valid (new Bundle {
4343 val tag = UInt (tagWidth.W )
4444 val idx = UInt (idxWidth.W )
4545 val offset = UInt (offsetWidth.W )
4646 val v = UInt (1 .W )
4747 val d = UInt (1 .W )
4848 val mask = UInt (((CacheConfig .LineSize / CacheConfig .NBank ) / 8 ).W )
49- val data = UInt (p( XLen ) .W )
49+ val data = UInt (64 .W )
5050 val op = UInt (1 .W ) // must 1
5151 })
5252 val rd = Valid (new Bundle {
@@ -55,13 +55,69 @@ class WayIn(val tagWidth: Int, val idxWidth: Int, val offsetWidth: Int) extends
5555 })
5656}
5757
58- class WayOut (val tagWidth : Int ) extends Bundle {
58+ class WAYOUTIO (val tagWidth : Int ) extends Bundle {
5959 val tag = UInt (tagWidth.W )
6060 val v = UInt (1 .W )
6161 val d = UInt (1 .W )
6262 val data = Vec (CacheConfig .NBank , UInt ((CacheConfig .LineSize / CacheConfig .NBank ).W ))
6363}
6464
65+ class Way (val tagWidth : Int , val idxWidth : Int , val offsetWidth : Int ) extends Module {
66+ val io = IO (new Bundle {
67+ val fence_invalid = Input (Bool ())
68+ val in = Flipped (new WAYINIO (tagWidth, idxWidth, offsetWidth))
69+ val out = Valid (new WAYOUTIO (tagWidth))
70+ })
71+
72+ val tag = UInt (tagWidth.W ) // tag
73+ val v = UInt (1 .W ) // valid
74+ val dirty = UInt (1 .W )
75+ val depth = math.pow(2 , idxWidth).toInt
76+
77+ val tagTable = SyncReadMem (depth, tag)
78+ val vTable = RegInit (VecInit (Seq .fill(depth)(0 .U (1 .W ))))
79+ val dirtyTable = RegInit (VecInit (Seq .fill(depth)(0 .U (1 .W ))))
80+ // nBank * (n * 8bit)
81+ val bankn = List .fill(CacheConfig .NBank )(SyncReadMem (depth, Vec ((CacheConfig .LineSize / CacheConfig .NBank ) / 8 , UInt (8 .W ))))
82+
83+ val result = WireInit (0 .U .asTypeOf(new WAYOUTIO (tagWidth)))
84+
85+ // read logic
86+ // TODO: check data order in simulator
87+ // tag,v, d, data
88+ result := Cat (
89+ List (tagTable.read(io.in.rd.bits.idx, io.in.rd.valid).asUInt()) ++ Seq (RegNext (vTable(io.in.rd.bits.idx), 0 .U (1 .W )), RegNext (dirtyTable(io.in.rd.bits.idx), 0 .U (1 .W ))) ++
90+ bankn.map(_.read(io.in.rd.bits.idx, io.in.rd.valid).asUInt())
91+ ).asTypeOf(new WAYOUTIO (tagWidth))
92+
93+ io.out.bits := result
94+ io.out.valid := RegNext (io.in.rd.valid, 0 .U )
95+ dontTouch(io.out.valid)
96+
97+ // write logic
98+ // write bank data
99+ val bank_sel = WireInit (io.in.wt.bits.offset(log2Ceil(64 / 8 ) + log2Ceil(CacheConfig .NBank ) - 1 , log2Ceil(64 / 8 )))
100+ val wdata = io.in.wt.bits.data.asTypeOf(Vec (CacheConfig .LineSize / CacheConfig .NBank / 8 , UInt (8 .W )))
101+ when(io.in.wt.fire()) {
102+ when(io.in.wt.bits.op === 1 .U ) {
103+ // write tag,v
104+ tagTable.write(io.in.wt.bits.idx, io.in.wt.bits.tag)
105+ vTable(io.in.wt.bits.idx) := io.in.wt.bits.v
106+ // write d
107+ dirtyTable(io.in.wt.bits.idx) := io.in.wt.bits.d
108+ // write data
109+ bankn.zipWithIndex.foreach((a) => {
110+ val (bank, i) = a
111+ when(bank_sel === i.U ) {
112+ bank.write(io.in.wt.bits.idx, wdata, io.in.wt.bits.mask.asBools())
113+ }
114+ })
115+ }
116+ }.elsewhen(io.fence_invalid) {
117+ vTable := VecInit (Seq .fill(depth)(0 .U (1 .W )))
118+ }
119+ }
120+
65121class CACHE2CPUIO extends Bundle {
66122 val req = Flipped (Decoupled (new CACHEREQIO ))
67123 val resp = Valid (new CACHERESPIO )
0 commit comments