Skip to content

Commit

Permalink
Merge pull request #79 from ucb-ucie/protocol
Browse files Browse the repository at this point in the history
Protocol layer with updated code
  • Loading branch information
vikramjain236 authored Apr 27, 2024
2 parents bc3c409 + 82c5aaa commit e9d2790
Show file tree
Hide file tree
Showing 12 changed files with 356 additions and 54 deletions.
12 changes: 7 additions & 5 deletions src/main/scala/protocol/Common.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import tilelink._
case class ProtocolLayerParams() {
val ucieFlitWidth = 64 // flit width
val ucieFlitSize = 4 // number of ucie flits
val ucieNonEccWidth = 448 // width of the actual data bits
val ucieEccWidth = 64 // width of the ECC bits
val hostIDWidth = 8 // hostID of the initiator chiplet
val partnerIDWidth = 8 // partnerID of the consumer chiplet
Expand All @@ -28,6 +29,7 @@ object UCIProtoMsgTypes extends ChiselEnum {
val Reserved0 = Value(0x5.U(4.W))
val Reserved1 = Value(0x6.U(4.W))
val Reserved2 = Value(0x7.U(4.W))
val Reserved3 = Value(0x8.U(4.W))
}

/**
Expand Down Expand Up @@ -106,12 +108,12 @@ class d2dConfig() extends Bundle {

class sbConfig() extends Bundle {
// SideBand Control Status Registers
val sideband_mailbox_index_low = Output(UInt(32.W))
val sideband_mailbox_index_high = Output(UInt(32.W))
val sideband_mailbox_data_low = Output(UInt(32.W))
val sideband_mailbox_data_high = Output(UInt(32.W))
val sideband_mailbox_index_low = Input(UInt(32.W))
val sideband_mailbox_index_high = Input(UInt(32.W))
val sideband_mailbox_data_low = Input(UInt(32.W))
val sideband_mailbox_data_high = Input(UInt(32.W))
val sideband_mailbox_ready = Output(UInt(1.W))
val sideband_mailbox_valid = Output(UInt(1.W))
val sideband_mailbox_valid = Input(UInt(1.W))

val sideband_mailbox_sw_to_node_index_low = Output(UInt(32.W))
val sidebank_mailbox_sw_to_node_index_high = Output(UInt(32.W))
Expand Down
111 changes: 111 additions & 0 deletions src/main/scala/protocol/HammingCode.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package edu.berkeley.cs.ucie.digital
package protocol

import chisel3._
import chisel3.util._

class HammingEncode(val protoParams: ProtocolLayerParams) extends Module {
val io = IO(new Bundle {
val data = Input(UInt(protoParams.ucieNonEccWidth.W))
val checksum = Output(UInt(protoParams.ucieEccWidth.W))
})

def hammingEncode(data: Vec[UInt]): UInt = {
val p1 = Wire(UInt(1.W))
val p1_taps = Wire(Vec(protoParams.ucieNonEccWidth, UInt(1.W)))
data.zipWithIndex.map { case (d, i) =>
i % 2 >= 1 match {
case true => p1_taps(i) := 1.U
case false => p1_taps(i) := 0.U
}
}
p1 := (p1_taps.asUInt & data.asUInt).xorR
val p2 = Wire(UInt(1.W))
val p2_taps = Wire(Vec(protoParams.ucieNonEccWidth, UInt(1.W)))
data.zipWithIndex.map { case (d, i) =>
i % 4 >= 2 match {
case true => p2_taps(i) := 1.U
case false => p2_taps(i) := 0.U
}
}
p2 := (p2_taps.asUInt & data.asUInt).xorR
val p4 = Wire(UInt(1.W))
val p4_taps = Wire(Vec(protoParams.ucieNonEccWidth, UInt(1.W)))
data.zipWithIndex.map { case (d, i) =>
i % 8 >= 4 match {
case true => p4_taps(i) := 1.U
case false => p4_taps(i) := 0.U
}
}
p4 := (p4_taps.asUInt & data.asUInt).xorR
val p8 = Wire(UInt(1.W))
val p8_taps = Wire(Vec(protoParams.ucieNonEccWidth, UInt(1.W)))
data.zipWithIndex.map { case (d, i) =>
i % 16 >= 8 match {
case true => p8_taps(i) := 1.U
case false => p8_taps(i) := 0.U
}
}
p8 := (p8_taps.asUInt & data.asUInt).xorR
val p16 = Wire(UInt(1.W))
val p16_taps = Wire(Vec(protoParams.ucieNonEccWidth, UInt(1.W)))
data.zipWithIndex.map { case (d, i) =>
i % 32 >= 16 match {
case true => p16_taps(i) := 1.U
case false => p16_taps(i) := 0.U
}
}
p16 := (p16_taps.asUInt & data.asUInt).xorR
val p32 = Wire(UInt(1.W))
val p32_taps = Wire(Vec(protoParams.ucieNonEccWidth, UInt(1.W)))
data.zipWithIndex.map { case (d, i) =>
i % 64 >= 32 match {
case true => p32_taps(i) := 1.U
case false => p32_taps(i) := 0.U
}
}
p32 := (p32_taps.asUInt & data.asUInt).xorR
val p64 = Wire(UInt(1.W))
val p64_taps = Wire(Vec(protoParams.ucieNonEccWidth, UInt(1.W)))
data.zipWithIndex.map { case (d, i) =>
i % 128 >= 64 match {
case true => p64_taps(i) := 1.U
case false => p64_taps(i) := 0.U
}
}
p64 := (p64_taps.asUInt & data.asUInt).xorR
val p128 = Wire(UInt(1.W))
val p128_taps = Wire(Vec(protoParams.ucieNonEccWidth, UInt(1.W)))
data.zipWithIndex.map { case (d, i) =>
i % 256 >= 128 match {
case true => p128_taps(i) := 1.U
case false => p128_taps(i) := 0.U
}
}
p128 := (p128_taps.asUInt & data.asUInt).xorR
val p256 = Wire(UInt(1.W))
val p256_taps = Wire(Vec(protoParams.ucieNonEccWidth, UInt(1.W)))
data.zipWithIndex.map { case (d, i) =>
i % 512 >= 256 match {
case true => p256_taps(i) := 1.U
case false => p256_taps(i) := 0.U
}
}
p256 := (p256_taps.asUInt & data.asUInt).xorR
Cat(p1, p2, p4, p8, p16, p32, p64, p128, p256)
}

io.checksum := hammingEncode(io.data.asTypeOf(Vec(protoParams.ucieNonEccWidth, UInt(1.W))))
}

class HammingDecode(val protoParams: ProtocolLayerParams) extends Module {
val io = IO(new Bundle {
val data = Input(UInt(protoParams.ucieNonEccWidth.W))
val checksum = Input(UInt(protoParams.ucieEccWidth.W))
val matches = Output(Bool())
})
val hammingEncode = Module(new HammingEncode(protoParams))
hammingEncode.io.data := io.data
io.matches := hammingEncode.io.checksum === io.checksum
}

41 changes: 29 additions & 12 deletions src/main/scala/protocol/ProtocolLayer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import chisel3._
import chisel3.util._

import interfaces._
import javax.swing.InputMap

/**
* Class to handle the FDI signalling between the D2D adapter and protocol layer. The class
Expand All @@ -23,6 +24,9 @@ class ProtocolLayer(val fdiParams: FdiParams) extends Module {
val TLlpData_irdy = Input(Bool())
val TLplData_bits = Output(Bits((8 * fdiParams.width).W))
val TLplData_valid = Output(Bool())
val TLready_to_rcv = Input(Bool())
val fault = Input(Bool())
val soft_reset = Input(Bool())
})

io.fdi.lpData.bits := io.TLlpData_bits
Expand All @@ -39,47 +43,48 @@ class ProtocolLayer(val fdiParams: FdiParams) extends Module {
io.fdi.lpDllp.bits := 0.U
io.fdi.lpDllpOfc := false.B
// Dynamic clock gating feature not supported in v1
io.fdi.lpClkAck := false.B
io.fdi.lpWakeReq := false.B
io.fdi.lpClkAck := true.B
io.fdi.lpWakeReq := true.B

// Tie lpStream to streaming protocol on stack 0
val streaming = Wire(new ProtoStream())
streaming.protoStack := ProtoStack.stack0
streaming.protoType := ProtoStreamType.Stream
io.fdi.lpStream <> streaming

val sb_linkReset_req = RegInit(false.B)
val sb_linkReset_req = io.soft_reset

// Refer to section 8.2.7 for rx_active_req/sts handshake
val lp_rx_active_sts_reg = RegInit(false.B)
// lpRxActiveStatus can change before the plStateStatus becomes Active
val lp_rx_active_pl_state = (io.fdi.plStateStatus === PhyState.reset ||
io.fdi.plStateStatus === PhyState.retrain ||
io.fdi.plStateStatus === PhyState.active)
// val lp_rx_active_pl_state = (io.fdi.plStateStatus === PhyState.reset ||
// io.fdi.plStateStatus === PhyState.retrain ||
// io.fdi.plStateStatus === PhyState.active)
val lp_rx_active_pl_state = (io.fdi.plStateStatus === PhyState.active)

when(io.fdi.plRxActiveReq && io.fdi.lpData.irdy && lp_rx_active_pl_state) {
when(io.fdi.plRxActiveReq && io.TLready_to_rcv && lp_rx_active_pl_state) {
lp_rx_active_sts_reg := true.B
}
io.fdi.lpRxActiveStatus := lp_rx_active_sts_reg

// Refer to section 8.2.8 for FDI bringup and state req logic
val lp_state_req_reg = RegInit(PhyStateReq.nop)

val reqActive = (io.fdi.plStateStatus === PhyState.reset &
val reqActive = ((io.fdi.plStateStatus === PhyState.reset &
lp_state_req_reg === PhyStateReq.nop &
io.fdi.plInbandPres)
io.fdi.plInbandPres) || io.fdi.plStateStatus === PhyState.linkReset)

when(reqActive) {
lp_state_req_reg := PhyStateReq.active
}.elsewhen(sb_linkReset_req) {// TODO: SB register to initiate LinkReset
}.elsewhen(~reqActive && sb_linkReset_req) {// TODO: SB register to initiate LinkReset
lp_state_req_reg := PhyStateReq.linkReset
}.otherwise { lp_state_req_reg := PhyStateReq.nop }

io.fdi.lpStateReq := lp_state_req_reg

// TODO: lpLinkError should be asserted when there is an error detected by protocol layer
// lpLinkError should be asserted when there is an error detected by protocol layer
// should be done as a ECC check in UCIe flit
io.fdi.lpLinkError := false.B
io.fdi.lpLinkError := io.fault

// Refer to section 8.3.2
// Whent he lpStallAck is asserted the TL A channel is stalled and the lp irdy and valid
Expand All @@ -88,6 +93,18 @@ class ProtocolLayer(val fdiParams: FdiParams) extends Module {
lp_stall_reg := io.fdi.plStallReq
io.fdi.lpStallAck := lp_stall_reg

/** pl_protocol
* saves pl_protocol and flitfmt, resets and negotiates if protocol/flitfmt is not raw
* Expects ProtocolID.STREAM and ProtocolFlitFmt.RAW if implemented
* WARNING: HAS NOT IMPLEMENTED RENEGOTIATION LOGIC, the d2d ties these to raw
*/
val pl_protocol_reg = RegInit(0.U(3.W))
val pl_protocol_flitfmt_reg = RegInit(0.U(4.W))
when (io.fdi.plProtocolValid) {
pl_protocol_reg := io.fdi.plProtocol.asUInt
pl_protocol_flitfmt_reg := io.fdi.plProtocolFlitFormat.asUInt
}

// TODO: these are SB messaging signals
io.fdi.lpConfig.bits := 0.asUInt(fdiParams.sbWidth.W)
io.fdi.lpConfig.valid := false.B
Expand Down
24 changes: 12 additions & 12 deletions src/main/scala/tilelink/UCIConfigRF.scala
Original file line number Diff line number Diff line change
Expand Up @@ -110,17 +110,17 @@ class UCIConfigRF(val beatBytes: Int, val address: BigInt)(implicit p: Parameter
io.d2d_csrs.d2d_state_can_reset := d2d_state_can_reset
io.d2d_csrs.d2d_flush_and_reset := d2d_flush_and_reset

io.sb_csrs.sideband_mailbox_index_low := sideband_mailbox_index_low
io.sb_csrs.sideband_mailbox_index_high := sideband_mailbox_index_high
io.sb_csrs.sideband_mailbox_data_low := sideband_mailbox_data_low
io.sb_csrs.sideband_mailbox_data_high := sideband_mailbox_data_high
io.sb_csrs.sideband_mailbox_ready := sideband_mailbox_ready
io.sb_csrs.sideband_mailbox_valid := sideband_mailbox_valid
io.sb_csrs.sideband_mailbox_sw_to_node_index_low := sideband_mailbox_sw_to_node_index_low
io.sb_csrs.sidebank_mailbox_sw_to_node_index_high := sidebank_mailbox_sw_to_node_index_high
io.sb_csrs.sideband_mailbox_sw_to_node_data_low := sideband_mailbox_sw_to_node_data_low
io.sb_csrs.sideband_mailbox_sw_to_node_data_high := sideband_mailbox_sw_to_node_data_high
io.sb_csrs.sideband_mailbox_sw_ready := sideband_mailbox_sw_ready
io.sb_csrs.sideband_mailbox_sw_valid := sideband_mailbox_sw_valid
sideband_mailbox_index_low := io.sb_csrs.sideband_mailbox_index_low
sideband_mailbox_index_high := io.sb_csrs.sideband_mailbox_index_high
sideband_mailbox_data_low := io.sb_csrs.sideband_mailbox_data_low
sideband_mailbox_data_high := io.sb_csrs.sideband_mailbox_data_high
io.sb_csrs.sideband_mailbox_ready := sideband_mailbox_ready
sideband_mailbox_valid := io.sb_csrs.sideband_mailbox_valid
io.sb_csrs.sideband_mailbox_sw_to_node_index_low := sideband_mailbox_sw_to_node_index_low
io.sb_csrs.sidebank_mailbox_sw_to_node_index_high := sidebank_mailbox_sw_to_node_index_high
io.sb_csrs.sideband_mailbox_sw_to_node_data_low := sideband_mailbox_sw_to_node_data_low
io.sb_csrs.sideband_mailbox_sw_to_node_data_high := sideband_mailbox_sw_to_node_data_high
io.sb_csrs.sideband_mailbox_sw_ready := sideband_mailbox_sw_ready
io.sb_csrs.sideband_mailbox_sw_valid := sideband_mailbox_sw_valid
}
}
Loading

0 comments on commit e9d2790

Please sign in to comment.