All Downloads are FREE. Search and download functionalities are using the official Maven repository.

spinal.lib.bus.wishbone.WishboneSlaveFactory.scala Maven / Gradle / Ivy

There is a newer version: 1.10.2a
Show newest version
/**@todo: Support RTY signal*/
/**@todo: SUpport Burts mode (specially for memory)*/

package spinal.lib.bus.wishbone

import spinal.core._
import spinal.lib.bus.misc._
import scala.collection.Seq

/** Factory for [[spinal.lib.bus.wishbone.WishboneSlaveFactory]] instances. */
object WishboneSlaveFactory {
  /** This is the slave facotory fot the wishbone bus
    * @param bus the wishbone bus istance that will connect with the module
    * @return an instanciated class of [[spinal.lib.bus.wishbone.WishboneSlaveFactory]]
    */
  def apply(bus: Wishbone,reg_fedback: Boolean = true) = new WishboneSlaveFactory(bus,reg_fedback)
}

/** This is the slave facotory fot the wishbone bus
  * @param bus the wishbone bus istance that will connect with the module
  * @param reg_fedback if set to false, the slave will acknoledge as soon as possible otherwise will wait the next clock cycle(default)
  */
class WishboneSlaveFactory(bus: Wishbone,reg_fedback: Boolean = true) extends BusSlaveFactoryDelayed{
  bus.DAT_MISO := 0
  if(bus.config.isPipelined) bus.STALL := False

  val askWrite = bus.isWrite.allowPruning()
  val askRead = bus.isRead.allowPruning()
  val doWrite = bus.doWrite.allowPruning()
  val doRead = bus.doRead.allowPruning()

  if(!reg_fedback){
    bus.ACK := bus.STB && bus.CYC                 //Acknoledge as fast as possible
  } else if(bus.config.isPipelined){
    val pip_reg = RegNext(bus.STB) init(False)
    bus.ACK := pip_reg || (bus.STALL && bus.CYC)  //Pipelined: Acknoledge at the next clock cycle
  } else {
    val reg_reg = RegNext(bus.STB && bus.CYC) init(False)
    bus.ACK := reg_reg && bus.STB                 //Classic: Acknoledge at the next clock cycle
  }

  val byteAddress = bus.ADR << log2Up(bus.config.dataWidth/8)

  override def readAddress()  = byteAddress
  override def writeAddress() = byteAddress

  override def readHalt() = bus.ACK := False
  override def writeHalt() = bus.ACK := False

  override def busDataWidth = bus.config.dataWidth
  override def wordAddressInc = busDataWidth / 8
  override def writeByteEnable() = bus.SEL

  override def build(): Unit = {
    super.doNonStopWrite(bus.DAT_MOSI)

    def doMappedElements(jobs : Seq[BusSlaveFactoryElement]) = super.doMappedElements(
      jobs = jobs,
      askWrite = askWrite,
      askRead = askRead,
      doWrite = doWrite,
      doRead = doRead,
      writeData = bus.DAT_MOSI,
      readData = bus.DAT_MISO
    )

    switch(byteAddress) {
      for ((address, jobs) <- elementsPerAddress if address.isInstanceOf[SingleMapping]) {
        is(address.asInstanceOf[SingleMapping].address) {
          doMappedElements(jobs)
        }
      }
    }

    for ((address, jobs) <- elementsPerAddress if !address.isInstanceOf[SingleMapping]) {
      when(address.hit(byteAddress)){
        doMappedElements(jobs)
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy