跳转至

VecRotate 工具类

VecRotate 用于对 Vec 类型的信号做循环移位,目前主要应用于 Bpu 的 half-align 设计中。

Vec(0, 1, 2, 3) -- rotate(1) --> Vec(3, 0, 1, 2)
Vec(0, 1, 2, 3) -- rotate(2) --> Vec(2, 3, 0, 1)
Vec(0, 1, 2, 3) -- rotate(3) --> Vec(1, 2, 3, 0)
...
Vec(0, 1, 2, 3) -- rotate(1, left) --> Vec(1, 2, 3, 0)
...

该类继承自 Bundle,并将移位的位数作为成员,意味着可以直接将其实例寄存,从而实现无感的移位和还原。

val s1_offset  = Wire(UInt(2.W))
val s1_rotator = VecRotate(s1_offset)
val s1_index   = VecInit(Seq(0, 1, 2, 3))

val s1_indexToSram = s1_rotator.rotate(s1_index)
// read sram request logic
val s2_resultFromSram = ... // read sram response logic

val s2_rotator = RegEnable(s1_rotator, s1_fire)
val s2_result  = s2_rotator.revert(s2_resultFromSram)

// equivalent to:
val s2_offset  = RegEnable(s1_offset, s1_fire)
val s2_rotator = VecRotate(s2_offset)
val s2_result  = s2_rotator.revert(s2_resultFromSram)

// also equivalent to:
val s2_offset  = RegEnable(s1_offset, s1_fire)
val s2_rotator = VecRotate(s2_offset, direction = VecRotate.Direction.Left)
val s2_result  = s2_rotator.rotate(s2_resultFromSram)

需要注意这里的方向和 scala 中 Seq 或 chisel 中 Vec 在代码中的行为是一致的,和 UInt 是相反的,即向右移位是向下标递增的方向移位,向左移位是向下标递减的方向移位。默认为向右移位。