|
写有一个查找表代码以做实验:
主要用到了ArrayBuffer[UInt]以及VecInit(ArrayBuffer[UInt]类型作参数):Vec[UInt],具体代码如下:
import chisel3._
import scala.collection.mutable.ArrayBuffer
// Implement a four-by-four multiplier using a look-up table.
class Mul extends Module{
val io = IO(new Bundle {
val x = Input(UInt(4.W))
val y = Input(UInt(4.W))
val z = Output(UInt(8.W))
})
val mulsValues = new ArrayBuffer[UInt]()
// Calculate io.z = io.x * io.y by generating a table of values for mulsValues
for(i <- 0 until 16)
for(j <- 0 until 16)
mulsValues += (i * j).asUInt(8.W) //def +=是trait Growable中方法,而继承关系是:ArrayBuffer<-BufferLike<-Growable 表示添加一个元素,
// 如果添加多个用++=,在Growable中def ++=是一个实现方法(def ++= (xs:TraversableOnce[A]):this.type),它通过递归将xs的每个head取出依次添加进来
//TraversabvleOnce[A]的子类有:Iterator,TraversableLike,Traversable,所以只要是Iterator的子类都可以被++=进来,当然TraversableLike的子类也一样
val tbl = VecInit(mulsValues) //VecInit的apply方法的参数是Seq[A],要注意的是:Seq[A]表示是序列的基类,即Seq表示这种集合中的元素是有顺序的,不象Set和Map
// io.z := tbl((io.x << 4.U) | io.y) //"|"操作符为什么语法出错??? io.x << 4.U和io.x << 4之间的区别:<< int是静态左移,而<<UInt是动态左移(见源码说明)
//难道<<4.U就变成4+4=8bitswidth??wire [7:0] _GEN_256 = {io_x, 4'h0};确实是8bits
// val u = 5.U(4.W)
// val us = u | 3.U //调用的是:final def | (that: UInt): UInt //但(u<<2)|3.U或(u<<2.U)|3.U都语法错,只要u<<就出错,为什么会这样呢????
//// val us2 = (u << 2) | 3.U //因为u<<2的操作符<<是bits类中的方法,返回的也是bits,感觉应该要将u<<2强转为UInt才行
// val us3:UInt = (u << 2).asUInt()
// val us4 = us3 | 3.U
//最终通过上面u,us,us2,us3,us4的实验证明了在高版本chisel中不能直接用Bits|UInt,必须要将Bits用asUInt转为UInt再用UInt的|操作符进行位处理
// io.z := tbl((io.x << 4.U).asUInt() | io.y) //还要实验io.x << 4 ,看verilog中代码的不同???
io.z := tbl((io.x << 4).asUInt() | io.y)
}
|
|