Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* *\
** _____ ____ _____ _____ __ **
** / ___// __ \/ _/ | / / | / / HDL Lib **
** \__ \/ /_/ // // |/ / /| | / / (c) Dolu, All rights reserved **
** ___/ / ____// // /| / ___ |/ /___ **
** /____/_/ /___/_/ |_/_/ |_/_____/ MIT Licence **
** **
** Permission is hereby granted, free of charge, to any person obtaining a **
** copy of this software and associated documentation files (the "Software"),**
** to deal in the Software without restriction, including without limitation **
** the rights to use, copy, modify, merge, publish, distribute, sublicense, **
** and/or sell copies of the Software, and to permit persons to whom the **
** Software is furnished to do so, subject to the following conditions: **
** **
** The above copyright notice and this permission notice shall be included **
** in all copies or substantial portions of the Software. **
** **
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS **
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF **
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. **
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY **
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT **
** OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR **
** THE USE OR OTHER DEALINGS IN THE SOFTWARE. **
\* */
package spinal.lib.bus.amba3.ahblite
import spinal.core._
import spinal.lib._
/**
* AHB on chip RAM
*
* @param AhbLite3Config : Ahb bus configuration
* @param byteCount : Size of the RAM
*/
case class AhbLite3OnChipRam(AhbLite3Config: AhbLite3Config, byteCount: BigInt) extends Component {
val io = new Bundle {
val ahb = slave(AhbLite3(AhbLite3Config))
}
val wordCount = byteCount / AhbLite3Config.bytePerWord
val ram = Mem(AhbLite3Config.dataType, wordCount.toInt)
val wordRange = log2Up(wordCount) + log2Up(AhbLite3Config.bytePerWord) - 1 downto log2Up(AhbLite3Config.bytePerWord)
// Address/control phase to write data phase
val pendingWrite = Reg(new Bundle{
val valid = Bool()
val address = ram.addressType()
val mask = Bits(AhbLite3Config.bytePerWord bits)
})
pendingWrite.valid init(False)
pendingWrite.valid := False
when(io.ahb.HREADY){
pendingWrite.valid := io.ahb.HSEL && io.ahb.HTRANS(1) && io.ahb.HWRITE
pendingWrite.address := io.ahb.HADDR(wordRange)
pendingWrite.mask := io.ahb.writeMask
}
io.ahb.setOKEY
// Avoid write to read hazards
io.ahb.HREADYOUT := !(io.ahb.HSEL && io.ahb.HTRANS(1) && !io.ahb.HWRITE && pendingWrite.valid && io.ahb.HADDR(wordRange) === pendingWrite.address)
io.ahb.HRDATA := ram.readSync(
address = io.ahb.HADDR(wordRange),
enable = io.ahb.HSEL && io.ahb.HTRANS(1) && !io.ahb.HWRITE && io.ahb.HREADY
)
ram.write(
enable = pendingWrite.valid,
address = pendingWrite.address,
mask = pendingWrite.mask,
data = io.ahb.HWDATA
)
}
case class AhbLite3OnChipRamMultiPort(portCount : Int, AhbLite3Config: AhbLite3Config, byteCount: BigInt) extends Component {
val io = new Bundle {
val ahbs = Vec(slave(AhbLite3(AhbLite3Config)), portCount)
}
val wordCount = byteCount / AhbLite3Config.bytePerWord
val ram = Mem(AhbLite3Config.dataType, wordCount.toInt)
val wordRange = log2Up(wordCount) + log2Up(AhbLite3Config.bytePerWord) - 1 downto log2Up(AhbLite3Config.bytePerWord)
for(ahb <- io.ahbs) {
// Address/control phase to write data phase
val pending = Reg(new Bundle {
val valid = Bool()
val write = Bool()
val readInvalid = Bool()
val address = ram.addressType()
val mask = Bits(AhbLite3Config.bytePerWord bits)
})
val addressPhaseCanRead = ahb.HREADY && !(pending.valid && (pending.write || pending.readInvalid))
val ramAddress = Mux(addressPhaseCanRead, ahb.HADDR(wordRange), pending.address)
pending.valid init (False)
when(ahb.HREADY) {
pending.valid := ahb.HSEL && ahb.HTRANS(1) && ahb.HWRITE
pending.write := ahb.HWRITE
pending.readInvalid := !addressPhaseCanRead
pending.address := ahb.HADDR(wordRange)
pending.mask := ahb.writeMask
}
ahb.setOKEY
// Avoid write to read hazards
ahb.HREADYOUT := !(ahb.HSEL && ahb.HTRANS(1) && !ahb.HWRITE && pending.valid && pending.write && ahb.HADDR(wordRange) === pending.address) && !(pending.valid && pending.readInvalid)
ahb.HRDATA := ram.readSync(
address = ramAddress
// enable = (ahb.HSEL && ahb.HTRANS(1) && !ahb.HWRITE && ahb.HREADY) || (pending.valid && pending.readInvalid)
)
ram.write(
enable = pending.valid,
address = ramAddress,
mask = pending.mask,
data = ahb.HWDATA
)
when(pending.valid && pending.readInvalid){
pending.readInvalid := False
}
}
}