Skip to content

Commit

Permalink
add axi4 lite support
Browse files Browse the repository at this point in the history
  • Loading branch information
hansemandse committed Jan 3, 2021
1 parent 33b0000 commit e0a3c22
Show file tree
Hide file tree
Showing 3 changed files with 214 additions and 37 deletions.
155 changes: 134 additions & 21 deletions axi4/src/main/scala/axi4/Bundles.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,46 @@ import chisel3._
import chisel3.util.isPow2
import chisel3.experimental.BundleLiterals._

/** AXI4 write address
/** AXI4 Lite write address
*
* @param addrW the width of the AWADDR signal in bits
*/
class WALite(val addrW: Int) extends Bundle {
require(addrW > 0, "the address width must be a positive integer")
val addr = UInt(addrW.W)
val prot = UInt(3.W)
}
object WALite {
/** Alternative constructor
*
* @param addrW the width of the AWADDR signal in bits
* @return an unitialized WALite object
*/
def apply(addrW: Int) = new WALite(addrW)

/** Default values for this channel
*
* @param in a WALite object
* @return an initialized (hardware) WALite object
*/
def default(in: WALite) = (new WALite(in.addrW)).Lit(_.addr -> 0.U, _.prot -> ProtectionEncodings.DataNsecUpriv)
}

