// Copyright 2025 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 common

import chisel3._
import chisel3.simulator.scalatest.ChiselSim
import org.scalatest.freespec.AnyFreeSpec

class CircularBufferMultiSpec extends AnyFreeSpec with ChiselSim {
  "Basic" in {
    simulate(new CircularBufferMulti(UInt(32.W), 4, 16)) { dut =>
      dut.io.nEnqueued.expect(0)
      dut.io.flush.poke(false)

      dut.io.enqValid.poke(2)
      dut.io.enqData(0).poke(3)
      dut.io.enqData(1).poke(5)
      dut.clock.step()

      dut.io.nEnqueued.expect(2)
      dut.io.dataOut(0).expect(3)
      dut.io.dataOut(1).expect(5)

      dut.io.enqValid.poke(1)
      dut.io.enqData(0).poke(9001)
      dut.io.enqData(1).poke(0)
      dut.clock.step()

      dut.io.nEnqueued.expect(3)
      dut.io.dataOut(0).expect(3)
      dut.io.dataOut(1).expect(5)
      dut.io.dataOut(2).expect(9001)

      dut.io.enqValid.poke(0)
      dut.io.deqReady.poke(1)
      dut.clock.step()

      dut.io.nEnqueued.expect(2)
      dut.io.dataOut(0).expect(5)
      dut.io.dataOut(1).expect(9001)
    }
  }

  "Write n" in {
    simulate(new CircularBufferMulti(UInt(32.W), 4, 16)) { dut =>
      dut.io.nEnqueued.expect(0)
      dut.io.flush.poke(false)

      for (n <- 0 until 4) {
        dut.io.enqData(n).poke(n)
      }
      dut.io.enqValid.poke(4)
      dut.clock.step()

      dut.io.nEnqueued.expect(4)

      for (n <- 0 until 4) {
        dut.io.dataOut(n).expect(n)
      }
    }
  }

  "Fill Buffer" in {
    simulate(new CircularBufferMulti(UInt(32.W), 4, 16)) { dut =>
      dut.io.nEnqueued.expect(0)
      dut.io.flush.poke(false)

      // Fill buffer completely
      for (writeCount <- 0 until 4) {
        for (nIndex <- 0 until 4) {
          val indata = writeCount*4 + nIndex
          dut.io.enqData(nIndex).poke(indata)
        }
        dut.io.enqValid.poke(4)
        dut.clock.step()
        // Confirm nEnqueued increments the amount corresponding to #enqValid each cycle
        dut.io.nEnqueued.expect((writeCount+1)*4)
      }
    }
  }

  "Fill and Empty Buffer" in {
    simulate(new CircularBufferMulti(UInt(32.W), 4, 16)) { dut =>
      dut.io.nEnqueued.expect(0)
      dut.io.flush.poke(false)

      // Fill buffer completely
      for (writeCount <- 0 until 4) {
        for (nIndex <- 0 until 4) {
          val indata = writeCount*4 + nIndex
          dut.io.enqData(nIndex).poke(indata)
        }
        dut.io.enqValid.poke(4)
        dut.clock.step()
      }
      dut.io.enqValid.poke(0)
      dut.io.nEnqueued.expect(16)

      // Empty buffer completely
      for (writeCount <- 0 until 4) {
        for (nIndex <- 0 until 4) {
          val outdata = writeCount*4 + nIndex
          dut.io.dataOut(nIndex).expect(outdata)
        }
        dut.io.deqReady.poke(4)
        dut.clock.step()
      }
      dut.io.deqReady.poke(0)
      dut.io.nEnqueued.expect(0)
    }
  }
  "Fill, Remove 4 items, and fill back to the top" in {
    simulate(new CircularBufferMulti(UInt(32.W), 4, 16)) { dut =>
      dut.io.nEnqueued.expect(0)
      dut.io.flush.poke(false)

      // Fill buffer completely
      // Use 4x transactions of n=4 items to fill up to size 16, incrementing each transaction
      for (writeCount <- 0 until 4) {
        for (nIndex <- 0 until 4) {
          val indata = writeCount*4 + nIndex
          dut.io.enqData(nIndex).poke(indata)
        }
        dut.io.enqValid.poke(4)
        dut.clock.step()
      }
      dut.io.enqValid.poke(0)
      dut.io.nEnqueued.expect(16)

      // Remove 4x items
      for (writeCount <- 0 until 1) {
        for (nIndex <- 0 until 4) {
          val outdata = writeCount*4 + nIndex
          dut.io.dataOut(nIndex).expect(outdata)
        }
        dut.io.deqReady.poke(4)
        dut.clock.step()
      }
      dut.io.deqReady.poke(0)
      dut.io.nEnqueued.expect(12)

      // Add back n=4 items
      for (writeCount <- 4 until 5) {
        for (nIndex <- 0 until 4) {
          val indata = writeCount*4 + nIndex
          dut.io.enqData(nIndex).poke(indata)
        }
        dut.io.enqValid.poke(4)
        dut.clock.step()
      }
      dut.io.enqValid.poke(0)
      dut.io.nEnqueued.expect(16)
      // Remove 4x items
      for (writeCount <- 1 until 2) {
        for (nIndex <- 0 until 4) {
          val outdata = writeCount*4 + nIndex
          dut.io.dataOut(nIndex).expect(outdata)
        }
        dut.io.deqReady.poke(4)
        dut.clock.step()
      }
      dut.io.nEnqueued.expect(12)
    }
  }

