Skip to content

Commit

Permalink
Merge pull request #3349 from chipsalliance/mergify/bp/master/pr-3287
Browse files Browse the repository at this point in the history
Porting Chisel 2 to Chisel 3: tilelink/ (backport #3287)
  • Loading branch information
jerryz123 authored May 10, 2023
2 parents 98a6fb6 + 3a7dc7a commit a435348
Show file tree
Hide file tree
Showing 25 changed files with 507 additions and 479 deletions.
49 changes: 25 additions & 24 deletions src/main/scala/tilelink/Atomics.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,26 @@

package freechips.rocketchip.tilelink

import Chisel.{defaultCompileOptions => _, _}
import chisel3._
import chisel3.util._
import freechips.rocketchip.util.CompileOptions.NotStrictInferReset


class Atomics(params: TLBundleParameters) extends Module
{
val io = new Bundle {
val write = Bool().flip // ignore opcode
val a = new TLBundleA(params).flip
val data_in = UInt(width = params.dataBits).flip
val data_out = UInt(width = params.dataBits)
}
val io = IO(new Bundle {
val write = Flipped(Bool()) // ignore opcode
val a = Flipped(new TLBundleA(params))
val data_in = Flipped(UInt(params.dataBits.W))
val data_out = UInt(params.dataBits.W)
})

// Arithmetic, what to do
val adder = io.a.param(2)
val unsigned = io.a.param(1)
val take_max = io.a.param(0)

val signBit = io.a.mask & Cat(UInt(1), ~io.a.mask >> 1)
val signBit = io.a.mask & Cat(1.U, ~io.a.mask >> 1)
val inv_d = Mux(adder, io.data_in, ~io.data_in)
val sum = (FillInterleaved(8, io.a.mask) & io.a.data) + inv_d
def sign(x: UInt): Bool = (Cat(x.asBools.grouped(8).map(_.last).toList.reverse) & signBit).orR
Expand All @@ -32,31 +33,31 @@ class Atomics(params: TLBundleParameters) extends Module
val pick_a = take_max === a_bigger

// Logical, what to do
val lut = Vec(Seq(
UInt(0x6), // XOR
UInt(0xe), // OR
UInt(0x8), // AND
UInt(0xc)))( // SWAP
val lut = VecInit(Seq(
(0x6).U, // XOR
(0xe).U, // OR
(0x8).U, // AND
(0xc).U))( // SWAP
io.a.param(1,0))
val logical = Cat((io.a.data.asBools zip io.data_in.asBools).map { case (a, d) =>
lut(Cat(a, d))
}.reverse)

// Operation, what to do? (0=d, 1=a, 2=sum, 3=logical)
val select = Mux(io.write, UInt(1), Vec(Seq(
UInt(1), // PutFullData
UInt(1), // PutPartialData
Mux(adder, UInt(2), Mux(pick_a, UInt(1), UInt(0))), // ArithmeticData
UInt(3), // LogicalData
UInt(0), // Get
UInt(0), // Hint
UInt(0), // AcquireBlock
UInt(0)))( // AcquirePerm
val select = Mux(io.write, 1.U, VecInit(Seq(
1.U, // PutFullData
1.U, // PutPartialData
Mux(adder, 2.U, Mux(pick_a, 1.U, 0.U)), // ArithmeticData
3.U, // LogicalData
0.U, // Get
0.U, // Hint
0.U, // AcquireBlock
0.U))( // AcquirePerm
io.a.opcode))

// Only the masked bytes can be modified
val selects = io.a.mask.asBools.map(b => Mux(b, select, UInt(0)))
val selects = io.a.mask.asBools.map(b => Mux(b, select, 0.U))
io.data_out := Cat(selects.zipWithIndex.map { case (s, i) =>
Vec(Seq(io.data_in, io.a.data, sum, logical).map(_((i + 1) * 8 - 1, i * 8)))(s)
VecInit(Seq(io.data_in, io.a.data, sum, logical).map(_((i + 1) * 8 - 1, i * 8)))(s)
}.reverse)
}
2 changes: 1 addition & 1 deletion src/main/scala/tilelink/Broadcast.scala
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ class TLBroadcastTracker(id: Int, lineBytes: Int, caches: Int, bufferless: Boole
io.cacheOH := cacheOH

val i_data = Wire(Decoupled(new TLBroadcastData(edgeIn.bundle)))
val o_data = Queue(i_data, if (bufferless) 1 else (lineBytes / edgeIn.manager.beatBytes), pipe=bufferless)
val o_data = Queue(i_data, if (bufferless) 1 else (lineBytes / edgeIn.manager.beatBytes), bufferless)

io.in_a.ready := (idle || !io.in_a_first) && i_data.ready
i_data.valid := (idle || !io.in_a_first) && io.in_a.valid
Expand Down
26 changes: 13 additions & 13 deletions src/main/scala/tilelink/Buffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

package freechips.rocketchip.tilelink

import Chisel._
import chisel3._
import org.chipsalliance.cde.config.Parameters
import freechips.rocketchip.diplomacy._

Expand Down Expand Up @@ -43,12 +43,12 @@ class TLBuffer(
out.c <> c(in .c)
out.e <> e(in .e)
} else {
in.b.valid := Bool(false)
in.c.ready := Bool(true)
in.e.ready := Bool(true)
out.b.ready := Bool(true)
out.c.valid := Bool(false)
out.e.valid := Bool(false)
in.b.valid := false.B
in.c.ready := true.B
in.e.ready := true.B
out.b.ready := true.B
out.c.valid := false.B
out.e.valid := false.B
}
}
}
Expand Down Expand Up @@ -120,12 +120,12 @@ class TLBufferAndNotCancel(
out.c <> c(in .c)
out.e <> e(in .e)
} else {
in.b.valid := Bool(false)
in.c.ready := Bool(true)
in.e.ready := Bool(true)
out.b.ready := Bool(true)
out.c.valid := Bool(false)
out.e.valid := Bool(false)
in.b.valid := false.B
in.c.ready := true.B
in.e.ready := true.B
out.b.ready := true.B
out.c.valid := false.B
out.e.valid := false.B
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/tilelink/BusWrapper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

package freechips.rocketchip.tilelink

import Chisel._
import chisel3._
import chisel3.util._
import org.chipsalliance.cde.config.Parameters
import freechips.rocketchip.diplomacy._

Expand Down
47 changes: 24 additions & 23 deletions src/main/scala/tilelink/CacheCork.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

package freechips.rocketchip.tilelink

import Chisel._
import chisel3._
import chisel3.util._
import org.chipsalliance.cde.config.Parameters
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.util._
Expand Down Expand Up @@ -62,34 +63,34 @@ class TLCacheCork(params: TLCacheCorkParams = TLCacheCorkParams())(implicit p: P
// Fortunately, no masters we know of behave this way!

// Take requests from A to A or D (if BtoT Acquire)
val a_a = Wire(out.a)
val a_d = Wire(in.d)
val a_a = Wire(chiselTypeOf(out.a))
val a_d = Wire(chiselTypeOf(in.d))
val isPut = in.a.bits.opcode === PutFullData || in.a.bits.opcode === PutPartialData
val toD = (in.a.bits.opcode === AcquireBlock && in.a.bits.param === TLPermissions.BtoT) ||
(in.a.bits.opcode === AcquirePerm)
in.a.ready := Mux(toD, a_d.ready, a_a.ready)

a_a.valid := in.a.valid && !toD
a_a.bits := in.a.bits
a_a.bits.source := in.a.bits.source << 1 | Mux(isPut, UInt(1), UInt(0))
a_a.bits.source := in.a.bits.source << 1 | Mux(isPut, 1.U, 0.U)

// Transform Acquire into Get
when (in.a.bits.opcode === AcquireBlock || in.a.bits.opcode === AcquirePerm) {
a_a.bits.opcode := Get
a_a.bits.param := UInt(0)
a_a.bits.source := in.a.bits.source << 1 | UInt(1)
a_a.bits.param := 0.U
a_a.bits.source := in.a.bits.source << 1 | 1.U
}

// Upgrades are instantly successful
a_d.valid := in.a.valid && toD
a_d.bits := edgeIn.Grant(
fromSink = UInt(0),
fromSink = 0.U,
toSource = in.a.bits.source,
lgSize = in.a.bits.size,
capPermissions = TLPermissions.toT)

// Take ReleaseData from C to A; Release from C to D
val c_a = Wire(out.a)
val c_a = Wire(chiselTypeOf(out.a))
c_a.valid := in.c.valid && in.c.bits.opcode === ReleaseData
c_a.bits := edgeOut.Put(
fromSource = in.c.bits.source << 1,
Expand All @@ -100,54 +101,54 @@ class TLCacheCork(params: TLCacheCorkParams = TLCacheCorkParams())(implicit p: P
c_a.bits.user :<= in.c.bits.user

// Releases without Data succeed instantly
val c_d = Wire(in.d)
val c_d = Wire(chiselTypeOf(in.d))
c_d.valid := in.c.valid && in.c.bits.opcode === Release
c_d.bits := edgeIn.ReleaseAck(in.c.bits)

assert (!in.c.valid || in.c.bits.opcode === Release || in.c.bits.opcode === ReleaseData)
in.c.ready := Mux(in.c.bits.opcode === Release, c_d.ready, c_a.ready)

// Discard E
in.e.ready := Bool(true)
in.e.ready := true.B

// Block B; should never happen
out.b.ready := Bool(false)
out.b.ready := false.B
assert (!out.b.valid)

// Track in-flight sinkIds
val pool = Module(new IDPool(sinkIds))
pool.io.free.valid := in.e.fire()
pool.io.free.valid := in.e.fire
pool.io.free.bits := in.e.bits.sink

val in_d = Wire(in.d)
val in_d = Wire(chiselTypeOf(in.d))
val d_first = edgeOut.first(in_d)
val d_grant = in_d.bits.opcode === GrantData || in_d.bits.opcode === Grant
pool.io.alloc.ready := in.d.fire() && d_first && d_grant
pool.io.alloc.ready := in.d.fire && d_first && d_grant
in.d.valid := in_d.valid && (pool.io.alloc.valid || !d_first || !d_grant)
in_d.ready := in.d.ready && (pool.io.alloc.valid || !d_first || !d_grant)
in.d.bits := in_d.bits
in.d.bits.sink := pool.io.alloc.bits holdUnless d_first

// Take responses from D and transform them
val d_d = Wire(in.d)
val d_d = Wire(chiselTypeOf(in.d))
d_d <> out.d
d_d.bits.source := out.d.bits.source >> 1

// Record if a target was writable and auto-promote toT if it was
// This is structured so that the vector can be constant prop'd away
val wSourceVec = Reg(Vec(edgeIn.client.endSourceId, Bool()))
val aWOk = edgeIn.manager.fastProperty(in.a.bits.address, !_.supportsPutFull.none, (b:Boolean) => Bool(b))
val aWOk = edgeIn.manager.fastProperty(in.a.bits.address, !_.supportsPutFull.none, (b:Boolean) => b.B)
val dWOk = wSourceVec(d_d.bits.source)
val bypass = Bool(edgeIn.manager.minLatency == 0) && in.a.valid && in.a.bits.source === d_d.bits.source
val bypass = (edgeIn.manager.minLatency == 0).B && in.a.valid && in.a.bits.source === d_d.bits.source
val dWHeld = Mux(bypass, aWOk, dWOk) holdUnless d_first

when (in.a.fire()) {
when (in.a.fire) {
wSourceVec(in.a.bits.source) := aWOk
}

// Wipe out any unused registers
edgeIn.client.unusedSources.foreach { id =>
wSourceVec(id) := Bool(edgeIn.manager.anySupportPutFull)
wSourceVec(id) := edgeIn.manager.anySupportPutFull.B
}

when (out.d.bits.opcode === AccessAckData && out.d.bits.source(0)) {
Expand All @@ -160,12 +161,12 @@ class TLCacheCork(params: TLCacheCorkParams = TLCacheCorkParams())(implicit p: P

// Combine the sources of messages into the channels
TLArbiter(TLArbiter.lowestIndexFirst)(out.a, (edgeOut.numBeats1(c_a.bits), c_a), (edgeOut.numBeats1(a_a.bits), a_a))
TLArbiter(TLArbiter.lowestIndexFirst)(in_d, (edgeIn .numBeats1(d_d.bits), d_d), (UInt(0), Queue(c_d, 2)), (UInt(0), Queue(a_d, 2)))
TLArbiter(TLArbiter.lowestIndexFirst)(in_d, (edgeIn .numBeats1(d_d.bits), d_d), (0.U, Queue(c_d, 2)), (0.U, Queue(a_d, 2)))

// Tie off unused ports
in.b.valid := Bool(false)
out.c.valid := Bool(false)
out.e.valid := Bool(false)
in.b.valid := false.B
out.c.valid := false.B
out.e.valid := false.B
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/main/scala/tilelink/Delayer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

package freechips.rocketchip.tilelink

import Chisel._
import chisel3._
import chisel3.util._
import org.chipsalliance.cde.config.Parameters
import freechips.rocketchip.diplomacy._

Expand All @@ -15,7 +16,7 @@ class TLDelayer(q: Double)(implicit p: Parameters) extends LazyModule
lazy val module = new Impl
class Impl extends LazyModuleImp(this) {
def feed[T <: Data](sink: DecoupledIO[T], source: DecoupledIO[T], noise: T): Unit = {
val allow = UInt((q * 65535.0).toInt) <= LFSRNoiseMaker(16, source.valid)
val allow = ((q * 65535.0).toInt).U <= LFSRNoiseMaker(16, source.valid)
sink.valid := source.valid && allow
source.ready := sink.ready && allow
sink.bits := source.bits
Expand Down
Loading

0 comments on commit a435348

Please sign in to comment.