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

spinal.lib.sim.Flow.scala Maven / Gradle / Ivy

There is a newer version: 1.10.2a
Show newest version
package spinal.lib.sim

import spinal.core.{ClockDomain, Data}
import spinal.core.sim._
import spinal.lib.Flow

import scala.collection.mutable.{Queue, ArrayBuffer}
import scala.util.Random

object FlowMonitor{
  def apply[T <: Data](Flow : Flow[T], clockDomain: ClockDomain)(callback : (T) => Unit) = new FlowMonitor(Flow,clockDomain).addCallback(callback)
}

class FlowMonitor[T <: Data](Flow : Flow[T], clockDomain: ClockDomain){
  val callbacks = ArrayBuffer[(T) => Unit]()

  def addCallback(callback : (T) => Unit): this.type = {
    callbacks += callback
    this
  }

  clockDomain.onSamplings{
    if(Flow.valid.toBoolean) callbacks.foreach(_ (Flow.payload))
  }
}

object FlowDriver {
  def apply[T <: Data](flow: Flow[T], clockDomain: ClockDomain)(driver: (T) => Boolean) =
    new FlowDriver(flow, clockDomain, driver)

  def queue[T <: Data](flow: Flow[T], clockDomain: ClockDomain) = {
    val cmdQueue = Queue[(T) => Unit]()
    val driver = FlowDriver(flow, clockDomain) { p =>
      if (cmdQueue.isEmpty) false
      else {
        cmdQueue.dequeue().apply(p)
        true
      }
    }
    (driver, cmdQueue)
  }
}

class FlowDriver[T <: Data](flow: Flow[T], clockDomain: ClockDomain, var driver: (T) => Boolean) {
  var transactionDelay: () => Int = () => {
    val x = Random.nextDouble()
    (x * x * 10).toInt
  }

  var state = 0
  var delay = transactionDelay()
  flow.valid #= false
  flow.payload.randomize()

  def fsm(): Unit = {
    state match {
      case 0 => {
        if (delay == 0) {
          state += 1
          fsm()
        } else {
          delay -= 1
        }
      }
      case 1 => {
        if (driver(flow.payload)) {
          flow.valid #= true
          state += 1
        }
      }
      case 2 => {
        flow.valid #= false
        flow.payload.randomize()
        delay = transactionDelay()
        state = 0
        fsm()
      }
    }
  }
  clockDomain.onSamplings(fsm)

  def reset() {
    state = 0
    flow.valid #= false
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy