package groundtest import Chisel._ import uncore.tilelink._ import uncore.converters._ import junctions._ import groundtest.common._ import cde.Parameters class NastiGenerator(id: Int)(implicit val p: Parameters) extends Module with HasNastiParameters with HasMIFParameters with HasAddrMapParameters with HasGeneratorParameters { val io = new Bundle { val status = new GroundTestStatus val mem = new NastiIO } 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) def ref_data(idx: UInt) = UInt(0x35abffcd, genWordBits) + (idx << UInt(3)) 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((1 << genWordBytes) - 1, nastiWStrobeBits) << write_align 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 = write_idx(nastiXIdBits - 1, 0), addr = write_addr, len = UInt(0), size = UInt(log2Ceil(genWordBytes))) io.mem.w.valid := (state === s_write_data) io.mem.w.bits := NastiWriteDataChannel( data = write_data, strb = Some(write_mask), last = Bool(true)) io.mem.ar.valid := (state === s_read) io.mem.ar.bits := NastiReadAddressChannel( id = UInt(0), addr = read_addr, len = UInt(0), size = UInt(log2Ceil(genWordBytes))) io.mem.r.ready := Bool(true) io.mem.b.ready := Bool(true) io.status.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) val data_mismatch = io.mem.r.valid && read_data =/= ref_data(read_resp_idx) assert(!data_mismatch, "NASTI Test: results do not match") io.status.error.valid := data_mismatch io.status.error.bits := UInt(1) 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 } when (write_done) { state := s_read } when (read_done) { state := s_wait } when (read_resp_done) { state := s_finish } val r_timer = Module(new Timer(1000, 2)) 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.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") io.status.timeout.valid := r_timer.io.timeout || w_timer.io.timeout io.status.timeout.bits := Mux(r_timer.io.timeout, UInt(1), UInt(2)) } class NastiConverterTest(implicit p: Parameters) extends GroundTest()(p) with HasNastiParameters { require(tileSettings.uncached == 1 && tileSettings.cached == 0) 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" })) converter.io.nasti <> test.io.mem TileLinkWidthAdapter(io.mem.head, converter.io.tl) io.status := test.io.status }