rocket scratchpad: support atomics
This commit is contained in:
		| @@ -498,17 +498,18 @@ class DCache(implicit p: Parameters) extends L1HellaCacheModule()(p) { | |||||||
| } | } | ||||||
|  |  | ||||||
| class ScratchpadSlavePort(implicit val p: Parameters) extends LazyModule with HasCoreParameters { | class ScratchpadSlavePort(implicit val p: Parameters) extends LazyModule with HasCoreParameters { | ||||||
|   val beatBytes = p(XLen)/8 |  | ||||||
|   val node = TLManagerNode(TLManagerPortParameters( |   val node = TLManagerNode(TLManagerPortParameters( | ||||||
|     Seq(TLManagerParameters( |     Seq(TLManagerParameters( | ||||||
|       address            = List(AddressSet(0x80000000L, BigInt(p(DataScratchpadSize)-1))), |       address            = List(AddressSet(0x80000000L, BigInt(p(DataScratchpadSize)-1))), | ||||||
|       regionType         = RegionType.UNCACHED, |       regionType         = RegionType.UNCACHED, | ||||||
|       executable         = true, |       executable         = true, | ||||||
|       supportsPutPartial = TransferSizes(1, beatBytes), |       supportsArithmetic = if (p(UseAtomics)) TransferSizes(1, coreDataBytes) else TransferSizes.none, | ||||||
|       supportsPutFull    = TransferSizes(1, beatBytes), |       supportsLogical    = if (p(UseAtomics)) TransferSizes(1, coreDataBytes) else TransferSizes.none, | ||||||
|       supportsGet        = TransferSizes(1, beatBytes), |       supportsPutPartial = TransferSizes(1, coreDataBytes), | ||||||
|  |       supportsPutFull    = TransferSizes(1, coreDataBytes), | ||||||
|  |       supportsGet        = TransferSizes(1, coreDataBytes), | ||||||
|       fifoId             = Some(0))), // requests handled in FIFO order |       fifoId             = Some(0))), // requests handled in FIFO order | ||||||
|     beatBytes = beatBytes, |     beatBytes = coreDataBytes, | ||||||
|     minLatency = 1)) |     minLatency = 1)) | ||||||
|  |  | ||||||
|   // Make sure this ends up with the same name as before |   // Make sure this ends up with the same name as before | ||||||
| @@ -522,9 +523,7 @@ class ScratchpadSlavePort(implicit val p: Parameters) extends LazyModule with Ha | |||||||
|  |  | ||||||
|     val tl_in = io.tl_in(0) |     val tl_in = io.tl_in(0) | ||||||
|     val edge = node.edgesIn(0) |     val edge = node.edgesIn(0) | ||||||
|     val beatBytes = edge.manager.beatBytes |  | ||||||
|  |  | ||||||
|     require(coreDataBits == beatBytes*8) |  | ||||||
|     require(usingDataScratchpad) |     require(usingDataScratchpad) | ||||||
|  |  | ||||||
|     val s_ready :: s_wait :: s_replay :: s_grant :: Nil = Enum(UInt(), 4) |     val s_ready :: s_wait :: s_replay :: s_grant :: Nil = Enum(UInt(), 4) | ||||||
| @@ -538,15 +537,29 @@ class ScratchpadSlavePort(implicit val p: Parameters) extends LazyModule with Ha | |||||||
|     when (io.dmem.resp.valid) { acq.data := io.dmem.resp.bits.data } |     when (io.dmem.resp.valid) { acq.data := io.dmem.resp.bits.data } | ||||||
|     when (tl_in.a.fire()) { acq := tl_in.a.bits } |     when (tl_in.a.fire()) { acq := tl_in.a.bits } | ||||||
|  |  | ||||||
|     val isWrite = edge.hasData(acq) |     val isWrite = acq.opcode === TLMessages.PutFullData || acq.opcode === TLMessages.PutPartialData | ||||||
|     val isRead = !isWrite |     val isRead = !edge.hasData(acq) | ||||||
|  |  | ||||||
|     def formCacheReq(acq: TLBundleA) = { |     def formCacheReq(acq: TLBundleA) = { | ||||||
|       val req = Wire(new HellaCacheReq) |       val req = Wire(new HellaCacheReq) | ||||||
|  |       req.cmd := MuxLookup(acq.opcode, Wire(M_XRD), Array( | ||||||
|  |         TLMessages.PutFullData    -> M_XWR, | ||||||
|  |         TLMessages.PutPartialData -> M_XWR, | ||||||
|  |         TLMessages.ArithmeticData -> MuxLookup(acq.param, Wire(M_XRD), Array( | ||||||
|  |           TLAtomics.MIN           -> M_XA_MIN, | ||||||
|  |           TLAtomics.MAX           -> M_XA_MAX, | ||||||
|  |           TLAtomics.MINU          -> M_XA_MINU, | ||||||
|  |           TLAtomics.MAXU          -> M_XA_MAXU, | ||||||
|  |           TLAtomics.ADD           -> M_XA_ADD)), | ||||||
|  |         TLMessages.LogicalData    -> MuxLookup(acq.param, Wire(M_XRD), Array( | ||||||
|  |           TLAtomics.XOR           -> M_XA_XOR, | ||||||
|  |           TLAtomics.OR            -> M_XA_OR, | ||||||
|  |           TLAtomics.AND           -> M_XA_AND, | ||||||
|  |           TLAtomics.SWAP          -> M_XA_SWAP)), | ||||||
|  |         TLMessages.Get            -> M_XRD)) | ||||||
|       // treat all loads as full words, so bytes appear in correct lane |       // treat all loads as full words, so bytes appear in correct lane | ||||||
|       req.typ := Mux(isRead, log2Ceil(beatBytes), acq.size) |       req.typ := Mux(isRead, log2Ceil(coreDataBytes), acq.size) | ||||||
|       req.cmd := Mux(isRead, M_XRD, M_XWR) |       req.addr := Mux(isRead, ~(~acq.address | (coreDataBytes-1)), acq.address) | ||||||
|       req.addr := Mux(isRead, ~(~acq.address | (beatBytes-1)), acq.address) |  | ||||||
|       req.tag := UInt(0) |       req.tag := UInt(0) | ||||||
|       req |       req | ||||||
|     } |     } | ||||||
| @@ -555,9 +568,9 @@ class ScratchpadSlavePort(implicit val p: Parameters) extends LazyModule with Ha | |||||||
|     io.dmem.req.valid := (tl_in.a.valid && ready) || state === s_replay |     io.dmem.req.valid := (tl_in.a.valid && ready) || state === s_replay | ||||||
|     tl_in.a.ready := io.dmem.req.ready && ready |     tl_in.a.ready := io.dmem.req.ready && ready | ||||||
|     io.dmem.req.bits := formCacheReq(Mux(state === s_replay, acq, tl_in.a.bits)) |     io.dmem.req.bits := formCacheReq(Mux(state === s_replay, acq, tl_in.a.bits)) | ||||||
|     // this blows.  the TL data is already in the correct byte lane, but the D$ |     // the TL data is already in the correct byte lane, but the D$ | ||||||
|     // expects right-justified store data, so that it can steer the bytes. |     // expects right-justified store data, so that it can steer the bytes. | ||||||
|     io.dmem.s1_data := new LoadGen(acq.size, Bool(false), acq.address(log2Ceil(beatBytes)-1,0), acq.data, Bool(false), beatBytes).data |     io.dmem.s1_data := new LoadGen(acq.size, Bool(false), acq.address(log2Ceil(coreDataBytes)-1,0), acq.data, Bool(false), coreDataBytes).data | ||||||
|     io.dmem.s1_kill := false |     io.dmem.s1_kill := false | ||||||
|     io.dmem.invalidate_lr := false |     io.dmem.invalidate_lr := false | ||||||
|  |  | ||||||
| @@ -567,9 +580,10 @@ class ScratchpadSlavePort(implicit val p: Parameters) extends LazyModule with Ha | |||||||
|     val alignedGrantData = Mux(acq.size <= log2Ceil(minAMOBytes), Fill(coreDataBytes/minAMOBytes, grantData(8*minAMOBytes-1, 0)), grantData) |     val alignedGrantData = Mux(acq.size <= log2Ceil(minAMOBytes), Fill(coreDataBytes/minAMOBytes, grantData(8*minAMOBytes-1, 0)), grantData) | ||||||
|  |  | ||||||
|     tl_in.d.valid := io.dmem.resp.valid || state === s_grant |     tl_in.d.valid := io.dmem.resp.valid || state === s_grant | ||||||
|     tl_in.d.bits := Mux(isRead, |     tl_in.d.bits := Mux(isWrite, | ||||||
|       edge.AccessAck(acq, UInt(0), alignedGrantData), |       edge.AccessAck(acq, UInt(0)), | ||||||
|       edge.AccessAck(acq, UInt(0))) |       edge.AccessAck(acq, UInt(0), UInt(0))) | ||||||
|  |     tl_in.d.bits.data := alignedGrantData | ||||||
|  |  | ||||||
|     // Tie off unused channels |     // Tie off unused channels | ||||||
|     tl_in.b.valid := Bool(false) |     tl_in.b.valid := Bool(false) | ||||||
|   | |||||||
| @@ -61,7 +61,7 @@ class RocketTile(implicit p: Parameters) extends LazyTile { | |||||||
|   val slave = if (p(DataScratchpadSize) == 0) None else Some(TLInputNode()) |   val slave = if (p(DataScratchpadSize) == 0) None else Some(TLInputNode()) | ||||||
|   val scratch = if (p(DataScratchpadSize) == 0) None else Some(LazyModule(new ScratchpadSlavePort()(dcacheParams))) |   val scratch = if (p(DataScratchpadSize) == 0) None else Some(LazyModule(new ScratchpadSlavePort()(dcacheParams))) | ||||||
|  |  | ||||||
|   (slave zip scratch) foreach { case (node, lm) => lm.node := TLFragmenter(p(XLen)/8, 256)(node) } |   (slave zip scratch) foreach { case (node, lm) => lm.node := TLFragmenter(p(XLen)/8, p(CacheBlockBytes))(node) } | ||||||
|  |  | ||||||
|   lazy val module = new TileImp(this) { |   lazy val module = new TileImp(this) { | ||||||
|     val io = new TileIO(bc, slave) |     val io = new TileIO(bc, slave) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user