/*
 * 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._

/** Host DPI parameters */
trait VTAHostDPIParams {
  val dpiAddrBits = 8
  val dpiDataBits = 32
}

/** Host master interface.
 *
 * This interface is tipically used by the Host
 */
class VTAHostDPIMaster extends Bundle with VTAHostDPIParams {
  val req = new Bundle {
    val valid = Output(Bool())
    val opcode = Output(Bool())
    val addr = Output(UInt(dpiAddrBits.W))
    val value = Output(UInt(dpiDataBits.W))
    val deq = Input(Bool())
  }
  val resp = Flipped(ValidIO(UInt(dpiDataBits.W)))
}

/** Host client interface.
 *
 * This interface is tipically used by the Accelerator
 */
class VTAHostDPIClient extends Bundle with VTAHostDPIParams {
  val req = new Bundle {
    val valid = Input(Bool())
    val opcode = Input(Bool())
    val addr = Input(UInt(dpiAddrBits.W))
    val value = Input(UInt(dpiDataBits.W))
    val deq = Output(Bool())
  }
  val resp = ValidIO(UInt(dpiDataBits.W))
}

/** Host DPI module.
 *
 * Wrapper for Host Verilog DPI module.
 */
class VTAHostDPI extends BlackBox with HasBlackBoxResource {
  val io = IO(new Bundle {
    val clock = Input(Clock())
    val reset = Input(Bool())
    val dpi = new VTAHostDPIMaster
  })
  setResource("/verilog/VTAHostDPI.v")
}

/** Host DPI to AXI Converter.
 *
 * Convert Host DPI to AXI for VTAShell
 */
class VTAHostDPIToAXI(debug: Boolean = false)(implicit p: Parameters) extends Module {
  val io = IO(new Bundle {
    val dpi = new VTAHostDPIClient
    val axi = new AXILiteMaster(p(ShellKey).hostParams)
  })
  val addr = RegInit(0.U.asTypeOf(chiselTypeOf(io.dpi.req.addr)))
  val data = RegInit(0.U.asTypeOf(chiselTypeOf(io.dpi.req.value)))
  val sIdle :: sReadAddress :: sReadData :: sWriteAddress :: sWriteData :: sWriteResponse :: Nil =
    Enum(6)
  val state = RegInit(sIdle)

  switch(state) {
    is(sIdle) {
      when(io.dpi.req.valid) {
        when(io.dpi.req.opcode) {
          state := sWriteAddress
        }.otherwise {
          state := sReadAddress
        }
      }
    }
    is(sReadAddress) {
      when(io.axi.ar.ready) {
        state := sReadData
      }
    }
    is(sReadData) {
      when(io.axi.r.valid) {
        state := sIdle
      }
    }
    is(sWriteAddress) {
      when(io.axi.aw.ready) {
        state := sWriteData
      }
    }
    is(sWriteData) {
      when(io.axi.w.ready) {
        state := sWriteResponse
      }
    }
    is(sWriteResponse) {
      when(io.axi.b.valid) {
        state := sIdle
      }
    }
  }

  when(state === sIdle && io.dpi.req.valid) {
    addr := io.dpi.req.addr
    data := io.dpi.req.value
  }

  io.axi.aw.valid := state === sWriteAddress
  io.axi.aw.bits.addr := addr
  io.axi.w.valid := state === sWriteData
  io.axi.w.bits.data := data
  io.axi.w.bits.strb := "h_f".U
  io.axi.b.ready := state === sWriteResponse

  io.axi.ar.valid := state === sReadAddress
  io.axi.ar.bits.addr := addr
  io.axi.r.ready := state === sReadData

  io.dpi.req.deq := (state === sReadAddress & io.axi.ar.ready) | (state === sWriteAddress & io.axi.aw.ready)
  io.dpi.resp.valid := io.axi.r.valid
  io.dpi.resp.bits := io.axi.r.bits.data

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