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

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

/** EventCounters.
 *
 * This unit contains all the event counting logic. One common event tracked in
 * hardware is the number of clock cycles taken to achieve certain task. We
 * can count the total number of clock cycles spent in a VTA run by checking
 * launch and finish signals.
 *
 * The event counter value is passed to the VCR module via the ecnt port, so
 * they can be accessed by the host. The number of event counters (nECnt) is
 * defined in the Shell VCR module as a parameter, see VCRParams.
 *
 * If one would like to add an event counter, then the value of nECnt must be
 * changed in VCRParams together with the corresponding counting logic here.
 */
class EventCounters(debug: Boolean = false)(implicit p: Parameters) extends Module {
  val vp = p(ShellKey).vcrParams
  val io = IO(new Bundle {
    val launch = Input(Bool())
    val finish = Input(Bool())
    val ecnt = Vec(vp.nECnt, ValidIO(UInt(vp.regBits.W)))
    val ucnt = Vec(vp.nUCnt, ValidIO(UInt(vp.regBits.W)))
    val acc_wr_event = Input(Bool())
  })
  val cycle_cnt = RegInit(0.U(vp.regBits.W))
  when(io.launch && !io.finish) {
    cycle_cnt := cycle_cnt + 1.U
  }.otherwise {
    cycle_cnt := 0.U
  }
  io.ecnt(0).valid := io.finish
  io.ecnt(0).bits := cycle_cnt

  val acc_wr_count = Reg(UInt(vp.regBits.W))
  when (!io.launch || io.finish) {
    acc_wr_count := 0.U
  }.elsewhen (io.acc_wr_event) {
    acc_wr_count := acc_wr_count + 1.U
  }
  io.ucnt(0).valid := io.finish
  io.ucnt(0).bits := acc_wr_count
}
