//Compile the simulatorvalcompiled=SimConfig.withWave.allOptimisation.compile(rtl=newStreamFifoCC(dataType=Bits(32bits),depth=32,pushClock=ClockDomain.external("clkA"),popClock=ClockDomain.external("clkB")))//Run the simulationcompiled.doSimUntilVoid{dut=>valqueueModel=mutable.Queue[Long]()//Fork a thread to manage the clock domains signalsvalclocksThread=fork{//Clear clock domains signals, to be sure the simulation capture their first edge.dut.pushClock.fallingEdge()dut.popClock.fallingEdge()dut.pushClock.disassertReset()dut.popClock.disassertReset()sleep(0)//Do the resetsdut.pushClock.assertReset()dut.popClock.assertReset()sleep(10)dut.pushClock.disassertReset()dut.popClock.disassertReset()sleep(1)//Forever, randomly toggle one of the clocks (will create asynchronous clocks without fixed frequencies)while(true){if(Random.nextBoolean()){dut.pushClock.clockToggle()}else{dut.popClock.clockToggle()}sleep(1)}}//Push data randomly and fill the queueModel with pushed transactionsvalpushThread=fork{while(true){dut.io.push.valid.randomize()dut.io.push.payload.randomize()dut.pushClock.waitSampling()if(dut.io.push.valid.toBoolean&&dut.io.push.ready.toBoolean){queueModel.enqueue(dut.io.push.payload.toLong)}}}//Pop data randomly and check that it match with the queueModelvalpopThread=fork{for(i<-0until100000){dut.io.pop.ready.randomize()dut.popClock.waitSampling()if(dut.io.pop.valid.toBoolean&&dut.io.pop.ready.toBoolean){assert(dut.io.pop.payload.toLong==queueModel.dequeue())}}simSuccess()}}