Chisel3在每个时钟周期比较UInt位[行程编码器]

时间:2018-09-26 00:16:25

标签: chisel

我正在构建行程编码器模块,但遇到了问题。

原始比特流以uint8的形式存储在内存中:11111100-> 252,00000110-> 6等

我将原始位流的每个块加载到寄存器val in = Reg(UInt(8.W))中,然后我想将第1位与第2位进行比较,然后将2nd与第3位进行比较,依此类推,以计算行程的长度。 这是我的状态机的一部分。

switch(state) {
  // code here ...
  is(step1) {
    logic.io.current_bit := in(7)
    logic.io.next_bit := in(6)
    // code here ...
  }
  is(step2) {
    current_bit := in(6)
    next_bit := in(5)
    // code here ...
  }
  // ... more steps ...
  is(step7) {
    current_bit := in(1)
    next_bit := in(0)
    // code here ...
  }
  // code here ...
}

我有一个称为逻辑的组合电路,该电路决定两个连续位的相等性,以及下一个状态是步骤n + 1还是存储行程长度。 我认为有很多代码冗余,但是我不能以其他方式思考。

是否可以输入in(x),其中x是状态机中定义的数字?

是否有任何想法让我可以更优雅地做到这一点?


编辑:

模块I / O:

val io = IO(new Bundle {
    val valid = Input(Bool()) // enables-disables the module
    val mem_addr_load = Input(UInt(mem_addr_length.W)) // memory position to load the uints
    val mem_addr_store = Input(UInt(mem_addr_length.W)) // memory position to store the uints
    val mem_in = Input(UInt(8.W)) // uint input - loads 252 so it translates 11111100 bitstream
    val mem_out = Output(UInt(8.W)) // store the run's length using 8-bit runs (up to 255 consecutive same bits)
    val mem_addr = Output(UInt(mem_addr_length.W)) // memory position that the module wants to access (store/load)
    val writeEn = Output(Bool()) // signifies that there are data to be written in the memory
    val ready = Output(Bool()) // signifies that the process is over
  })

模块功能:压缩内存中的内容

Memory contents (IN)
|11101111|11111111|11111111|11111111|10111110|00000000|00111111|11111111|11111111|11111111|11111111|11111111|11111111|11111100|

Memory contents (OUT)
|00000011|00000001|00011101|00000001|00000101|00001011|00111000|00000010|
|   4x1  |   1x0  |  29x1  |   1x0  |   5x1  |  11x0  |  56x1  |   2x0  | 

1 个答案:

答案 0 :(得分:1)

  

是否可以输入in(x),其中x是状态机中定义的数字?

您可以在设计中使用寄存器/导线进行位提取。例如,状态机中的每个is

  is(step7) {
    current_bit := in(1)
    next_bit := in(0)
    // code here ...
  }

可以折叠成类似的东西

current_bit := in(state)
next_bit := in(state - 1.U)

(需要整理一些细节)

我要考虑的另一件事是使用更多的聚合。我并不完全了解内存接口,但是可以将其表示为以下内容:

val io = IO(new Bundle {
  val mem = new Bundle {
    val addr = Output(UInt(mem_addr_length.W))
    val dataIn = Input(UInt(8.W))
    val dataOut = Output(UInt(8.W))
    val writeEn = Output(Bool())
  }
})

使用某种形式的去耦(即就绪有效)设计通常也更容易。例如,在这种情况下,我可能会有一个外部模块与内存接口(例如您编辑中的模块I / O),以及一个内部模块仅执行编码。例如。

val io = IO(new Bundle {
  val in = Decoupled(UInt(8.W)) // note Decoupled is defined in chisel3.util._
  val out = Decoupled(UInt(8.W))
})

经常解耦有助于减小问题的大小

根据资源与延迟的限制,您还可以考虑对每个周期的输入的多个位进行编码。编写生成器时,这种事情可能会引起一个有趣的问题。

人们可能会认为这种编码实际上是可以作为ROM实现的真值表。您可以通过几个维度对其进行参数化,包括每个周期的最大编码位数以及每个周期的最大编码运行次数(尽管我怀疑对于单个字节/周期的内存接口,没有理由使其大于1)。