def read(self, address, sync=True): """ Read from an address. """ if sync: yield RisingEdge(self.clock) self.bus.ARADDR <= address self.bus.ARVALID <= 1 while True: yield ReadOnly() if self.bus.ARREADY.value: break yield RisingEdge(self.clock) yield RisingEdge(self.clock) self.bus.ARVALID <= 0 while True: yield ReadOnly() 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) if int(result): raise AXIProtocolError("Read address 0x%08x failed with RRESP: %d" % (address, int(result))) raise ReturnValue(data)
def _wait_ready(self): """Wait for the bus to be ready """ yield ReadOnly() while not self.bus.tready.value: yield RisingEdge(self.clock) yield ReadOnly()
def ping(self): timeout_count = 0 while timeout_count < self.timeout: yield RisingEdge(self.dut.clk) timeout_count += 1 yield ReadOnly() if self.master_ready.value.get_value() == 0: continue else: break if timeout_count == self.timeout: self.dut.log.error("Timed out while waiting for master to be ready") return yield ReadWrite() timeout_count = 0 while timeout_count < self.timeout: yield RisingEdge(self.dut.clk) timeout_count += 1 yield ReadOnly() #if self.dut.out_en.value.get_value() == 0: # continue #else: # break break if timeout_count == self.timeout: self.dut.log.error("Timed out while waiting for master to respond") return self.dut.log.info("Master Responded to ping") self.dut.log.info("\t0x%08X" % self.out_status.value.get_value())
def derivative_producer( self ): """ Registering detected pulses for the derivative_peakfinder.vhd peak finder. TODO: Yield for something else than rising edge. TODO: "No coroutines waiting on trigger that fired: RisingEdge(peaks(1))" -> solved with yielding to ReadOnly after RisingEdge """ while True: yield [ RisingEdge(self.dut.peaks[i]) for i in range(self.dut.NPEAKSMAX) ] yield ReadOnly() if self.dut.peaks==3 or self.dut.peaks==5 or self.dut.peaks==6 or self.dut.peaks==7: self.dut._log.info( pfu.string_color("Dobule Pulse!", "yellow") ) for i in range( self.dut.NPEAKSMAX ): detected_pulse = p.pulse( orbit=self.orb_cnt, bx=self.bx_cnt, amplitude=int(self.dut.peaks_val[i]), position=int(self.dut.peaks_pos[i]), tot=None ) self.pulses.append( detected_pulse ) trig = True while trig: yield RisingEdge( self.dut.clk ) yield ReadOnly() if int(self.dut.peaks) > 0: for i in range( self.dut.NPEAKSMAX ): if self.dut.peaks[i]: # self.dut._log.info( pfu.string_color("CONSECUTIVE", "yellow") ) self.consec_cnt += 1 detected_pulse = p.pulse( orbit=self.orb_cnt, bx=self.bx_cnt, amplitude=int(self.dut.peaks_val[i]), position=int(self.dut.peaks_pos[i]), tot=None ) self.pulses.append( detected_pulse ) trig = True else: trig = False
def prallel_producer( self ): """ Registering detected pulses for the parallel_analyzer.vhd peak finder. Function yields for a rising edge in detected peaks and then checks if still asserted in next bx to count consecutive bx peaks. TODO: Yield for something else than rising edge in the first place """ while True: yield [ RisingEdge(self.dut.peaks[i]) for i in range(self.NSAMP) ] yield ReadOnly() detected_pulse = p.pulse( orbit=self.orb_cnt, bx=self.bx_cnt, amplitude=int(self.dut.local_maximum), position=int(math.log(int(self.dut.peaks),2)), tot=int(self.dut.time_over_threshold) ) self.pulses.append( detected_pulse ) trig = True while trig: yield RisingEdge( self.dut.bunch_clk ) yield ReadOnly() if int(self.dut.peaks) > 0: # self.dut._log.info( pfu.string_color("CONSECUTIVE", "yellow") ) self.consec_cnt += 1 detected_pulse = p.pulse( orbit=self.orb_cnt, bx=self.bx_cnt, amplitude=int(self.dut.local_maximum), position=int(math.log(int(self.dut.peaks),2)), tot=int(self.dut.time_over_threshold) ) self.pulses.append( detected_pulse ) trig = True else: trig = False
def _wait_for_ack_nack(self): yield ReadOnly() while (self.bus.ack.value.integer != 1) and (self.bus.nack.value.integer != 1): yield [RisingEdge(self.bus.ack), RisingEdge(self.bus.nack)] #yield RisingEdge(self.bus.ack) yield ReadOnly() yield NextTimeStep()
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 if hasattr(self.bus, "byteenable"): self.bus.byteenable <= int("1" * len(self.bus.byteenable), 2) if hasattr(self.bus, "cs"): self.bus.cs <= 1 # Wait for waitrequest to be low if hasattr(self.bus, "waitrequest"): yield self._wait_for_nsignal(self.bus.waitrequest) yield RisingEdge(self.clock) # Deassert read self.bus.read <= 0 if hasattr(self.bus, "byteenable"): self.bus.byteenable <= 0 if hasattr(self.bus, "cs"): self.bus.cs <= 0 v = self.bus.address.value v.binstr = "x" * len(self.bus.address) self.bus.address <= v if hasattr(self.bus, "readdatavalid"): while True: yield ReadOnly() if int(self.bus.readdatavalid): break yield RisingEdge(self.clock) else: # Assume readLatency = 1 if no readdatavalid # FIXME need to configure this, # should take a dictionary of Avalon properties. yield ReadOnly() # Get the data data = self.bus.readdata.value self._release_lock() raise ReturnValue(data)
def append_channel(self): yield ReadOnly() while True: if self.dut.dac_0_valid.value: data = self.dut.dac_0_data.value.get_value() else: data = 0 # print("append_channel") self.channel_model.push_packed_sample(data) yield RisingEdge(self.dut.clock) yield ReadOnly()
def _wait_for_signal(self, signal): """This method will return with the specified signal has hit logic ``1``. The state will be in the :any:`ReadOnly` phase so sim will need to move to :any:`NextTimeStep` before registering more callbacks can occur. """ yield ReadOnly() while signal.value.integer != 1: yield RisingEdge(signal) yield ReadOnly() yield NextTimeStep()
def _wait_ready(self): """Wait for a ready cycle on the bus before continuing Can no longer drive values this cycle... FIXME assumes readyLatency of 0 """ yield ReadOnly() while not self.bus.ready.value: yield RisingEdge(self.clock) yield ReadOnly()
def _wait_for_nsignal(self, signal): """This method will return with the specified signal has hit logic 0. The state will be in the ReadOnly phase so sim will need to move to NextTimeStep before registering more callbacks can occour """ yield ReadOnly() while signal.value.integer != 0: yield Edge(signal) yield ReadOnly() yield NextTimeStep()
def _wait_for_nsignal(self, signal): """This method will return when the specified signal has hit logic ``0``. The state will be in the :class:`~cocotb.triggers.ReadOnly` phase so sim will need to move to :class:`~cocotb.triggers.NextTimeStep` before registering more callbacks can occur. """ yield ReadOnly() while signal.value.integer != 0: yield Edge(signal) yield ReadOnly() yield NextTimeStep()
def write(self, data=None): if data is None: #Generate a test image data = [[0] * width] * height for y in range(height): for x in range(width): data[y][x] = i % 256 yield self.busy.acquire() yield RisingEdge(self.clock) ''' self.bus.SOF_STB <= 1 yield RisingEdge(self.clock) self.bus.SOF_STB <= 0 ''' #Perform Y Front Porch Delay for i in range(self.y_fp): yield RisingEdge(self.clock) yield ReadOnly() for y in range(self.height): #Perform X Front Porch Delay for i in range(self.x_fp): yield RisingEdge(self.clock) yield ReadOnly() yield RisingEdge(self.clock) self.bus.SOF_STB <= 1 yield RisingEdge(self.clock) self.bus.SOF_STB <= 0 for x in range(self.width): yield RisingEdge() self.busy.HSYNC <= 1 self.bus.RED <= (data[y][x] >> 5) & 0x5 self.bus.GREEN <= (data[y][x] >> 2) & 0x5 self.bus.BLUE <= (data[y][x] >> 0) & 0x3 yield RisingEdge() self.busy.HSYNC <= 0 #Perform X Back Porch Delay for i in range(self.x_bp): yield RisingEdge(self.clock) yield ReadOnly() #Perform Y Back Porch Delay for i in range(self.y_bp): yield RisingEdge(self.clock) yield ReadOnly()
def write(self, data, byte_enable=-1, keep=1, tid=0, dest=0, user=0): """ Send the write data, with optional delay """ yield self.write_data_busy.acquire() self.bus.tvalid <= 0 self.bus.tlast <= 0 if hasattr(self.bus, 'tid'): self.bus.tid <= tid if hasattr(self.bus, 'tdest'): self.bus.tdest <= dest if hasattr(self.bus, 'tuser'): self.bus.tuser <= user if hasattr(self.bus, 'tstrb'): self.bus.tstrb <= (1 << self.strobe_width) - 1 if byte_enable == -1: byte_enable = (self.width >> 3) - 1 #Wait for the slave to assert tready while True: yield ReadOnly() if self.bus.tready.value: break yield RisingEdge(self.clock) yield RisingEdge(self.clock) #every clock cycle update the data for i in range (len(data)): self.bus.tvalid <= 1 self.bus.tdata <= data[i] if i >= len(data) - 1: self.bus.tlast <= 1; yield ReadOnly() if not self.bus.tready.value: while True: yield RisingEdge(self.clock) yield ReadOnly() if self.bus.tready.value: yield RisingEdge(self.clock) break continue yield RisingEdge(self.clock) self.bus.tlast <= 0; self.bus.tvalid <= 0; yield RisingEdge(self.clock) self.write_data_busy.release()
def _read_data(self): clock_re = RisingEdge(self.clock) while True: while True: yield ReadOnly() if self.bus.ARVALID.value: break yield clock_re yield ReadOnly() _araddr = int(self.bus.ARADDR) _arlen = int(self.bus.ARLEN) _arsize = int(self.bus.ARSIZE) _arburst = int(self.bus.ARBURST) _arprot = int(self.bus.ARPROT) burst_length = _arlen + 1 bytes_in_beat = self._size_to_bytes_in_beat(_arsize) word = BinaryValue(n_bits=bytes_in_beat*8, bigEndian=self.big_endian) if __debug__: self.log.debug( "ARADDR %d\n" % _araddr + "ARLEN %d\n" % _arlen + "ARSIZE %d\n" % _arsize + "ARBURST %d\n" % _arburst + "ARPROT %d\n" % _arprot + "BURST_LENGTH %d\n" % burst_length + "Bytes in beat %d\n" % bytes_in_beat) burst_count = burst_length yield clock_re while True: self.bus.RVALID <= 1 yield ReadOnly() if self.bus.RREADY.value: _burst_diff = burst_length - burst_count _st = _araddr + (_burst_diff * bytes_in_beat) _end = _araddr + ((_burst_diff + 1) * bytes_in_beat) word.buff = self._memory[_st:_end].tobytes() self.bus.RDATA <= word if burst_count == 1: self.bus.RLAST <= 1 yield clock_re burst_count -= 1 self.bus.RLAST <= 0 if burst_count == 0: 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) # self.bus.ARADDR <= address # self.bus.ARVALID <= 1 self.bus.araddr <= address self.bus.arvalid <= 1 while True: yield ReadOnly() # if self.bus.ARREADY.value: if self.bus.arready.value: break yield RisingEdge(self.clock) yield RisingEdge(self.clock) # self.bus.ARVALID <= 0 self.bus.arvalid <= 0 while True: yield ReadOnly() # if self.bus.RVALID.value and self.bus.RREADY.value: if self.bus.rvalid.value and self.bus.rready.value: # data = self.bus.RDATA.value # result = self.bus.RRESP.value data = self.bus.rdata.value result = self.bus.rresp.value break 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_data(self): clock_re = RisingEdge(self.clock) while True: while True: self.bus.WREADY <= 0 yield ReadOnly() if self.bus.AWVALID.value: self.bus.WREADY <= 1 break yield clock_re yield ReadOnly() _awaddr = int(self.bus.AWADDR) _awlen = int(self.bus.AWLEN) _awsize = int(self.bus.AWSIZE) _awburst = int(self.bus.AWBURST) _awprot = int(self.bus.AWPROT) burst_length = _awlen + 1 bytes_in_beat = self._size_to_bytes_in_beat(_awsize) word = BinaryValue(bits=bytes_in_beat*8, bigEndian=self.big_endain) if __debug__: self.log.debug( "AWADDR %d\n" % _awaddr + "AWLEN %d\n" % _awlen + "AWSIZE %d\n" % _awsize + "AWBURST %d\n" % _awburst + "BURST_LENGTH %d\n" % burst_length + "Bytes in beat %d\n" % bytes_in_beat) burst_count = burst_length yield clock_re while True: if self.bus.WVALID.value: word = self.bus.WDATA.value word.big_endian = self.big_endain _burst_diff = burst_length - burst_count _st = _awaddr + (_burst_diff * bytes_in_beat) # start _end = _awaddr + ((_burst_diff + 1) * bytes_in_beat) # end self._memory[_st:_end] = array.array('B', word.get_buff()) burst_count -= 1 if burst_count == 0: break yield clock_re
def start_reset(reset, active_mode=1, associated_clock=None, wait_cycles=4, wait_time=(50, "ns")): ''' reset = SimHandle of the reset. active_mode = Specifies the active state of the reset. associated_clock = If set to the SimHandle of an associated clock, the reset will become inactive after the specified amount of wait cycles. If set to None, the reset will instead become inactive after the specified amount of time. wait_cycles = Specifies the amount of clock cycles needed before the reset becomes inactive. wait_time = Specifies the amount of time needed before the reset becomes inactive. ''' reset.value = active_mode if associated_clock is not None: for each_cycle in range(wait_cycles): yield ReadOnly() yield RisingEdge(associated_clock) else: yield Timer(*wait_time) reset.value = 1 - active_mode
def write(self, address, value, sync=True): """ """ 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 read_ram(dut, address): """This coroutine performs a read of the RAM and returns a value""" yield RisingEdge(dut.clk_read) # Synchronise to the read clock dut.address_read = address # Drive the value onto the signal yield RisingEdge(dut.clk_read) # Wait for 1 clock cycle yield ReadOnly() # Wait until all events have executed for this timestep raise ReturnValue(int(dut.data_read.value)) # Read back the value
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 reset(self, duration=30000): yield Timer(5500) self.dut.reset_n <= 0 yield Timer(duration) yield RisingEdge(self.dut.clk) self.dut.reset_n <= 1 yield ReadOnly()
def write(self, address: int, value: int, sync: bool = True) -> None: """Issue a write to the given address with the specified value. Args: address: The address to read from. value: The data value to write. sync: 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 read_external(self, address): """Copied from silusb.sv testbench interface""" self.bus.RD_B <= 1 self.bus.ADD <= self._x self.bus.BUS_DATA <= self._high_impedence for _ in range(5): yield RisingEdge(self.clock) yield RisingEdge(self.clock) self.bus.ADD <= address + 0x4000 yield RisingEdge(self.clock) self.bus.RD_B <= 0 yield RisingEdge(self.clock) self.bus.RD_B <= 0 yield ReadOnly() result = self.bus.BUS_DATA.value.integer yield RisingEdge(self.clock) self.bus.RD_B <= 1 yield RisingEdge(self.clock) self.bus.RD_B <= 1 self.bus.ADD <= self._x yield RisingEdge(self.clock) for _ in range(5): yield RisingEdge(self.clock) raise ReturnValue(result)
def bcycle(self): ''' Waits a single clock cycle. ''' yield ReadOnly() yield RisingEdge(self.bclock)
def update(self): yield ReadOnly() self.empty = (self.dut.fifo_empty == 1) self.full = (self.dut.fifo_full == 1) self.threshold = (self.dut.fifo_threshold == 1) self.overflow = (self.dut.fifo_overflow == 1) self.underflow = (self.dut.fifo_underflow == 1)
async def test_singleton_isinstance(dut): """ Test that the result of trigger expression have a predictable type """ assert isinstance(NextTimeStep(), NextTimeStep) assert isinstance(ReadOnly(), ReadOnly) assert isinstance(ReadWrite(), ReadWrite)
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. """ 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 get_count(self): while True: yield ReadOnly() if self._entity.ld_cnt == 0: break raise ReturnValue(self._entity.cntdwn)
def do_test_readwrite_in_readonly(dut): global exited yield RisingEdge(dut.clk) yield ReadOnly() dut.clk <= 0 yield ReadWrite() exited = True