/** AXI4 full write address
*
* @param addrW the width of the AWADDR signal in bits
* @param idW the width of the AWID signal in bits
* @param userW the width of the AWUSER signal in bits
*/
class WA(val addrW: Int, val idW: Int, val userW: Int) extends Bundle {
require(addrW > 0, "the address width must be a positive integer")
class WA(override val addrW: Int, val idW: Int, val userW: Int) extends WALite(addrW) {
require(idW >= 0, "the id width must be a non-negative integer")
require(userW >= 0, "the user with must be a non-negative integer")
val id = UInt(idW.W)
val addr = UInt(addrW.W)
val len = UInt(8.W)
val size = UInt(3.W)
val burst = UInt(2.W)
val lock = Bool()
val cache = UInt(4.W)
val prot = UInt(3.W)
val qos = UInt(4.W)
val region = UInt(4.W)
val user = UInt(userW.W)
Expand Down Expand Up @@ -60,17 +82,40 @@ object WA {
}
}

/** AXI4 write data
/** AXI4 Lite write data
*
* @param dataW the width of the WDATA signal in bits
*/
class WDLite(val dataW: Int) extends Bundle {
require(dataW == 32 || dataW == 64, "the data width must be either 32 or 64 bits")
val data = UInt(dataW.W)
val strb = UInt((dataW/8).W)
}
object WDLite {
/** Alternative constructor
*
* @param dataW the width of the WDATA signal in bits, defaults to 32
* @return an unitialized WDLite object
*/
def apply(dataW: Int = 32) = new WDLite(dataW)

/** Default values for this channel
*
* @param in a WDLite object
* @return an initialized (hardware) WDLite object
*/
def default(in: WDLite) = (new WDLite(in.dataW)).Lit(_.data -> 0.U, _.strb -> 0.U)
}

/** AXI4 full write data
*
* @param dataW the width of the WDATA signal in bits
* @param userW the width of the WUSER signal in bits
*/
class WD(val dataW: Int, val userW: Int) extends Bundle {
class WD(override val dataW: Int, val userW: Int) extends WDLite(dataW) {
require(dataW > 0, "the data width must be a positive integer")
require(isPow2(dataW / 8), "the data width must be a power of 2 multiple of bytes")
require(userW >= 0, "the user with must be a non-negative integer")
val data = UInt(dataW.W)
val strb = UInt((dataW/8).W)
val last = Bool()
val user = UInt(userW.W)
}
Expand All @@ -95,16 +140,37 @@ object WD {
}
}

/** AXI4 write response
/** AXI4 Lite write response
*
* @param idW the width of the BID signal in bits
*/
class WRLite extends Bundle {
val resp = UInt(2.W)
}
object WRLite {
/** Alternative constructor
*
* @return an unitialized WRLite object
*/
def apply() = new WRLite()

/** Default values for this channel
*
* @param in a WRLite object
* @return an initialized (hardware) WRLite object
*/
def default(in: WRLite) = (new WRLite()).Lit(_.resp -> ResponseEncodings.Okay)
}

/** AXI4 full write response
*
* @param idW the width of the BID signal in bits
* @param userW the width of the BUSER signal in bits
*/
class WR(val idW: Int, val userW: Int) extends Bundle {
class WR(val idW: Int, val userW: Int) extends WRLite {
require(idW >= 0, "the id width must be a non-negative integer")
require(userW >= 0, "the user with must be a non-negative integer")
val id = UInt(idW.W)
val resp = UInt(2.W)
val user = UInt(userW.W)
}
object WR {
Expand All @@ -129,24 +195,46 @@ object WR {
}
}

/** AXI4 read address
/** AXI4 Lite read address
*
* @param addrW the width of the ARADDR signal in bits
*/
class RALite(val addrW: Int) extends Bundle {
require(addrW > 0, "the address width must be a positive integer")
val addr = UInt(addrW.W)
val prot = UInt(3.W)
}
object RALite {
/** Alternative constructor
*
* @param addrW the width of the ARADDR signal in bits
* @return an unitialized RALite object
*/
def apply(addrW: Int) = new RALite(addrW)

/** Default values for this channel
*
* @param in a RALite object
* @return an initialized (hardware) RALite object
*/
def default(in: RALite) = (new RALite(in.addrW)).Lit(_.addr -> 0.U, _.prot -> ProtectionEncodings.DataNsecUpriv)
}

/** AXI4 full read address
*
* @param addrW the width of the ARADDR signal in bits
* @param idW the width of the ARID signal in bits
* @param userW the width of the ARUSER signal in bits
*/
class RA(val addrW: Int, val idW: Int, val userW: Int) extends Bundle {
require(addrW > 0, "the address width must be a positive integer")
class RA(override val addrW: Int, val idW: Int, val userW: Int) extends RALite(addrW) {
require(idW >= 0, "the id width must be a non-negative integer")
require(userW >= 0, "the user with must be a non-negative integer")
val id = UInt(idW.W)
val addr = UInt(addrW.W)
val len = UInt(8.W)
val size = UInt(3.W)
val burst = UInt(2.W)
val lock = Bool()
val cache = UInt(4.W)
val prot = UInt(3.W)
val qos = UInt(4.W)
val region = UInt(4.W)
val user = UInt(userW.W)
Expand Down Expand Up @@ -177,19 +265,44 @@ object RA {
}
}

/** AXI4 read data
/** AXI4 Lite read data
*
* @param dataW the width of the RDATA signal in bits
* @param idW the width of the RID signal in bits
* @param userW the width of the RUSER signal in bits
*/
class RDLite(val dataW: Int) extends Bundle {
require(dataW == 32 || dataW == 64, "the data width must be either 32 or 64 bits")
val data = UInt(dataW.W)
val resp = UInt(2.W)
}
object RDLite {
/** Alternative constructor
*
* @param dataW the width of the RDATA signal in bits, defaults to 32
* @return an uninitialized RDLite object
*/
def apply(dataW: Int = 32) = new RDLite(dataW)

/** Default values for this channel
*
* @param in a RDLite object
* @return an initialized (hardware) RDLite object
*/
def default(in: RDLite) = (new RDLite(in.dataW)).Lit(_.data -> 0.U, _.resp -> ResponseEncodings.Okay)
}

/** AXI4 full read data
*
* @param dataW the width of the RDATA signal in bits
* @param idW the width of the RID signal in bits
* @param userW the width of the RUSER signal in bits
*/
class RD(val dataW: Int, val idW: Int, val userW: Int) extends Bundle {
class RD(override val dataW: Int, val idW: Int, val userW: Int) extends RDLite(dataW) {
require(isPow2(dataW / 8), "the data width must be a power of 2 multiple of bytes")
require(idW >= 0, "the id width must be a non-negative integer")
require(userW >= 0, "the user with must be a non-negative integer")
val id = UInt(idW.W)
val data = UInt(dataW.W)
val resp = UInt(2.W)
val last = Bool()
val user = UInt(userW.W)
}
Expand Down
70 changes: 56 additions & 14 deletions axi4/src/main/scala/axi4/Interfaces.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,56 @@ package axi4
import chisel3._
import chisel3.util.Decoupled

/** AXI4 master interface
/** AXI4-Lite master interface
*
* @param addrW the width of the address signals in bits
* @param dataW the width of the data read/write signals in bits
*/
class MasterInterfaceLite(val addrW: Int, val dataW: Int) extends Bundle {
/** Fields implementing each of the AXI channels
*
* [[wa]] is the write address channel
* [[wd]] is the write data channel
* [[wr]] is the write response channel
* [[ra]] is the read address channel
* [[rd]] is the read data channel
*/
val wa = Decoupled(Output(WALite(addrW)))
val wd = Decoupled(Output(WDLite(dataW)))
val wr = Flipped(Decoupled(Output(WRLite())))
val ra = Decoupled(RALite(addrW))
val rd = Flipped(Decoupled(Output(RDLite(dataW))))
}

/** AXI4 full master interface
*
* @param addrW the width of the address signals in bits
* @param dataW the width of the data read/write signals in bits
* @param idW the width of the ID signals in bits, defaults to 0
* @param userW the width of the user signals in bits, defaults to 0
*/
class MasterInterface(val addrW: Int, val dataW: Int, val idW: Int = 0, val userW: Int = 0) extends Bundle {
class MasterInterface(override val addrW: Int, override val dataW: Int, val idW: Int = 0, val userW: Int = 0) extends MasterInterfaceLite(addrW, dataW) {
/** Fields implementing each of the AXI channels
*
* [[wa]] is the write address channel
* [[wd]] is the write data channel
* [[wr]] is the write response channel
* [[ra]] is the read address channel
* [[rd]] is the read data channel
*/
override val wa = Decoupled(Output(WA(addrW, idW, userW)))
override val wd = Decoupled(Output(WD(dataW, userW)))
override val wr = Flipped(Decoupled(Output(WR(idW, userW))))
override val ra = Decoupled(RA(addrW, idW, userW))
override val rd = Flipped(Decoupled(Output(RD(dataW, idW, userW))))
}

/** AXI4-Lite slave interface
*
* @param addrW the width of the address signals in bits
* @param dataW the width of the data read/write signals in bits
*/
class SlaveInterfaceLite(val addrW: Int, val dataW: Int) extends Bundle {
/** Fields implementing each of the AXI channels
*
* [[wa]] is the write address channel
Expand All @@ -27,21 +69,21 @@ class MasterInterface(val addrW: Int, val dataW: Int, val idW: Int = 0, val user
* [[ra]] is the read address channel
* [[rd]] is the read data channel
*/
val wa = Decoupled(Output(WA(addrW, idW, userW)))
val wd = Decoupled(Output(WD(dataW, userW)))
val wr = Flipped(Decoupled(Output(WR(idW, userW))))
val ra = Decoupled(RA(addrW, idW, userW))
val rd = Flipped(Decoupled(Output(RD(dataW, idW, userW))))
val wa = Flipped(Decoupled(Output(WALite(addrW))))
val wd = Flipped(Decoupled(Output(WDLite(dataW))))
val wr = Decoupled(Output(WRLite()))
val ra = Flipped(Decoupled(Output(RALite(addrW))))
val rd = Decoupled(Output(RDLite(dataW)))
}

/** AXI4 slave interface
/** AXI4 full slave interface
*
* @param addrW the width of the address signals in bits
* @param dataW the width of the data read/write signals in bits
* @param idW the width of the ID signals in bits, defaults to 0
* @param userW the width of the user signals in bits, defaults to 0
*/
class SlaveInterface(val addrW: Int, val dataW: Int, val idW: Int = 0, val userW: Int = 0) extends Bundle {
class SlaveInterface(override val addrW: Int, override val dataW: Int, val idW: Int = 0, val userW: Int = 0) extends SlaveInterfaceLite(addrW, dataW) {
/** Fields implementing each of the AXI channels
*
* [[wa]] is the write address channel
Expand All @@ -50,9 +92,9 @@ class SlaveInterface(val addrW: Int, val dataW: Int, val idW: Int = 0, val userW
* [[ra]] is the read address channel
* [[rd]] is the read data channel
*/
val wa = Flipped(Decoupled(Output(WA(addrW, idW, userW))))
val wd = Flipped(Decoupled(Output(WD(dataW, userW))))
val wr = Decoupled(Output(WR(idW, userW)))
val ra = Flipped(Decoupled(Output(RA(addrW, idW, userW))))
val rd = Decoupled(Output(RD(dataW, idW, userW)))
override val wa = Flipped(Decoupled(Output(WA(addrW, idW, userW))))
override val wd = Flipped(Decoupled(Output(WD(dataW, userW))))
override val wr = Decoupled(Output(WR(idW, userW)))
override val ra = Flipped(Decoupled(Output(RA(addrW, idW, userW))))
override val rd = Decoupled(Output(RD(dataW, idW, userW)))
}
26 changes: 24 additions & 2 deletions axi4/src/main/scala/axi4/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,18 @@
import chisel3._

package object axi4 {
/** AXI4 master
/** AXI4-Lite master
*
* An empty class representing an AXI master
*
* @param addrW the width of the address signals in bits
* @param dataW the width of the data read/write signals in bits
*/
abstract class LiteMaster(val addrW: Int, val dataW: Int) extends Module {
val io = IO(new MasterInterfaceLite(addrW, dataW))
}

/** AXI4 full master
*
* An empty class representing an AXI master
*
Expand All @@ -22,7 +33,18 @@ package object axi4 {
val io = IO(new MasterInterface(addrW, dataW, idW, userW))
}

/** AXI4 slave
/** AXI4-Lite slave
*
* An empty class representing an AXI slave
*
* @param addrW the width of the address signals in bits
* @param dataW the width of the data read/write signals in bits
*/
abstract class LiteSlave(val addrW: Int, val dataW: Int) extends Module {
val io = IO(new SlaveInterfaceLite(addrW, dataW))
}

/** AXI4 full slave
*
* An empty class representing an AXI slave
*
Expand Down

0 comments on commit e0a3c22

Please sign in to comment.