def read(self, address, sync=True): """Issue a request to the bus and block until this comes back. Simulation time still progresses but syntactically it blocks. Args: address (int): The address to read from. sync (bool, optional): Wait for rising edge on clock initially. Defaults to True. Returns: BinaryValue: The read data value. Raises: OPBException: If read took longer than 16 cycles. """ yield self._acquire_lock() # Apply values for next clock edge if sync: yield RisingEdge(self.clock) self.bus.ABus <= address self.bus.select <= 1 self.bus.RNW <= 1 self.bus.BE <= 0xF count = 0 while not int(self.bus.xferAck.value): yield RisingEdge(self.clock) yield ReadOnly() if int(self.bus.toutSup.value): count = 0 else: count += 1 if count >= self._max_cycles: raise OPBException("Read took longer than 16 cycles") data = int(self.bus.DBus_out.value) # Deassert read self.bus.select <= 0 self._release_lock() self.log.info("Read of address 0x%x returned 0x%08x" % (address, data)) raise ReturnValue(data)
def _send_write_address(self, address, delay=0): """ Send the write address, with optional delay """ yield self.write_address_busy.acquire() for cycle in range(delay): yield RisingEdge(self.clock) self.bus.AWADDR <= address self.bus.AWVALID <= 1 while True: yield ReadOnly() if self.bus.AWREADY.value: break yield RisingEdge(self.clock) yield RisingEdge(self.clock) self.bus.AWVALID <= 0 self.write_address_busy.release()
def get_image(self): yield self.flush_pipeline() image = Image.new("RGBA", (self.width, self.height)) for y in range(10): for x in range(self.total_width): yield RisingEdge(self.dut.pixel_clk) if x < self.width and y < self.height: yield ReadOnly() pixel = self.dut.pixel_data.value.integer print x, y print self.dut.pixel_data r = (pixel >> 24) & bitmask(8) g = (pixel >> 16) & bitmask(8) b = (pixel >> 8) & bitmask(8) a = pixel & bitmask(8) image.putpixel((x, y), (r, g, b, a)) image.save("tmp.png")
def _send_write_data(self, data, delay=0, byte_enable=0xF): """ Send the write address, with optional delay """ yield self.write_data_busy.acquire() for cycle in range(delay): yield RisingEdge(self.clock) self.bus.WDATA <= data self.bus.WVALID <= 1 self.bus.WSTRB <= byte_enable while True: yield ReadOnly() if self.bus.WREADY.value: break yield RisingEdge(self.clock) yield RisingEdge(self.clock) self.bus.WVALID <= 0 self.write_data_busy.release()
def _monitor_recv(self): """Watch the pins and reconstruct transactions.""" # Avoid spurious object creation by recycling clkedge = RisingEdge(self.clock) rdonly = ReadOnly() def valid(): if hasattr(self.bus, "ready"): return self.bus.valid.value and self.bus.ready.value return self.bus.valid.value # NB could yield on valid here more efficiently? while True: yield clkedge yield rdonly if valid(): vec = self.bus.data.value vec.big_endian = self.config["firstSymbolInHighOrderBits"] self._recv(vec.buff)
def test_writes_have_taken_effect_after_readwrite(dut): """ Test that ReadWrite fires first for the background write coro """ dut.stream_in_data.setimmediatevalue(0) @cocotb.coroutine def write_manually(): yield ReadWrite() # this should overwrite the write written below dut.stream_in_data.setimmediatevalue(2) # queue a backround task to do a manual write waiter = cocotb.fork(write_manually()) # do a delayed write. This will be overwritten dut.stream_in_data <= 3 yield waiter # check that the write we expected took precedence yield ReadOnly() assert dut.stream_in_data.value == 2
def i2c_byte_read(dut, is_end): r_data = 0 for i in range(0, 8): dut.sck_scl = 0 yield Timer(I2C_PERIOD / 2) dut.sck_scl = 1 yield ReadOnly() r_data = (r_data << 1) | (dut.sdo_sda.value.binstr != "0") yield Timer(I2C_PERIOD / 2) dut.sck_scl = 0 yield Timer(200000) dut.sdo_sda = BinaryValue( "z") if is_end else 0 # no ack mean no further read yield Timer(I2C_PERIOD / 2) dut.sck_scl = 1 yield Timer(I2C_PERIOD / 2) dut.sck_scl = 0 dut.sdo_sda = BinaryValue("z") yield Timer(I2C_PERIOD / 2) raise ReturnValue(r_data)
def _monitor_recv(self): """Capture all DUT to Host IRQ requests""" irq = self.dut.reg_host_irq # Wait for the logic to be reset yield ReadOnly() yield RisingEdge(self.dut.reset_n) while True: # Wait on the regfile to assert the IRQ while irq.value.integer != 1: yield RisingEdge(irq) # Signal any subscribers that the IRQ has fired self._recv({'time': get_sim_time('ns')}) # Wait for the interrupt(s) to be cleared while irq.value.integer == 1: yield FallingEdge(irq)
def write(self, address, value, byte_enable=0xf, address_latency=0, data_latency=0): """ Write a value to an address. The *_latency KWargs allow control over the delta """ c_addr = cocotb.fork( self._send_write_address(address, delay=address_latency)) c_data = cocotb.fork( self._send_write_data(value, byte_enable=byte_enable, delay=data_latency)) if c_addr: yield c_addr.join() if c_data: yield c_data.join() # Wait for the response while True: yield ReadOnly() if self.bus.BVALID.value and self.bus.BREADY.value: result = self.bus.BRESP.value break yield RisingEdge(self.clock) yield RisingEdge(self.clock) if int(result): raise AXIProtocolError( "Write to address 0x%08x failed with BRESP: %d" % (address, int(result))) raise ReturnValue(result)
def _get_read_data(self, address, id, dlen, dsize, delay): """ Send a data word or a list of data words (supports multi-burst) @param address start address to read data from (just for logging) @param id expected receive data ID @param dlen number of words to read @param dsize - data width - (1 << dsize) bytes (MAXIGP has only 2 bits while AXI specifies 3) 2 means 32 bits @param delay latency in clock cycles """ self.log.debug ("MAXIGPMaster._get_read_data("+str(address)+", "+str(id)+", "+str(dlen)+", "+str(dsize)+", "+str(delay)) yield self.busy_channels[R_CHN].acquire() self.log.debug ("MAXIGPMaster._get_read_data(): acquired lock") for cycle in range(delay): yield RisingEdge(self.clock) self.log.debug ("MAXIGPMaster._get_read_data(): delay over") self.bus.rready <= 1 data=[] for i in range(dlen): self.log.debug ("MAXIGPMaster._get_read_data(), i= %d"%(i)) while True: yield ReadOnly() if self.bus.rvalid.value: try: data.append(self.bus.rdata.value.integer) except: bv = self.bus.rdata.value bv.binstr = re.sub("[^1]","0",bv.binstr) data.append(bv.integer) rid = int(self.bus.rid.value) if rid != id: self.log.error("Read data 0x%x ID mismatch - expected: 0x%x, got 0x%x"%(address+i,id, rid)) break yield RisingEdge(self.clock) yield RisingEdge(self.clock) self.bus.rready <= 0 # FLoat all assigned bus signals but wvalid # _float_signals((self.bus.wdata,self.bus.wstb,self.bus.wlast)) self.busy_channels[R_CHN].release() self.log.debug ("MAXIGPMaster._get_read_data(): released lock %s"%(R_CHN)) raise ReturnValue(data)
def write(self, data): yield self.busy.acquire() pos = 0 count = 0 total_length = len(data) rdy = 0 while pos < total_length: while True: yield ReadOnly() rdy = int(self.bus.RDY) if rdy != 0: yield RisingEdge(self.clock) break yield RisingEdge(self.clock) if (rdy & 0x01) > 0: self.bus.ACT <= 0x01 else: self.bus.ACT <= 0x02 yield RisingEdge(self.clock) length = total_length if length > int(self.bus.SIZE): length = self.bus.SIZE print "Length: %d" % length for d in data[pos:length]: self.bus.STB <= 1 self.bus.DATA <= d yield RisingEdge(self.clock) self.bus.STB <= 0 pos += length yield RisingEdge(self.clock) self.bus.ACT <= 0 yield RisingEdge(self.clock) self.busy.release()
def read_muon(self): i = 0 self.sim_sorted_muon = [] while i < self.n: yield RisingEdge(self.dut.clk) yield ReadOnly() if self.dut.source_valid.value.is_resolvable: if self.dut.source_valid.value.integer: cand = [] for j in range(self.O): cand.append({ 'pt': self.dut.muon_o[j].pt.value.integer, 'idx': self.dut.muon_o[j].idx.value.integer, 'roi': self.dut.muon_o[j].roi.value.integer, 'flags': self.dut.muon_o[j].flags.value.integer, }) self.sim_sorted_muon.append(cand) i += 1
def _monitor_recv(self): """Watch the pins and reconstruct transactions. We monitor on falling edge to support post synthesis simulations """ # Avoid spurious object creation by recycling clkedge = RisingEdge(self.clock) rdonly = ReadOnly() pkt = BinaryValue() def valid(): if hasattr(self.bus, "tready"): return self.bus.tvalid.value and self.bus.tready.value return self.bus.tvalid.value # NB could yield on valid here more efficiently? while True: yield clkedge yield rdonly isValid = valid() self.log.debug("validity : {}".format(isValid)) if isValid: vec = self.bus.tdata.value keep = BinaryValue(n_bits=int(len(self.bus.tdata)/8)) keep = -1 if hasattr(self.bus, "tkeep"): keep = self.bus.tkeep.value if 'U' in keep.binstr: self.log.warning( "received keep contains U value :{}, data : {}" .format(keep.binstr, vec.binstr)) for i, v in enumerate(keep.binstr[::-1]): if v in '1U': pkt.buff += bytes((vec.buff[::-1][i],)) self.log.debug("received frame : {}".format(hex(vec))) if self.bus.tlast.value == 1: self.log.debug("received packet : {}".format(hex(pkt))) self._recv(pkt) pkt = BinaryValue()
def test_fifo(dut): """Try writing values into the FIFO and reading back""" RAM = {} dut.rst = 0 dut.wr = 0 dut.rd = 0 # Read the parameters back from the DUT to set up our testbench width = dut.WIDTH.value.integer depth = 2**dut.AWIDTH.value.integer dut.log.info("Found %d entry RAM by %d bits wide" % (depth, width)) # Set up independent read/write clocks cocotb.fork(Clock(dut.clk, 10000).start()) # Rest FIFO dut.log.info("Resetting FIFO...") yield reset_fifo(dut) yield ReadOnly() #dut.rst = 0 dut.log.info("Writing in random values...") yield RisingEdge(dut.clk) for i in xrange(depth): RAM[i] = int(random.getrandbits(width)) yield write_fifo(dut, RAM[i]) dut.log.info("Reading back values and checking") dut.log.info("Write Data Read Data") yield RisingEdge(dut.clk) for i in xrange(depth): value = yield read_fifo(dut) dut.log.info("0x%X\t\t0x%X" % (RAM[i], value)) #if value != RAM[i]: #dut.log.error("RAM[%d] expected %d but got %d" % (i, RAM[i], value)) #raise TestFailure("RAM contents incorrect") dut.log.info("RAM contents OK") dut.log.info("FIFO Read and Write Successful!!")
def _monitor_recv(self): transCollected = APBTransaction() transCollected.randomize() while True: yield RisingEdge(self.clock) if (self.bus.psel == 1 and self.bus.penable == 1): while True: yield ReadOnly() if (self.bus.pready): transCollected.addr = self.bus.paddr.value transCollected.slverr = self.bus.pslverr.value if (self.bus.pwrite == 1): transCollected.data = self.bus.pwdata.value else: transCollected.data = self.bus.prdata.value transCollected.rw <= 0 if self.bus.pwrite else 1 break self._recv(transCollected)
def simulator_timing_triggers(dut): """Playing with the Simulator Timing Triggers""" cocotb.fork(Clock(dut.clk_i, 2).start()) yield reset(dut) # yield Timer( 2) # Fires after the specified simulation time period has elapsed print_fired(dut, "Timer") yield Timer(2, "ns") print_fired(dut, "Timer") yield Timer(2000, "ps") print_fired(dut, "Timer") yield Timer(0.002, "us") print_fired(dut, "Timer") # yield NextTimeStep() # Fires when the next time step is started print_fired(dut, "NextTimeStep") yield ReadWrite( ) # Fires when the readwrite portion of the sim cycles is reached print_fired(dut, "ReadWrite") yield ReadOnly( ) # Fires when the current simulation timestep moves to the readonly phase print_fired(dut, "ReadOnly")
def write(self, data): yield self.busy.acquire() pos = 0 count = 0 total_length = len(data) rdy = 0 while pos < total_length: while True: yield ReadOnly() rdy = int(self.bus.RDY) if rdy != 0: yield RisingEdge(self.clock) self.bus.ACT <= 1 break yield RisingEdge(self.clock) yield RisingEdge(self.clock) length = total_length - pos if length > int(self.bus.SIZE): length = int(self.bus.SIZE) print "Length: %d" % length print "pos: %d" % pos for d in data[pos:(pos + length)]: self.bus.STB <= 1 self.bus.DATA <= d yield RisingEdge(self.clock) self.bus.STB <= 0 pos += length yield RisingEdge(self.clock) self.bus.ACT <= 0 yield RisingEdge(self.clock) self.busy.release()
def _send_write_data(self, data, wrstb, delay, id, dsize): """ Send a data word or a list of data words (supports multi-burst) @param data a list/tuple of words to send @param wrstb - write mask list (same size as data) @param delay latency in clock cycles @param id transaction ID @param dsize - data width - (1 << dsize) bytes (MAXIGP has only 2 bits while AXI specifies 3) 2 means 32 bits """ self.log.debug ("MAXIGPMaster._send_write_data("+str(data)+", "+str(wrstb)+", "+str(delay)+", "+str(id)+", "+str(dsize)) yield self.busy_channels[W_CHN].acquire() self.log.debug ("MAXIGPMaster._send_write_data(): acquired lock") for cycle in range(delay): yield RisingEdge(self.clock) self.log.debug ("MAXIGPMaster._send_write_data(): delay over") self.bus.wvalid <= 1 self.bus.wid <= id for i,val_wstb in enumerate(zip(data,wrstb)): self.log.debug ("MAXIGPMaster._send_write_data(), i= %d, val_stb=%s "%(i,str(val_wstb))) if (i == (len(data) - 1)) or ((i % 16) == 15): self.bus.wlast <= 1 else: self.bus.wlast <= 0 self.bus.wdata <= val_wstb[0] self.bus.wstb <= val_wstb[1] while True: yield ReadOnly() if self.bus.wready.value: break yield RisingEdge(self.clock) yield RisingEdge(self.clock) self.bus.wvalid <= 0 # FLoat all assigned bus signals but wvalid _float_signals((self.bus.wdata,self.bus.wstb,self.bus.wlast)) self.busy_channels[W_CHN].release() self.log.debug ("MAXIGPMaster._send_write_data(): released lock %s"%(W_CHN)) raise ReturnValue(dsize)
def read(self, address, sync=True): """ Issue a request to the bus and block until this comes back. Simulation time still progresses but syntactically it blocks. See http://www.altera.com/literature/manual/mnl_avalon_spec_1_3.pdf """ if not self._can_read: self.log.error("Cannot read - have no read signal") raise TestError("Attempt to read on a write-only AvalonMaster") yield self._acquire_lock() # Apply values for next clock edge if sync: yield RisingEdge(self.clock) self.bus.address <= address self.bus.read <= 1 # Wait for waitrequest to be low if hasattr(self.bus, "waitrequest"): yield self._wait_for_nsignal(self.bus.waitrequest) # Assume readLatency = 1 # FIXME need to configure this, # should take a dictionary of Avalon properties. yield RisingEdge(self.clock) # Deassert read self.bus.read <= 0 # Get the data yield ReadOnly() data = self.bus.readdata.value yield NextTimeStep() self._release_lock() raise ReturnValue(data)
def send(self, transaction): rval = 0 yield RisingEdge(self.clock) self.bus.PADDR <= transaction.addr self.bus.PWDATA <= transaction.data self.bus.PSELx <= 1 self.bus.PWRITE <= 1 if transaction.write else 0 yield RisingEdge(self.clock) self.bus.PENABLE <= 1 while True: yield ReadOnly() if (self.bus.PREADY == 1): rval = self.bus.PRDATA break yield RisingEdge(self.clock) yield RisingEdge(self.clock) self.bus.PADDR <= 0 self.bus.PWDATA <= 0 self.bus.PSELx <= 0 self.bus.PWRITE <= 0 self.bus.PENABLE <= 0 for i in range(transaction.delay): yield RisingEdge(self.clock) raise ReturnValue(rval)
def write_four_bytes(self, data, last): yield RisingEdge(self.clock) self.bus.RXFn <= 0 self.bus.DIN <= int(data & 0xFF) while True: yield ReadOnly() if self.bus.RDn.value == 0: break yield FallingEdge(self.clock) yield RisingEdge(self.clock) self.bus.DIN <= int((data >> 8) & 0xFF) yield RisingEdge(self.clock) self.bus.DIN <= int((data >> 16) & 0xFF) yield RisingEdge(self.clock) self.bus.DIN <= int((data >> 24) & 0xFF) if last is True: yield RisingEdge(self.clock) self.bus.RXFn <= 1
def _monitor_recv(self): started = False pre_started = False prev_scl = 1 while True: yield RisingEdge(self.clock) yield ReadOnly() try: sda = 0 if self.bus.SDA == 'x' else int(self.bus.SDA) except ValueError: sda = 0 if (self.bus.SCL == 1): #start bit if (not started) & (not pre_started) & (sda == 1): pre_started = True elif (not started) & pre_started & (sda == 0): started = True pre_started = False rdata = 0 data_cnt = 0 ack = 1 #sample data at SCL elif started & (prev_scl == 0): prev_scl = 1 if data_cnt == 32: started = False xaction = I2CTransaction(rdata, write=False) self._recv(xaction) elif (data_cnt % 8 != 0) | ack: ack = 0 rdata = rdata + (sda << data_cnt) data_cnt += 1 else: #ack state ack = 1 elif started: prev_scl = 0
def multiply(self, data, accumulator=0): # Check that we've set a weight if self.weight == None: raise TestFailure("No weight set in tb yet!") # Perform the MAC operation self.dut.data_in = data self.dut.accumulator_in = accumulator self.dut.mac_stall_in = 0 yield RisingEdge(self.dut.clock) # Get the result and compare yield ReadOnly() acc_out = self.dut.accumulator_out data_out = self.dut.data_out acc_cor = data * self.weight + accumulator if acc_out != acc_cor: raise TestFailure("Result was %d instead of %d" % (acc_out, acc_cor)) if data_out != data: raise TestFailure("Data out was %d instead of %d" % (data_out, data))
def read(self, wait_for_valid = False): """Read a packe of data from the Axi Ingress stream""" yield self.read_data_busy.acquire() yield RisingEdge(self.clock) if wait_for_valid: while not self.bus.TVALID.value: #cocotb.log.info("Valid Not Detected") yield RisingEdge(self.clock) #cocotb.log.info("Found valid!") yield RisingEdge(self.clock) self.bus.TREADY <= 1 while self.bus.TVALID.value: yield RisingEdge(self.clock) self.data.extend(self.bus.TDATA.value) if self.bus.TLAST.value: break else: self.bus.TREADY <= 1 while True: yield ReadOnly() yield RisingEdge(self.clock) if self.bus.TVALID.value: cocotb.log.debug("Found Valid") break yield RisingEdge(self.clock) while self.bus.TVALID.value: yield RisingEdge(self.clock) self.data.extend(self.bus.TDATA.value) if self.bus.TLAST.value: break
def read(self, address, sync=True): """Read from an address. Args: address (int): The address to read from. sync (bool, optional): Wait for rising edge on clock initially. Defaults to True. Returns: BinaryValue: The read data value. Raises: AXIProtocolError: If read response from AXI is not ``OKAY``. """ if sync: yield RisingEdge(self.clock) yield self._send_read_address(address) # Wait for the response while True: if self.bus.RVALID.value and self.bus.RREADY.value: data = self.bus.RDATA.value result = self.bus.RRESP.value break yield RisingEdge(self.clock) yield ReadOnly() yield RisingEdge(self.clock) if int(result): raise AXIProtocolError( "Read address 0x%08x failed with RRESP: %d" % (address, int(result))) raise ReturnValue(data)
def write(self, address, value, sync=True): """Issue a write to the given address with the specified value. Args: address (int): The address to read from. value (int): The data value to write. sync (bool, optional): Wait for rising edge on clock initially. Defaults to True. Raises: OPBException: If write took longer than 16 cycles """ yield self._acquire_lock() if sync: yield RisingEdge(self.clock) self.bus.ABus <= address self.bus.select <= 1 self.bus.RNW <= 0 self.bus.BE <= 0xF self.bus.DBus_out <= value count = 0 while not int(self.bus.xferAck.value): yield RisingEdge(self.clock) yield ReadOnly() if int(self.bus.toutSup.value): count = 0 else: count += 1 if count >= self._max_cycles: raise OPBException("Write took longer than 16 cycles") self.bus.select <= 0 self._release_lock()
def _respond(self): """ Coroutine to response to the actual requests """ edge = RisingEdge(self.clock) while True: yield edge self._do_response() yield ReadOnly() if self._readable and self.bus.read.value: if not self._burstread: self._pad() addr = self.bus.address.value.integer if addr not in self._mem: self.log.warning("Attempt to read from uninitialised " "address 0x%x" % addr) self._responses.append(True) else: self.log.debug( "Read from address 0x%x returning 0x%x" % (addr, self._mem[addr])) self._responses.append(self._mem[addr]) else: addr = self.bus.address.value.integer if addr % self.dataByteSize != 0: self.log.error( "Address must be aligned to data width" + "(addr = " + hex(addr) + ", width = " + str(self._width)) addr = int(addr / self.dataByteSize) burstcount = self.bus.burstcount.value.integer byteenable = self.bus.byteenable.value if byteenable != int("1" * len(self.bus.byteenable), 2): self.log.error("Only full word access is supported " + "for burst read (byteenable must be " + "0b" + "1" * len(self.bus.byteenable) + ")") if burstcount == 0: self.log.error("Burstcount must be 1 at least") # toggle waitrequest # TODO: configure waitrequest time with avalon properties yield NextTimeStep() # can't write during read-only phase self.bus.waitrequest <= 1 yield edge yield edge self.bus.waitrequest <= 0 # wait for read data for i in range(self._avalon_properties["readLatency"]): yield edge for count in range(burstcount): if (addr + count) * self.dataByteSize not in self._mem: self.log.warning( "Attempt to burst read from uninitialised " + "address 0x%x (addr 0x%x count 0x%x)" % ((addr + count) * self.dataByteSize, addr, count)) self._responses.append(True) else: value = 0 for i in range(self.dataByteSize): rvalue = self._mem[(addr + count) * self.dataByteSize + i] value += rvalue << i * 8 self.log.debug( "Read from address 0x%x returning 0x%x" % ((addr + count) * self.dataByteSize, value)) self._responses.append(value) yield edge self._do_response() if self._writeable and self.bus.write.value: if not self._burstwrite: addr = self.bus.address.value.integer data = self.bus.writedata.value.integer if hasattr(self.bus, "byteenable"): byteenable = int(self.bus.byteenable.value) mask = 0 oldmask = 0 olddata = 0 if (addr in self._mem): olddata = self._mem[addr] self.log.debug("Old Data : %x" % olddata) self.log.debug("Data in : %x" % data) self.log.debug("Width : %d" % self._width) self.log.debug("Byteenable: %x" % byteenable) for i in range(self._width / 8): if (byteenable & 2**i): mask |= 0xFF << (8 * i) else: oldmask |= 0xFF << (8 * i) self.log.debug("Data mask : %x" % mask) self.log.debug("Old mask : %x" % oldmask) data = (data & mask) | (olddata & oldmask) self.log.debug("Data out : %x" % data) self.log.debug("Write to address 0x%x -> 0x%x" % (addr, data)) self._mem[addr] = data else: self.log.debug("writing burst") # maintain waitrequest high randomly yield self._waitrequest() addr, byteenable, burstcount = self._write_burst_addr() count = 0 for count in range(burstcount): while self.bus.write.value == 0: yield NextTimeStep() # self._mem is aligned on 8 bits words yield self._writing_byte_value(addr + count * self.dataByteSize) self.log.debug("writing %016X @ %08X" % (self.bus.writedata.value.integer, addr + count * self.dataByteSize)) yield edge # generate waitrequest randomly yield self._waitrequest() if self._avalon_properties.get("WriteBurstWaitReq", True): self.bus.waitrequest <= 1
def run(self): self.bus.HIT <= self.hit self.bus.TRIG_EXT <= 0 res = 0 while res == 0: # Wait for RESET signal yield FallingEdge(self.clock) yield ReadOnly() res = self.bus.RESET_TB.value.integer while res == 1: # Wait for falling edge of RESET signal yield FallingEdge(self.clock) yield ReadOnly() res = self.bus.RESET_TB.value.integer for _ in range(5): # Delay hit w.r.t. RESET. Minimum 3 clk cycles yield FallingEdge(self.clock) bv = BitLogic(len(self.hit)) bv[10] = 1 bv[15] = 1 self.hit.assign(str(bv)) self.bus.HIT <= self.hit self.bus.TRIG_EXT <= 0 for _ in range(14): # Stop HIT after 10 CLK_BX yield FallingEdge(self.clock) bv = BitLogic(len(self.hit)) bv.setall(False) self.hit.assign(str(bv)) self.bus.HIT <= self.hit self.bus.TRIG_EXT <= 1 yield FallingEdge(self.clock) self.bus.TRIG_EXT <= 0 # for _ in range(5): # # Delay hit # yield FallingEdge(self.clock) # # bv = BitLogic(len(self.hit)) # bv[20] = 1 # self.hit.assign(str(bv)) # self.bus.HIT <= self.hit # self.bus.TRIG_EXT <= 0 # # for _ in range(10): # # Stop HIT after 10 CLK_BX # yield FallingEdge(self.clock) # # bv = BitLogic(len(self.hit)) # bv.setall(False) # self.hit.assign(str(bv)) # self.bus.HIT <= self.hit # self.bus.TRIG_EXT <= 1 # yield FallingEdge(self.clock) # self.bus.TRIG_EXT <= 0 # for _ in range(5): # # Delay hit # yield FallingEdge(self.clock) # # # bv = BitLogic(len(self.hit)) # bv[20] = 1 # self.hit.assign(str(bv)) # self.bus.HIT <= self.hit # self.bus.TRIG_EXT <= 0 # # for _ in range(10): # # Stop HIT after 10 CLK_BX # yield FallingEdge(self.clock) # # bv = BitLogic(len(self.hit)) # bv.setall(False) # self.hit.assign(str(bv)) # self.bus.HIT <= self.hit # self.bus.TRIG_EXT <= 1 # yield FallingEdge(self.clock) self.bus.TRIG_EXT <= 0
def do_test_afterdelay_in_readonly(dut, delay): global exited yield RisingEdge(dut.clk) yield ReadOnly() yield Timer(delay) exited = True
def do_test_cached_write_in_readonly(dut): global exited yield RisingEdge(dut.clk) yield ReadOnly() dut.clk <= 0 exited = True