def i2cSlaveThread(cmdBus, rspBus, cmds, rsps, clk): rspBus.valid <= False while rsps: yield RisingEdge(clk) rspBus.valid <= False if cmdBus.valid == True: expected = cmds.pop(0) log.debug(expected) if expected == "start": assert cmdBus.payload.mode == 0 elif expected == "stop": assert cmdBus.payload.mode == 3 elif expected == "drive": assert cmdBus.payload.mode == 1 rsp = rsps.pop(0) if rsp == "Z": rspBus.valid <= True rspBus.payload.enable <= False rspBus.payload.data <= randInt(0, 1) elif isinstance(rsp, bool): rspBus.valid <= True rspBus.payload.enable <= True rspBus.payload.data <= rsp else: raise Exception(rsp) elif isinstance(expected, bool): assert cmdBus.payload.mode == 2 assert cmdBus.payload.data == expected else: raise Exception("???")
def __init__(self, data=-1, delayCmd=0, delayRsp=0): if data == -1 : self.data = randInt(0,2**I2CConfig.dataWdith-1) else: self.data = data self.delayCMD = delayCmd self.delayRSP = delayRsp self.enCollision = False
def test_fibonacci_left(dut): dut.log.info("Cocotb test LFSR fibonacci left") clockDomain = ClockDomain(dut.clk, 500, None , RESET_ACTIVE_LEVEL.LOW) # Start clock cocotb.fork(clockDomain.start()) # Init IO and wait the end of the reset dut.io_fib_inc <= 0 dut.io_fib_init <= 0 dut.io_fib_seed <= 0 dut.io_fib_rightLeft <= LFSR_SHIFT_DIR.SHIFT_LEFT yield RisingEdge(dut.clk) yield RisingEdge(dut.clk) # init LFSR widthData = 32 initValue = randInt(0, 2**widthData) dut.io_fib_init <= 1 dut.io_fib_seed <= initValue lfsr = FibonacciLFSR(initValue, [0,2,3,5,10], widthData, LFSR_SHIFT_DIR.SHIFT_LEFT) yield RisingEdge(dut.clk) dut.io_fib_init <= 0 yield RisingEdge(dut.clk) yield RisingEdge(dut.clk) for _ in range(0,10): dut.io_fib_inc <= 1 yield RisingEdge(dut.clk) dut.io_fib_inc <= 0 yield RisingEdge(dut.clk) lfsr.getRand() realResult = int(dut.io_fib_result) assertEquals(lfsr.state, realResult, "LFSR Fibonacci Left - Comparaison Error python : %s - %s : hdl" % (hex(lfsr.state), hex(realResult))) yield RisingEdge(dut.clk) dut.io_fib_inc <= 0 yield RisingEdge(dut.clk) dut.log.info("Cocotb test LFSR fibonacci left")
def test_galois_right(dut): dut.log.info("Cocotb test right LFSR Galois") clockDomain = ClockDomain(dut.clk, 500, None , RESET_ACTIVE_LEVEL.LOW) # Start clock cocotb.fork(clockDomain.start()) # Init IO and wait the end of the reset dut.io_gal_inc <= 0 dut.io_gal_init <= 0 dut.io_gal_seed <= 0 dut.io_gal_rightLeft <= LFSR_SHIFT_DIR.SHIFT_RIGHT yield RisingEdge(dut.clk) yield RisingEdge(dut.clk) # init LFSR widthData = 16 initValue = randInt(0, 2**widthData) dut.io_gal_init <= 1 dut.io_gal_seed <= initValue lfsr = GaloisLFSR(initValue, [1,2], widthData, LFSR_SHIFT_DIR.SHIFT_RIGHT) yield RisingEdge(dut.clk) dut.io_gal_init <= 0 yield RisingEdge(dut.clk) yield RisingEdge(dut.clk) for _ in range(0,10): dut.io_gal_inc <= 1 yield RisingEdge(dut.clk) dut.io_gal_inc <= 0 yield RisingEdge(dut.clk) lfsr.getRand() realResult = int(dut.io_gal_result) assertEquals(lfsr.state, realResult, "LFSR Galois Right - Comparaison Error python : %s - %s : hdl" % (hex(lfsr.state), hex(realResult))) yield RisingEdge(dut.clk) yield RisingEdge(dut.clk) dut.log.info("Cocotb test right LFSR galois")
def i2cSlaveThread(cmdBus, rspBus, cmds, rsps, clk): rspBus.valid <= False while cmds: yield FallingEdge(clk) rspBus.valid <= False if str(cmdBus.kind) == "xxx" or cmdBus.kind == NONE: continue expected = cmds.pop(0) # log.debug(expected) if expected == "start": assert cmdBus.kind == START elif expected == "restart": assert cmdBus.kind == RESTART elif expected == "stop": assert cmdBus.kind == STOP elif expected == "drop": assert cmdBus.kind == DROP elif expected == "drive": assert cmdBus.kind == DRIVE if random.uniform(0, 1) < 1.0 / (2500000/100000) * 2: rsp = rsps.pop(0) if rsp == "Z": rspBus.valid <= True rspBus.enable <= False rspBus.data <= randInt(0, 1) elif isinstance(rsp, bool): rspBus.valid <= True rspBus.enable <= True rspBus.data <= rsp else: raise Exception(rsp) else: cmds.insert(0,expected) elif isinstance(expected, bool): assert cmdBus.kind == READ assert cmdBus.data == expected else: raise Exception("???")
def SlaveThread(scl, sda, clk, baudPeriod): global crapyConflictCounter global normalConflictCounter global normalTransactionCounter log.debug("x") IDLE = 0 START = 1 DATA = 2 state = IDLE dataState = 0 scl.write(True) sda.write(True) sclLast = True sdaLast = True while True: yield RisingEdge(clk) sclValue = scl.read() sdaValue = sda.read() sclRising = sclValue and not sclLast sclFalling = not sclValue and sclLast sdaRising = sdaValue and not sdaLast sdaFalling = not sdaValue and sdaLast sclLast = sclValue sdaLast = sdaValue if state == IDLE: if sdaFalling and sclValue: state = START elif state == START: if sclFalling: state = DATA dataState = 0 address = 0 elif state == DATA: if sclRising: if dataState < 8: address |= sdaValue << (7 - dataState) elif sclFalling: dataState += 1 if dataState >= 8 and dataState < 16: if random.random() < 0.2: #Clock stretching scl.write(False) yield Timer(randInt(baudPeriod / 10, baudPeriod * 10)) sda.write((cmdToData[address] >> (15 - dataState)) & 1) yield Timer(baudPeriod / 4) scl.write(True) yield clockedFuncWaitTrue(clk, scl.read) sclLast = False else: sda.write((cmdToData[address] >> (15 - dataState)) & 1) elif (dataState == 6 and random.random() < 0.2): scl.write(False) if random.random() < 0.2: # Clock stretching yield Timer(randInt(baudPeriod / 10, baudPeriod * 10)) yield Timer(baudPeriod / 2) sda.write(False) yield Timer(baudPeriod / 2) scl.write(True) yield clockedFuncWaitTrue(clk, scl.read) yield Timer(baudPeriod) if random.random() < 0.5: #Normal conflict normalConflictCounter += 1 for i in range(4): rand = randBool() scl.write(False) yield Timer(baudPeriod / 2) sda.write(rand) yield Timer(baudPeriod / 2) scl.write(True) yield clockedFuncWaitTrue(clk, scl.read) yield Timer(baudPeriod) assert sda.read() == rand scl.write(False) yield Timer(baudPeriod / 2) sda.write(False) yield Timer(baudPeriod / 2) scl.write(True) yield clockedFuncWaitTrue(clk, scl.read) yield Timer(baudPeriod) sda.write(True) else: #crapy conflict wihtout STOP crapyConflictCounter += 1 scl.write(False) yield Timer(baudPeriod / 2) sda.write(True) yield Timer(baudPeriod / 2) scl.write(True) yield clockedFuncWaitTrue(clk, scl.read) yield Timer(baudPeriod) state = IDLE continue else: if random.random() < 0.2: #Clock stretching scl.write(False) yield Timer(randInt(baudPeriod / 10, baudPeriod * 10)) sda.write(True) yield Timer(baudPeriod / 4) scl.write(True) sclLast = False else: sda.write(True) elif sclValue: if sdaRising: state = 0 if sdaFalling: state = 1 pass
def run(self): global crapyConflictCounter global normalConflictCounter global normalTransactionCounter yield Timer(self.baudPeriod * 10) while crapyConflictCounter < 2 or normalConflictCounter < 3 or normalTransactionCounter < 40: while True: colision = False cmd = Transaction() cmd.mode = 0 cmd.data = randBool() self.cmdQueue.append(cmd) address = randBits(8) | 2 for bitId in range(8): cmd = Transaction() cmd.mode = 1 cmd.data = (address >> (7 - bitId)) & 1 self.cmdQueue.append(cmd) yield clockedWaitTrue(self.clk, self.rsp.valid) if self.rsp.payload.data != cmd.data: assert bitId == 6 colision = True cmd = Transaction() cmd.mode = 3 #DROP cmd.data = randBool() self.cmdQueue.append(cmd) break if colision: continue for bitId in range(8): cmd = Transaction() cmd.mode = 1 cmd.data = True self.cmdQueue.append(cmd) yield clockedWaitTrue(self.clk, self.rsp.valid) assert self.rsp.payload.data == ((cmdToData[address] >> (7 - bitId)) & 1) if random.random() < 0.75: cmd = Transaction() cmd.mode = 2 cmd.data = randBool() self.cmdQueue.append(cmd) if random.random() < 0.75: #no other master frame if random.random() < 0.5: # With inter frame delay yield Timer(randInt(0, self.baudPeriod * 20)) else: @coroutine def anotherFrameEmiter(): yield self.softMaster.sendStart() for i in range(5): yield self.softMaster.sendBit(randBool()) yield self.softMaster.sendStop() yield Timer( randInt(self.baudPeriod * 4, self.baudPeriod * 10)) fork(anotherFrameEmiter()) yield Timer( randInt(self.baudPeriod * 1, self.baudPeriod * 14)) normalTransactionCounter += 1 break while self.cmdQueue: yield Timer(self.baudPeriod * 10)
def test1(dut): # random.seed(13) cocotb.fork(ClockDomainAsyncReset(dut.clk, dut.reset,100000)) cocotb.fork(simulationSpeedPrinter(dut.clk)) sclInterconnect = OpenDrainInterconnect() sclInterconnect.addHardDriver(dut.io_i2c_scl_write) sclInterconnect.addHardReader(dut.io_i2c_scl_read) sdaInterconnect = OpenDrainInterconnect() sdaInterconnect.addHardDriver(dut.io_i2c_sda_write) sdaInterconnect.addHardReader(dut.io_i2c_sda_read) dut.io_config_samplingClockDivider <= 3 dut.io_config_timeout <= 25*10-1 dut.io_config_tsuDat <= 4 softMaster = I2cSoftMaster(sclInterconnect.newSoftConnection(), sdaInterconnect.newSoftConnection(), 2500000,dut.clk) masterCmds = [] slaveCmds = [] slaveRsps = [] masterRsps = [] masterCmds.append(10) for frameId in range(50): masterCmds.append("start") slaveCmds.append("start") while True: for bitId in range(randInt(1,10)): masterValue = random.uniform(0,1) > 0.5 slaveValue = random.uniform(0,1) > 0.5 slaveEnable = random.uniform(0,1) > 0.5 value = masterValue and (slaveValue or not slaveEnable) masterCmds.append(masterValue) slaveRsps.append(slaveValue if slaveEnable else "Z") slaveCmds.append("drive") slaveCmds.append(value) masterRsps.append(value) if random.uniform(0,1) < 0.1: slaveCmds.append("drive") slaveRsps.append(random.uniform(0,1) > 0.5) masterCmds.append(20) masterCmds.append("drop") masterCmds.append(randInt(1,10)) slaveCmds.append("drop") break slaveRsps.append("Z") if random.uniform(0,1) < 0.5: masterCmds.append("stop") slaveCmds.append("drive") slaveCmds.append(False) slaveCmds.append("stop") masterCmds.append(randInt(1,10)) break masterCmds.append("restart") slaveCmds.append("drive") slaveCmds.append(True) slaveCmds.append("restart") masterThread = fork(i2cMasterThread(softMaster, masterCmds,masterRsps)) slaveThread = fork(i2cSlaveThread(Bundle(dut,"io_bus_cmd"), Bundle(dut,"io_bus_rsp"),slaveCmds,slaveRsps, dut.clk)) yield masterThread.join() cocotb.fork(SimulationTimeout(100 * 2500000)) while True: if not slaveCmds and not slaveRsps and not masterRsps: break yield Timer(10000)
def SlaveThread(scl,sda,clk,baudPeriod): global crapyConflictCounter global normalConflictCounter global normalTransactionCounter log.debug("x") IDLE = 0 START = 1 DATA = 2 state = IDLE dataState = 0 scl.write(True) sda.write(True) sclLast = True sdaLast = True while True: yield RisingEdge(clk) sclValue = scl.read() sdaValue = sda.read() sclRising = sclValue and not sclLast sclFalling = not sclValue and sclLast sdaRising = sdaValue and not sdaLast sdaFalling = not sdaValue and sdaLast sclLast = sclValue sdaLast = sdaValue if state == IDLE: if sdaFalling and sclValue: state = START elif state == START: if sclFalling: state = DATA dataState = 0 address = 0 elif state == DATA: if sclRising: if dataState < 8: address |= sdaValue << (7-dataState) elif sclFalling: dataState += 1 if dataState >= 8 and dataState < 16: if random.random() < 0.2: #Clock stretching scl.write(False) yield Timer(randInt(baudPeriod/10, baudPeriod*10)) sda.write((cmdToData[address] >> (15-dataState)) & 1) yield Timer(baudPeriod/4); scl.write(True) yield clockedFuncWaitTrue(clk, scl.read) sclLast = False else: sda.write((cmdToData[address] >> (15 - dataState)) & 1) elif(dataState == 6 and random.random() < 0.2): scl.write(False) if random.random() < 0.2: # Clock stretching yield Timer(randInt(baudPeriod / 10, baudPeriod * 10)) yield Timer(baudPeriod / 2) sda.write(False) yield Timer(baudPeriod / 2) scl.write(True) yield clockedFuncWaitTrue(clk, scl.read) yield Timer(baudPeriod) if random.random() < 0.5: #Normal conflict normalConflictCounter += 1 for i in range(4): rand = randBool() scl.write(False) yield Timer(baudPeriod/2) sda.write(rand) yield Timer(baudPeriod/2) scl.write(True) yield clockedFuncWaitTrue(clk, scl.read) yield Timer(baudPeriod) assert sda.read() == rand scl.write(False) yield Timer(baudPeriod / 2) sda.write(False) yield Timer(baudPeriod / 2) scl.write(True) yield clockedFuncWaitTrue(clk, scl.read) yield Timer(baudPeriod) sda.write(True) else: #crapy conflict wihtout STOP crapyConflictCounter += 1 scl.write(False) yield Timer(baudPeriod / 2) sda.write(True) yield Timer(baudPeriod / 2) scl.write(True) yield clockedFuncWaitTrue(clk, scl.read) yield Timer(baudPeriod) state = IDLE continue else: if random.random() < 0.2: #Clock stretching scl.write(False) yield Timer(randInt(baudPeriod/10, baudPeriod*10)) sda.write(True) yield Timer(baudPeriod/4); scl.write(True) sclLast = False else: sda.write(True) elif sclValue: if sdaRising: state = 0 if sdaFalling: state = 1 pass
def run(self): global crapyConflictCounter global normalConflictCounter global normalTransactionCounter yield Timer(self.baudPeriod * 10) while crapyConflictCounter < 2 or normalConflictCounter < 3 or normalTransactionCounter < 40: while True: colision = False cmd = Transaction() cmd.mode = 0 cmd.data = randBool() self.cmdQueue.append(cmd) address = randBits(8) | 2 for bitId in range(8): cmd = Transaction() cmd.mode = 1 cmd.data = (address >> (7 - bitId)) & 1 self.cmdQueue.append(cmd) yield clockedWaitTrue(self.clk,self.rsp.valid) if self.rsp.payload.data != cmd.data: assert bitId == 6 colision = True cmd = Transaction() cmd.mode = 3 #DROP cmd.data = randBool() self.cmdQueue.append(cmd) break if colision: continue for bitId in range(8): cmd = Transaction() cmd.mode = 1 cmd.data = True self.cmdQueue.append(cmd) yield clockedWaitTrue(self.clk,self.rsp.valid) assert self.rsp.payload.data == ((cmdToData[address] >> (7-bitId)) & 1) if random.random() < 0.75: cmd = Transaction() cmd.mode = 2 cmd.data = randBool() self.cmdQueue.append(cmd) if random.random() < 0.75: #no other master frame if random.random() < 0.5: # With inter frame delay yield Timer(randInt(0,self.baudPeriod*20)) else: @coroutine def anotherFrameEmiter(): yield self.softMaster.sendStart() for i in range(5): yield self.softMaster.sendBit(randBool()) yield self.softMaster.sendStop() yield Timer(randInt(self.baudPeriod * 4, self.baudPeriod * 10)) fork(anotherFrameEmiter()) yield Timer(randInt(self.baudPeriod * 1, self.baudPeriod * 14)) normalTransactionCounter += 1 break while self.cmdQueue: yield Timer(self.baudPeriod * 10)
def test1(dut): cocotb.fork(ClockDomainAsyncReset(dut.clk, dut.reset,100000)) cocotb.fork(simulationSpeedPrinter(dut.clk)) sclInterconnect = OpenDrainInterconnect() sclInterconnect.addHardDriver(dut.io_i2c_scl_write) sclInterconnect.addHardReader(dut.io_i2c_scl_read) sdaInterconnect = OpenDrainInterconnect() sdaInterconnect.addHardDriver(dut.io_i2c_sda_write) sdaInterconnect.addHardReader(dut.io_i2c_sda_read) dut.io_config_samplingClockDivider <= 3 dut.io_config_timeout <= 25*10-1 dut.io_config_tsuDat <= 4 softMaster = I2cSoftMaster(sclInterconnect.newSoftConnection(), sdaInterconnect.newSoftConnection(), 2500000,dut.clk) masterCmds = [] slaveCmds = [] slaveRsps = [] masterRsps = [] masterCmds.append(10) for frameId in range(50): masterCmds.append("start") slaveCmds.append("start") while True: for bitId in range(randInt(1,10)): masterValue = random.uniform(0,1) > 0.5 slaveValue = random.uniform(0,1) > 0.5 slaveEnable = random.uniform(0,1) > 0.5 value = masterValue and (slaveValue or not slaveEnable) masterCmds.append(masterValue) slaveRsps.append(slaveValue if slaveEnable else "Z") slaveCmds.append("drive") slaveCmds.append(value) masterRsps.append(value) if random.uniform(0,1) < 0.1: slaveCmds.append("drive") slaveRsps.append(random.uniform(0,1) > 0.5) masterCmds.append(20) masterCmds.append("drop") masterCmds.append(randInt(1,10)) slaveCmds.append("stop") break slaveRsps.append("Z") if random.uniform(0,1) < 0.5: masterCmds.append("stop") slaveCmds.append("drive") slaveCmds.append(False) slaveCmds.append("stop") masterCmds.append(randInt(1,10)) break masterCmds.append("restart") slaveCmds.append("drive") slaveCmds.append(True) slaveCmds.append("start") masterThread = fork(i2cMasterThread(softMaster, masterCmds,masterRsps)) slaveThread = fork(i2cSlaveThread(Flow(dut,"io_cmd"),Flow(dut,"io_rsp"),slaveCmds,slaveRsps, dut.clk)) yield masterThread.join()
def __init__(self, data=-1): if data == -1: self.data = randInt(0, 1) else: self.data = data