## Utils(实用工具) 有一些实用工具已在Spinal.core(请见**其他语言特征**章节中的Utils部分)。 ### 一、State less utilities(免状态工具) | 句式 | 返回类型 | 描述 | | :-------------------------------------------------------------------------: | :------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | | `toGray(x : UInt)` | Bits | 返回X的格雷码 | | `fromGray(x : Bits)` | UInt | 返回格雷码X转换后的UInt值 | | `Reverse(x : T)` | T | 翻转所有比特 (lsb + n -> msb - n) | | `OHToUInt(x : Seq[Bool])`
`OHToUInt(x : BitVector)` | UInt | 返回独热编码`x`中1的坐标 | | `CountOne(x : Seq[Bool])`
`CountOne(x : BitVector)` | UInt | 返回`x`中1的个数 | | `MajorityVote(x : Seq[Bool])`
`MajorityVote(x : BitVector)` | Bool | 当1的数量>(x.size/2)时, 返回true | | `EndiannessSwap(that: T[, base:BitCount])` | T | Big-Endian <-> Little-Endian 大头端与小头端互换 | | `OHMasking.first(x : Bits)` | Bits | 保持x中的第一个比特1不变 | | `OHMasking.last(x : Bits)` | Bits | 保持x中的最后一个比特1不变 | | `OHMasking.roundRobin(`
`requests : Bits,`
`ohPriority : Bits`
`)` | Bits | 根据`ohPriority`给出的优先级使得`requests`中的某个比特1保持不变。例如, 假设`requests`等于"1001", `ohPriority`等于"0010", 则`roundRobin`函数会根据`ohPriority`提供的优先级对`requests`进行轮询仲裁, 并且返回"1000" | | `MuxOH (`
`oneHot : IndexedSeq[Bool],`
`inputs : Iterable[T]`
`)` | T | 根据`oneHot`向量提供的信息, 对输入`inputs`进行选通并返回选通后的`T` | | `PriorityMux (`
`sel: Seq[Bool],`
`in: Seq[T]`
`)` | T | 返回`in`中第一个对应`sel`位为`True`的元素 | | `PriorityMux (`
`in: Seq[(Bool, T)]`
`)` | T | 返回`in`中第一个对应`sel`位为`True`的元素 | ### 二、State full utilities(全状态工具) | 句式 | 返回类型 | 描述 | | :-------------------------------------------: | :------: | :----------------------------------------------------------------------------------------------------------------------------------: | | `Delay(that: T, cycleCount: Int)` | T | 延迟`cycleCount`个周期后返回`that` | | `History(that: T, length: Int[,when : Bool])` | List[T] | 返回一个长度为`length`的向量。其中第一个元素是`that`, 最后一个是延迟(`length`-1)后的`that`。内部的移位寄存器会在`when`有效时进行采样 | | `BufferCC(input : T)` | T | 返回利用两个触发器同步到当前时钟域的同步输入信号 | 1. 计数器 Counter工具可以用来实例化一个硬件计数器。 | 句式 | 描述 | | :-------------------------------------------------: | :-------------------------------------: | | `Counter(start: BigInt, end: BigInt[, inc : Bool])` | 无 | | `Counter(range : Range[, inc : Bool])` | 与`x to y``x until y`语句匹配 | | `Counter(stateCount: BigInt[, inc : Bool])` | 从0开始计数, 到`statecCount - 1`结束 | | `Counter(bitCount: BitCount[, inc : Bool])` | 从0开始计数, 到`(1 << bitCoun) - 1`结束 | 一个计数器可以被方法所控制, 并且导线可以被读取: ```Scala val counter = Counter(2 to 9) // 建立一个八状态计数器 (2 to 9) // 方法 counter.clear() // 复位计数器 counter.increment() // 计数增加 // Wires counter.value // 当前值 counter.valueNext // 下一个值 counter.willOverflow // 若当前循环计数器溢出, 则返回true counter.willOverflowIfInc // 若当前循环增加一会导致计数器溢出, 则返回true // Cast搜寻 when(counter === 5){ ... } // 计数器会隐式地投射搜寻到当前值 ``` 当一个是计数器溢出(达到最终值), 它会在下一个周期重启并设置为初始值。`CounterFreeRun`构建一个始终运行的计数器:`CounterFreeRun(stateCount: BigInt)`。 2. 超时(Timeout) Timeout工具可以用来方便地例化一个硬件Timeout。 | 例化句式 | 描述 | | :--------------------------------: | :-----------------------------: | | `Timeout(cycles : BigInt)` | `cycles`个时钟后进行标记 | | `Delay(that: T, cycleCount: Int)` | 持续`time`时间后进行标记 | | `Timeout(frequency : HertzNumber)` | 以`frequency`的速率进行计时标记 | 下方代码举例了可以和Counter工具一起使用的不同语法句式的例子: ```Scala val timeout = Timeout(10 ms) //计时10ms后的对象会被记为超时 when(timeout){ //检查是否被判断为超时 timeout.clear() //请求timeout工具清空他的标志位 } ``` > **备注:如果使用时间或频率设置实例化`Timeout`, 则隐含的`ClockDomain`应该具有频率设置。** 3. 复位控制(ResetControl) 复位控制提供了一些工具以管理复位。 - asyncAssertSyncDeassert 用户可以利用一个异步有效同步无效(asynchronously asserted synchronously de-asserted)逻辑来筛选异步复位。可以使用`ResetCtrl.asyncAssertSyncDeassert`函数来筛选并返回相应的值。 | 声明命名 | 返回类型 | 描述 | | :------------: | :---------: | :----------------------------------------------------: | | input | Bool | 筛选的信号 | | clockDomain | ClockDomain | 返回将要使用所筛选值的时钟域 | | inputPolarity | Polarity | HIGH/LOW (default=HIGH) | | outputPolarity | Polarity | HIGH/LOW (default=clockDomain.config.resetActiveLevel) | | bufferDepth | Int | 防止亚稳态所需的寄存器级数(默认为2) | 另外有一个ResetCtrl.asyncAssertSyncDeassertDrive版本的工具, 它直接分配clockDomain以重置的值。 ### 三、特殊工具(Special utilities) | 句式 | 返回类型 | 描述 | | :------------------------------: | :------: | :--------------------------------------------------: | | `LatencyAnalysis(paths : Node*)` | Int | 以周期为单位返回从第一个节点到最后一个节点的最短路径 |