代码之家  ›  专栏  ›  技术社区  ›  Mrchacha

在时钟周期内多次重新分配变量-凿子

  •  2
  • Mrchacha  · 技术社区  · 8 年前

    我想重新分配变量 hit_bits 在单个时钟周期内多次。 hit_bits 将在任何时候增加 io.bits_perf.bits(i) 是真的。我得到了“找到组合路径!”当我尝试编译代码时。

    知道吗?

      val hit_bits = Bits()
      hit_bits := Bits(0)
    
      when(io.bits_perf.valid){
        for(i<- 0 until 3){
          when(io.bits_perf.bits(i)) { hit_bits := hit_bits + Bits(1) 
          }
        }
      }
    
    1 回复  |  直到 8 年前
        1
  •  3
  •   Jack Koenig    8 年前

    对于本例,重要的是要记住 凿子 斯卡拉 更具体地, when 是一个凿构造,映射到Verilog中的条件连接,而 for 是我们可以用来生成硬件的Scala构造(类似于 generate 在Verilog中)。

    让我们展开这个for循环,看看我们得到了什么:

    when(io.bits_perf.valid){
      when(io.bits_perf.bits(0)) { hit_bits := hit_bits + Bits(1) }
      when(io.bits_perf.bits(1)) { hit_bits := hit_bits + Bits(1) }
      when(io.bits_perf.bits(2)) { hit_bits := hit_bits + Bits(1) }
    }
    

    请注意,所有连接都是相同的,当 io.bits_perf.valid 为高,并且 io.bits_perf.bits 高,您将连接 hit_bits hit_bits + Bits(1) 这是组合循环。

    现在,让我们找出如何表达您真正想要做的事情:如何将hit_bits连接到 io.bits_perf.bits 什么时候 io.bits_perf.valid 是高的。这也被称为 人口 而凿子正好有一个用途。你应该做的是使用它:

      val hit_bits = Bits()
      hit_bits := Bits(0)
    
      when(io.bits_perf.valid) {
        hit_bits := PopCount(io.bits_perf.bits)
      }
    

    然而,您编写的代码接近正确,所以我们还是让它工作吧。我们想要做的是使用Scala for循环来生成一些代码。一种方法是使用Scala var (允许重新分配)作为一种“指针”来凿节点,而不是 瓦尔 它只允许单个赋值(因此不能更改为指向不同的凿节点)。

    var hit_bits = Bits(0, 2) // We set the width because + does not expand width
    when (io.bits_perf.valid) {
      for (i <- 0 until 3) {
        hit_bits = hit_bits + io.bits_perf.bits(i)
      }
    }
    // Now hit_bits is equal to the popcount of io.bits_perf.bits (or 0 if not valid)
    

    请注意,我还删除了内部when条件,因为您可以直接添加位,而不是有条件地添加1 hit_bits 是对凿节点的引用,从 0 然后,对于for循环中的每个索引,我们将节点hit_bits引用更改为凿节点,该凿节点是所引用的先前节点hit-bits和 io.bits_perf.bits .