Skip to content

Commit c721862

Browse files
committed
2 parents 82f9d37 + 8708c6a commit c721862

12 files changed

Lines changed: 72 additions & 29 deletions

File tree

docs/isa.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,12 @@ to the value of `rs2` of the "leader" lane, i.e. the left-most active lane.
252252
vx_spawn rs1, rs2
253253
```
254254

255-
Activates warps 1 up to the value of `rs1` in the "leader" lane, if not already active. Has no effect on warp 0.
256-
Sets `PC` of newly active warps to the value of `rs2` in the "leader" lane. Sets tmask of newly active warps to all 1's.
255+
Activates warps `[0, rs1)`, except the warp that executed this instruction, and
256+
sets their `PC` to `rs2`. Sets tmask of newly active warps to all 1's.
257+
The values of `rs1` and `rs2` are taken from the "leader" lane.
257258

258-
Note: this will eventually be superceded by command processor + neutrino
259+
Note: `vx_wspawn` eventually be superceded by command processor's scheduling
260+
capabilities.
259261

260262
## New Registers
261263

src/main/resources/csrc/Cyclotron.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,8 @@ void cyclotron_trace(
597597

598598
void cyclotron_difftest_reg_rs(
599599
const uint8_t trace_sim_tick,
600+
const uint32_t cluster_id,
601+
const uint32_t core_id,
600602
const uint8_t trace_valid,
601603
const uint32_t trace_pc,
602604
const uint32_t trace_warpId,
@@ -614,6 +616,8 @@ void cyclotron_difftest_reg_rs(
614616

615617
void cyclotron_difftest_reg(
616618
const uint8_t trace_sim_tick,
619+
const uint32_t cluster_id,
620+
const uint32_t core_id,
617621
const uint8_t trace_valid,
618622
const uint32_t trace_pc,
619623
const uint32_t trace_warpId,
@@ -630,6 +634,8 @@ void cyclotron_difftest_reg(
630634
) {
631635
cyclotron_difftest_reg_rs(
632636
trace_sim_tick,
637+
cluster_id,
638+
core_id,
633639
trace_valid,
634640
trace_pc,
635641
trace_warpId,

src/main/resources/vsrc/CyclotronDiffTest.v

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
module CyclotronDiffTestBlackBox #(
2+
parameter CLUSTER_ID = 0,
3+
parameter CORE_ID = 0,
24
parameter ARCH_LEN = 32,
35
parameter INST_BITS = 64,
46
parameter NUM_WARPS = 8,
@@ -37,6 +39,8 @@ module CyclotronDiffTestBlackBox #(
3739

3840
import "DPI-C" function cyclotron_difftest_reg(
3941
input bit trace_sim_tick,
42+
input int cluster_id,
43+
input int core_id,
4044
input bit trace_valid,
4145
input int trace_pc,
4246
input int trace_warpId,
@@ -73,6 +77,8 @@ module CyclotronDiffTestBlackBox #(
7377
end else begin
7478
cyclotron_difftest_reg(
7579
SIM_TICK,
80+
CLUSTER_ID,
81+
CORE_ID,
7682
trace_valid,
7783
trace_pc,
7884
trace_warpId,

src/main/scala/radiance/muon/Backend.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,10 +226,10 @@ class Backend(implicit p: Parameters) extends CoreModule()(p) {
226226
collector.io.writeReq.bits.regs.head.enable := exRegWbFire
227227
collector.io.writeReq.bits.regs.head.pReg := exRegWb.bits.rd
228228
collector.io.writeReq.bits.regs.head.data.get := exRegWb.bits.data
229+
collector.io.writeReq.bits.regs.head.tmask.get := exRegWb.bits.tmask
229230
collector.io.writeReq.bits.pc.foreach(_ := 0.U /* bogus */)
230231
collector.io.writeReq.bits.rsEntryId := 0.U // TODO: writes don't need to allocate RS entry; remove this
231232
collector.io.writeReq.valid := collector.io.writeReq.bits.anyEnabled()
232-
// TODO: tmask
233233
dontTouch(collector.io)
234234

235235
// debug

src/main/scala/radiance/muon/Collector.scala

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ class CollectorRequest(
1212
val regs = Vec(numPorts, new Bundle {
1313
val enable = Bool()
1414
val pReg = pRegT
15+
val tmask = Option.when(isWrite)(tmaskT)
1516
val data = Option.when(isWrite)(Vec(numLanes, regDataT))
16-
// TODO: tmask
1717
})
1818
val rsEntryId = UInt(rsEntryIdWidth.W)
1919
val pc = Option.when(muonParams.debug)(pcT)
@@ -39,7 +39,6 @@ class CollectorResponse(
3939
val collEntry = UInt(collEntryWidth.W)
4040
val regs = Vec(numPorts, new Bundle {
4141
val enable = Bool()
42-
// TODO: tmask
4342
})
4443
}
4544

@@ -58,14 +57,14 @@ class CollectorOperandRead(implicit p: Parameters) extends CoreBundle()(p) {
5857
val collEntry = UInt(collEntryWidth.W)
5958
val regs = Vec(Isa.maxNumRegs, new Bundle {
6059
val enable = Bool()
60+
// TODO: tmask for @power
6161
})
6262
}))
6363
// same-cycle as `req`
6464
val resp = Valid(Vec(Isa.maxNumRegs, new Bundle {
6565
val enable = Bool()
6666
val pReg = Option.when(hasPReg)(pRegT)
6767
val data = Vec(numLanes, regDataT)
68-
// TODO: tmask
6968
}))
7069
}
7170

@@ -92,7 +91,7 @@ class DuplicatedCollector(implicit p: Parameters) extends CoreModule()(p) {
9291

9392
def vecRegDataT = Vec(numLanes, regDataT)
9493
val vecZeros = 0.U.asTypeOf(vecRegDataT)
95-
val rfBanks = Seq.fill(Isa.maxNumRegs)(Seq.fill(muonParams.numRegBanks)(SRAM(
94+
val rfBanks = Seq.fill(Isa.maxNumRegs)(Seq.fill(muonParams.numRegBanks)(SRAM.masked(
9695
size = muonParams.numPhysRegs / muonParams.numRegBanks,
9796
tpe = vecRegDataT,
9897
numReadPorts = 1,
@@ -166,7 +165,13 @@ class DuplicatedCollector(implicit p: Parameters) extends CoreModule()(p) {
166165
val regOut = Mux(nextPReg =/= 0.U,
167166
VecInit(bankPorts.map(_.data))(nextBankId),
168167
vecZeros)
169-
// TODO: @perf: Skip latching 0.U to collBank
168+
169+
// latch SRAM output to collector banks
170+
//
171+
// TODO: @power: Respect readReq.tmask, and latch 0.U for inactive lanes.
172+
// Currently the downstream EX does the right thing even when the
173+
// collector supplies garbage values for inactive lanes, but this is
174+
// better for power.
170175
collBank.zipWithIndex.foreach { case (entry, i) =>
171176
when (nextEn && (i.U === nextAllocId)) {
172177
entry := regOut
@@ -189,14 +194,19 @@ class DuplicatedCollector(implicit p: Parameters) extends CoreModule()(p) {
189194
io.writeReq.ready := true.B
190195
val writeEnable = io.writeReq.fire && io.writeReq.bits.regs.head.enable
191196
val writePReg = io.writeReq.bits.regs.head.pReg
197+
val writeTmask = io.writeReq.bits.regs.head.tmask.get
192198
val writeData = io.writeReq.bits.regs.head.data.get
193-
// write to all of rs1/2/3 banks
199+
// broadcast write to all of rs1/2/3 banks
194200
rfBanks.foreach { case banks =>
195201
val bankWrites = VecInit(banks.map(_.writePorts.head))
196-
bankWrites.foreach { b =>
197-
b.address := regBankAddr(writePReg)
198-
b.data := writeData
199-
b.enable := false.B
202+
bankWrites.foreach { port =>
203+
port.address := regBankAddr(writePReg)
204+
port.data := writeData
205+
assert(port.mask.isDefined, "RegFile SRAM must be masked")
206+
assert(port.mask.get.length == writeTmask.getWidth,
207+
"RegFile SRAM mask width does not match tmask width")
208+
port.mask.get := VecInit(writeTmask.asBools)
209+
port.enable := false.B
200210
}
201211
bankWrites(regBankId(writePReg)).enable := writeEnable && (writePReg =/= 0.U)
202212
}

src/main/scala/radiance/muon/MuonTile.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,11 @@ class MuonTileModuleImp(outer: MuonTile) extends BaseTileModuleImp(outer) {
405405
// RTL-model difftest
406406
if (core.muonParams.difftest) {
407407
assert(isSim, "muon traces cannot enabled in non-sim mode!")
408-
val cdiff = Module(new CyclotronDiffTest(tick = true))
408+
val cdiff = Module(new CyclotronDiffTest(
409+
clusterId = outer.muonParams.clusterId,
410+
coreId = outer.muonParams.coreId,
411+
tick = true
412+
))
409413
cdiff.io.trace <> core.io.trace.get
410414
}
411415
}

src/main/scala/radiance/muon/ReservationStation.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,11 @@ class ReservationStation(implicit p: Parameters) extends CoreModule()(p) {
172172
io.collector.readReq.valid := collValid
173173
// this is clunky, but Mem does not support partial-field updates
174174
(collOpNeed lazyZip collRegs lazyZip io.collector.readReq.bits.regs)
175-
.zipWithIndex.foreach { case ((need, pReg, cReq), rsi) =>
176-
assert(cReq.data.isEmpty) // isRead
177-
cReq.enable := collValid && need
178-
cReq.pReg := Mux(need, pReg, 0.U)
175+
.zipWithIndex.foreach { case ((need, pReg, readReqReg), rsi) =>
176+
assert(readReqReg.data.isEmpty) // isRead
177+
assert(readReqReg.tmask.isEmpty) // isRead
178+
readReqReg.enable := collValid && need
179+
readReqReg.pReg := Mux(need, pReg, 0.U)
179180
}
180181
io.collector.readReq.bits.rsEntryId := collRow
181182
io.collector.readReq.bits.pc.foreach(_ := collPC)

src/main/scala/radiance/muon/WarpScheduler.scala

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -275,18 +275,19 @@ class WarpScheduler(implicit p: Parameters)
275275
wspawnMask.asBools.zipWithIndex.map { case (en, wid) =>
276276
when(en) {
277277
when (!pcTracker(wid).valid) {
278-
// only set thread mask if warp not already active
279-
threadMasks(wid) := fullThreadMask
280-
}
281-
when ((io.commit.bits.wid === wid.U) || (!pcTracker(wid).valid)) {
282-
// set pc if warp is
283-
// (1) initiator of wspawn or
278+
// set pc and tmask if warp is
279+
// (1) not the initiator of wspawn and
284280
// (2) was not already active before
285281
pcTracker(wid).bits := wspawn.bits.pc
286282
pcTracker(wid).valid := true.B
283+
threadMasks(wid) := fullThreadMask
287284
// spawning(wid) := true.B
288285
stallTracker.unstall(wid.U)
289286
}
287+
when (io.commit.bits.wid === wid.U) {
288+
assert(pcTracker(wid).valid === true.B)
289+
stallTracker.unstall(wid.U)
290+
}
290291
}
291292
}
292293
}

src/main/scala/radiance/subsystem/Configs.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import radiance.memory._
2020
import radiance.muon._
2121
import radiance.virgo.{NumVortexCores, VirgoClusterParams, VortexCoreParams, VortexL1Key}
2222
import radiance.muon.LoadStoreUnitParams
23+
import radiance.unittest.CyclotronLinked
2324

2425
sealed trait RadianceSmemSerialization
2526
case object FullySerialized extends RadianceSmemSerialization
@@ -66,6 +67,7 @@ class WithMuonCores(
6667
standalone: Boolean,
6768
noILP: Boolean,
6869
trace: Boolean,
70+
/** cyclotron-as-a-tile: use golden core model */
6971
cyclotron: Boolean,
7072
difftest: Boolean,
7173
disabled: Boolean,
@@ -94,6 +96,9 @@ class WithMuonCores(
9496
difftest = difftest,
9597
)
9698
}
99+
case CyclotronLinked => {
100+
up(CyclotronLinked) || site(RadianceSimArgs) || trace || difftest || cyclotron
101+
}
97102
case TilesLocated(`location`) => {
98103
if (standalone) {
99104
Seq()

0 commit comments

Comments
 (0)