4*4 곱셈을, Multiplier가 아니라 Lookup Table을 256가지 모든 경우의 수에 대해 만들어서 구현하라는 문제이다.
Verilog로 하면 5분컷이지만, Chisel로 하니까 낯설었다.
// See LICENSE.txt for license details.
package problems
import chisel3.iotesters.PeekPokeTester
class MulTests(c: Mul) extends PeekPokeTester(c) {
val maxInt = 1 << 4
for (i <- 0 until 10) {
val x = rnd.nextInt(maxInt)
val y = rnd.nextInt(maxInt)
poke(c.io.x, x)
poke(c.io.y, y)
step(1)
expect(c.io.z, x * y)
}
}
일단 직관적으로 짜봤다.
// See LICENSE.txt for license details.
package problems
import chisel3._
import scala.collection.mutable.ArrayBuffer
// Problem:
//
// 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(x <- 0 until 1<<4-1){
for(y<-0 until 1<<4-1){
mulsValues(x,y) := x*y
}
}
// Implement below ----------
z := mulsValues(io.x,io.y)
// Implement above ----------
}
틀린 부분이 보인다.
1. until은 등호없는 for이기에, 16-1이 아니라 16으로 해야한다.
2. 2차원 ArrayBuffer는 콤마로 접근해서 Write하는게 아니다. +=를 써서 Append한다.
뺄 때는 myList -= "Welcome"; 처럼, -=를 쓰면 된다.
즉, index로 접근하여 직접 건드는게 아니라, value로 넣고 value로 뺀다.
(어 그러면 연속성 깨지지 않나..? 왜 이렇게 구현했지)
3. mulsValues를 W할때 말고 R 할때도, (io.x, io.y) 로 인덱싱하여 접근하면 안된다. VecInit로 Scala형으로 바꾼 뒤에, 그것을 RHS에 둬서 assign해야한다.
// See LICENSE.txt for license details.
package problems
import chisel3._
import scala.collection.mutable.ArrayBuffer
// Problem:
//
// 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(x <- 0 until 1<<4){
for(y<-0 until 1<<4){
// mulsValues(x,y) := x*y
mulsValues += (x*y)
}
}
val LUT = VecInit(mulsValues)
// println(LUT.mkString(" "))
// printf(cf"LUT = $LUT")
// Implement below ----------
// z := mulsValues(io.x,io.y)
io.z := LUT((io.x << 4.U) | io.y)
// Implement above ----------
}
cf custom string interpolation 출처
// See LICENSE.txt for license details.
package problems
import chisel3._
import scala.collection.mutable.ArrayBuffer
// Problem:
//
// 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(x <- 0 until 1<<4){
for(y<-0 until 1<<4){
// mulsValues(x,y) := x*y
mulsValues += (x*y).asUInt(8.W)
}
}
val LUT = VecInit(mulsValues)
// println(LUT.mkString(" "))
// printf(cf"LUT = $LUT")
// Implement below ----------
// z := mulsValues(io.x,io.y)
io.z := LUT((io.x << 4.U) | io.y)
// Implement above ----------
}