/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 vta.dpi

import chisel3._
import chisel3.util._
import vta.util.config._
import vta.interface.axi._
import vta.shell._

/** Memory DPI parameters */
trait VTAMemDPIParams {
  val dpiLenBits = 8
  val dpiAddrBits = 64
  val dpiDataBits = 64
}

/** Memory master interface.
 *
 * This interface is tipically used by the Accelerator
 */
class VTAMemDPIMaster extends Bundle with VTAMemDPIParams {
  val req = new Bundle {
    val valid = Output(Bool())
    val opcode = Output(Bool())
    val len = Output(UInt(dpiLenBits.W))
    val addr = Output(UInt(dpiAddrBits.W))
  }
  val wr = ValidIO(UInt(dpiDataBits.W))
  val rd = Flipped(Decoupled(UInt(dpiDataBits.W)))
}

/** Memory client interface.
 *
 * This interface is tipically used by the Host
 */
class VTAMemDPIClient extends Bundle with VTAMemDPIParams {
  val req = new Bundle {
    val valid = Input(Bool())
    val opcode = Input(Bool())
    val len = Input(UInt(dpiLenBits.W))
    val addr = Input(UInt(dpiAddrBits.W))
  }
  val wr = Flipped(ValidIO(UInt(dpiDataBits.W)))
  val rd = Decoupled(UInt(dpiDataBits.W))
}

/** Memory DPI module.
 *
 * Wrapper for Memory Verilog DPI module.
 */
class VTAMemDPI extends BlackBox with HasBlackBoxResource {
  val io = IO(new Bundle {
    val clock = Input(Clock())
    val reset = Input(Reset())
    val dpi = new VTAMemDPIClient
  })
  addResource("/verilog/VTAMemDPI.v")
}

class VTAMemDPIToAXI(debug: Boolean = false)(implicit p: Parameters) extends Module {
  val io = IO(new Bundle {
    val dpi = new VTAMemDPIMaster
    val axi = new AXIClient(p(ShellKey).memParams)
  })
  val opcode = RegInit(false.B)
  val len = RegInit(0.U.asTypeOf(chiselTypeOf(io.dpi.req.len)))
  val addr = RegInit(0.U.asTypeOf(chiselTypeOf(io.dpi.req.addr)))
  val sIdle :: sReadAddress :: sReadData :: sWriteAddress :: sWriteData :: sWriteResponse :: Nil =
    Enum(6)
  val state = RegInit(sIdle)

  switch(state) {
    is(sIdle) {
      when(io.axi.ar.valid) {
        state := sReadAddress
      }.elsewhen(io.axi.aw.valid) {
        state := sWriteAddress
      }
    }
    is(sReadAddress) {
      when(io.axi.ar.valid) {
        state := sReadData
      }
    }
    is(sReadData) {
      when(io.axi.r.ready && io.dpi.rd.valid && len === 0.U) {
        state := sIdle
      }
    }
    is(sWriteAddress) {
      when(io.axi.aw.valid) {
        state := sWriteData
      }
    }
    is(sWriteData) {
      when(io.axi.w.valid && io.axi.w.bits.last) {
        state := sWriteResponse
      }
    }
    is(sWriteResponse) {
      when(io.axi.b.ready) {
        state := sIdle
      }
    }
  }

  when(state === sIdle) {
    when(io.axi.ar.valid) {
      opcode := false.B
      len := io.axi.ar.bits.len
      addr := io.axi.ar.bits.addr
    }.elsewhen(io.axi.aw.valid) {
      opcode := true.B
      len := io.axi.aw.bits.len
      addr := io.axi.aw.bits.addr
    }
  }.elsewhen(state === sReadData) {
    when(io.axi.r.ready && io.dpi.rd.valid && len =/= 0.U) {
      len := len - 1.U
    }
  }

  io.dpi.req.valid := (state === sReadAddress & io.axi.ar.valid) | (state === sWriteAddress & io.axi.aw.valid)
  io.dpi.req.opcode := opcode
  io.dpi.req.len := len
  io.dpi.req.addr := addr

  io.axi.ar.ready := state === sReadAddress
  io.axi.aw.ready := state === sWriteAddress

  io.axi.r.valid := state === sReadData & io.dpi.rd.valid
  io.axi.r.bits.data := io.dpi.rd.bits
  io.axi.r.bits.last := len === 0.U
  io.axi.r.bits.resp := 0.U
  io.axi.r.bits.user := 0.U
  io.axi.r.bits.id := 0.U
  io.dpi.rd.ready := state === sReadData & io.axi.r.ready

  io.dpi.wr.valid := state === sWriteData & io.axi.w.valid
  io.dpi.wr.bits := io.axi.w.bits.data
  io.axi.w.ready := state === sWriteData

  io.axi.b.valid := state === sWriteResponse
  io.axi.b.bits.resp := 0.U
  io.axi.b.bits.user := 0.U
  io.axi.b.bits.id := 0.U

  if (debug) {
    when(state === sReadAddress && io.axi.ar.valid) {
      printf("[VTAMemDPIToAXI] [AR] addr:%x len:%x\n", addr, len)
    }
    when(state === sWriteAddress && io.axi.aw.valid) {
      printf("[VTAMemDPIToAXI] [AW] addr:%x len:%x\n", addr, len)
    }
    when(io.axi.r.fire()) {
      printf("[VTAMemDPIToAXI] [R] last:%x data:%x\n",
        io.axi.r.bits.last,
        io.axi.r.bits.data)
    }
    when(io.axi.w.fire()) {
      printf("[VTAMemDPIToAXI] [W] last:%x data:%x\n",
        io.axi.w.bits.last,
        io.axi.w.bits.data)
    }
  }
}
