/*
 * 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(Reset())
    val dpi = new VTAHostDPIMaster
  })
  addResource("/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)
    }
  }
}
