chisel3
Chisel3 的 GitHub 仓库中找到它的源代码:GitHub - chipsalliance/chisel: Chisel: A Modern Hardware Design Language
Chisel3文档地址:chisel_2.13 6.0.0-M2 javadoc (org.chipsalliance)
Arbiter
https://github.com/chipsalliance/chisel/blob/main/src/main/scala/chisel3/util/Arbiter.scala
Arbiter模块位于Chiel3的util包中,util包提供了一些常用的工具类和函数。如:
- 数据结构,如Decoupled、Valid等。
- FIFO和队列,如Queue、Pipe等。
- 握手协议,如DecoupledIO、ValidIO等。
- 时钟和复位,如:withClock、withReset等。
- 多路选择,如Mux1H、MuxLookup等。
提供四种仲裁:
- Arbiter,普通Arbiter,根据优先级选择,该模块里优先级按照索引从大到小排列。
- RRArbiter,使用轮询调度算法的Arbiter,每次仲裁会确保下一次的授权比上一次的授权id大。
- LockingArbiter
- LockingRRArbiter
Arbiter
1、ArbiterIO类:
classArbiterIO[T <: Data](private val gen: T, val n: Int) extendsBundle{}
该类定义仲裁器的端口。参数gen数据类型的数据,n为输入数量。
val in = Flipped(Vec(n, Decoupled(gen)))
val out = Decoupled(gen)
val chosen = Output(UInt(log2Ceil(n).W))
Decoupled表示带有有效位(ready-valid)和数据的流式接口。
2、ArbiterCtrl
该方法根据请求的信号,计算出相应的一组控制信号。确定哪个输入信号有权访问资源。
具体:
- 如果请求长度为0,则返回空的seq,表示没有请求。
- 如果请求长度为1,则返回一个包含true值的seq,表示只有一个请求信号,该信号有权访问资源。
- 如果请求长度大于1,使用.tail.init得到request去除第一个和最后一个元素外的所有元素,并使用scanLeft方法依次对这些元素执行或操作。该方法是对序列进行迭代操作,从request第一位开始,即request.head,每次计算都使用当前元素与前一次计算结果进行逻辑或运算。然后,.map对每一个元素取反。最后,序列前面加上true。计算结果是第一位和除第一位外的request第一个一的位置为一,其他位为0.
3、Arbiter
第一个请求始终仲裁成功,之后的请求根据valid值依次判断。
in.ready := g && io.out.ready
io.out.valid := !grant.last || io.in.last.valid
LockingArbiter
class LockingArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool] = None) extends LockingArbiterLike[T](gen, n, count, needsLock){}
参数包括:
- gen:T(表示数据类型)
- n:Int(表示输入的数量)
- count:Int(锁定计数)
- needsLock: Option[T => Bool] = None(根据需求来控制仲裁器的锁定行为)
带锁定的Arbiter会根据count计数器来进行条件分支的处理:
- 如果count>1,则为锁定仲裁器。首先,会创建一个计数器lockCount和一个寄存器lockIdx来记录锁定的的输入端口。然后,根据根据wantsLock来确定是否进行锁定。满足锁定条件时,更新计数器和lockIdx。最后,锁定状态和授权信号来设置输入端口的ready状态,锁定的话就只赋予lockIdx值的端口输入ready。
- count<1,则根据授权信号和io.out.ready来决定in.ready。
RRArbiter
lazy val
是 Scala 语言中的一个特性,用于声明延迟计算的值。延迟计算意味着该值只有在需要时才会被计算,而不是立即计算。这样可以提高性能和效率,因为只有在真正需要使用该值时才进行计算,避免了不必要的计算开销。
1、RegEnable
RegEnable是chisel中的一个函数:
defRegEnable[T <: Data](next: T, enable: Bool): T
参数说明:
- next:下一个时钟周期要写入寄存器的值,类型为T<:Data,表示Chisel的数据类型。
- enable:使能信号,类型为bool。
函数功能:
- 在时钟上升沿时,如果 enable 为真,则将 next 的值写入到寄存器中;否则保持原来的值不变。
- 返回值为 T 类型,表示输出的寄存器值。
2、grantMask,通过比较索引值(0到n-1)和lastGrant来生成true或false。
3、validMask,使用zip将信号io.in和grantMask进行配对,然后通过map函数对配对组进行计算in.valid&&g。
仲裁按照此两个循环进行,第一个循环是保证在没有合适的validMask(i)时,选择一个valid值对应的i进行输出。正常来说是,validMask(i)来决定choice。