def connect_bits2bitstruct(signal1, signal2): type1 = signal1.get_type() type2 = signal2.get_type() if is_bitstruct_class(type1): assert issubclass( type2, Bits ), \ f'Connecting {type1.__qualname__} to {type2.__qualname__}: ' \ f'{type1.__qualname__} is a bitstruct ' \ f'but {type2.__qualname__} is not a Bits type!' bits_signal, bitstruct_signal = signal2, signal1 elif is_bitstruct_class(type2): assert issubclass( type1, Bits ), \ f'Connecting {type1.__qualname__} to {type2.__qualname__}: ' \ f'{type2.__qualname__} is a bitstruct ' \ f'but {type1.__qualname__} is not a Bits type!' bits_signal, bitstruct_signal = signal1, signal2 else: assert False, 'Can only connect a bitstruct wire to bits wire' bw1 = get_nbits(type1) bw2 = get_nbits(type2) assert bw1 == bw2, 'Bitwidth mismatch! ' \ f'{type1.__qualname__} is {bw1}-bit ' \ f'but {type2.__qualname__} is {bw2}-bit.' # Connect field to corresponding slice stop = _connect_bits2bitstruct_h(bitstruct_signal, bits_signal, 0) assert stop == bw1, 'Sanity check failed! Might be a bug. ' \ 'Please create a Github issue.'
def connect_bitstruct(signal1, signal2): type1 = signal1._dsl.Type type2 = signal2._dsl.Type if is_bitstruct_class(type1): assert issubclass(type2, Bits) bits_signal, bitstruct_signal = signal2, signal1 elif is_bitstruct_class(type2): assert issubclass(type1, Bits) bits_signal, bitstruct_signal = signal1, signal2 else: assert False, "Can only connect a bitstruct wire to bits wire" # Connect field to corresponding slice _connect_bitstruct_h(bitstruct_signal, bits_signal, [])
def get_field_type( cls, field_name ): assert is_bitstruct_class( cls ) fields_dict = getattr( cls, bitstruct_fields ) if not field_name in fields_dict: raise AssertionError( f'{cls.__qualname__} does not have field {field_name}!' ) return fields_dict[ field_name ]
def _bitstruct_to_slices_h(cls, slices): if issubclass(cls, Bits): start = 0 if not slices else slices[-1].stop stop = start + cls.nbits slices.append(slice(start, stop)) else: assert is_bitstruct_class(cls) fields_dict = getattr(cls, bitstruct_fields) fields_lst = list(fields_dict.items()) # Use reverse instead of [::-1] because it is faster fields_lst.reverse() for _, ftype in fields_lst: _bitstruct_to_slices_h(ftype, slices)
def _connect_bitstruct_h(field, bits_signal, slices): field_type = field._dsl.Type if issubclass(field_type, Bits): start = 0 if not slices else slices[-1].stop stop = start + field_type.nbits cur_slice = slice(start, stop) slices.append(cur_slice) connect(field, bits_signal[cur_slice]) else: assert is_bitstruct_class(field_type) fields_dict = getattr(field_type, bitstruct_fields) fields_lst = list(fields_dict.items()) # Use reverse instead of [::-1] because it is faster fields_lst.reverse() for fname, _ in fields_lst: subfield = getattr(field, fname) _connect_bitstruct_h(subfield, bits_signal, slices)
def has_field(cls, field_name): assert is_bitstruct_class(cls) fields_dict = getattr(cls, bitstruct_fields) return field_name in fields_dict