blob: e0eac0e0508c5c5b13dc8aaa429e3fc936e202e2 [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 unittest.util._
import vta.core._
import vta.util.config._
class TensorGemmTester(c: TensorGemmSimple) extends PeekPokeTester(c) {
poke(c.io.start, 0)
poke(c.io.dec.reset, 0)
poke(c.io.dec.uop_begin, 0)
poke(c.io.dec.uop_end, 1)
poke(c.io.dec.lp_0, 1)
poke(c.io.dec.lp_1, 1)
poke(c.io.dec.acc_0, 1)
poke(c.io.dec.acc_1, 1)
poke(c.io.dec.inp_0, 1)
poke(c.io.dec.inp_1, 1)
poke(c.io.dec.wgt_0, 1)
poke(c.io.dec.wgt_1, 1)
// Don't need empty_0, {push, pop}_{next, prev}, op
poke(c.io.uop.data.bits.u0, 0)
poke(c.io.uop.data.bits.u1, 0)
poke(c.io.uop.data.bits.u2, 0)
val inp = IndexedSeq.fill(c.io.inp.rd(0).data.bits(0).size){BigInt(1)}
for {lhs <- c.io.inp.rd(0).data.bits} {
poke(lhs, inp.reverse)
}
val wgt = IndexedSeq.fill(c.io.wgt.rd(0).data.bits(0).size){BigInt(1)}
for {lhs <- c.io.wgt.rd(0).data.bits} {
poke(lhs, wgt.reverse)
}
val acc = IndexedSeq.fill(c.io.acc.rd(0).data.bits(0).size){BigInt(1)}
for {lhs <- c.io.acc.rd(0).data.bits} {
poke(lhs, acc.reverse)
}
class TensorMasterMock(tm: TensorMaster) {
poke(tm.rd(0).data.valid, 0)
var valid = peek(tm.rd(0).idx.valid)
def logical_step(v: BigInt) {
poke(tm.rd(0).data.valid, valid)
valid = peek(tm.rd(0).idx.valid)
expect(tm.rd(0).idx.valid, v)
}
}
class UopMasterMock(um: UopMaster) {
poke(um.data.valid, 0)
var valid = peek(um.idx.valid)
def logical_step(v: BigInt) {
poke(um.data.valid, valid)
valid = peek(um.idx.valid)
expect(um.idx.valid, v)
}
}
class Mocks {
val uop_mock = new UopMasterMock(c.io.uop)
val inp_mock = new TensorMasterMock(c.io.inp)
val wgt_mock = new TensorMasterMock(c.io.wgt)
val acc_mock = new TensorMasterMock(c.io.acc)
def logical_step(sram_valid: BigInt, uop_valid: BigInt) {
step(1)
uop_mock.logical_step(uop_valid)
inp_mock.logical_step(sram_valid)
wgt_mock.logical_step(sram_valid)
acc_mock.logical_step(sram_valid)
}
}
val mocks = new Mocks
poke(c.io.start, 0)
step(1)
expect(c.io.state, c.sIdle)
poke(c.io.start, 1)
mocks.logical_step(0, 1)
expect(c.io.state, c.sReadUop)
expect(c.io.out.wr(0).valid, 0)
expect(c.io.acc.wr(0).valid, 0)
poke(c.io.start, 0)
mocks.logical_step(0, 0)
expect(c.io.state, c.sComputeIdx)
expect(c.io.out.wr(0).valid, 0)
expect(c.io.acc.wr(0).valid, 0)
mocks.logical_step(1, 0)
expect(c.io.state, c.sReadTensor)
expect(c.io.out.wr(0).valid, 0)
expect(c.io.acc.wr(0).valid, 0)
mocks.logical_step(0, 0)
expect(c.io.state, c.sExe)
expect(c.io.out.wr(0).valid, 0)
expect(c.io.acc.wr(0).valid, 0)
expect(c.io.done, 0)
mocks.logical_step(0, 0)
expect(c.io.state, c.sWait)
expect(c.io.inflight, 1)
expect(c.io.out.wr(0).valid, 0)
expect(c.io.acc.wr(0).valid, 0)
mocks.logical_step(0, 0)
expect(c.io.state, c.sWait)
expect(c.io.inflight, 1)
expect(c.io.out.wr(0).valid, 1)
expect(c.io.acc.wr(0).valid, 1)
mocks.logical_step(0, 0)
expect(c.io.state, c.sWait)
expect(c.io.inflight, 0)
expect(c.io.out.wr(0).valid, 0)
expect(c.io.acc.wr(0).valid, 0)
mocks.logical_step(0, 0)
expect(c.io.state, c.sIdle)
expect(c.io.inflight, 0)
expect(c.io.out.wr(0).valid, 0)
expect(c.io.acc.wr(0).valid, 0)
}
class TensorGemmTest extends GenericTest("TensorGemm", (p:Parameters) => new TensorGemmSimple()(p),
(c:TensorGemmSimple) => new TensorGemmTester(c))
class TensorGemmIdxTester(c: TensorGemmSimple) extends PeekPokeTester(c) {
poke(c.io.start, 0)
val uop_begin = 0
val uop_end = 2
assert(uop_begin < uop_end)
val lp_0 = 2
val lp_1 = 3
val acc_0 = 1*lp_1
val inp_0 = 2*lp_1
val wgt_0 = 4*lp_1
val acc_1 = 1
val inp_1 = 2
val wgt_1 = 4
val u0 = BigInt("000", 16)
val u1 = BigInt("100", 16)
val u2 = BigInt("200", 16)
poke(c.io.dec.reset, 0)
poke(c.io.dec.uop_begin, uop_begin)
poke(c.io.dec.uop_end, uop_end)
poke(c.io.dec.lp_0, lp_0)
poke(c.io.dec.lp_1, lp_1)
poke(c.io.dec.acc_0, acc_0)
poke(c.io.dec.acc_1, acc_1)
poke(c.io.dec.inp_0, inp_0)
poke(c.io.dec.inp_1, inp_1)
poke(c.io.dec.wgt_0, wgt_0)
poke(c.io.dec.wgt_1, wgt_1)
// Don't need empty_0,{push,pop}_{next,prev},op
poke(c.io.uop.data.bits.u0, u0)
poke(c.io.uop.data.bits.u1, u1)
poke(c.io.uop.data.bits.u2, u2)
val inp = IndexedSeq.fill(c.io.inp.rd(0).data.bits(0).size){BigInt(1)}
for {lhs <- c.io.inp.rd(0).data.bits} {
poke(lhs, inp.reverse)
}
val wgt = IndexedSeq.fill(c.io.wgt.rd(0).data.bits(0).size){BigInt(1)}
for {lhs <- c.io.wgt.rd(0).data.bits} {
poke(lhs, wgt.reverse)
}
val acc = IndexedSeq.fill(c.io.acc.rd(0).data.bits(0).size){BigInt(1)}
for {lhs <- c.io.acc.rd(0).data.bits} {
poke(lhs, acc.reverse)
}
class TensorMasterMock(tm: TensorMaster) {
poke(tm.rd(0).data.valid, 0)
var valid = peek(tm.rd(0).idx.valid)
def logical_step(v: BigInt) {
poke(tm.rd(0).data.valid, valid)
valid = peek(tm.rd(0).idx.valid)
expect(tm.rd(0).idx.valid, v)
}
}
class UopMasterMock(um: UopMaster) {
poke(um.data.valid, 0)
var valid = peek(um.idx.valid)
def logical_step(v: BigInt) {
poke(um.data.valid, valid)
valid = peek(um.idx.valid)
expect(um.idx.valid, v)
}
}
class Mocks {
val uop_mock = new UopMasterMock(c.io.uop)
val inp_mock = new TensorMasterMock(c.io.inp)
val wgt_mock = new TensorMasterMock(c.io.wgt)
val acc_mock = new TensorMasterMock(c.io.acc)
val uop_indices = new scala.collection.mutable.Queue[BigInt]
val acc_indices = new scala.collection.mutable.Queue[BigInt]
val inp_indices = new scala.collection.mutable.Queue[BigInt]
val wgt_indices = new scala.collection.mutable.Queue[BigInt]
val accout_indices = new scala.collection.mutable.Queue[BigInt]
val out_indices = new scala.collection.mutable.Queue[BigInt]
def logical_step(sram_valid: BigInt, uop_valid: BigInt) {
step(1)
uop_mock.logical_step(uop_valid)
inp_mock.logical_step(sram_valid)
wgt_mock.logical_step(sram_valid)
acc_mock.logical_step(sram_valid)
if (peek(c.io.uop.idx.valid) == 1) {
expect(c.io.uop.idx.bits, uop_indices.dequeue())
}
if (peek(c.io.acc.rd(0).idx.valid) == 1) {
expect(c.io.acc.rd(0).idx.bits, acc_indices.dequeue())
}
if (peek(c.io.inp.rd(0).idx.valid) == 1) {
expect(c.io.inp.rd(0).idx.bits, inp_indices.dequeue())
}
if (peek(c.io.wgt.rd(0).idx.valid) == 1) {
expect(c.io.wgt.rd(0).idx.bits, wgt_indices.dequeue())
}
if (peek(c.io.acc.wr(0).valid) == 1) {
expect(c.io.acc.wr(0).bits.idx, accout_indices.dequeue())
}
if (peek(c.io.out.wr(0).valid) == 1) {
expect(c.io.out.wr(0).bits.idx, out_indices.dequeue())
}
}
def test_if_done() {
assert(uop_indices.isEmpty)
assert(acc_indices.isEmpty)
assert(inp_indices.isEmpty)
assert(wgt_indices.isEmpty)
}
}
val mocks = new Mocks
for {
cnt_o <- 0 until lp_0
cnt_i <- 0 until lp_1
uop_idx <- uop_begin until uop_end
} {
mocks.uop_indices.enqueue(uop_idx)
mocks.acc_indices.enqueue(u0 + acc_0*cnt_o + acc_1*cnt_i)
mocks.inp_indices.enqueue(u1 + inp_0*cnt_o + inp_1*cnt_i)
mocks.wgt_indices.enqueue(u2 + wgt_0*cnt_o + wgt_1*cnt_i)
mocks.accout_indices.enqueue(u0 + acc_0*cnt_o + acc_1*cnt_i)
mocks.out_indices.enqueue(u0 + acc_0*cnt_o + acc_1*cnt_i)
}
poke(c.io.start, 0)
step(1)
expect(c.io.state, c.sIdle)
poke(c.io.start, 1)
for {q <- 0 until (uop_end-uop_begin)*lp_0*lp_1} {
mocks.logical_step(0, 1)
expect(c.io.out.wr(0).valid, 0)
expect(c.io.acc.wr(0).valid, 0)
poke(c.io.start, 0)
mocks.logical_step(0, 0)
expect(c.io.out.wr(0).valid, if (q > 0) 1 else 0)
expect(c.io.acc.wr(0).valid, if (q > 0) 1 else 0)
mocks.logical_step(1, 0)
expect(c.io.out.wr(0).valid, 0)
expect(c.io.acc.wr(0).valid, 0)
mocks.logical_step(0, 0)
expect(c.io.out.wr(0).valid, 0)
expect(c.io.acc.wr(0).valid, 0)
expect(c.io.done, 0)
}
mocks.logical_step(0, 0)
expect(c.io.inflight, 1)
expect(c.io.out.wr(0).valid, 0)
expect(c.io.acc.wr(0).valid, 0)
mocks.logical_step(0, 0)
expect(c.io.inflight, 1)
expect(c.io.out.wr(0).valid, 1)
expect(c.io.acc.wr(0).valid, 1)
mocks.logical_step(0, 0)
expect(c.io.inflight, 0)
expect(c.io.out.wr(0).valid, 0)
expect(c.io.acc.wr(0).valid, 0)
mocks.logical_step(0, 0)
expect(c.io.inflight, 0)
expect(c.io.out.wr(0).valid, 0)
expect(c.io.acc.wr(0).valid, 0)
mocks.test_if_done()
}
class TensorGemmIdxTest extends GenericTest("TensorGemmIdx", (p:Parameters) => new TensorGemmSimple()(p),
(c:TensorGemmSimple) => new TensorGemmIdxTester(c))
class TensorGemmIndexGeneratorTester(c: TensorGemmIndexGenerator) extends PeekPokeTester(c) {
val uop_begin = 0
val uop_end = 2
assert(uop_begin < uop_end)
val lp_0 = 2
val lp_1 = 3
val acc_0 = 1*lp_1
val inp_0 = 2*lp_1
val wgt_0 = 4*lp_1
val acc_1 = 1
val inp_1 = 2
val wgt_1 = 4
poke(c.io.dec.reset, 0)
poke(c.io.dec.uop_begin, uop_begin)
poke(c.io.dec.uop_end, uop_end)
poke(c.io.dec.lp_0, lp_0)
poke(c.io.dec.lp_1, lp_1)
poke(c.io.dec.acc_0, acc_0)
poke(c.io.dec.acc_1, acc_1)
poke(c.io.dec.inp_0, inp_0)
poke(c.io.dec.inp_1, inp_1)
poke(c.io.dec.wgt_0, wgt_0)
poke(c.io.dec.wgt_1, wgt_1)
// Don't need empty_0,{push,pop}_{next,prev},op
class Mocks {
val uop_indices = new scala.collection.mutable.Queue[BigInt]
val acc_indices = new scala.collection.mutable.Queue[BigInt]
val inp_indices = new scala.collection.mutable.Queue[BigInt]
val wgt_indices = new scala.collection.mutable.Queue[BigInt]
def logical_step() {
step(1)
if (peek(c.io.valid) == 1) {
expect(c.io.uop_idx, uop_indices.dequeue())
expect(c.io.acc_i, acc_indices.dequeue())
expect(c.io.inp_i, inp_indices.dequeue())
expect(c.io.wgt_i, wgt_indices.dequeue())
}
}
def test_if_done() {
println(s"uop_indices remaining: ${uop_indices.size}")
println(s"acc_indices remaining: ${acc_indices.size}")
println(s"inp_indices remaining: ${inp_indices.size}")
println(s"wgt_indices remaining: ${wgt_indices.size}")
assert(uop_indices.isEmpty)
assert(acc_indices.isEmpty)
assert(inp_indices.isEmpty)
assert(wgt_indices.isEmpty)
}
}
val mocks = new Mocks
for {
cnt_o <- 0 until lp_0
cnt_i <- 0 until lp_1
uop_idx <- uop_begin until uop_end
} {
mocks.uop_indices.enqueue(uop_idx)
mocks.acc_indices.enqueue(acc_0*cnt_o + acc_1*cnt_i)
mocks.inp_indices.enqueue(inp_0*cnt_o + inp_1*cnt_i)
mocks.wgt_indices.enqueue(wgt_0*cnt_o + wgt_1*cnt_i)
}
poke(c.io.start, 1)
mocks.logical_step()
poke(c.io.start, 0)
val end = (uop_end-uop_begin)*lp_0*lp_1
var count = 0
while(peek(c.io.last) == 0 && count < 10*end + 100) {
mocks.logical_step()
count += 1
}
mocks.test_if_done()
}
class TensorGemmIndexGeneratorTest extends GenericTest("TensorGemmIndexGenerator",
(p:Parameters) => new TensorGemmIndexGenerator()(p),
(c:TensorGemmIndexGenerator) => new TensorGemmIndexGeneratorTester(c))
class TensorGemmPipelinedTester(c: TensorGemmPipelinedSplit) extends PeekPokeTester(c) {
poke(c.io.start, 0)
val uop_begin = 0
val uop_end = 2
assert(uop_begin < uop_end)
val lp_0 = 2
val lp_1 = 3
val acc_0 = 1*lp_1
val inp_0 = 2*lp_1
val wgt_0 = 4*lp_1
val acc_1 = 1
val inp_1 = 2
val wgt_1 = 4
val u0 = BigInt("000", 16)
val u1 = BigInt("100", 16)
val u2 = BigInt("200", 16)
poke(c.io.dec.reset, 0)
poke(c.io.dec.uop_begin, uop_begin)
poke(c.io.dec.uop_end, uop_end)
poke(c.io.dec.lp_0, lp_0)
poke(c.io.dec.lp_1, lp_1)
poke(c.io.dec.acc_0, acc_0)
poke(c.io.dec.acc_1, acc_1)
poke(c.io.dec.inp_0, inp_0)
poke(c.io.dec.inp_1, inp_1)
poke(c.io.dec.wgt_0, wgt_0)
poke(c.io.dec.wgt_1, wgt_1)
// Don't need empty_0,{push,pop}_{next,prev},op
poke(c.io.uop.data.bits.u0, u0)
poke(c.io.uop.data.bits.u1, u1)
poke(c.io.uop.data.bits.u2, u2)
val inp = IndexedSeq.fill(c.io.inp.rd(0).data.bits(0).size){BigInt(1)}
for {lhs <- c.io.inp.rd(0).data.bits} {
poke(lhs, inp.reverse)
}
val wgt = IndexedSeq.fill(c.io.wgt.rd(0).data.bits(0).size){BigInt(1)}
for {lhs <- c.io.wgt.rd(0).data.bits} {
poke(lhs, wgt.reverse)
}
val acc = IndexedSeq.fill(c.io.acc.rd(0).data.bits(0).size){BigInt(1)}
for {lhs <- c.io.acc.rd(0).data.bits} {
poke(lhs, acc.reverse)
}
class TensorMasterMock(tm: TensorMaster) {
poke(tm.rd(0).data.valid, 0)
var valid = peek(tm.rd(0).idx.valid)
def logical_step(v: Option[BigInt]) {
poke(tm.rd(0).data.valid, valid)
valid = peek(tm.rd(0).idx.valid)
for {x <- v} expect(tm.rd(0).idx.valid, x)
}
}
class UopMasterMock(um: UopMaster) {
poke(um.data.valid, 0)
var valid = peek(um.idx.valid)
def logical_step(v: Option[BigInt]) {
poke(um.data.valid, valid)
valid = peek(um.idx.valid)
for {x <- v} expect(um.idx.valid, x)
}
}
class Mocks {
val uop_mock = new UopMasterMock(c.io.uop)
val inp_mock = new TensorMasterMock(c.io.inp)
val wgt_mock = new TensorMasterMock(c.io.wgt)
val acc_mock = new TensorMasterMock(c.io.acc)
val uop_indices = new scala.collection.mutable.Queue[BigInt]
val acc_indices = new scala.collection.mutable.Queue[BigInt]
val inp_indices = new scala.collection.mutable.Queue[BigInt]
val wgt_indices = new scala.collection.mutable.Queue[BigInt]
val accout_indices = new scala.collection.mutable.Queue[BigInt]
val out_indices = new scala.collection.mutable.Queue[BigInt]
def logical_step() {
step(1)
uop_mock.logical_step(None)
inp_mock.logical_step(None)
wgt_mock.logical_step(None)
acc_mock.logical_step(None)
if (peek(c.io.uop.idx.valid) == 1) {
expect(c.io.uop.idx.bits, uop_indices.dequeue())
}
if (peek(c.io.acc.rd(0).idx.valid) == 1) {
expect(c.io.acc.rd(0).idx.bits, acc_indices.dequeue())
}
if (peek(c.io.inp.rd(0).idx.valid) == 1) {
expect(c.io.inp.rd(0).idx.bits, inp_indices.dequeue())
}
if (peek(c.io.wgt.rd(0).idx.valid) == 1) {
expect(c.io.wgt.rd(0).idx.bits, wgt_indices.dequeue())
}
if (peek(c.io.acc.wr(0).valid) == 1) {
expect(c.io.acc.wr(0).bits.idx, accout_indices.dequeue())
}
if (peek(c.io.out.wr(0).valid) == 1) {
expect(c.io.out.wr(0).bits.idx, out_indices.dequeue())
}
}
def test_if_done() {
println(s"uop_indices remaining: ${uop_indices.size}")
println(s"acc_indices remaining: ${acc_indices.size}")
println(s"inp_indices remaining: ${inp_indices.size}")
println(s"wgt_indices remaining: ${wgt_indices.size}")
println(s"accout_indices remaining: ${accout_indices.size}")
println(s"out_indices remaining: ${out_indices.size}")
}
}
val mocks = new Mocks
for {
cnt_o <- 0 until lp_0
cnt_i <- 0 until lp_1
uop_idx <- uop_begin until uop_end
} {
mocks.uop_indices.enqueue(uop_idx)
mocks.acc_indices.enqueue(u0 + acc_0*cnt_o + acc_1*cnt_i)
mocks.inp_indices.enqueue(u1 + inp_0*cnt_o + inp_1*cnt_i)
mocks.wgt_indices.enqueue(u2 + wgt_0*cnt_o + wgt_1*cnt_i)
mocks.accout_indices.enqueue(u0 + acc_0*cnt_o + acc_1*cnt_i)
mocks.out_indices.enqueue(u0 + acc_0*cnt_o + acc_1*cnt_i)
}
poke(c.io.start, 0)
step(1)
expect(c.io.state, c.sIdle)
poke(c.io.start, 1)
var count = 0
val end = (uop_end-uop_begin)*lp_0*lp_1
while (peek(c.io.done) == 0 && count < 10*end + 100) {
mocks.logical_step()
poke(c.io.start, 0)
}
expect(c.io.done, 1)
mocks.test_if_done()
}
class TensorGemmPipelinedTest extends GenericTest("TensorGemmPipelined",
(p:Parameters) => new TensorGemmPipelinedSplit()(p),
(c:TensorGemmPipelinedSplit) => new TensorGemmPipelinedTester(c))
class TensorGemmResetTester(c: TensorGemm) extends PeekPokeTester(c) {
poke(c.io.start, 0)
val uop_begin = 0
val uop_end = 2
assert(uop_begin < uop_end)
val lp_0 = 2
val lp_1 = 3
val acc_0 = 1*lp_1
val inp_0 = 2*lp_1
val wgt_0 = 4*lp_1
val acc_1 = 1
val inp_1 = 2
val wgt_1 = 4
val u0 = BigInt("000", 16)
val u1 = BigInt("100", 16)
val u2 = BigInt("200", 16)
val dec_reset = 1
poke(c.io.dec.reset, dec_reset)
poke(c.io.dec.uop_begin, uop_begin)
poke(c.io.dec.uop_end, uop_end)
poke(c.io.dec.lp_0, lp_0)
poke(c.io.dec.lp_1, lp_1)
poke(c.io.dec.acc_0, acc_0)
poke(c.io.dec.acc_1, acc_1)
poke(c.io.dec.inp_0, inp_0)
poke(c.io.dec.inp_1, inp_1)
poke(c.io.dec.wgt_0, wgt_0)
poke(c.io.dec.wgt_1, wgt_1)
// Don't need empty_0,{push,pop}_{next,prev},op
poke(c.io.uop.data.bits.u0, u0)
poke(c.io.uop.data.bits.u1, u1)
poke(c.io.uop.data.bits.u2, u2)
val inp = IndexedSeq.fill(c.io.inp.rd(0).data.bits(0).size){BigInt(1)}
for {lhs <- c.io.inp.rd(0).data.bits} {
poke(lhs, inp.reverse)
}
val wgt = IndexedSeq.fill(c.io.wgt.rd(0).data.bits(0).size){BigInt(1)}
for {lhs <- c.io.wgt.rd(0).data.bits} {
poke(lhs, wgt.reverse)
}
val acc = IndexedSeq.fill(c.io.acc.rd(0).data.bits(0).size){BigInt(1)}
for {lhs <- c.io.acc.rd(0).data.bits} {
poke(lhs, acc.reverse)
}
class TensorMasterMock(tm: TensorMaster) {
poke(tm.rd(0).data.valid, 0)
var valid = peek(tm.rd(0).idx.valid)
def logical_step(v: Option[BigInt]) {
poke(tm.rd(0).data.valid, valid)
valid = peek(tm.rd(0).idx.valid)
for {x <- v} expect(tm.rd(0).idx.valid, x)
}
}
class UopMasterMock(um: UopMaster) {
poke(um.data.valid, 0)
var valid = peek(um.idx.valid)
def logical_step(v: Option[BigInt]) {
poke(um.data.valid, valid)
valid = peek(um.idx.valid)
for {x <- v} expect(um.idx.valid, x)
}
}
class Mocks {
val uop_mock = new UopMasterMock(c.io.uop)
val inp_mock = new TensorMasterMock(c.io.inp)
val wgt_mock = new TensorMasterMock(c.io.wgt)
val acc_mock = new TensorMasterMock(c.io.acc)
val uop_indices = new scala.collection.mutable.Queue[BigInt]
val acc_indices = new scala.collection.mutable.Queue[BigInt]
val inp_indices = new scala.collection.mutable.Queue[BigInt]
val wgt_indices = new scala.collection.mutable.Queue[BigInt]
val accout_indices = new scala.collection.mutable.Queue[BigInt]
val out_indices = new scala.collection.mutable.Queue[BigInt]
def logical_step(sram_valid: BigInt, uop_valid: BigInt) {
step(1)
uop_mock.logical_step(None)
inp_mock.logical_step(None)
wgt_mock.logical_step(None)
acc_mock.logical_step(None)
if (peek(c.io.uop.idx.valid) == 1) {
expect(c.io.uop.idx.bits, uop_indices.dequeue())
}
if (peek(c.io.acc.rd(0).idx.valid) == 1) {
expect(c.io.acc.rd(0).idx.bits, acc_indices.dequeue())
}
if (peek(c.io.inp.rd(0).idx.valid) == 1) {
expect(c.io.inp.rd(0).idx.bits, inp_indices.dequeue())
}
if (peek(c.io.wgt.rd(0).idx.valid) == 1) {
expect(c.io.wgt.rd(0).idx.bits, wgt_indices.dequeue())
}
if (peek(c.io.acc.wr(0).valid) == 1) {
expect(c.io.acc.wr(0).bits.idx, accout_indices.dequeue())
}
if (peek(c.io.out.wr(0).valid) == 1) {
expect(c.io.out.wr(0).bits.idx, out_indices.dequeue())
}
}
def test_if_done() {
assert(uop_indices.isEmpty)
assert(acc_indices.isEmpty)
assert(inp_indices.isEmpty)
assert(wgt_indices.isEmpty)
assert(accout_indices.isEmpty)
assert(out_indices.isEmpty)
}
}
val mocks = new Mocks
for {
cnt_o <- 0 until lp_0
cnt_i <- 0 until lp_1
uop_idx <- uop_begin until uop_end
} {
mocks.uop_indices.enqueue(uop_idx)
mocks.acc_indices.enqueue(u0 + acc_0*cnt_o + acc_1*cnt_i)
mocks.inp_indices.enqueue(u1 + inp_0*cnt_o + inp_1*cnt_i)
mocks.wgt_indices.enqueue(u2 + wgt_0*cnt_o + wgt_1*cnt_i)
mocks.accout_indices.enqueue(u0 + acc_0*cnt_o + acc_1*cnt_i)
if (dec_reset == 0) {
mocks.out_indices.enqueue(u0 + acc_0*cnt_o + acc_1*cnt_i)
}
}
poke(c.io.start, 0)
step(1)
expect(c.io.state, c.sIdle)
poke(c.io.start, 1)
while(peek(c.io.done) == 0) {
mocks.logical_step(0, 0)
poke(c.io.start, 0)
}
mocks.test_if_done()
}
class TensorGemmResetTest extends GenericTest("TensorGemmReset", (p:Parameters) => new TensorGemm()(p),
(c:TensorGemm) => new TensorGemmResetTester(c))