diff --git a/groundtest/src/main/scala/nastitest.scala b/groundtest/src/main/scala/nastitest.scala index 67c4d060..a540aea3 100644 --- a/groundtest/src/main/scala/nastitest.scala +++ b/groundtest/src/main/scala/nastitest.scala @@ -6,93 +6,48 @@ import uncore.converters._ import junctions._ import cde.Parameters -abstract class NastiTest(implicit val p: Parameters) extends Module - with HasNastiParameters with HasMIFParameters with HasAddrMapParameters { +class NastiGenerator(id: Int)(implicit val p: Parameters) extends Module + with HasNastiParameters + with HasMIFParameters + with HasAddrMapParameters + with HasGeneratorParameters { + val io = new Bundle { val finished = Bool(OUTPUT) val mem = new NastiIO } - val memStart = addrMap("mem").start + 0x40000 -} -class NastiBlockTest(implicit p: Parameters) extends NastiTest()(p) { - - val (s_start :: s_write_req :: s_write_resp :: - s_read_req :: s_read_resp :: s_finish :: Nil) = Enum(Bits(), 6) - val state = Reg(init = s_start) - - val addr_sent = Reg(init = Bool(false)) - val data_sent = Reg(init = UInt(0, mifDataBeats)) - val data_beats = Vec.tabulate(mifDataBeats) { i => UInt(i * 0x20) } - - val (r_count, r_done) = Counter(io.mem.r.fire(), mifDataBeats) - val (w_count, w_done) = Counter(io.mem.w.fire(), mifDataBeats) - - io.mem.aw.valid := (state === s_write_req) && !addr_sent - io.mem.aw.bits := NastiWriteAddressChannel( - id = UInt(0), - addr = UInt(memStart), - len = UInt(mifDataBeats - 1), - size = UInt(log2Up(mifDataBits / 8))) - - io.mem.w.valid := (state === s_write_req) && !data_sent.andR - io.mem.w.bits := NastiWriteDataChannel( - data = data_beats(w_count), - last = w_count === UInt(mifDataBeats - 1)) - - io.mem.b.ready := (state === s_write_resp) - - io.mem.ar.valid := (state === s_read_req) - io.mem.ar.bits := NastiReadAddressChannel( - id = UInt(1), - addr = UInt(memStart), - len = UInt(mifDataBeats - 1), - size = UInt(log2Up(mifDataBits / 8))) - - io.mem.r.ready := (state === s_read_resp) - - when (state === s_start) { state := s_write_req } - - when (io.mem.aw.fire()) { addr_sent := Bool(true) } - when (io.mem.w.fire()) { data_sent := data_sent | UIntToOH(w_count) } - when (w_done) { state := s_write_resp } - when (io.mem.b.fire()) { state := s_read_req } - - when (io.mem.ar.fire()) { state := s_read_resp } - when (r_done) { state := s_finish } - - io.finished := (state === s_finish) - - assert(!io.mem.r.valid || io.mem.r.bits.data === data_beats(r_count), - "NASTI Block Test: results do not match") -} - -class NastiSmallTest(implicit p: Parameters) extends NastiTest()(p) { val mifDataBytes = mifDataBits / 8 val (s_start :: s_write_addr :: s_write_data :: s_read :: s_wait :: s_finish :: Nil) = Enum(Bits(), 6) val state = Reg(init = s_start) - val nTests = 512 - val ref_data = Vec.tabulate(nTests) { i => UInt(0x35abffcd + i, 32) } + def ref_data(idx: UInt) = UInt(0x35abffcd, genWordBits) + (idx << UInt(3)) - val (write_idx, write_done) = Counter(io.mem.w.fire(), nTests) - val write_addr = UInt(memStart + 0x200) + Cat(write_idx, UInt(0, 2)) - val write_data = Fill(mifDataBits / 32, ref_data(write_idx)) + val part_of_addr = + if (log2Ceil(nGens) > 0) { + Cat(UInt(id, log2Ceil(nGens)), + UInt(0, wordOffset)) + } else { + UInt(0, wordOffset) + } + + val (write_idx, write_done) = Counter(io.mem.w.fire(), maxRequests) + val write_addr = UInt(startAddress) + Cat(write_idx, part_of_addr) + val write_data = Fill(mifDataBits / genWordBits, ref_data(write_idx)) val write_align = write_addr(log2Up(mifDataBytes) - 1, 0) - val write_mask = UInt("h0f") << write_align + val write_mask = UInt((1 << genWordBytes) - 1, nastiWStrobeBits) << write_align - val (read_idx, read_done) = Counter(io.mem.ar.fire(), nTests) - val read_addr = UInt(memStart + 0x200) + Cat(read_idx, UInt(0, 2)) - val (read_resp_idx, read_resp_done) = Counter(io.mem.r.fire(), nTests) + val (read_idx, read_done) = Counter(io.mem.ar.fire(), maxRequests) + val read_addr = UInt(startAddress) + Cat(read_idx, part_of_addr) io.mem.aw.valid := (state === s_write_addr) io.mem.aw.bits := NastiWriteAddressChannel( id = UInt(0), addr = write_addr, len = UInt(0), - size = UInt("b010")) + size = UInt(log2Ceil(genWordBytes))) io.mem.w.valid := (state === s_write_data) io.mem.w.bits := NastiWriteDataChannel( @@ -105,11 +60,22 @@ class NastiSmallTest(implicit p: Parameters) extends NastiTest()(p) { id = UInt(0), addr = read_addr, len = UInt(0), - size = UInt("b010")) + size = UInt(log2Ceil(genWordBytes))) io.mem.r.ready := Bool(true) io.mem.b.ready := Bool(true) + io.finished := (state === s_finish) + + val (read_resp_idx, read_resp_done) = Counter(io.mem.r.fire(), maxRequests) + val read_resp_addr = UInt(startAddress) + Cat(read_resp_idx, part_of_addr) + val read_offset = read_resp_addr(log2Up(nastiXDataBits / 8) - 1, 0) + val read_shift = Cat(read_offset, UInt(0, 3)) + val read_data = (io.mem.r.bits.data >> read_shift)(genWordBits - 1, 0) + + assert(!io.mem.r.valid || read_data === ref_data(read_resp_idx), + "NASTI Test: results do not match") + when (state === s_start) { state := s_write_addr } when (io.mem.aw.fire()) { state := s_write_data } when (io.mem.w.fire()) { state := s_write_addr } @@ -117,81 +83,34 @@ class NastiSmallTest(implicit p: Parameters) extends NastiTest()(p) { when (read_done) { state := s_wait } when (read_resp_done) { state := s_finish } - io.finished := (state === s_finish) - - val readShiftBits = log2Ceil(mifDataBits / 32) - val read_shift = Cat(read_resp_idx(readShiftBits - 1, 0), UInt(0, 5)) - val read_data = (io.mem.r.bits.data >> read_shift)(31, 0) - - assert(!io.mem.r.valid || read_data === ref_data(read_resp_idx), - "NASTI Small Test: results do not match") -} - -class NastiSequencer(n: Int)(implicit p: Parameters) extends Module { - val io = new Bundle { - val in = Vec(n, new NastiIO).flip - val out = new NastiIO() - val finished = Vec(n, Bool(INPUT)) - } - - val selection = Reg(init = UInt(0, log2Up(n))) - val all_finished = io.finished.reduce(_ && _) - - when (!all_finished && io.finished(selection)) { - selection := selection + UInt(1) - } - - io.out.ar.valid := io.in(selection).ar.valid - io.out.ar.bits := io.in(selection).ar.bits - - io.out.aw.valid := io.in(selection).aw.valid - io.out.aw.bits := io.in(selection).aw.bits - - io.out.w.valid := io.in(selection).w.valid - io.out.w.bits := io.in(selection).w.bits - - io.out.b.ready := io.in(selection).b.ready - - io.out.r.ready := io.in(selection).r.ready - - for ((in, i) <- io.in.zipWithIndex) { - val me = selection === UInt(i) - in.ar.ready := io.out.ar.ready && me - in.aw.ready := io.out.aw.ready && me - in.w.ready := io.out.w.ready && me - in.b.valid := io.out.b.valid && me - in.b.bits := io.out.b.bits - in.r.valid := io.out.r.valid && me - in.r.bits := io.out.r.bits - } - val r_timer = Module(new Timer(1000, 2)) - r_timer.io.start.valid := io.out.ar.fire() - r_timer.io.start.bits := io.out.ar.bits.id - r_timer.io.stop.valid := io.out.r.fire() && io.out.r.bits.last - r_timer.io.stop.bits := io.out.r.bits.id + r_timer.io.start.valid := io.mem.ar.fire() + r_timer.io.start.bits := io.mem.ar.bits.id + r_timer.io.stop.valid := io.mem.r.fire() && io.mem.r.bits.last + r_timer.io.stop.bits := io.mem.r.bits.id assert(!r_timer.io.timeout, "NASTI Read timed out") val w_timer = Module(new Timer(1000, 2)) - w_timer.io.start.valid := io.out.aw.fire() - w_timer.io.start.bits := io.out.aw.bits.id - w_timer.io.stop.valid := io.out.b.fire() - w_timer.io.stop.bits := io.out.b.bits.id + w_timer.io.start.valid := io.mem.aw.fire() + w_timer.io.start.bits := io.mem.aw.bits.id + w_timer.io.stop.valid := io.mem.b.fire() + w_timer.io.stop.bits := io.mem.b.bits.id assert(!w_timer.io.timeout, "NASTI Write timed out") } class NastiConverterTest(implicit p: Parameters) extends GroundTest()(p) with HasNastiParameters { - val tests = Seq(Module(new NastiBlockTest), Module(new NastiSmallTest)) + require(tileSettings.uncached == 1 && tileSettings.cached == 0) - val sequencer = Module(new NastiSequencer(tests.size)) + val genId = p(GroundTestKey).take(tileId) + .map(settings => settings.cached + settings.uncached) + .foldLeft(0)(_ + _) + + val test = Module(new NastiGenerator(genId)) val converter = Module(new TileLinkIONastiIOConverter()( p.alterPartial { case TLId => "Outermost" })) - sequencer.io.in <> tests.map(_.io.mem) - sequencer.io.finished := tests.map(_.io.finished) - converter.io.nasti <> sequencer.io.out + converter.io.nasti <> test.io.mem TileLinkWidthAdapter(io.mem.head, converter.io.tl) - - io.finished := tests.map(_.io.finished).reduce(_ && _) + io.finished := test.io.finished }