Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port legacy chisel code to chisel3 for amba and tilelink #3059

Merged
merged 9 commits into from
Oct 7, 2022
4 changes: 2 additions & 2 deletions src/main/scala/amba/ahb/AHBLite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

package freechips.rocketchip.amba.ahb

import Chisel._
import chisel3._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._

Expand All @@ -16,7 +16,7 @@ class AHBLite()(implicit p: Parameters) extends LazyModule {
require (edgeOut.slave.lite) // or else this adapter is pointless

out.hmastlock.get := in.hlock.get
in.hgrant.get := Bool(true)
in.hgrant.get := true.B
in.hresp := out.hresp // zero-extended

in.hready := out.hready
Expand Down
110 changes: 32 additions & 78 deletions src/main/scala/amba/ahb/Bundles.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,120 +2,74 @@

package freechips.rocketchip.amba.ahb

import Chisel._
import chisel3._
import freechips.rocketchip.util._

// Signal directions are from the master's point-of-view
class AHBSlaveBundle(val params: AHBBundleParameters) extends Bundle
{
// Control signals from the arbiter to slave
val hmastlock = Bool(OUTPUT)
val hsel = Bool(OUTPUT)
val hmastlock = Output(Bool())
val hsel = Output(Bool())

// Flow control signals (hreadyout=FALSE => hready=FALSE)
val hready = Bool(OUTPUT) // from arbiter
val hreadyout = Bool(INPUT) // to arbiter
val hready = Output(Bool()) // from arbiter
val hreadyout = Input(Bool()) // to arbiter

// A-phase signals from arbiter to slave
val htrans = UInt(OUTPUT, width = params.transBits)
val hsize = UInt(OUTPUT, width = params.sizeBits)
val hburst = UInt(OUTPUT, width = params.burstBits)
val hwrite = Bool(OUTPUT)
val hprot = UInt(OUTPUT, width = params.protBits)
val haddr = UInt(OUTPUT, width = params.addrBits)
val htrans = Output(UInt(params.transBits.W))
val hsize = Output(UInt(params.sizeBits.W))
val hburst = Output(UInt(params.burstBits.W))
val hwrite = Output(Bool())
val hprot = Output(UInt(params.protBits.W))
val haddr = Output(UInt(params.addrBits.W))
val hauser = BundleMap(params.requestFields)

// D-phase signals from arbiter to slave
val hduser = BundleMap(params.responseFields)
val hwdata = UInt(OUTPUT, width = params.dataBits)
val hwdata = Output(UInt(params.dataBits.W))

// D-phase signals from slave to arbiter
val hresp = UInt(INPUT, width = params.hrespBits)
val hrdata = UInt(INPUT, width = params.dataBits)
val hresp = Input(UInt(params.hrespBits.W))
val hrdata = Input(UInt(params.dataBits.W))

// Split signals
val hmaster = if (params.lite) None else Some(UInt(OUTPUT, width = 4))
val hsplit = if (params.lite) None else Some(UInt(INPUT, width = 16))

def tieoff(): Unit = {
hrdata.dir match {
case INPUT =>
hreadyout := Bool(false)
hduser :<= BundleMap()
hresp := AHBParameters.RESP_OKAY
hrdata := UInt(0)
case OUTPUT =>
hmastlock := Bool(false)
hsel := Bool(false)
hready := Bool(false)
htrans := AHBParameters.TRANS_IDLE
hsize := UInt(0)
hburst := AHBParameters.BURST_SINGLE
hwrite := Bool(false)
hprot := AHBParameters.PROT_DEFAULT
haddr := UInt(0)
hauser :<= BundleMap()
hwdata := UInt(0)
case _ =>
}
sequencer marked this conversation as resolved.
Show resolved Hide resolved
}
Comment on lines -40 to -61
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why tieoff() is removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is from a discussion between Jerry and me, he thinks tieoff is not good practice, is rarely used and doesn't map cleanly to chisel3 concepts. You can see later in the code that we manually tied off 2 places where it was different

val hmaster = if (params.lite) None else Some(Output(UInt(4.W)))
val hsplit = if (params.lite) None else Some(Input(UInt(16.W)))
}

class AHBMasterBundle(val params: AHBBundleParameters) extends Bundle
{
// Control signals from master to arbiter
val hmastlock = if (params.lite) Some(Bool(OUTPUT)) else None
val hlock = if (params.lite) None else Some(Bool(OUTPUT))
val hbusreq = if (params.lite) None else Some(Bool(OUTPUT))
val hmastlock = if (params.lite) Some(Output(Bool())) else None
val hlock = if (params.lite) None else Some(Output(Bool()))
val hbusreq = if (params.lite) None else Some(Output(Bool()))

// Flow control from arbiter to master
val hgrant = if (params.lite) None else Some(Bool(INPUT))
val hready = Bool(INPUT)
val hgrant = if (params.lite) None else Some(Input(Bool()))
val hready = Input(Bool())

// Handy methods that don't care about lite
def lock(): Bool = if (params.lite) hmastlock.get else hlock.get
def busreq(): Bool = if (params.lite) Wire(init = Bool(true)) else hbusreq.get
def grant(): Bool = if (params.lite) Wire(init = Bool(true)) else hgrant.get
def busreq(): Bool = if (params.lite) Wire(true.B) else hbusreq.get
def grant(): Bool = if (params.lite) Wire(true.B) else hgrant.get

// A-phase signals from master to arbiter
val htrans = UInt(OUTPUT, width = params.transBits)
val hsize = UInt(OUTPUT, width = params.sizeBits)
val hburst = UInt(OUTPUT, width = params.burstBits)
val hwrite = Bool(OUTPUT)
val hprot = UInt(OUTPUT, width = params.protBits)
val haddr = UInt(OUTPUT, width = params.addrBits)
val htrans = Output(UInt(params.transBits.W))
val hsize = Output(UInt(params.sizeBits.W))
val hburst = Output(UInt(params.burstBits.W))
val hwrite = Output(Bool())
val hprot = Output(UInt(params.protBits.W))
val haddr = Output(UInt(params.addrBits.W))
val hauser = BundleMap(params.requestFields)

// D-phase signals from master to arbiter
val hduser = BundleMap(params.responseFields)
val hwdata = UInt(OUTPUT, width = params.dataBits)
val hwdata = Output(UInt(params.dataBits.W))

// D-phase response from arbiter to master
val hresp = UInt(INPUT, width = params.hrespBits)
val hrdata = UInt(INPUT, width = params.dataBits)

def tieoff(): Unit = {
hrdata.dir match {
case INPUT =>
hgrant.foreach { _ := Bool(false) }
hready := Bool(false)
hduser :<= BundleMap()
hresp := AHBParameters.RESP_OKAY
hrdata := UInt(0)
case OUTPUT =>
lock() := Bool(false)
busreq() := Bool(false)
htrans := AHBParameters.TRANS_IDLE
hsize := UInt(0)
hburst := AHBParameters.BURST_SINGLE
hwrite := Bool(false)
hprot := AHBParameters.PROT_DEFAULT
haddr := UInt(0)
hauser :<= BundleMap()
hwdata := UInt(0)
case _ =>
}
}
val hresp = Input(UInt(params.hrespBits.W))
val hrdata = Input(UInt(params.dataBits.W))
}

object AHBSlaveBundle
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/amba/ahb/Nodes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

package freechips.rocketchip.amba.ahb

import Chisel._
import chisel3._
import chisel3.internal.sourceinfo.SourceInfo
import freechips.rocketchip.config.{Parameters, Field}
import freechips.rocketchip.diplomacy._
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/amba/ahb/Parameters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

package freechips.rocketchip.amba.ahb

import Chisel._
import chisel3.util._
import chisel3.internal.sourceinfo.SourceInfo
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._
Expand Down
42 changes: 21 additions & 21 deletions src/main/scala/amba/ahb/Protocol.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

package freechips.rocketchip.amba.ahb

import Chisel._
import chisel3._

object AHBParameters
{
Expand All @@ -14,31 +14,31 @@ object AHBParameters
val userBits = 3
val hrespBits = 2 // AHB full

def TRANS_IDLE = UInt(0, width = transBits) // No transfer requested, not in a burst
def TRANS_BUSY = UInt(1, width = transBits) // No transfer requested, in a burst
def TRANS_NONSEQ = UInt(2, width = transBits) // First (potentially only) request in a burst
def TRANS_SEQ = UInt(3, width = transBits) // Following requests in a burst
def TRANS_IDLE = 0.U(transBits.W) // No transfer requested, not in a burst
def TRANS_BUSY = 1.U(transBits.W) // No transfer requested, in a burst
def TRANS_NONSEQ = 2.U(transBits.W) // First (potentially only) request in a burst
def TRANS_SEQ = 3.U(transBits.W) // Following requests in a burst

def BURST_SINGLE = UInt(0, width = burstBits) // Single access (no burst)
def BURST_INCR = UInt(1, width = burstBits) // Incrementing burst of arbitrary length, not crossing 1KB
def BURST_WRAP4 = UInt(2, width = burstBits) // 4-beat wrapping burst
def BURST_INCR4 = UInt(3, width = burstBits) // 4-beat incrementing burst
def BURST_WRAP8 = UInt(4, width = burstBits) // 8-beat wrapping burst
def BURST_INCR8 = UInt(5, width = burstBits) // 8-beat incrementing burst
def BURST_WRAP16 = UInt(6, width = burstBits) // 16-beat wrapping burst
def BURST_INCR16 = UInt(7, width = burstBits) // 16-beat incrementing burst
def BURST_SINGLE = 0.U(burstBits.W) // Single access (no burst)
def BURST_INCR = 1.U(burstBits.W) // Incrementing burst of arbitrary length, not crossing 1KB
def BURST_WRAP4 = 2.U(burstBits.W) // 4-beat wrapping burst
def BURST_INCR4 = 3.U(burstBits.W) // 4-beat incrementing burst
def BURST_WRAP8 = 4.U(burstBits.W) // 8-beat wrapping burst
def BURST_INCR8 = 5.U(burstBits.W) // 8-beat incrementing burst
def BURST_WRAP16 = 6.U(burstBits.W) // 16-beat wrapping burst
def BURST_INCR16 = 7.U(burstBits.W) // 16-beat incrementing burst

val maxTransfer = 16

def RESP_OKAY = UInt(0, width=2)
def RESP_ERROR = UInt(1, width=2)
def RESP_OKAY = 0.U(2.W)
def RESP_ERROR = 1.U(2.W)
// Only in AHB-Full:
def RESP_RETRY = UInt(2, width=2)
def RESP_SPLIT = UInt(3, width=2)
def RESP_RETRY = 2.U(2.W)
def RESP_SPLIT = 3.U(2.W)

def PROT_DATA = UInt(1, width = protBits)
def PROT_PRIVILEGED = UInt(2, width = protBits)
def PROT_BUFFERABLE = UInt(4, width = protBits)
def PROT_CACHEABLE = UInt(8, width = protBits)
def PROT_DATA = 1.U(protBits.W)
def PROT_PRIVILEGED = 2.U(protBits.W)
def PROT_BUFFERABLE = 4.U(protBits.W)
def PROT_CACHEABLE = 8.U(protBits.W)
def PROT_DEFAULT = PROT_DATA | PROT_PRIVILEGED
}
17 changes: 9 additions & 8 deletions src/main/scala/amba/ahb/RegisterRouter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

package freechips.rocketchip.amba.ahb

import Chisel._
import chisel3._
import chisel3.util._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.regmapper._
Expand Down Expand Up @@ -32,11 +33,11 @@ case class AHBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes:
val in = Wire(Decoupled(new RegMapperInput(params)))
val out = RegMapper(beatBytes, concurrency, undefZero, in, mapping:_*)

val d_phase = RegInit(Bool(false))
val d_phase = RegInit(false.B)
val d_taken = Reg(Bool())
val d_read = Reg(Bool())
val d_index = Reg(UInt(width = indexBits))
val d_mask = Reg(UInt(width = beatBytes))
val d_index = Reg(UInt(indexBits.W))
val d_mask = Reg(UInt(beatBytes.W))

// Only send the request to the RR once
d_taken := d_phase && in.ready
Expand All @@ -47,22 +48,22 @@ case class AHBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes:
in.bits.data := ahb.hwdata
in.bits.mask := d_mask

when (ahb.hready) { d_phase := Bool(false) }
when (ahb.hready) { d_phase := false.B }
ahb.hreadyout := !d_phase || out.valid
ahb.hresp := AHBParameters.RESP_OKAY
ahb.hrdata := out.bits.data

val request = ahb.htrans === AHBParameters.TRANS_NONSEQ || ahb.htrans === AHBParameters.TRANS_SEQ
when (ahb.hready && ahb.hsel && request) {
assert (!in.valid || in.ready)
d_phase := Bool(true)
d_taken := Bool(false)
d_phase := true.B
d_taken := false.B
d_read := !ahb.hwrite
d_index := ahb.haddr >> log2Ceil(beatBytes)
d_mask := MaskGen(ahb.haddr, ahb.hsize, beatBytes)
}

out.ready := Bool(true)
out.ready := true.B
assert (d_phase || !out.valid)
}
}
Expand Down
23 changes: 12 additions & 11 deletions src/main/scala/amba/ahb/SRAM.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