  "Flush Test" in {
    simulate(new CircularBufferMulti(UInt(32.W), 4, 16)) { dut =>
      dut.io.nEnqueued.expect(0)
      dut.io.flush.poke(false)

      // Fill buffer completely and flush
      for (writeCount <- 0 until 4) {
        for (nIndex <- 0 until 4) {
          val indata = writeCount*4 + nIndex
          dut.io.enqData(nIndex).poke(indata)
        }
        dut.io.enqValid.poke(4)
        dut.clock.step()
      }
      dut.io.enqValid.poke(0)

      dut.io.nEnqueued.expect(16)

      dut.io.flush.poke(true)
      dut.clock.step()
      dut.clock.step()
      dut.io.nEnqueued.expect(0)
      dut.io.flush.poke(false)

      // Add 4x items and flush
      for (writeCount <- 0 until 1) {
        for (nIndex <- 0 until 4) {
          val indata = writeCount*4 + nIndex
          dut.io.enqData(nIndex).poke(indata)
        }
        dut.io.enqValid.poke(4)
        dut.clock.step()
      }
      dut.io.enqValid.poke(0)

      dut.io.nEnqueued.expect(4)

      dut.io.flush.poke(true)
      dut.clock.step()
      dut.clock.step()
      dut.io.nEnqueued.expect(0)
      dut.io.flush.poke(false)
      }
    }

  "Read and Write Buffer on Same Cycle" in {
    simulate(new CircularBufferMulti(UInt(32.W), 4, 16)) { dut =>
      dut.io.nEnqueued.expect(0)
      dut.io.flush.poke(false)

      // Use 2x transactions of n=4 items to fill up to size 8, incrementing each transaction
      for (writeCount <- 0 until 2) {
        for (nIndex <- 0 until 4) {
          val indata = writeCount*4 + nIndex
          dut.io.enqData(nIndex).poke(indata)
        }
        dut.io.enqValid.poke(4)
        dut.clock.step()
      }
      dut.io.enqValid.poke(0)
      dut.io.nEnqueued.expect(8)

      // Enque and Deque on same cycle
      dut.io.enqValid.poke(3)
      dut.io.enqData(0).poke(3)
      dut.io.enqData(1).poke(5)
      dut.io.enqData(2).poke(7)

      dut.io.deqReady.poke(4)

      dut.clock.step()
      dut.io.deqReady.poke(0)
      dut.io.enqValid.poke(0)
      dut.io.nEnqueued.expect(7)

      // Flush
      dut.io.flush.poke(true)
      dut.clock.step()
      dut.clock.step()
      dut.io.nEnqueued.expect(0)
      dut.io.flush.poke(false)
      dut.clock.step()

      // Fill buffer up to 12 items
      for (writeCount <- 0 until 3) {
        for (nIndex <- 0 until 4) {
          val indata = writeCount*4 + nIndex
          dut.io.enqData(nIndex).poke(indata)
        }
        dut.io.enqValid.poke(4)
        dut.clock.step()
      }
      dut.io.nEnqueued.expect(12)

      // Fill buffer completely and dequeue on same cycle
      for (nIndex <- 0 until 4) {
        val indata = nIndex
        dut.io.enqData(nIndex).poke(indata)
      }
      dut.io.enqValid.poke(4)
      dut.io.deqReady.poke(4)
      dut.clock.step()
      dut.io.enqValid.poke(0)
      dut.io.deqReady.poke(0)

      dut.io.nEnqueued.expect(12)
    }
  }

}

