def example(): yield Timer(10, 'ns') raise ReturnValue(1)
def some_coro(): yield Timer(1) raise ReturnValue(retval)
def wait_for(clk, cycles): rising_edge = RisingEdge(clk) for _ in range(cycles): yield rising_edge raise ReturnValue(3)
def immediate_value(): raise ReturnValue(42) yield
def perform_setup(dut): # Create clock and reset drivers. fifo = dut.dut clkdrv = ClockDriver(interface=Interface(wrclk=fifo.wrclk, rdclk=fifo.rdclk), param_namespace=Namespace(wrclk=Namespace(period=(randint(1,10),"ns")), rdclk=Namespace(period=(randint(1,10),"ns")))) rstdrv = ResetDriver(interface=Interface(wrrst=fifo.wrrst, rdrst=fifo.rdrst), param_namespace=Namespace(wrrst=Namespace(associated_clock=fifo.wrclk), rdrst=Namespace(associated_clock=fifo.rdclk))) # Create the components. wrdrv = HandshakeWriteDriver(interface=Interface(clk=fifo.wrclk, rst=fifo.wrrst, vld=fifo.wrvld, rdy=fifo.wrrdy, data=fifo.wrdata)) rdintr = Interface(clk=fifo.rdclk, rst=fifo.rdrst, vld=fifo.rdvld, rdy=fifo.rdrdy, data=fifo.rddata) rddrv = HandshakeReadDriver(interface=rdintr) rdmon = HandshakeMonitor(interface=rdintr) # Create the block that determines the # simulation's end condition. cntns = Namespace(count=0,total=0) def cntfun(ignore): cntns.count += 1 return cntns.count==cntns.total cntblk = SwissBlock(trans_func=cntfun) # Generate a synchronize coroutine for waiting. wrwait = RegisterInterface(rst=fifo.wrrst,clk=fifo.wrclk)._synchronize # Create the block intended for logging. logobj = SimLog("cocotb.log") logblk = SwissBlock(trans_func=lambda x : logobj.info("{}".format(x))) # Other nodes. source = SourceBlock() # Where data is written. score = ScoreBlock() check = AssertBlock() end = SucceedBlock() # Connect the blocks together to create the system. source.outport.connect(wrdrv.inport) source.outport.connect(score.inports(0)).outport.connect(check.inport) rdmon.outport.connect(score.inports(1)) rdmon.outport.connect(cntblk.inport).outport.connect(end.inport) # Wrap up the objects needed for each test. te = Namespace(source=source,width=int(fifo.W.value),cntns=cntns,log=logobj, wrwait=wrwait, setwrallow=lambda x : setattr(wrdrv,"allow",x), setrdallow=lambda x : setattr(rddrv,"allow",x)) yield rstdrv.wait() raise ReturnValue(te)
def _wait(self): trigger = self._type(self.signal) for _ in range(self.num_cycles): yield trigger raise ReturnValue(self)
def get_output(dut): while(int(dut.ov) == 0): yield RisingEdge(dut.c125) rv = int(dut.o) yield RisingEdge(dut.c125) raise ReturnValue(rv)
def yield_to_readwrite(dut): yield RisingEdge(dut.clk) dut.log.info("Returning from yield_to_readwrite") raise ReturnValue(2)
def wrapper(): ext = cocotb.scheduler.run_in_executor(self._func, *args, **kwargs) yield ext.event.wait() ret = ext.result # raises if there was an exception raise ReturnValue(ret)
def perform_setup(dut): TDUTS = 1 # Total number of duts. # The following structures need to be created # prior to another initialization. sizes_dict = {} gat_blk_dict = {} src_blk_dict = {} drv_blk_dict = {} rst_sig_dict = {} rst_prm_dict = {} clk_sig_dict = {} clk_prm_dict = {} # Perform the following operations on each dut. for each_dut in range(TDUTS): # Get SimHandleBase of the dut and necessary parameters.. bus = getattr(dut, "dut{}".format(each_dut)) # SimHandleBase bwrs = int(bus.B_WRS.value) # Total write interfaces brds = int(bus.B_RDS.value) # Total read interfaces bclkprdw = int(bus.B_CLKPRDW.value) # Gets the clock period width. baw = int(bus.B_AW.value) # Address width bwd = int(bus.B_DW.value) # Data width ast_blk = AssertBlock( ) # Used for failing test if hardware doesn't match hardware. sizes_dict[(each_dut, "wr")] = bwrs sizes_dict[(each_dut, "rd")] = brds # Create the bus model. out_prms_lst = [] for idx in range(brds): bases = int(bus.B_BASES.value) sizes = int(bus.B_SIZES.value) base = (bases >> (baw * idx)) & ((1 << baw) - 1) size = (sizes >> (baw * idx)) & ((1 << baw) - 1) out_prms_lst.append(Namespace(base=base, size=size)) mdl_blk = BusCrossBlock(inputs=bwrs, outputs=brds, outport_params=out_prms_lst) # Pack clock/resets and create agents. synclst = [("wr", each_sync) for each_sync in range(bwrs)] synclst.extend([("rd", each_sync) for each_sync in range(brds)]) for intr, idx in synclst: # Acquire signals rst_sig = getattr(bus, "{}rstscc".format(intr))[idx] clk_sig = getattr(bus, "{}clkscc".format(intr))[idx] vld_sig = getattr(bus, "{}vldscc".format(intr))[idx] rdy_sig = getattr(bus, "{}rdyscc".format(intr))[idx] data_sig = getattr(bus, "{}datas".format(intr))[idx] addr_sig = getattr(bus, "{}addrs".format(intr))[idx] # Create the agents. inter = Interface(rst=rst_sig, clk=clk_sig, vld=vld_sig, rdy=rdy_sig, data=data_sig, addr=addr_sig) drv = HandshakeWriteDriver( interface=inter) if intr == "wr" else HandshakeReadDriver( interface=inter) mon = HandshakeMonitor(interface=inter) # Store the drivers in order to allow for changes to flow control. drv_blk_dict[(each_dut, idx, intr)] = drv # Create name identifiers for clocks and resets. rst_nme = "dut{}{}rst{}".format(each_dut, intr, idx) clk_nme = "dut{}{}clk{}".format(each_dut, intr, idx) # Get periods. clkprds = int( getattr(bus, "B_{}CLKPRDS".format(intr.upper())).value) prdval = (clkprds >> (bclkprdw * idx)) & ((1 << bclkprdw) - 1) # Store the data in dictionaries. rst_sig_dict[rst_nme] = rst_sig rst_prm_dict[rst_nme] = Namespace(associated_clock=clk_sig) clk_sig_dict[clk_nme] = clk_sig clk_prm_dict[clk_nme] = Namespace(period=(prdval, "ns")) # Operations associated with only the writing interface. if intr == "wr": # Create blocks. src_blk = SourceBlock() msk_blk = SwissBlock(trans_func=lambda trans: ChangeWidth( trans=trans, aw=baw, dw=bwd)) ComposedBlock(src_blk, msk_blk, drv) msk_blk.outport.connect(mdl_blk.inports(idx)) #msk_blk.outport.connect(PrintBlock("bus{}.wr{}".format(each_dut,idx)).inport) # Store the source blocks. src_blk_dict[(each_dut, idx)] = src_blk # Operations associated with only the reading interface. if intr == "rd": # Store the base and size parmateres. bases = int(bus.B_BASES.value) sizes = int(bus.B_SIZES.value) base = (bases >> (baw * idx)) & ((1 << baw) - 1) size = (sizes >> (baw * idx)) & ((1 << baw) - 1) out_prms_lst.append(Namespace(base=base, size=size)) # Create a scoreboard for each reading interface. sb_blk = ScoreBlock(name="bus{}.rd{}".format(each_dut, idx)) cvt_blk = SwissBlock(trans_func=BinaryToInt) gat_exp_blk = GatherBlock() gat_act_blk = GatherBlock() # Perform connections. The gather blocks are necessary to ensure # sets of data are compared, this way order can be ignored. mdl_blk.outports(idx).connect( gat_exp_blk.inport).outport.connect(sb_blk.inports(0)) ComposedBlock(mon, cvt_blk, gat_act_blk).outport.connect(sb_blk.inports(1)) ComposedBlock(sb_blk, ast_blk) #mon.outport.connect(PrintBlock("bus{}.rd{}".format(each_dut,idx)).inport) # Store the gather blocks so that the user can specify when a comparison # should occur. gat_blk_dict[(each_dut, idx, "exp")] = gat_exp_blk gat_blk_dict[(each_dut, idx, "act")] = gat_act_blk # Generate the system agents. clk_drv = ClockDriver(interface=Interface(**clk_sig_dict), param_namespace=Namespace(**clk_prm_dict)) rst_drv = ResetDriver(interface=Interface(**rst_sig_dict), param_namespace=Namespace(**rst_prm_dict)) # Yield until all resets have been de-asserted. yield rst_drv.wait() # Create testbench environment namespace. te = Namespace(sources=lambda bus, idx: src_blk_dict[(bus, idx)], gathers=lambda bus, idx, exp_act: gat_blk_dict[ (bus, idx, exp_act)], drivers=lambda bus, idx, wr_rd: drv_blk_dict[ (bus, idx, wr_rd)], buses=TDUTS, inputs=lambda bus: sizes_dict[(bus, "wr")], outputs=lambda bus: sizes_dict[(bus, "rd")]) raise ReturnValue(te)
def executeCommand(self, line): self.dut._log.debug("1.executeCommand: %s" % (line)) if not line: raise ReturnValue(None) self.dut._log.debug("2.executeCommand: %s" % (line)) self.cmd.fromJSON(line) #TODO: add interrupt related commands (including wait IRQ with timeout if self.cmd.getStart(): self.dut._log.info('Received START, waiting reset to be over') yield Timer(10000) while self.dut.reset_out.value.get_binstr() != "1": yield Timer(10000) while self.dut.reset_out.value: yield Timer(10000) self.saxihp0r_thread = cocotb.fork(self.saxihp0r.saxi_rd_run()) self.saxihp0w_thread = cocotb.fork(self.saxihp0w.saxi_wr_run()) self.saxihp1w_thread = cocotb.fork(self.saxihp1w.saxi_wr_run()) self.saxigp0_thread = cocotb.fork(self.saxigp0.saxi_wr_run()) self.saxigp1_thread = cocotb.fork(self.saxigp1.saxi_wr_run()) self.soc_conn.send(self.cmd.toJSON(0) + "\n") self.dut._log.debug('Sent 0 to the socket') started = True elif self.cmd.getStop(): self.dut._log.info('Received STOP, closing...') self.soc_conn.send(self.cmd.toJSON(0) + "\n") self.soc_conn.close() yield Timer(10000) # small pause for the wave output self.socket_conn.shutdown(socket.SHUT_RDWR) self.socket_conn.close() cocotb.regression.tear_down() started = False raise TestSuccess('Terminating as received STOP command') #For now write - one at a time, TODO: a) consolidate, b) decode address (some will be just a disk file) elif self.cmd.getWrite(): ad = self.cmd.getWrite() self.dut._log.debug('Received WRITE, 0x%0x: %s' % (ad[0], hex_list(ad[1]))) if ad[0] in self.RESERVED: if ad[0] == self.INTM_ADDRESS: self.int_mask = ad[1][0] rslt = 0 elif (ad[0] >= self.memlow) and (ad[0] < self.memhigh): addr = ad[0] self._memfile.seek(addr) for data in ad[1]: # currently only single word is supported sdata = struct.pack("<L", data) # little-endian, u32 self._memfile.write(sdata) self.dut._log.debug( "Written 'system memory': 0x%08x => 0x%08x" % (data, addr)) addr += 4 rslt = 0 elif (ad[0] >= 0x40000000) and (ad[0] < 0x80000000): rslt = yield self.maxigp0.axi_write(address=ad[0], value=ad[1], byte_enable=None, id=self.writeID, dsize=2, burst=1, address_latency=0, data_latency=0) self.dut._log.debug('maxigp0.axi_write yielded %s' % (str(rslt))) self.writeID = (self.writeID + 1) & self.writeIDMask elif (ad[0] >= 0xc0000000) and (ad[0] < 0xfffffffc): self.ps_sbus.write_reg(ad[0], ad[1][0]) rslt = 0 else: self.dut._log.info( 'Write address 0x%08x is outside of maxgp0, not yet supported' % (ad[0])) rslt = 0 self.dut._log.info('WRITE 0x%08x <= %s' % (ad[0], hex_list(ad[1], max_items=4))) self.soc_conn.send(self.cmd.toJSON(rslt) + "\n") self.dut._log.debug('Sent rslt to the socket') elif self.cmd.getRead(): ad = self.cmd.getRead() self.dut._log.debug(str(ad)) if not isinstance(ad, (list, tuple)): ad = (ad, 1) elif len(ad) < 2: ad = (ad[0], 1) self.dut._log.debug(str(ad)) if ad[0] in self.RESERVED: if ad[0] == self.INTR_ADDRESS: try: dval = [self.dut.irq_r.value.integer] except: bv = self.dut.irq_r.value bv.binstr = re.sub("[^1]", "0", bv.binstr) dval = [bv.integer] elif ad[0] == self.INTM_ADDRESS: dval = [self.int_mask] else: dval = [0] elif (ad[0] >= self.memlow) and (ad[0] < self.memhigh): addr = ad[0] self._memfile.seek(addr) self.dut._log.debug("read length=" + str(len(self._memfile.read(4 * ad[1])))) self._memfile.seek(addr) self.dut._log.debug(str(ad)) dval = list( struct.unpack("<" + "L" * ad[1], self._memfile.read(4 * ad[1]))) msg = "'Written 'system memory: 0x%08x => " % (addr) for d in dval: msg += "0x%08x " % (d) self.dut._log.debug(msg) elif (ad[0] >= 0x40000000) and (ad[0] < 0x80000000): dval = yield self.maxigp0.axi_read(address=ad[0], id=self.readID, dlen=ad[1], dsize=2, address_latency=0, data_latency=0) self.dut._log.debug("axi_read returned 0x%08x => %s" % (ad[0], hex_list(dval, max_items=4))) self.readID = (self.readID + 1) & self.readIDMask elif (ad[0] >= 0xc0000000) and (ad[0] < 0xfffffffc): dval = yield self.ps_sbus.read_reg(ad[0]) else: self.dut._log.info( 'Read address 0x%08x is outside of maxgp0, not yet supported' % (ad[0])) dval = [0] self.soc_conn.send(self.cmd.toJSON(dval) + "\n") self.dut._log.debug('Sent dval to the socket') self.dut._log.info("READ 0x%08x =>%s" % (ad[0], hex_list(dval, max_items=4))) elif self.cmd.getFlush(): self.dut._log.info('Received flush') self.flush_all() self.soc_conn.send(self.cmd.toJSON(0) + "\n") self.dut._log.debug('Sent 0 to the socket') elif self.cmd.getWait(): #self.MAXIGP0_CLK_FREQ int_dly = self.cmd.getWait() self.int_mask = int_dly[0] num_clk = (int_dly[1] * self.ACLK_FREQ) // 1000000000 self.dut._log.info( 'Received WAIT, interrupt mask = 0x%0x, timeout = %d ns, %d clocks' % (self.int_mask, int_dly[1], num_clk)) n = 0 for _ in range(num_clk): yield RisingEdge(self.dut.dutm0_aclk) try: irq_r = self.dut.irq_r.value.integer except: bv = self.dut.irq_r.value bv.binstr = re.sub("[^1]", "0", bv.binstr) irq_r = bv.integer if (self.int_mask & irq_r): break n += 1 self.soc_conn.send(self.cmd.toJSON(n) + "\n") self.dut._log.debug('Sent %d to the socket' % (n)) self.dut._log.info(' WAIT over, passed %d ns' % ((n * 1000000000) // self.ACLK_FREQ)) else: self.dut._log.warning('Received unknown command: ' + str(self.cmd)) self.soc_conn.send(self.cmd.toJSON(1) + "\n") self.dut._log.debug('Sent 1 to the socket')