diff --git a/axi4/src/main/scala/axi4/Bundles.scala b/axi4/src/main/scala/axi4/Bundles.scala index cbf1fe6..50d49fb 100644 --- a/axi4/src/main/scala/axi4/Bundles.scala +++ b/axi4/src/main/scala/axi4/Bundles.scala @@ -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) @@ -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) } @@ -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 { @@ -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) @@ -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) } diff --git a/axi4/src/main/scala/axi4/Interfaces.scala b/axi4/src/main/scala/axi4/Interfaces.scala index 73a2e39..ce78eea 100644 --- a/axi4/src/main/scala/axi4/Interfaces.scala +++ b/axi4/src/main/scala/axi4/Interfaces.scala @@ -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 @@ -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 @@ -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))) } diff --git a/axi4/src/main/scala/axi4/package.scala b/axi4/src/main/scala/axi4/package.scala index 229204f..776724e 100644 --- a/axi4/src/main/scala/axi4/package.scala +++ b/axi4/src/main/scala/axi4/package.scala @@ -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 * @@ -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 *