spinal.lib.bus.amba3.apb.Apb3CCToggle.scala Maven / Gradle / Ivy
The newest version!
/* *\
** _____ ____ _____ _____ __ **
** / ___// __ \/ _/ | / / | / / 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.apb
import spinal.core._
import spinal.lib._
import spinal.lib.fsm._
case class Apb3CC(config : Apb3Config,
inputClock : ClockDomain,
outputClock : ClockDomain) extends Component{
assert(config.selWidth == 1)
val io = new Bundle {
val input = slave(Apb3(config))
val output = master(Apb3(config))
}
case class Cmd() extends Bundle{
val PADDR = UInt(config.addressWidth bits)
val PWRITE = Bool()
val PWDATA = Bits(config.dataWidth bits)
}
case class Rsp() extends Bundle{
val PRDATA = Bits(config.dataWidth bits)
val PSLVERROR = if(config.useSlaveError) Bool() else null
}
val inputLogic = new ClockingArea(inputClock){
val inputCmd = Flow(Cmd())
val inputRsp = Flow(Rsp())
val state = RegInit(False) setWhen(inputCmd.fire) clearWhen(inputRsp.valid)
inputCmd.valid := io.input.PSEL.lsb && io.input.PENABLE && !state
inputCmd.PADDR := io.input.PADDR
inputCmd.PWRITE := io.input.PWRITE
inputCmd.PWDATA := io.input.PWDATA
io.input.PREADY := inputRsp.valid
io.input.PRDATA := inputRsp.PRDATA
if(config.useSlaveError) io.input.PSLVERROR := inputRsp.PSLVERROR
}
val outputLogic = new ClockingArea(outputClock){
val outputCmdFlow = FlowCCUnsafeByToggle(inputLogic.inputCmd, inputClock, outputClock, withOutputM2sPipe = false)
val outputCmd = outputCmdFlow.toStream.m2sPipe(crossClockData = true, holdPayload = true)
val state = RegInit(False)
io.output.PENABLE := False
io.output.PSEL := 0
io.output.PADDR := outputCmd.PADDR
io.output.PWDATA := outputCmd.PWDATA
io.output.PWRITE := outputCmd.PWRITE
outputCmd.ready := False
when(outputCmd.valid) {
io.output.PSEL := 1
when(!state) {
io.output.PENABLE := False
state := True
} otherwise {
io.output.PENABLE := True
when(io.output.PREADY){
outputCmd.ready := True
state := False
}
}
}
val outputRsp = Flow(Rsp())
outputRsp.valid := outputCmd.fire
outputRsp.PRDATA := io.output.PRDATA
if(config.useSlaveError) outputRsp.PSLVERROR := io.output.PSLVERROR
inputLogic.inputRsp := FlowCCUnsafeByToggle(outputRsp, outputClock, inputClock)
}
}
/**
* Apb3 Cross Clock Domain by toggling
*
* @param busConfig Apb3 configuration
* @param inClk Input Clock Domain
* @param outClk Output Clock Domain
* @param selIds Sequence indicating to which PSEL(x) signals the component replies to.
*/
class Apb3CCToggle(busConfig: Apb3Config, inClk: ClockDomain, outClk: ClockDomain, selIds: Seq[Int] = Seq(0)) extends Component {
val io = new Bundle{
val input = slave(Apb3(busConfig))
val output = master(Apb3(busConfig))
}
assert(selIds == Seq(0))
val cc = Apb3CC(busConfig, inClk, outClk)
cc.io.input <> io.input
cc.io.output <> io.output
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy