Skip to content

Commit

Permalink
add slots demo
Browse files Browse the repository at this point in the history
  • Loading branch information
Dolu1990 committed Jul 24, 2023
1 parent 2f46857 commit 7a0fc87
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 0 deletions.
68 changes: 68 additions & 0 deletions examples/src/main/scala/spinaldoc/examples/advanced/Slots.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package spinaldoc.examples.advanced

import spinal.core._
import spinal.lib._
import scala.language.postfixOps

case class SlotsDemo(slotsCount : Int) extends Component {
//...


//Create the hardware for each slot
//Note each slot is an Area, not a Bundle
val slots = for(i <- 0 until slotsCount) yield new Area{
//Because the slot is an Area, we can define mix signal, registers, logic definitions
//Here are the registers for each slots
val valid = RegInit(False)
val address = Reg(UInt(8 bits))
val age = Reg(UInt(16 bits)) //Will count since how many cycles the slot is valid

//Here is some hardware behaviour for each slots
//Implement the age logic
when(valid){
age := age + 1
}

//removeIt will be used as a slot interface later on
val removeIt = False
when(removeIt){
valid := False
}
}

//Logic to allocate a new slot
val insert = new Area{
val cmd = Stream(UInt(8 bits)) //interface to issue requests
val free = slots.map(!_.valid)
val freeOh = OHMasking.first(free) //Get the first free slot (on hot mask)
cmd.ready := free.orR //Only allow cmd when there is a free slot
when(cmd.fire){
//slots.onMask(freeOh)(code) will execute the code for each slot where the corresponding freeOh bit is set
slots.onMask(freeOh){slot =>
slot.valid := True
slot.address := cmd.payload
slot.age := 0
}
}
}

//Logic to remove the slots which match a given address (assuming there is not more than one match)
val remove = new Area{
val cmd = Flow(UInt(8 bits))//interface to issue requests
val oh = slots.map(s => s.valid && s.address === cmd.payload) //oh meaning "one hot"
when(cmd.fire){
slots.onMask(oh){ slot =>
slot.removeIt := True
}
}

val reader = slots.reader(oh) //Create a facility to read the slots using "oh" as index
val age = reader(_.age) //Age of the slot which is selected by "oh"
}

//...
}

object SlotsDemo extends App {
SpinalVerilog(SlotsDemo(4))
}
20 changes: 20 additions & 0 deletions source/SpinalHDL/Examples/Advanced ones/slots.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.. _Slots:

Slots
=====

Introduction
------------

Let's say you have some hardware which has to keep track of multiple similar ongoing activities, you may want to implement an array of "slots" to do so. This example show how to do it using Area, OHMasking.first, onMask and reader.


Implementation
^^^^^^^^^^^^^^

This implementation avoid the use of Vec. Instead, it use Area which allow to mix signal, registers and logic definitions in each slot.

.. literalinclude:: /../examples/src/main/scala/spinaldoc/examples/advanced/Timer.scala
:language: scala


0 comments on commit 7a0fc87

Please sign in to comment.