blob: b001cf06fcbcc7fa4bdf1a9ca32e9edd4ca01251 [file] [log] [blame]
/*
* 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 unittest
import chisel3._
import chisel3.util._
import chiseltest._
import chiseltest.iotesters._
import scala.util.Random
import unittest.util._
import vta.util._
import vta.util.config._
class TestOnePortMem(c: OnePortMem[UInt]) extends PeekPokeTester(c) {
// write a:0 d:24
println("-----------------------------")
println("Cycle 0 write 24 to address 0")
poke (c.io.wr_en, 1)
poke (c.io.wr_data, 24)
poke (c.io.ch_en, 1)
poke (c.io.addr, 0)
step(1)
println("-----------------------------")
// read a:0
println("Cycle 1 read address 0")
poke (c.io.wr_en, 0)
poke (c.io.addr, 0)
poke (c.io.ch_en, 1)
step(1)
println("-----------------------------")
// write a:1 d:99
println("Cycle 2 write 99 to address 1")
poke (c.io.wr_en, 1)
poke (c.io.wr_data, 99)
poke (c.io.ch_en, 1)
poke (c.io.addr, 1)
// read d:24
println("Cycle 2 read expect data 24")
expect (c.io.rd_data, 24)
step(1)
println("-----------------------------")
println("Cycle 3 should still read data 24")
poke (c.io.ch_en, 0)
// read d:24
expect (c.io.rd_data, 24)
step(1)
println("-----------------------------")
println("Cycle 4 read address 0")
poke (c.io.wr_en, 0)
poke (c.io.addr, 0)
poke (c.io.ch_en, 1)
step(1)
println("-----------------------------")
// write a:1 d:99
poke (c.io.wr_en, 0)
poke (c.io.wr_data, 99)
poke (c.io.ch_en, 0)
poke (c.io.addr, 1)
// read d:24
println("Cycle 5 read expect data 24")
expect (c.io.rd_data, 24)
step(1)
println("-----------------------------")
}
class Checker(c: SyncQueueTestWrapper[UInt], t: PeekPokeTester[SyncQueueTestWrapper[UInt]]) {
def bits (bits: Int) = {
t.expect(c.io.tq.deq.bits, bits)
t.expect(c.io.rq.deq.bits, bits)
}
def ready (bits: Int) = {
t.expect(c.io.tq.enq.ready, bits)
t.expect(c.io.rq.enq.ready, bits)
}
def valid (bits: Int) = {
t.expect(c.io.tq.deq.valid, bits)
t.expect(c.io.rq.deq.valid, bits)
}
def status () = {
val rv = t.peek(c.io.rq.enq.ready)
t.expect(c.io.tq.enq.ready, rv)
val rc = t.peek(c.io.rq.count)
t.expect(c.io.tq.count, rc)
val vv = t.peek(c.io.rq.deq.valid)
t.expect(c.io.tq.deq.valid, vv)
if (vv != 0) {
val bv = t.peek(c.io.rq.deq.bits)
t.expect(c.io.tq.deq.bits, bv)
}
t.peek(c.io.rq.count)
t.peek(c.io.tq.count)
}
}
class TestSyncQueueLongRead(c: SyncQueueTestWrapper[UInt]) extends PeekPokeTester(c) {
val chr = new Checker (c, this)
def testFillRW(depth: Int) = {
val qsize = peek(c.io.tq.count)
require(qsize == 0, s"-F- An empty queue is expected ${qsize}")
poke (c.io.tq.deq.ready, 0)
poke (c.io.tq.enq.valid, 0)
chr.ready(1)
step(1)
// fill up to depth
for (i <- 10 until 10 + depth) {
poke (c.io.tq.enq.bits, i)
poke (c.io.tq.enq.valid, 1)
chr.status()
step(1)
}
// read and write same cycle
for (i <- 30 + depth until 30 + depth * 2) {
poke (c.io.tq.enq.valid, 1)
poke (c.io.tq.deq.ready, 1)
poke (c.io.tq.enq.bits, i)
chr.status()
step(1)
}
// read out
for (i <- 0 until depth + 1) {
poke (c.io.tq.enq.valid, 0)
poke (c.io.tq.deq.ready, 1)
poke (c.io.tq.enq.bits, 99)
chr.status()
step(1)
}
}
for (i <- 1 until 28) {
testFillRW(i)
}
}
class TestSyncQueueWaveRead(c: SyncQueueTestWrapper[UInt]) extends PeekPokeTester(c) {
val chr = new Checker (c, this)
def testFillRW(depth: Int) = {
val qsize = peek(c.io.tq.count)
require(qsize == 0, s"-F- An empty queue is expected ${qsize}")
poke (c.io.tq.deq.ready, 0)
poke (c.io.tq.enq.valid, 0)
chr.ready(1)
step(1)
// fill up to depth
for (i <- 10 until 10 + depth) {
poke (c.io.tq.enq.bits, i)
poke (c.io.tq.enq.valid, 1)
chr.status()
step(1)
}
// read out, no write
poke (c.io.tq.enq.valid, 0)
poke (c.io.tq.deq.ready, 1)
for (i <- 0 until 7) {
chr.status()
step(1)
}
// fill more
poke (c.io.tq.deq.ready, 0)
poke (c.io.tq.enq.valid, 1)
for (i <- 0 until 13) {
poke (c.io.tq.enq.bits, 99 + i)
chr.status()
step(1)
}
// read out, no write
poke (c.io.tq.enq.valid, 0)
poke (c.io.tq.deq.ready, 1)
for (i <- 1 until 14 + depth) {
chr.status()
step(1)
}
}
// read
for (i <- 1 until 28) {
testFillRW(i)
}
}
class SyncQueueTestWrapper[T <: Data](
gen: T,
val entries: Int)
extends Module() {
val genType = gen
val io = IO(new Bundle {
val tq = new QueueIO(genType, entries)
val rq = new QueueIO(genType, entries)
})
val tq = Module(new SyncQueue1PortMem(genType.asUInt, entries))
val rq = Module(new Queue(genType.asUInt, entries))
io.tq <> tq.io
io.rq <> rq.io
tq.io.enq.valid := RegNext(io.tq.enq.valid)
tq.io.enq.bits := RegNext(io.tq.enq.bits)
tq.io.deq.ready := RegNext(io.tq.deq.ready)
// connect reference queue inport to test input
rq.io.enq.valid := RegNext(io.tq.enq.valid)
rq.io.enq.bits := RegNext(io.tq.enq.bits)
rq.io.deq.ready := RegNext(io.tq.deq.ready)
}
class SyncQueueTestLongRead24 extends GenericTest(
"Queue",
(p:Parameters) => new SyncQueueTestWrapper(UInt(16.W), 24),
(c:SyncQueueTestWrapper[UInt]) => new TestSyncQueueLongRead(c))
class SyncQueueTestLongRead13 extends GenericTest(
"Queue",
(p:Parameters) => new SyncQueueTestWrapper(UInt(16.W), 13),
(c:SyncQueueTestWrapper[UInt]) => new TestSyncQueueLongRead(c))
class SyncQueueTestWaveRead24 extends GenericTest(
"Queue",
(p:Parameters) => new SyncQueueTestWrapper(UInt(16.W), 24),
(c:SyncQueueTestWrapper[UInt]) => new TestSyncQueueWaveRead(c))
class OnePorMemTest extends GenericTest(
"Queue",
(p:Parameters) => new OnePortMem(UInt(16.W), 16, ""),
(c:OnePortMem[UInt]) => new TestOnePortMem(c))
class SyncQueueTestWaveRead1 extends GenericTest(
"Queue",
(p:Parameters) => new SyncQueueTestWrapper(UInt(16.W), 1),
(c:SyncQueueTestWrapper[UInt]) => new TestSyncQueueWaveRead(c))
class SyncQueueTestWaveRead2 extends GenericTest(
"Queue",
(p:Parameters) => new SyncQueueTestWrapper(UInt(16.W), 2),
(c:SyncQueueTestWrapper[UInt]) => new TestSyncQueueWaveRead(c))
class SyncQueueTestWaveRead3 extends GenericTest(
"Queue",
(p:Parameters) => new SyncQueueTestWrapper(UInt(16.W), 3),
(c:SyncQueueTestWrapper[UInt]) => new TestSyncQueueWaveRead(c))
class SyncQueueTestWaveRead4 extends GenericTest(
"Queue",
(p:Parameters) => new SyncQueueTestWrapper(UInt(16.W), 4),
(c:SyncQueueTestWrapper[UInt]) => new TestSyncQueueWaveRead(c))