package freechips.rocketchip.amba.ahb

import Chisel._
import chisel3._
import chisel3.util._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.util._
Expand Down Expand Up @@ -50,7 +51,7 @@ class AHBRAM(
val a_legal = address.contains(in.haddr)

// The data phase signals
val d_wdata = Vec.tabulate(beatBytes) { i => in.hwdata(8*(i+1)-1, 8*i) }
val d_wdata = VecInit.tabulate(beatBytes) { i => in.hwdata(8*(i+1)-1, 8*i) }

// AHB writes must occur during the data phase; this poses a structural
// hazard with reads which must occur during the address phase. To solve
Expand All @@ -64,7 +65,7 @@ class AHBRAM(
// happen to have matching address.

// Pending write?
val p_valid = RegInit(Bool(false))
val p_valid = RegInit(false.B)
val p_address = Reg(a_address)
val p_mask = Reg(a_mask)
val p_latch_d = Reg(Bool())
Expand All @@ -77,14 +78,14 @@ class AHBRAM(
val d_legal = RegEnable(a_legal, in.hreadyout)
// Whenever the port is not needed for reading, execute pending writes
when (!read && p_valid) {
p_valid := Bool(false)
p_valid := false.B
mem.write(p_address, p_wdata, p_mask.asBools)
}

// Record the request for later?
p_latch_d := a_request && a_write
when (a_request && a_write && a_legal) {
p_valid := Bool(true)
p_valid := true.B
p_address := a_address
p_mask := a_mask
}
Expand All @@ -94,19 +95,19 @@ class AHBRAM(
val d_bypass = RegEnable(a_bypass, a_request)

// Mux in data from the pending write
val muxdata = Vec((p_mask.asBools zip (p_wdata zip d_rdata))
val muxdata = VecInit((p_mask.asBools zip (p_wdata zip d_rdata))
map { case (m, (p, r)) => Mux(d_bypass && m, p, r) })

// Don't fuzz hready when not in data phase
val d_request = Reg(Bool(false))
when (in.hready) { d_request := Bool(false) }
when (a_request) { d_request := Bool(true) }
val d_request = Reg(false.B)
when (in.hready) { d_request := false.B }
when (a_request) { d_request := true.B }

val disable_ahb_fuzzing = PlusArg("disable_ahb_fuzzing", default = 0, "1:Disabled 0:Enabled.")(0)

// Finally, the outputs
in.hreadyout := Mux(disable_ahb_fuzzing, Bool(true), { if(fuzzHreadyout) { !d_request || LFSRNoiseMaker(1)(0) } else { Bool(true) }} )
in.hreadyout := Mux(disable_ahb_fuzzing, true.B, { if(fuzzHreadyout) { !d_request || LFSRNoiseMaker(1)(0) } else { true.B }} )
in.hresp := Mux(!d_request || d_legal || !in.hreadyout, AHBParameters.RESP_OKAY, AHBParameters.RESP_ERROR)
in.hrdata := Mux(in.hreadyout, muxdata.asUInt, UInt(0))
in.hrdata := Mux(in.hreadyout, muxdata.asUInt, 0.U)
}
}
4 changes: 2 additions & 2 deletions src/main/scala/amba/ahb/Test.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

package freechips.rocketchip.amba.ahb

import Chisel._
import chisel3._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.devices.tilelink.TLTestRAM
import freechips.rocketchip.diplomacy._
Expand Down Expand Up @@ -66,7 +66,7 @@ class AHBFuzzMaster(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends L

lazy val module = new LazyModuleImp(this) {
val io = IO(new Bundle {
val finished = Bool(OUTPUT)
val finished = Output(Bool())
})

io.finished := fuzz.module.io.finished
Expand Down
Loading