/*
 * Copyright 2023 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package kelvin

import chisel3._
import chisel3.util._

object VDot {
  // Conv2D
  def apply(en: Bool, adata: UInt, bdata: UInt,
      abias: UInt, bbias: UInt, asign: Bool, bsign: Bool): UInt = {
    assert(abias.getWidth == 9)
    assert(bbias.getWidth == 9)
    assert(adata.getWidth == 32)
    assert(bdata.getWidth == 32)

    val mul = Wire(Vec(4, SInt(20.W)))

    // input clamps
    val adatac = MuxOR(en, adata)
    val bdatac = MuxOR(en, bdata)
    val abiasc = MuxOR(en, abias)
    val bbiasc = MuxOR(en, bbias)

    for (i <- 0 until 4) {
      val as = adatac(8 * i + 7) & asign
      val bs = bdatac(8 * i + 7) & bsign
      val aval = Cat(as, adatac(8 * i + 7, 8 * i)).asSInt +& abiasc.asSInt
      val bval = Cat(bs, bdatac(8 * i + 7, 8 * i)).asSInt +& bbiasc.asSInt
      val mval = aval * bval
      mul(i) := mval

      assert(aval.getWidth == 10)
      assert(bval.getWidth == 10)
      assert(mval.getWidth == 20)
    }

    val dotp = (mul(0) +& mul(1)) +& (mul(2) +& mul(3))
    val sdotp = Cat(MuxOR(dotp(21), ~0.U(10.W)), dotp)

    assert(dotp.getWidth == 22)
    assert(sdotp.getWidth == 32)

    sdotp
  }

  // Depthwise
  def apply(alu: Int, en: Bool, adata: Vec[UInt], bdata: Vec[UInt],
      scalar: UInt): (UInt, UInt) = {
    assert(adata.length == 3)
    assert(bdata.length == 3)
    assert(scalar.getWidth == 32)
    val sparse = scalar(3,2)
    val abias = scalar(20,12)
    val asign = scalar(21)
    val bbias = scalar(30,22)
    val bsign = scalar(31)

    val sparse0 = sparse === 0.U
    val sparse1 = sparse === 1.U
    val sparse2 = sparse === 2.U

    val w = adata(0).getWidth
    val cnt = w / 32
    val dout0 = Wire(Vec(cnt, UInt(32.W)))
    val dout1 = Wire(Vec(cnt, UInt(32.W)))

    // Input clamps and dense/sparse swizzle.
    val adatac = Wire(Vec(3, Vec(cnt, UInt(32.W))))
    val bdatac = Wire(Vec(3, Vec(cnt, UInt(32.W))))

    val abiasc = MuxOR(en, abias)
    val bbiasc = MuxOR(en, bbias)

    // Sparse 1 [n-1,n,n+1].
    val adata1 = Wire(Vec(cnt + 2, UInt(32.W)))
    if (true) {
      val lsb = (cnt - 1) * 32
      val msb = lsb + 32 - 1
      adata1(0) := MuxOR(en && sparse1, adata(0)(msb,lsb))
    }
    for (i <- 0 until cnt) {
      val lsb = i * 32
      val msb = lsb + 32 - 1
      adata1(i + 1) := MuxOR(en && sparse1, adata(1)(msb,lsb))
    }
    if (true) {
      val lsb = 0
      val msb = 31
      adata1(cnt + 1) := MuxOR(en && sparse1, adata(2)(msb,lsb))
    }

    // Sparse 2 [n,n+1,n+2].
    val adata2 = Wire(Vec(cnt + 2, UInt(32.W)))
    for (i <- 0 until cnt) {
      val lsb = i * 32
      val msb = lsb + 32 - 1
      adata2(i) := MuxOR(en && sparse2, adata(0)(msb,lsb))
    }
    for (i <- 0 until 2) {
      val lsb = i * 32
      val msb = lsb + 32 - 1
      adata2(cnt + i) := MuxOR(en && sparse2, adata(1)(msb,lsb))
    }

    // vdot(a,b) for sparse[0,1,2].
    for (j <- 0 until 3) {
      for (i <- 0 until cnt) {
        val lsb = i * 32
        val msb = lsb + 32 - 1
        val k = i + j

        val adata0 = MuxOR(en && sparse0, adata(j)(msb,lsb))

        adatac(j)(i) := adata0 | adata1(k) | adata2(k)
        bdatac(j)(i) := MuxOR(en, bdata(j)(msb,lsb))
      }
    }

    for (i <- 0 until cnt) {
      val ad = VecInit(adatac(0)(i), adatac(1)(i), adatac(2)(i))
      val bd = VecInit(bdatac(0)(i), bdatac(1)(i), bdatac(2)(i))
      val (o0, o1) = dwlane(alu, en, ad, bd, abiasc, bbiasc, asign, bsign)
      dout0(i) := o0
      dout1(i) := o1
    }

    val out0 = dout0.asUInt
    val out1 = dout1.asUInt
    assert(out0.getWidth == w)
    assert(out1.getWidth == w)
    (out0, out1)
  }

  private def dwlane(alu: Int, en: Bool, adata: Vec[UInt], bdata: Vec[UInt],
      abias: UInt, bbias: UInt, asign: Bool, bsign: Bool):
        (UInt, UInt) = {
    assert(adata.length == 3)
    assert(bdata.length == 3)
    assert(abias.getWidth == 9)
    assert(bbias.getWidth == 9)
    for (i <- 0 until 3) {
      assert(adata(i).getWidth == 32)
      assert(bdata(i).getWidth == 32)
    }

    val out = Wire(Vec(2, UInt(32.W)))

    for (j <- 0 until 2) {
      val m = 2 * j + alu  // alu[0]: {0, 2}; alu[1]: {1, 3}
      val mul = Wire(Vec(3, SInt(20.W)))

      for (i <- 0 until 3) {
        val as = adata(i)(8 * m + 7) & asign
        val bs = bdata(i)(8 * m + 7) & bsign
        val aval = Cat(as, adata(i)(8 * m + 7, 8 * m)).asSInt +& abias.asSInt
        val bval = Cat(bs, bdata(i)(8 * m + 7, 8 * m)).asSInt +& bbias.asSInt
        val mval = aval * bval
        mul(i) := mval

        assert(aval.getWidth == 10)
        assert(bval.getWidth == 10)
        assert(mval.getWidth == 20)
      }

      val dotp = (mul(0) +& mul(1)) +& mul(2)
      val sdotp = Cat(MuxOR(dotp(21), ~0.U(10.W)), dotp)
      assert(dotp.getWidth == 22)
      assert(sdotp.getWidth == 32)

      out(j) := sdotp
    }

    (out(0), out(1))
  }
}
