[Weekly Review] 2020/01/06-12

Published: by Creative Commons Licence (Last updated: )

2020/01/06-12

This week I read several papers written by Song Han including reference 12, 15-17, related to both deep learning accelerator architecture with Weight stationery and design automation for Neural Architecture Search. They are:

  1. EIE: Efficient Inference Engine on Compressed Deep Neural Network;
  2. ProxylessNAS: Direct Neural Architecture Search on Target Task and Hardware;
  3. Design Automation for Efficient Deep Learning Computing;
  4. Learning to Design Circuits.

Also, I began the implementation of Processing Element, and finished the main function without any test.

So next week, I plan to finish the PE with a test file and then establish the analysis system based on Eyexam with some scripts to compute the details of the hardware. So I need to re-read the papers related to Eyeriss.


Chisel & Scala Syntax

Useful resource:

Chisel Wiki

Chisel CookBook

Chisel3 API

Runoob Scala tutorial

Scala language PDF

Chisel.Queue

val qa = Queue(io.a) // io.a is the input to the FIFO
					// qa is DecoupledIO output from FIFO

Chisel.Decoupled

val b = Flipped(Decoupled(UInt(32.W)))// valid and bits are inputs
val z = Decoupled(UInt(32.W)) // valid and bits are outputs

Chisel.suggestName

def inc(x: UInt): UInt = {
	val incremented = x + 1.U // We cannot name this, it's inside a method
	incremented.suggestName("incremented") // Now it is named!
}

Chisel.print

println(s"${io.in}") 
// chisel3.core.UInt@e

printf(p"$io") 
// Bundle(in->3, out->3)

println(s"out = ${peek(c.io.out)}") 
// out = Vector(0, 0, 0, 0, 0, 0)

Scala.zip

Pair up values in two lists.

scala> List("a", "b", "c").zipWithIndex
res0: List[(String, Int)] = List((a,0), (b,1), (c,2))

scala> List("a", "b", "c") zip (Stream from 1)
res1: List[(String, Int)] = List((a,1), (b,2), (c,3))

scala> List(1, 2, 3).zip(List("a", "b", "c"))
res2: List[(Int, String)] = List((1,a), (2,b), (3,c))

Scala.map

Applies a function to each element in a list and returns the resulting transformation in a list

scala> val list1 = 0 to 5 toList
res3: List[Int] = List(0, 1, 2, 3, 4, 5)
 
scala> list1.map(x=>x*x)
res4: List[Int] = List(0, 1, 4, 9, 16, 25)

Scala.reduce (reduceLeft & reduceRight)

In each step, a function is performed on the list element and the result of the last fold operation, returning a single value.

scala> val list1 = 0 to 5 toList
res51: List[Int] = List(1, 2, 3, 4, 5)

scala> val sum = (x:Int, y:Int) => {println(x,y) ; x + y}
sum: (Int, Int) => Int = <function2>

scala> list1.reduce(sum)
(1,2) // 1 + 2 =  3, list1 = List(3, 3, 4, 5)
(3,3) // 3 + 3 =  6, list1 = List(6, 4, 5)
(6,4) // 6 + 4 = 10, list1 = List(10, 5)
(10,5)
res52: Int = 15

Scala.List.take(Int)

See Scala List.

val mcrenf = RegInit(VecInit(Seq.fill(6)(0.U(loop_width.W))))
val when_carry: IndexedSeq[Bool] = mcrenf.zip(MCRENF.map(x=> x - 1)).map{ case (x,y) => x === y.U}

when_carry.take(i).reduce(_ && _)

Reg Delay Test

class TheOperModule extends Module {
  val io = IO(new Bundle {
    val a  = Input(UInt(4.W))
    val b  = Input(UInt(4.W))
    val out_reg0 = Output(UInt(4.W))
    val out_reg1 = Output(UInt(4.W))
    val out_reg2 = Output(UInt(4.W))
  })

  val a_reg = RegInit(0.U(4.W))
  val b_reg = RegInit(0.U(4.W))
  val c_reg1 = RegInit(0.U(4.W))
  val d_reg2 = RegInit(0.U(4.W))
  a_reg := io.a
  b_reg := io.b
  c_reg1 := io.a + io.b
  d_reg2 := a_reg + b_reg

  io.out_reg0 := io.a + io.b
  io.out_reg1 := c_reg1
  io.out_reg2 := d_reg2
}
class MyOperTester(c: TheOperModule) extends PeekPokeTester(c) {
  val in_a = 2
  val in_b = 3
  poke(c.io.a, in_a)
  poke(c.io.b, in_b)
  println(s"clock 0, out_reg0 = ${peek(c.io.out_reg0)}")
  println(s"         out_reg1 = ${peek(c.io.out_reg1)}")
  println(s"         out_reg2 = ${peek(c.io.out_reg2)}")
  step(1)
  println(s"clock 1, out_reg0 = ${peek(c.io.out_reg0)}")
  println(s"         out_reg1 = ${peek(c.io.out_reg1)}")
  println(s"         out_reg2 = ${peek(c.io.out_reg2)}")
  step(1)
  println(s"clock 2, out_reg0 = ${peek(c.io.out_reg0)}")
  println(s"         out_reg1 = ${peek(c.io.out_reg1)}")
  println(s"         out_reg2 = ${peek(c.io.out_reg2)}")
  }
assert(Driver(() => new TheOperModule) {c => new MyOperTester(c)})
[info] [0.001] clock 0, out_reg0 = 5
[info] [0.001]          out_reg1 = 0
[info] [0.001]          out_reg2 = 0
[info] [0.001] clock 1, out_reg0 = 5
[info] [0.001]          out_reg1 = 5 // arrive reg 1
[info] [0.002]          out_reg2 = 0
[info] [0.002] clock 2, out_reg0 = 5
[info] [0.002]          out_reg1 = 5
[info] [0.002]          out_reg2 = 5 // arrive reg 2