def _write_data(self): clock_re = RisingEdge(self.clock) while True: while True: self.bus.WREADY <= 0 yield ReadOnly() yield NextTimeStep() 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 0x{:x}\n".format(_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: self.bus.BVALID.value = 1 while self.bus.BREADY == 0: yield clock_re self.bus.BVALID.value = 0 break yield clock_re
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() self._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(bits=bytes_in_beat*8, bigEndian=self.big_endain) if __debug__: self.log.debug( "ARLEN %d\n" % _arlen + "ARSIZE %d\n" % _arsize + "ARBURST %d\n" % _arburst + "BURST_LENGTH %d\n" % burst_length + "Bytes in beat %d\n" % bytes_in_beat) burst_count = burst_length word.buff = self._read_memory(burst_length, burst_count, bytes_in_beat) yield clock_re self.bus.RDATA <= word while True: self.bus.RVALID <= 1 yield clock_re if self.bus.RREADY.value: word.buff = self._read_memory(burst_length, burst_count, bytes_in_beat) self.bus.RDATA <= word if burst_count == 1: self.bus.RLAST <= 1 yield clock_re self.bus.RLAST <= 0 self.bus.RVALID <= 0 break burst_count -= 1
def Ram_Read(self,dut, A): ############# Reading value from RAM Ad = BinaryValue() Ad.assign(A) #print Ad, Bd dut.a_adbus.value = Ad yield RisingEdge(self.dut.clk) yield ReadOnly() raise ReturnValue(dut.a_data_out.value)
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 + "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].tostring() 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 _driver_send(self, value, sync=True): """Send a transmission over the bus. Args: value: data to drive onto the bus. """ self.log.debug("Sending Avalon transmission: %d" % value) # Avoid spurious object creation by recycling clkedge = RisingEdge(self.clock) word = BinaryValue(n_bits=len(self.bus.data), bigEndian=False) # Drive some defaults since we don't know what state we're in self.bus.valid <= 0 if sync: yield clkedge # Insert a gap where valid is low if not self.on: self.bus.valid <= 0 for i in range(self.off): yield clkedge # Grab the next set of on/off values self._next_valids() # Consume a valid cycle if self.on is not True and self.on: self.on -= 1 self.bus.valid <= 1 word.assign(value) self.bus.data <= word # If this is a bus with a ready signal, wait for this word to # be acknowledged if hasattr(self.bus, "ready"): yield self._wait_ready() yield clkedge self.bus.valid <= 0 word.binstr = ("x"*len(self.bus.data)) self.bus.data <= word self.log.debug("Successfully sent Avalon transmission: %d" % value)
def PUSH(self,dut, A,command): Ad = BinaryValue() Ad.assign(A) dut.Data_in_Core1_Inp.value = Ad dut.wr_en_Core1_Inp.value=1 dut.wr_en_Core1_Cmd.value =1 dut.Data_in_Core1_Cmd.value=command yield RisingEdge(self.dut.clk) dut.wr_en_Core1_Inp.value=0 dut.wr_en_Core1_Cmd.value =0 yield ReadOnly()
def __init__(self, *args, **kwargs): config = kwargs.pop('config', {}) ValidatedBusDriver.__init__(self, *args, **kwargs) self.config = AvalonSTPkts._default_config.copy() # Set default config maxChannel to max value on channel bus if hasattr(self.bus, 'channel'): self.config['maxChannel'] = (2 ** len(self.bus.channel)) -1 for configoption, value in config.items(): self.config[configoption] = value self.log.debug("Setting config option %s to %s" % (configoption, str(value))) num_data_symbols = (len(self.bus.data) / self.config["dataBitsPerSymbol"]) if (num_data_symbols > 1 and not hasattr(self.bus, 'empty')): raise AttributeError( "%s has %i data symbols, but contains no object named empty" % (self.name, num_data_symbols)) self.use_empty = (num_data_symbols > 1) self.config["useEmpty"] = self.use_empty word = BinaryValue(n_bits=len(self.bus.data), bigEndian=self.config['firstSymbolInHighOrderBits']) single = BinaryValue(n_bits=1, bigEndian=False) word.binstr = ("x"*len(self.bus.data)) single.binstr = ("x") self.bus.valid <= 0 self.bus.data <= word self.bus.startofpacket <= single self.bus.endofpacket <= single if self.use_empty: empty = BinaryValue(n_bits=len(self.bus.empty), bigEndian=False) empty.binstr = ("x"*len(self.bus.empty)) self.bus.empty <= empty if hasattr(self.bus, 'channel'): if len(self.bus.channel) > 128: raise AttributeError( "Avalon-ST interface specification defines channel width as 1-128. %d channel width is %d" % (self.name, len(self.bus.channel)) ) maxChannel = (2 ** len(self.bus.channel)) -1 if self.config['maxChannel'] > maxChannel: raise AttributeError( "%s has maxChannel=%d, but can only support a maximum channel of (2**channel_width)-1=%d, channel_width=%d" % (self.name,self.config['maxChannel'],maxChannel,len(self.bus.channel))) channel = BinaryValue(n_bits=len(self.bus.channel), bigEndian=False) channel.binstr = ("x"*len(self.bus.channel)) self.bus.channel <= channel
class ConstantObject(NonHierarchyObject): """ Constant objects have a value that can be read, but not set. We can also cache the value since it is elaboration time fixed and won't change within a simulation """ def __init__(self, handle, handle_type): NonHierarchyObject.__init__(self, handle) if handle_type in [simulator.INTEGER, simulator.ENUM]: self._value = simulator.get_signal_val_long(self._handle) elif handle_type == simulator.REAL: self._value = simulator.get_signal_val_real(self._handle) elif handle_type == simulator.STRING: self._value = simulator.get_signal_val_str(self._handle) else: val = simulator.get_signal_val_binstr(self._handle) self._value = BinaryValue(bits=len(val)) try: self._value.binstr = val except: self._value = val def __int__(self): return int(self._value) def __eq__(self, other): return self._value.__eq__(other) def __ne__(self, other): if isinstance(self._value, str): return self._value.__ne__(other) else: return self._value != other def __repr__(self): return str(self._value) @property def value(self): return self._value def _setcachedvalue(self, *args, **kwargs): raise ValueError("Not permissible to set values on a constant object") def __le__(self, *args, **kwargs): raise ValueError("Not permissible to set values on a constant object")
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 self._memory[_awaddr+((burst_length-burst_count)*bytes_in_beat):_awaddr+(((burst_length-burst_count)+1)*bytes_in_beat)] = array.array('B',word.get_buff()) burst_count -= 1 if burst_count == 0: break yield clock_re
def __init__(self, *args, **kwargs): config = kwargs.pop('config', {}) ValidatedBusDriver.__init__(self, *args, **kwargs) self.config = AvalonSTPkts._default_config.copy() for configoption, value in config.items(): self.config[configoption] = value self.log.debug("Setting config option %s to %s" % (configoption, str(value))) word = BinaryValue(bits=len(self.bus.data), bigEndian=self.config['firstSymbolInHighOrderBits']) word.binstr = ("x"*len(self.bus.data)) self.bus.valid <= 0 self.bus.data <= word self.bus.empty <= word self.bus.startofpacket <= word self.bus.endofpacket <= word
def _ad9361_tx_to_rx_loopback(self): cocotb.fork(self._tx_data_from_ad9361()) i_bin_val = BinaryValue(bits=12, bigEndian=False) q_bin_val = BinaryValue(bits=12, bigEndian=False) while True: yield RisingEdge(self.dut.rx_clk_in_p) if self.rx_frame_asserted: self.dut.rx_data_in_p <= i_bin_val[5:0] self.dut.rx_data_in_n <= ~i_bin_val[5:0] self.rx_frame_asserted = False self.dut.rx_frame_in_p <= 0 self.dut.rx_frame_in_n <= 1 else: if len(self.lbqi) > 0: i_bin_val = self.lbqi.popleft() else: i_bin_val.set_value(0) if len(self.lbqq) > 0: q_bin_val = self.lbqq.popleft() else: q_bin_val.set_value(0) self.dut.rx_data_in_p <= i_bin_val[11:6] self.dut.rx_data_in_n <= ~i_bin_val[11:6] self.rx_frame_asserted = True self.dut.rx_frame_in_p <= 1 self.dut.rx_frame_in_n <= 0 yield RisingEdge(self.dut.rx_clk_in_n) if self.rx_frame_asserted: self.dut.rx_data_in_p <= q_bin_val[11:6] self.dut.rx_data_in_n <= ~q_bin_val[11:6] else: self.dut.rx_data_in_p <= q_bin_val[5:0] self.dut.rx_data_in_n <= ~q_bin_val[5:0]
def test_binary_value_compat(dut): """ Test backwards-compatibility wrappers for BinaryValue """ dut._log.info("Checking the renaming of bits -> n_bits") vec = BinaryValue(value=0, bits=16) if vec.n_bits != 16: raise TestFailure("n_bits is not set correctly - expected %d, got %d" % (16, vec.n_bits)) vec = BinaryValue(0, 16) if vec.n_bits != 16: raise TestFailure("n_bits is not set correctly - expected %d, got %d" % (16, vec.n_bits)) try: vec = BinaryValue(value=0, bits=16, n_bits=17) except TypeError: pass else: raise TestFailure( "Expected TypeError when using bits and n_bits at the same time.") # Test for the DeprecationWarning when using |bits| with warnings.catch_warnings(record=True) as w: warnings.simplefilter("error") try: vec = BinaryValue(value=0, bits=16) except DeprecationWarning: pass else: TestFailure( "Expected DeprecationWarning when using bits instead of n_bits." ) yield Timer(100) # Make it do something with time
def PacketParser(dut: cocotb.handle, packet: scapy_packet, scapy_to_VHDL): """setUp interface of dut with packet info If process header recursively, if not on dut raise error. This function is the expected output of a packet parser """ if not isinstance(packet, scapy_packet): raise TypeError("expected scapy Packet type") dut._log.info("debut parsage") for i in scapy_to_VHDL: signal_en = "{}_valid".format(scapy_to_VHDL[i][0]) if signal_en in dut._sub_handles: dut._sub_handles[signal_en].value = 0 if packet.haslayer(i): signal = "{}_bus".format(scapy_to_VHDL[i][0]) if not (signal in dut._sub_handles): raise ValueError("unvalid header : {}".format(signal)) val = BinaryValue() signal_width = int(scapy_to_VHDL[i][1] / 8) val.binstr = BitArray(raw(packet.getlayer(i))[0:signal_width]).bin val.buff = val.buff[::-1] dut._sub_handles[signal].value = val dut._sub_handles[signal_en].value = 1 dut._log.info("fin parser")
def dump_cccrs(self): """ Print out all of the CCCRs (card common control registers) See section 6.9 (page 33) of the SDIO spec. """ self.log.info("CCCRs:") for reg in sdio_utils._cccrs: val = yield self.read_reg(fn=0, addr=reg['addr']) if 'bin' in reg and reg['bin']: # Print out in binary format self.log.info("0x%02x %-30s: %s" %(reg['addr'], reg['name'], BinaryValue(value=val,bits=8,bigEndian=False).binstr)) else: self.log.info("0x%02x %-30s: %02x" %(reg['addr'], reg['name'], val))
def rdxact(self, addr, addr_delay=0, data_delay=0, resp_delay=0): addr = BinaryValue(addr, bits=self._bits, bigEndian=False) addr_phase = cocotb.fork(self._rdxact_addr_phase(addr, addr_delay)) data_phase = cocotb.fork(self._rdxact_data_phase(data_delay)) yield addr_phase.join() yield data_phase.join() resp = self._entity.rresp if int(resp): raise AxiError("axi4 lite master", True, int(addr), resp) raise ReturnValue(self._entity.rdata)
def print_trans(self, transaction): self.dut._log.info("Frame : {}, {}B:{}".format(self.nb_frame, len(transaction.buff), transaction)) self.packet.buff += transaction.buff self.nb_frame += 1 if self.dut.packet_out_tlast == 1: print(self.packet.buff) if len(self.packet.binstr) < 6*8: self.dut._log.warning("received packet lesser than 6Bytes\n" "received :\n{}".format(self.packet.binstr)) else: print("received :\n{}".format(raw(BinaryValue_to_scapy(self.packet)))) self.packet = BinaryValue()
def test_cdbus(dut): """ test_cdbus """ dut._log.info("test_cdbus start.") cocotb.fork(Clock(dut.clk, CLK_PERIOD).start()) yield reset(dut) value = yield csr_read(dut, REG_VERSION, True) dut._log.info("REG_VERSION: 0x%02x" % int(value)) value = yield csr_read(dut, REG_SETTING) dut._log.info("REG_SETTING: 0x%02x" % int(value)) yield csr_write(dut, REG_SETTING, BinaryValue("00010001")) yield csr_write(dut, REG_DIV_LS_H, 0, True) yield csr_write(dut, REG_DIV_LS_L, 39, True) # 1Mbps yield csr_write(dut, REG_DIV_HS_H, 0, True) yield csr_write(dut, REG_DIV_HS_L, 3, True) # 10Mbps yield csr_write(dut, REG_FILTER, 0x00, True) # set local filter to 0x00 # TODO: reset rx... yield csr_write(dut, REG_TX, 0x01, True) # disguise as node 0x01 to send data yield csr_write(dut, REG_TX, 0x00, True) yield csr_write(dut, REG_TX, 0x01, True) yield csr_write(dut, REG_TX, 0xcd, True) yield csr_write(dut, REG_TX_CTRL, BIT_TX_START | BIT_TX_RST_POINTER) yield Timer(40000000) yield csr_write(dut, REG_TX_CTRL, BIT_TX_ABORT) yield csr_write(dut, REG_TX, 0x0f, True) # disguise as node 0x0f to send data yield csr_write(dut, REG_TX, 0x00, True) yield csr_write(dut, REG_TX, 0x01, True) yield csr_write(dut, REG_TX, 0xcd, True) yield csr_write(dut, REG_TX_CTRL, BIT_TX_START | BIT_TX_RST_POINTER) #yield RisingEdge(dut.cdbus_m.rx_pending) #yield RisingEdge(dut.cdbus_m.bus_idle) yield RisingEdge(dut.cdbus_m.bus_idle) yield Timer(5000000) yield send_frame(dut, b'\x05\x00\x01\xcd', 39, 3) # receive before previous packet send out yield Timer(100000000) dut._log.info("test_cdbus done.")
def __init__(self, entity, name, clock, *, config={}, **kwargs): ValidatedBusDriver.__init__(self, entity, name, clock, **kwargs) self.config = AvalonST._default_config.copy() for configoption, value in config.items(): self.config[configoption] = value self.log.debug("Setting config option %s to %s", configoption, str(value)) word = BinaryValue(n_bits=len(self.bus.data), bigEndian=self.config["firstSymbolInHighOrderBits"], value="x" * len(self.bus.data)) self.bus.valid <= 0 self.bus.data <= word
def __init__(self, *args, **kwargs): config = kwargs.pop('config', {}) ValidatedBusDriver.__init__(self, *args, **kwargs) self.config = AvalonST._default_config.copy() for configoption, value in config.items(): self.config[configoption] = value self.log.debug("Setting config option %s to %s" % (configoption, str(value))) word = BinaryValue(n_bits=len(self.bus.data), bigEndian=self.config['firstSymbolInHighOrderBits']) self.bus.valid <= 0 self.bus.data <= word
def test_init_short_binstr_value(): bin1 = BinaryValue(value="0", n_bits=4, bigEndian=True, binaryRepresentation=BinaryRepresentation.UNSIGNED) assert bin1._str == "0000" assert bin1.binstr == "0000" assert bin1.integer == 0 bin2 = BinaryValue(value="Z", n_bits=8, bigEndian=False, binaryRepresentation=BinaryRepresentation.UNSIGNED) assert bin2._str == "0000000Z" assert bin2.binstr == "0000000Z" with pytest.raises(ValueError): bin2.integer pytest.fail("Expected ValueError when resolving Z to integer") bin3 = BinaryValue( value="01", n_bits=8, bigEndian=False, binaryRepresentation=BinaryRepresentation.SIGNED_MAGNITUDE) assert bin3._str == "00000001" assert bin3.binstr == "00000001" assert bin3.integer == 1 bin4 = BinaryValue( value="1", n_bits=8, bigEndian=True, binaryRepresentation=BinaryRepresentation.SIGNED_MAGNITUDE) # 1 digit is too small for Signed Magnitude representation, so setting binstr will fail, falling back to buff bin4._str == "10000000" bin4.binstr == "10000000" bin4.integer == 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 if valid(): 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 read(self, address, size): result = [] if address >= self.BASE_ADDRESS_STREAM: result = yield self.read_stream(address, size) else: self.bus.BUS_DATA <= self._high_impedence self.bus.BUS_ADD <= self._x self.bus.BUS_RD <= 0 yield RisingEdge(self.clock) byte = 0 while(byte <= size): if(byte == size): self.bus.BUS_RD <= 0 else: self.bus.BUS_RD <= 1 self.bus.BUS_ADD <= address + byte yield RisingEdge(self.clock) if(byte != 0): if(self._has_byte_acces and self.bus.BUS_BYTE_ACCESS.value.integer == 0): result.append(self.bus.BUS_DATA.value.integer & 0x000000ff) result.append((self.bus.BUS_DATA.value.integer & 0x0000ff00) >> 8) result.append((self.bus.BUS_DATA.value.integer & 0x00ff0000) >> 16) result.append((self.bus.BUS_DATA.value.integer & 0xff000000) >> 24) else: # result.append(self.bus.BUS_DATA.value[24:31].integer & 0xff) if len(self.bus.BUS_DATA.value) == 8: result.append(self.bus.BUS_DATA.value.integer & 0xff) else: # value = self.bus.BUS_DATA.value[24:31].integer & 0xff # workaround for cocotb https://github.com/potentialventures/cocotb/pull/459 value = BinaryValue(self.bus.BUS_DATA.value.binstr[24:32]) result.append(value.integer) if(self._has_byte_acces and self.bus.BUS_BYTE_ACCESS.value.integer == 0): byte += 4 else: byte += 1 self.bus.BUS_ADD <= self._x self.bus.BUS_DATA <= self._high_impedence yield RisingEdge(self.clock) raise ReturnValue(result)
def np2bv(int_arr, n_bits=8): """ Convert a n_bits integer numpy array to cocotb BinaryValue """ # Step 1: Turn ndarray into a list of integers int_list = int_arr.tolist() # Step 2: Format each number as two's complement strings binarized = [format(x & 2 ** n_bits - 1, f'0{n_bits}b') if x < 0 else format(x, f'0{n_bits}b') for x in int_list] # Step 3: Join all strings into one large binary string bin_string = ''.join(binarized) # Step 4: Convert to cocotb BinaryValue and return return BinaryValue(bin_string)
def test_binary_value_compat(dut): """ Test backwards-compatibility wrappers for BinaryValue """ dut._log.info("Checking the renaming of bits -> n_bits") with assert_deprecated(): vec = BinaryValue(value=0, bits=16) if vec.n_bits != 16: raise TestFailure("n_bits is not set correctly - expected %d, got %d" % (16, vec.n_bits)) vec = BinaryValue(0, 16) if vec.n_bits != 16: raise TestFailure("n_bits is not set correctly - expected %d, got %d" % (16, vec.n_bits)) try: vec = BinaryValue(value=0, bits=16, n_bits=17) except TypeError: pass else: raise TestFailure("Expected TypeError when using bits and n_bits at the same time.") yield Timer(100) # Make it do something with time
def __init__(self, dut, clkperiod=6.4): self.dut = dut dut._discover_all() # scan all signals on the design dut._log.setLevel(30) fork(Clock(dut.clk, clkperiod, 'ns').start()) self.payload_in = AXI4STPKts(dut, "payload_in", dut.clk) self.stream_out = AXI4STMonitor(dut, "packet_out", dut.clk, callback=self.print_trans) self.scoreboard = Scoreboard(dut, fail_immediately=False) self.expected_output = [] self.scoreboard.add_interface(self.stream_out, self.expected_output) self.nb_frame = 0 self.packet = BinaryValue()
def __init__(self, handle, path, handle_type): NonHierarchyObject.__init__(self, handle, path) if handle_type in [simulator.INTEGER, simulator.ENUM]: self._value = simulator.get_signal_val_long(self._handle) elif handle_type == simulator.REAL: self._value = simulator.get_signal_val_real(self._handle) elif handle_type == simulator.STRING: self._value = simulator.get_signal_val_str(self._handle) else: val = simulator.get_signal_val_binstr(self._handle) self._value = BinaryValue(n_bits=len(val)) try: self._value.binstr = val except: self._value = val
def dump_fbrs(self, func=0): """ Print out the FBR (function basic registers) for a particular function See section 6.9 (page 33) of the SDIO spec. """ self.log.info("FBR for function %d:" % func) for reg in sdio_utils._fbrs: addr = (func << 8) + reg['addr'] val = yield self.read_reg(fn=0, addr=addr) if 'bin' in reg and reg['bin']: # Print out in binary format self.log.info("0x%02x %-35s: %s" %(reg['addr'], reg['name'], BinaryValue(value=val,bits=8,bigEndian=False).binstr)) else: self.log.info("0x%02x %-35s: %02x" %(reg['addr'], reg['name'], val))
def set_data( self, data: int, data_length=None, representation=BinaryRepresentation.TWOS_COMPLEMENT, ): if data_length is not None: self.data_length = data_length return BinaryValue( value=data, n_bits=self.data_length, bigEndian=False, binaryRepresentation=representation, )
def model(self, transaction): """ Model the DUT based on the input transaction. """ # Do not append an output transaction for the last clock cycle of the # simulation, that is, after stop() has been called. if not self.stopped: print "--- PING" print(type(transaction)) print(transaction.integer) if self.triggered: print "Appending 1" self.expected_output.append(BinaryValue(1, 1)) self.counter = self.counter + 1 if self.counter == 21 - 1: self.triggered = False else: print "Appending 0" if transaction.integer == 0: self.expected_output.append(BinaryValue(0, 1)) if transaction.integer == 1: self.expected_output.append(BinaryValue(1, 1)) self.counter = self.counter = 0 self.triggered = True
def test_init_not_enough_bits(): with pytest.warns(RuntimeWarning, match=TRUNCATION_MATCH): bin1_unsigned = BinaryValue( value=128, n_bits=7, bigEndian=True, binaryRepresentation=BinaryRepresentation.UNSIGNED) assert bin1_unsigned._str == "0000000" assert bin1_unsigned.binstr == "0000000" assert bin1_unsigned.integer == 0 with pytest.warns(RuntimeWarning, match=TRUNCATION_MATCH): bin1_sigmag = BinaryValue( value=128, n_bits=7, bigEndian=True, binaryRepresentation=BinaryRepresentation.SIGNED_MAGNITUDE) assert bin1_sigmag._str == "0000000" assert bin1_sigmag.binstr == "0000000" assert bin1_sigmag.integer == 0 with pytest.warns(RuntimeWarning, match=TRUNCATION_MATCH): bin1_twoscomp = BinaryValue( value=128, n_bits=7, bigEndian=True, binaryRepresentation=BinaryRepresentation.TWOS_COMPLEMENT) assert bin1_twoscomp._str == "0000000" assert bin1_twoscomp.binstr == "0000000" assert bin1_twoscomp.integer == 0 with pytest.warns(RuntimeWarning, match=TRUNCATION_MATCH): bin1_binstr = BinaryValue(value="110000000", n_bits=7, bigEndian=True) assert bin1_binstr._str == "0000000" assert bin1_binstr.binstr == "0000000" assert bin1_binstr.integer == 0 with pytest.warns(RuntimeWarning, match=TRUNCATION_MATCH): bin2 = BinaryValue( value="1111110000101100", n_bits=12, bigEndian=False, binaryRepresentation=BinaryRepresentation.TWOS_COMPLEMENT) assert bin2._str == "110000101100" assert bin2.binstr == "110000101100" assert bin2.integer == -980 with pytest.warns(RuntimeWarning, match=TRUNCATION_MATCH): bin3 = BinaryValue( value="1111110000101100", n_bits=11, bigEndian=False, binaryRepresentation=BinaryRepresentation.SIGNED_MAGNITUDE) assert bin3._str == "10000101100" assert bin3.binstr == "10000101100" assert bin3.integer == -44
async def test_assigning_structure_deprecated(dut): """signal <= ctypes.Structure assignment is deprecated""" class Example(ctypes.Structure): _fields_ = [("a", ctypes.c_byte), ("b", ctypes.c_uint32)] e = Example(a=0xCC, b=0x12345678) with assert_deprecated(): dut.stream_in_data_wide <= e await Timer(1, 'step') assert dut.stream_in_data_wide == BinaryValue(value=bytes(e), n_bits=len( dut.stream_in_data_wide))
def __init__(self, handle, handle_type): NonHierarchyObject.__init__(self, handle) if handle_type in [simulator.INTEGER, simulator.ENUM]: self._value = simulator.get_signal_val_long(self._handle) elif handle_type == simulator.REAL: self._value = simulator.get_signal_val_real(self._handle) elif handle_type == simulator.STRING: self._value = simulator.get_signal_val_str(self._handle) else: val = simulator.get_signal_val_binstr(self._handle) self._value = BinaryValue(bits=len(val)) try: self._value.binstr = val except: self._value = val
def driver_tx_rx (self): highZ = BinaryValue() highZ.binstr = "zzzzzzzz" while True: if(len(self.tx_fifo) < TX_FIFO_MAX): self.dut.txe_245 <= 0 else: self.dut.txe_245 <= 1 if(len(self.rx_fifo) > 0): self.dut.rxf_245 <= 0 else: self.dut.rxf_245 <= 1 if(self.dut.txe_245.value.integer == 0 and self.dut.wr_245.value.integer == 0): self.dut.rxf_245 <= 1 # TX --> then NOT RX # start tx sequence self.dut.in_out_245 <= highZ yield Timer(1, units='ps') self.tx_fifo.append(self.dut.in_out_245.value.integer) #print ("FDTI TX: " + repr(self.dut.in_out_245.value.integer)) yield nsTimer(14+WR_TO_INACTIVE) #T6+... if (self.dut.wr_245.value.integer == 0): yield RisingEdge(self.dut.wr_245) self.dut.txe_245 <= 1 yield nsTimer(TXE_INACTIVE) else: if(self.dut.rxf_245.value.integer == 0 and self.dut.rx_245.value.integer == 0): self.dut.txe_245 <= 1 # RX --> then NOT TX yield Timer(1, units='ps') yield nsTimer(RD_TO_DATA) aux = self.rx_fifo.pop(0) self.dut.in_out_245 <= aux #self.rx_fifo.pop(0) #print "AUX = " + repr(aux) yield Timer(1,units='ps') if(self.dut.rx_245.value.integer == 0): yield RisingEdge(self.dut.rx_245) yield nsTimer(14) self.dut.rxf_245 <= 1 yield nsTimer(RFX_INACTIVE) else: yield Timer(10, units='ns')
def test_cdctl_bx(dut): """ test_cdctl_bx """ dut._log.info("test_cdctl_bx start.") dut.intf_sel = 1 dut.nss = 1 dut.sck_scl = 0 cocotb.fork(Clock(dut.clk, CLK_PERIOD).start()) yield Timer(500000) # wait reset value = yield spi_read(dut, REG_VERSION) dut._log.info("REG_VERSION: 0x%02x" % int(value[0])) value = yield spi_read(dut, REG_SETTING) dut._log.info("REG_SETTING: 0x%02x" % int(value[0])) yield spi_write(dut, REG_SETTING, [BinaryValue("00010001").integer]) yield spi_write(dut, REG_DIV_LS_H, [0]) yield spi_write(dut, REG_DIV_LS_L, [39]) yield spi_write(dut, REG_DIV_HS_H, [0]) yield spi_write(dut, REG_DIV_HS_L, [3]) yield spi_write(dut, REG_FILTER, [0x00]) # TODO: reset rx... yield spi_write(dut, REG_TX, [0x01]) yield spi_write(dut, REG_TX, [0x00]) yield spi_write(dut, REG_TX, [0x01, 0xcd]) #yield spi_write(dut, REG_TX, [0xcd]) yield spi_write(dut, REG_TX_CTRL, [BIT_TX_START | BIT_TX_RST_POINTER]) yield RisingEdge(dut.cdctl_bx_m.cdbus_m.rx_pending) value = yield spi_read(dut, REG_RX, 3) print(" ".join([("%02x" % x) for x in value])) value = yield spi_read(dut, REG_RX, 3) print(" ".join([("%02x" % x) for x in value])) #yield RisingEdge(dut.cdctl_bx_m.cdbus_m.bus_idle) #yield RisingEdge(dut.cdctl_bx_m.cdbus_m.bus_idle) yield Timer(15000000) yield send_frame(dut, b'\x05\x00\x01\xcd', 39, 3) yield Timer(50000000) dut._log.info("test_cdctl_bx done.")
def model(self, a_matrix: List[int], b_matrix: List[int]) -> List[int]: """Transaction-level model of the matrix multipler as instantiated""" A_ROWS = self.dut.A_ROWS.value A_COLUMNS_B_ROWS = self.dut.A_COLUMNS_B_ROWS.value B_COLUMNS = self.dut.B_COLUMNS.value DATA_WIDTH = self.dut.DATA_WIDTH.value return [ BinaryValue(sum([ a_matrix[(i * A_COLUMNS_B_ROWS) + n] * b_matrix[(n * B_COLUMNS) + j] for n in range(A_COLUMNS_B_ROWS) ]), n_bits=(DATA_WIDTH * 2) + math.ceil(math.log2(A_COLUMNS_B_ROWS)), bigEndian=False) for i in range(A_ROWS) for j in range(B_COLUMNS) ]
def send_cmd(self, cmd): """ Transmit a command, we will calculate the CRC and append it """ crc7 = sdio_utils.crc7_gen(number=cmd[47:8].integer) cmd[7:1] = BinaryValue(value=crc7, bits=7, bigEndian=False).integer self.log.debug("SDIO host sending CMD%d: 'b%s" % (cmd[45:40].integer, cmd.binstr)) self.bus.cmd_coco_dir <= 1 for x in range(47, -1, -1): # Now shift this out bit by bit, host sends on falling edge yield FallingEdge(self.clock) self.bus.cmd_coco_out <= cmd[x].integer if x == 0: # Deassert the output enable onto the bus on the final bit self.bus.cmd_coco_dir <= 0
async def fpga_write_continuous(self, inputs): """ Continuously write from FPGA. When inputs have been exhausted, write zeros. """ sample_ctr = 0 num_samples = len(inputs) self.dut.wren <= 1 while True: if sample_ctr < num_samples: self.dut.wrdata <= BinaryValue( int(inputs[sample_ctr].item()), 64, binaryRepresentation=2) else: self.dut.wrdata <= 0 sample_ctr += 1 await RisingEdge(self.dut.clk)
def __init__(self, entity, name, clock): BusDriver.__init__(self, entity, name, clock) word = BinaryValue(bits=32) single = BinaryValue(bits=1) word.binstr = ("x" * 32) single.binstr = ("x") self.bus.load_i <= single self.bus.rst_i <= single self.bus.dat_i <= word
def __init__(self, tb, request=0, readWrite=0, invalidate=0, replace=0, address=0, cacheLineIn=0): "tb must be an instance of the Testbench class" if (replace==1) and ((request==1) or (invalidate==1)): raise ValueError("InputTransaction.__init__ called with request=%d, invalidate=%d, replace=%d" % request, invalidate, replace) self.Replace = BinaryValue(replace, 1) self.Request = BinaryValue(request, 1) self.ReadWrite = BinaryValue(readWrite, 1) self.Invalidate = BinaryValue(invalidate, 1) self.Address = BinaryValue(address, tb.address_bits, False) self.CacheLineIn = BinaryValue(cacheLineIn, tb.data_bits, False)
def run_test(dut): """Setup testbench and run a test.""" cocotb.fork(clock_gen(dut.c)) tb = DFF_TB(dut, BinaryValue(0,1)) clkedge = RisingEdge(dut.c) # Apply random input data by input_gen via BitDriver for 100 clock cycle. tb.start() for i in range(100): yield clkedge # Stop generation of input data. One more clock cycle is needed to capture # the resulting output of the DUT. tb.stop() yield clkedge # Print result of scoreboard. raise tb.scoreboard.result
def Ram_write(self,dut, A, B): ###### Writing value from RAM Ad = BinaryValue() Ad.assign(A) Bd = BinaryValue() Bd.assign(B) dut.a_adbus.value = Bd dut.a_data_in.value = Ad dut.a_w.value=1 yield RisingEdge(self.dut.clk) dut.a_w.value=0 yield ReadOnly()
def _idle_outputs(self): # Drive default values self.bus.tvalid <= 0 if hasattr(self.bus, 'tdata'): self.bus.tdata <= BinaryValue("x" * len(self.bus.tdata)) if hasattr(self.bus, 'tlast'): self.bus.tlast <= BinaryValue('x') if hasattr(self.bus, 'tkeep'): self.bus.tkeep <= BinaryValue("x" * self._n_bytes) if hasattr(self.bus, 'tstrb'): self.bus.tstrb <= BinaryValue("x" * self._n_bytes) if hasattr(self.bus, 'tid'): self.bus.tid <= BinaryValue("x" * len(self.bus.tid)) if hasattr(self.bus, 'tdest'): self.bus.tdest <= BinaryValue("x" * len(self.bus.tdest)) if hasattr(self.bus, 'tuser'): self.bus.tuser <= BinaryValue("x" * len(self.bus.tuser))
def __init__(self, nbytes: int, interleaved: bool = True): """Args: nbytes: The number of bytes transferred per clock cycle (usually 8 for SDR, 4 for DDR). interleaved: The arrangement of control bits on the bus. If interleaved we have a bus with 9-bits per byte, the control bit being the 9th bit of each byte. If not interleaved then we have a byte per data byte plus a control bit per byte in the MSBs. """ self._value = BinaryValue(n_bits=nbytes * 9, bigEndian=False) self._integer = 0 self._interleaved = interleaved self._nbytes = nbytes
def _monitor_recv(self): """Watch the pins and reconstruct transactions.""" # Avoid spurious object creation by recycling clkedge = RisingEdge(self.clock) rdonly = ReadOnly() pkt = "" in_pkt = False invalid_cyclecount = 0 channel = None def valid(): if hasattr(self.bus, 'ready'): return self.bus.valid.value and self.bus.ready.value return self.bus.valid.value while True: yield clkedge yield rdonly if self.in_reset: continue if valid(): invalid_cyclecount = 0 if self.bus.startofpacket.value: if pkt and self.config['fail_immediately']: raise AvalonProtocolError( "Duplicate start-of-packet received on %s" % ( str(self.bus.startofpacket))) pkt = "" in_pkt = True if not in_pkt and self.config['fail_immediately']: raise AvalonProtocolError("Data transfer outside of " "packet") # Handle empty and X's in empty / data vec = BinaryValue() if not self.bus.endofpacket.value: vec = self.bus.data.value else: value = self.bus.data.value.get_binstr() if self.config["useEmpty"] and self.bus.empty.value.integer: empty = self.bus.empty.value.integer * self.config["dataBitsPerSymbol"] if self.config["firstSymbolInHighOrderBits"]: value = value[:-empty] else: value = value[empty:] vec.assign(value) if not vec.is_resolvable: raise AvalonProtocolError("After empty masking value is still bad? Had empty {:d}, got value {:s}".format(empty, self.bus.data.value.get_binstr())) vec.big_endian = self.config['firstSymbolInHighOrderBits'] pkt += vec.buff if hasattr(self.bus, 'channel'): if channel is None: channel = self.bus.channel.value.integer if channel > self.config["maxChannel"]: raise AvalonProtocolError("Channel value (%d) is greater than maxChannel (%d)" % (channel,self.config["maxChannel"])) elif self.bus.channel.value.integer != channel: raise AvalonProtocolError("Channel value changed during packet") if self.bus.endofpacket.value: self.log.info("Received a packet of %d bytes" % len(pkt)) self.log.debug(hexdump(str((pkt)))) self.channel = channel self._recv(pkt) pkt = "" in_pkt = False channel = None else : if in_pkt : invalid_cyclecount += 1 if self.config["invalidTimeout"] : if invalid_cyclecount >= self.config["invalidTimeout"] : raise AvalonProtocolError( "In-Packet Timeout. Didn't receive any valid data for %d cycles!" % invalid_cyclecount)
def rx_data_to_ad9361(self, i_data, q_data, i_data2=None, q_data2=None, binaryRepresentation=BinaryRepresentation.TWOS_COMPLEMENT): """Receive data to AD9361. This is a coroutine. Args: i_data (int): Data of the I0 channel. q_data (int): Data of the Q0 channel. i_data2 (int, optional): Data of the I1 channel. q_data2 (int, optional): Data of the Q1 channel. binaryRepresentation (BinaryRepresentation): The representation of the binary value. Default is :any:`TWOS_COMPLEMENT`. """ i_bin_val = BinaryValue(n_bits=12, bigEndian=False, binaryRepresentation=binaryRepresentation) q_bin_val = BinaryValue(n_bits=12, bigEndian=False, binaryRepresentation=binaryRepresentation) index = 0 if i_data2 is None and q_data2 is None: while True: yield RisingEdge(self.dut.rx_clk_in_p) if self.rx_frame_asserted: self.dut.rx_data_in_p <= i_bin_val[5:0] self.dut.rx_data_in_n <= ~i_bin_val[5:0] self.rx_frame_asserted = False self.dut.rx_frame_in_p <= 0 self.dut.rx_frame_in_n <= 1 else: if index < len(i_data): i_bin_val.set_value(i_data[index]) q_bin_val.set_value(q_data[index]) index += 1 else: return self.dut.rx_data_in_p <= i_bin_val[11:6] self.dut.rx_data_in_n <= ~i_bin_val[11:6] self.rx_frame_asserted = True self.dut.rx_frame_in_p <= 1 self.dut.rx_frame_in_n <= 0 yield RisingEdge(self.dut.rx_clk_in_n) if self.rx_frame_asserted: self.dut.rx_data_in_p <= q_bin_val[11:6] self.dut.rx_data_in_n <= ~q_bin_val[11:6] else: self.dut.rx_data_in_p <= q_bin_val[5:0] self.dut.rx_data_in_n <= ~q_bin_val[5:0] else: I_SEND_HIGH = True Q_SEND_HIGH = True channel = 1 while True: yield RisingEdge(self.dut.rx_clk_in_p) if I_SEND_HIGH: self.dut.rx_data_in_p <= i_bin_val[11:6] self.dut.rx_data_in_n <= ~i_bin_val[11:6] I_SEND_HIGH = False if channel == 1: self.dut.rx_frame_in_p <= 1 self.dut.rx_frame_in_n <= 0 elif channel == 2: self.dut.rx_frame_in_p <= 0 self.dut.rx_frame_in_n <= 1 else: self.dut.rx_data_in_p <= i_bin_val[5:0] self.dut.rx_data_in_n <= ~i_bin_val[5:0] I_SEND_HIGH = True yield RisingEdge(self.dut.rx_clk_in_n) if Q_SEND_HIGH: self.dut.rx_data_in_p <= q_bin_val[5:0] self.dut.rx_data_in_n <= ~q_bin_val[5:0] Q_SEND_HIGH = False else: self.dut.rx_data_in_p <= q_bin_val[11:6] self.dut.rx_data_in_n <= ~q_bin_val[11:6] Q_SEND_HIGH = True if index < len(i_data): if channel == 1: i_bin_val.set_value(i_data[index]) q_bin_val.set_value(q_data[index]) channel = 2 elif channel == 2: i_bin_val.set_value(i_data2[index]) q_bin_val.set_value(q_data2[index]) channel = 1 index += 1 else: return
def rx_data_to_ad9361(self, i_data, q_data, i_data2=None, q_data2=None, binaryRepresentation=BinaryRepresentation.TWOS_COMPLEMENT): i_bin_val = BinaryValue(bits=12, bigEndian=False, binaryRepresentation=binaryRepresentation) q_bin_val = BinaryValue(bits=12, bigEndian=False, binaryRepresentation=binaryRepresentation) index = 0 if i_data2 is None and q_data2 is None: while True: yield RisingEdge(self.dut.rx_clk_in_p) if self.rx_frame_asserted: self.dut.rx_data_in_p <= i_bin_val[5:0] self.dut.rx_data_in_n <= ~i_bin_val[5:0] self.rx_frame_asserted = False self.dut.rx_frame_in_p <= 0 self.dut.rx_frame_in_n <= 1 else: if index < len(i_data): i_bin_val.set_value(i_data[index]) q_bin_val.set_value(q_data[index]) index += 1 else: return self.dut.rx_data_in_p <= i_bin_val[11:6] self.dut.rx_data_in_n <= ~i_bin_val[11:6] self.rx_frame_asserted = True self.dut.rx_frame_in_p <= 1 self.dut.rx_frame_in_n <= 0 yield RisingEdge(self.dut.rx_clk_in_n) if self.rx_frame_asserted: self.dut.rx_data_in_p <= q_bin_val[11:6] self.dut.rx_data_in_n <= ~q_bin_val[11:6] else: self.dut.rx_data_in_p <= q_bin_val[5:0] self.dut.rx_data_in_n <= ~q_bin_val[5:0] else: I_SEND_HIGH = True Q_SEND_HIGH = True channel = 1 while True: yield RisingEdge(self.dut.rx_clk_in_p) if I_SEND_HIGH: self.dut.rx_data_in_p <= i_bin_val[11:6] self.dut.rx_data_in_n <= ~i_bin_val[11:6] I_SEND_HIGH = False if channel == 1: self.dut.rx_frame_in_p <= 1 self.dut.rx_frame_in_n <= 0 elif channel == 2: self.dut.rx_frame_in_p <= 0 self.dut.rx_frame_in_n <= 1 else: self.dut.rx_data_in_p <= i_bin_val[5:0] self.dut.rx_data_in_n <= ~i_bin_val[5:0] I_SEND_HIGH = True yield RisingEdge(self.dut.rx_clk_in_n) if Q_SEND_HIGH: self.dut.rx_data_in_p <= q_bin_val[5:0] self.dut.rx_data_in_n <= ~q_bin_val[5:0] Q_SEND_HIGH = False else: self.dut.rx_data_in_p <= q_bin_val[11:6] self.dut.rx_data_in_n <= ~q_bin_val[11:6] Q_SEND_HIGH = True if index < len(i_data): if channel == 1: i_bin_val.set_value(i_data[index]) q_bin_val.set_value(q_data[index]) channel = 2 elif channel == 2: i_bin_val.set_value(i_data2[index]) q_bin_val.set_value(q_data2[index]) channel = 1 index += 1 else: return
def _getvalue(self): result = BinaryValue() result.binstr = simulator.get_signal_val_binstr(self._handle) return result
def _send_string(self, string, sync=True, channel=None): """Args: string (str): A string of bytes to send over the bus. channel (int): Channel to send the data on. """ # Avoid spurious object creation by recycling clkedge = RisingEdge(self.clock) firstword = True # FIXME busses that aren't integer numbers of bytes bus_width = int(len(self.bus.data) / 8) word = BinaryValue(n_bits=len(self.bus.data), bigEndian=self.config['firstSymbolInHighOrderBits']) single = BinaryValue(n_bits=1, bigEndian=False) if self.use_empty: empty = BinaryValue(n_bits=len(self.bus.empty), bigEndian=False) # Drive some defaults since we don't know what state we're in if self.use_empty: self.bus.empty <= 0 self.bus.startofpacket <= 0 self.bus.endofpacket <= 0 self.bus.valid <= 0 if hasattr(self.bus, 'error'): self.bus.error <= 0 if hasattr(self.bus, 'channel'): self.bus.channel <= 0 elif channel is not None: raise TestError("%s does not have a channel signal" % self.name) while string: if not firstword or (firstword and sync): yield clkedge # Insert a gap where valid is low if not self.on: self.bus.valid <= 0 for i in range(self.off): yield clkedge # Grab the next set of on/off values self._next_valids() # Consume a valid cycle if self.on is not True and self.on: self.on -= 1 self.bus.valid <= 1 if hasattr(self.bus, 'channel'): if channel is None: self.bus.channel <= 0 elif channel > self.config['maxChannel'] or channel < 0: raise TestError( "%s: Channel value %d is outside range 0-%d" % (self.name,channel,self.config['maxChannel'])) else: self.bus.channel <= channel if firstword: self.bus.startofpacket <= 1 firstword = False else: self.bus.startofpacket <= 0 nbytes = min(len(string), bus_width) data = string[:nbytes] word.buff = data if len(string) <= bus_width: self.bus.endofpacket <= 1 if self.use_empty: self.bus.empty <= bus_width - len(string) string = "" else: string = string[bus_width:] self.bus.data <= word # If this is a bus with a ready signal, wait for this word to # be acknowledged if hasattr(self.bus, "ready"): yield self._wait_ready() yield clkedge self.bus.valid <= 0 self.bus.endofpacket <= 0 word.binstr = ("x"*len(self.bus.data)) single.binstr = ("x") self.bus.data <= word self.bus.startofpacket <= single self.bus.endofpacket <= single if self.use_empty: empty.binstr = ("x"*len(self.bus.empty)) self.bus.empty <= empty if hasattr(self.bus, 'channel'): channel_value = BinaryValue(n_bits=len(self.bus.channel), bigEndian=False) channel_value.binstr = ("x"*len(self.bus.channel)) self.bus.channel <= channel_value
def getvalue(self): result = BinaryValue() result.binstr = self._get_value_str() return result
def _send_string(self, string, sync=True): """ Args: string (str): A string of bytes to send over the bus """ # Avoid spurious object creation by recycling clkedge = RisingEdge(self.clock) firstword = True # FIXME busses that aren't integer numbers of bytes bus_width = int(len(self.bus.data) / 8) word = BinaryValue(bits=len(self.bus.data), bigEndian=self.config['firstSymbolInHighOrderBits']) empty = BinaryValue(bits=len(self.bus.empty), bigEndian=False) single = BinaryValue(bits=1, bigEndian=False) # Drive some defaults since we don't know what state we're in # self.bus.empty <= 0 self.bus.startofpacket <= 0 self.bus.endofpacket <= 0 self.bus.valid <= 0 if hasattr(self.bus, 'error'): self.bus.error <= 0 while string: if not firstword or (firstword and sync): yield clkedge # Insert a gap where valid is low if not self.on: self.bus.valid <= 0 for i in range(self.off): yield clkedge # Grab the next set of on/off values self._next_valids() # Consume a valid cycle if self.on is not True and self.on: self.on -= 1 self.bus.valid <= 1 if firstword: #self.bus.empty <= 0 self.bus.startofpacket <= 1 firstword = False else: self.bus.startofpacket <= 0 nbytes = min(len(string), bus_width) data = string[:nbytes] word.buff = data if len(string) <= bus_width: self.bus.endofpacket <= 1 self.bus.empty <= bus_width - len(string) string = "" else: string = string[bus_width:] self.bus.data <= word # If this is a bus with a ready signal, wait for this word to # be acknowledged if hasattr(self.bus, "ready"): yield self._wait_ready() yield clkedge self.bus.valid <= 0 self.bus.endofpacket <= 0 word.binstr = ("x"*len(self.bus.data)) empty.binstr = ("x"*len(self.bus.empty)) single.binstr = ("x") self.bus.data <= word self.bus.empty <= empty self.bus.startofpacket <= single self.bus.endofpacket <= single