12 changed files with 616 additions and 940 deletions
			
			
		@ -1,300 +0,0 @@
				@@ -1,300 +0,0 @@
					 | 
				
			||||
import numpy as np | 
				
			||||
from . import popcount | 
				
			||||
from .logic import bit_in | 
				
			||||
 | 
				
			||||
 | 
				
			||||
class PackedVectors: | 
				
			||||
    def __init__(self, nvectors=8, width=1, vdim=1, from_cache=None): | 
				
			||||
        if from_cache is not None: | 
				
			||||
            self.bits = np.array(from_cache) | 
				
			||||
            self.width, self.vdim, nbytes = self.bits.shape | 
				
			||||
        else: | 
				
			||||
            self.bits = np.zeros((width, vdim, (nvectors - 1) // 8 + 1), dtype='uint8') | 
				
			||||
            self.vdim = vdim | 
				
			||||
            self.width = width | 
				
			||||
        self.nvectors = nvectors | 
				
			||||
        m1 = np.array([2 ** x for x in range(7, -1, -1)], dtype='uint8') | 
				
			||||
        m0 = ~m1 | 
				
			||||
        self.mask = np.rollaxis(np.vstack((m0, m1)), 1) | 
				
			||||
 | 
				
			||||
    @classmethod | 
				
			||||
    def from_pair(cls, init, final): | 
				
			||||
        assert init.nvectors == final.nvectors | 
				
			||||
        assert len(init.bits) == len(final.bits) | 
				
			||||
        init_v = init.bits[:, 0] | 
				
			||||
        if init.vdim == 3: | 
				
			||||
            init_c = (init.bits[:, 0] ^ init.bits[:, 1]) | init.bits[:, 2] | 
				
			||||
        elif init.vdim == 2: | 
				
			||||
            init_c = init.bits[:, 1] | 
				
			||||
        else: | 
				
			||||
            init_c = ~np.zeros_like(init.bits[:, 0]) | 
				
			||||
        final_v = final.bits[:, 0] | 
				
			||||
        if final.vdim == 3: | 
				
			||||
            final_c = (final.bits[:, 0] ^ final.bits[:, 1]) | final.bits[:, 2] | 
				
			||||
            final_v = ~final.bits[:, 1] | 
				
			||||
        elif final.vdim == 2: | 
				
			||||
            final_c = final.bits[:, 1] | 
				
			||||
        else: | 
				
			||||
            final_c = ~np.zeros_like(final.bits[:, 0]) | 
				
			||||
        c = init_c & final_c | 
				
			||||
        a0 = init_v & c | 
				
			||||
        a1 = ~final_v & c | 
				
			||||
        a2 = (init_v ^ final_v) & c | 
				
			||||
        p = PackedVectors(init.nvectors, len(init.bits), 3) | 
				
			||||
        p.bits[:, 0] = a0 | 
				
			||||
        p.bits[:, 1] = a1 | 
				
			||||
        p.bits[:, 2] = a2 | 
				
			||||
        return p | 
				
			||||
         | 
				
			||||
    def transition_vectors(self): | 
				
			||||
        a = PackedVectors(self.nvectors-1, self.width, 3) | 
				
			||||
        for pos in range(self.width): | 
				
			||||
            for vidx in range(self.nvectors-1): | 
				
			||||
                tr = self.get_value(vidx, pos) + self.get_value(vidx+1, pos) | 
				
			||||
                if tr == '00': | 
				
			||||
                    a.set_value(vidx, pos, '0') | 
				
			||||
                elif tr == '11': | 
				
			||||
                    a.set_value(vidx, pos, '1') | 
				
			||||
                elif tr == '01': | 
				
			||||
                    a.set_value(vidx, pos, 'R') | 
				
			||||
                elif tr == '10': | 
				
			||||
                    a.set_value(vidx, pos, 'F') | 
				
			||||
                elif tr == '--': | 
				
			||||
                    a.set_value(vidx, pos, '-') | 
				
			||||
                else: | 
				
			||||
                    a.set_value(vidx, pos, 'X') | 
				
			||||
        return a | 
				
			||||
         | 
				
			||||
    def __add__(self, other): | 
				
			||||
        a = PackedVectors(self.nvectors + other.nvectors, self.width, max(self.vdim, other.vdim)) | 
				
			||||
        # a.bits[:self.bits.shape[0], 0] = self.bits[:, 0] | 
				
			||||
        # if self.vdim == 2: | 
				
			||||
        #    a.bits[:self.bits.shape[0], 1] = self.care_bits | 
				
			||||
        # elif self.vdim == 3: | 
				
			||||
        #    a.bits[:self.bits.shape[0], 1] = ~self.value_bits | 
				
			||||
        #    a.bits[:self.bits.shape[0], 2] = self.toggle_bits | 
				
			||||
        for i in range(self.nvectors): | 
				
			||||
            a[i] = self[i] | 
				
			||||
        for i in range(len(other)): | 
				
			||||
            a[self.nvectors+i] = other[i] | 
				
			||||
        return a | 
				
			||||
 | 
				
			||||
    def __len__(self): | 
				
			||||
        return self.nvectors | 
				
			||||
     | 
				
			||||
    def randomize(self, one_probability=0.5): | 
				
			||||
        for data in self.bits: | 
				
			||||
            data[0] = np.packbits((np.random.rand(self.nvectors) < one_probability).astype(int)) | 
				
			||||
            if self.vdim == 2: | 
				
			||||
                data[1] = 255 | 
				
			||||
            elif self.vdim == 3: | 
				
			||||
                data[1] = ~np.packbits((np.random.rand(self.nvectors) < one_probability).astype(int)) | 
				
			||||
                data[2] = data[0] ^ ~data[1] | 
				
			||||
             | 
				
			||||
    def copy(self, selection_mask=None): | 
				
			||||
        if selection_mask is not None: | 
				
			||||
            cpy = PackedVectors(popcount(selection_mask), len(self.bits), self.vdim) | 
				
			||||
            cur = 0 | 
				
			||||
            for vidx in range(self.nvectors): | 
				
			||||
                if bit_in(selection_mask, vidx): | 
				
			||||
                    cpy[cur] = self[vidx] | 
				
			||||
                    cur += 1 | 
				
			||||
        else: | 
				
			||||
            cpy = PackedVectors(self.nvectors, len(self.bits), self.vdim) | 
				
			||||
            np.copyto(cpy.bits, self.bits) | 
				
			||||
        return cpy | 
				
			||||
 | 
				
			||||
    @property | 
				
			||||
    def care_bits(self): | 
				
			||||
        if self.vdim == 1: | 
				
			||||
            return self.bits[:, 0] | 255 | 
				
			||||
        elif self.vdim == 2: | 
				
			||||
            return self.bits[:, 1] | 
				
			||||
        elif self.vdim == 3: | 
				
			||||
            return (self.bits[:, 0] ^ self.bits[:, 1]) | self.bits[:, 2] | 
				
			||||
 | 
				
			||||
    @property | 
				
			||||
    def initial_bits(self): | 
				
			||||
        return self.bits[:, 0] | 
				
			||||
 | 
				
			||||
    @property | 
				
			||||
    def value_bits(self): | 
				
			||||
        if self.vdim == 3: | 
				
			||||
            return ~self.bits[:, 1] | 
				
			||||
        else: | 
				
			||||
            return self.bits[:, 0] | 
				
			||||
 | 
				
			||||
    @property | 
				
			||||
    def toggle_bits(self): | 
				
			||||
        if self.vdim == 3: | 
				
			||||
            return self.bits[:, 2] | 
				
			||||
        else: | 
				
			||||
            return self.bits[:, 0] & 0 | 
				
			||||
 | 
				
			||||
    def get_value(self, vector, position): | 
				
			||||
        if vector >= self.nvectors: | 
				
			||||
            raise IndexError(f'vector out of range: {vector} >= {self.nvectors}') | 
				
			||||
        a = self.bits[position, :, vector // 8] | 
				
			||||
        m = self.mask[vector % 8] | 
				
			||||
        if self.vdim == 1: | 
				
			||||
            return '1' if a[0] & m[1] else '0' | 
				
			||||
        elif self.vdim == 2: | 
				
			||||
            if a[0] & m[1]: | 
				
			||||
                return '1' if a[1] & m[1] else 'X' | 
				
			||||
            else: | 
				
			||||
                return '0' if a[1] & m[1] else '-' | 
				
			||||
        elif self.vdim == 3: | 
				
			||||
            if a[2] & m[1]: | 
				
			||||
                if a[0] & m[1]: | 
				
			||||
                    return 'F' if a[1] & m[1] else 'N' | 
				
			||||
                else: | 
				
			||||
                    return 'P' if a[1] & m[1] else 'R' | 
				
			||||
            else: | 
				
			||||
                if a[0] & m[1]: | 
				
			||||
                    return 'X' if a[1] & m[1] else '1' | 
				
			||||
                else: | 
				
			||||
                    return '0' if a[1] & m[1] else '-'                 | 
				
			||||
 | 
				
			||||
    def get_values_for_position(self, position): | 
				
			||||
        return ''.join(self.get_value(x, position) for x in range(self.nvectors)) | 
				
			||||
 | 
				
			||||
    def set_value(self, vector, position, v): | 
				
			||||
        if vector >= self.nvectors: | 
				
			||||
            raise IndexError(f'vector out of range: {vector} >= {self.nvectors}') | 
				
			||||
        a = self.bits[position, :, vector // 8] | 
				
			||||
        m = self.mask[vector % 8] | 
				
			||||
        if self.vdim == 1: | 
				
			||||
            self._set_value_vd1(a, m, v) | 
				
			||||
        elif self.vdim == 2: | 
				
			||||
            self._set_value_vd2(a, m, v) | 
				
			||||
        elif self.vdim == 3: | 
				
			||||
            self._set_value_vd3(a, m, v) | 
				
			||||
     | 
				
			||||
    def set_values(self, vector, v, mapping=None, inversions=None): | 
				
			||||
        if vector >= self.nvectors: | 
				
			||||
            raise IndexError(f'vector out of range: {vector} >= {self.nvectors}') | 
				
			||||
        if not mapping: | 
				
			||||
            mapping = [y for y in range(len(v))] | 
				
			||||
        if inversions is None: | 
				
			||||
            inversions = [False] * len(v) | 
				
			||||
        for i, c in enumerate(v): | 
				
			||||
            if inversions[i]: | 
				
			||||
                if c == '1': | 
				
			||||
                    c = '0' | 
				
			||||
                elif c == '0': | 
				
			||||
                    c = '1' | 
				
			||||
                elif c == 'H': | 
				
			||||
                    c = 'L' | 
				
			||||
                elif c == 'L': | 
				
			||||
                    c = 'H' | 
				
			||||
                elif c == 'R': | 
				
			||||
                    c = 'F' | 
				
			||||
                elif c == 'F': | 
				
			||||
                    c = 'R' | 
				
			||||
            self.set_value(vector, mapping[i], c) | 
				
			||||
     | 
				
			||||
    def set_values_for_position(self, position, values): | 
				
			||||
        for i, v in enumerate(values): | 
				
			||||
            self.set_value(i, position, v) | 
				
			||||
             | 
				
			||||
    def __setitem__(self, vector, value): | 
				
			||||
        for i, c in enumerate(value): | 
				
			||||
            self.set_value(vector, i, c) | 
				
			||||
 | 
				
			||||
    def __getitem__(self, vector): | 
				
			||||
        if isinstance(vector, slice): | 
				
			||||
            first = self.get_values_for_position(0)[vector] | 
				
			||||
            ret = PackedVectors(len(first), self.width, self.vdim) | 
				
			||||
            ret.set_values_for_position(0, first) | 
				
			||||
            for pos in range(1, self.width): | 
				
			||||
                ret.set_values_for_position(pos, self.get_values_for_position(pos)[vector]) | 
				
			||||
            return ret | 
				
			||||
        return ''.join(self.get_value(vector, pos) for pos in range(len(self.bits))) | 
				
			||||
 | 
				
			||||
    @staticmethod | 
				
			||||
    def _set_value_vd1(a, m, v): | 
				
			||||
        if v in [True, 1, '1', 'H', 'h']: | 
				
			||||
            a[0] |= m[1] | 
				
			||||
        else: | 
				
			||||
            a[0] &= m[0] | 
				
			||||
     | 
				
			||||
    @staticmethod | 
				
			||||
    def _set_value_vd2(a, m, v): | 
				
			||||
        if v in [True, 1, '1', 'H', 'h']: | 
				
			||||
            a[0] |= m[1] | 
				
			||||
            a[1] |= m[1] | 
				
			||||
        elif v in [False, 0, '0', 'L', 'l']: | 
				
			||||
            a[0] &= m[0] | 
				
			||||
            a[1] |= m[1] | 
				
			||||
        elif v in ['X', 'x']: | 
				
			||||
            a[0] |= m[1] | 
				
			||||
            a[1] &= m[0] | 
				
			||||
        else: | 
				
			||||
            a[0] &= m[0] | 
				
			||||
            a[1] &= m[0] | 
				
			||||
 | 
				
			||||
    #   i fb act | 
				
			||||
    # a 0 1 2 | 
				
			||||
    # - 0 0 0  None, '-' | 
				
			||||
    # 0 0 1 0  False, 0, '0', 'l', 'L' | 
				
			||||
    # 1 1 0 0  True, 1, '1', 'h', 'H' | 
				
			||||
    # X 1 1 0  'x', 'X' | 
				
			||||
    # / 0 0 1  '/', 'r', 'R' | 
				
			||||
    # ^ 0 1 1  '^', 'p', 'P' | 
				
			||||
    # v 1 0 1  'v', 'n', 'N' | 
				
			||||
    # \ 1 1 1  '\', 'f', 'F' | 
				
			||||
    @staticmethod | 
				
			||||
    def _set_value_vd3(a, m, v): | 
				
			||||
        if v in [False, 0, '0', 'L', 'l']: | 
				
			||||
            a[0] &= m[0] | 
				
			||||
            a[1] |= m[1] | 
				
			||||
            a[2] &= m[0] | 
				
			||||
        elif v in [True, 1, '1', 'H', 'h']: | 
				
			||||
            a[0] |= m[1] | 
				
			||||
            a[1] &= m[0] | 
				
			||||
            a[2] &= m[0] | 
				
			||||
        elif v in ['X', 'x']: | 
				
			||||
            a[0] |= m[1] | 
				
			||||
            a[1] |= m[1] | 
				
			||||
            a[2] &= m[0] | 
				
			||||
        elif v in ['/', 'r', 'R']: | 
				
			||||
            a[0] &= m[0] | 
				
			||||
            a[1] &= m[0] | 
				
			||||
            a[2] |= m[1] | 
				
			||||
        elif v in ['^', 'p', 'P']: | 
				
			||||
            a[0] &= m[0] | 
				
			||||
            a[1] |= m[1] | 
				
			||||
            a[2] |= m[1] | 
				
			||||
        elif v in ['v', 'n', 'N']: | 
				
			||||
            a[0] |= m[1] | 
				
			||||
            a[1] &= m[0] | 
				
			||||
            a[2] |= m[1] | 
				
			||||
        elif v in ['\\', 'f', 'F']: | 
				
			||||
            a[0] |= m[1] | 
				
			||||
            a[1] |= m[1] | 
				
			||||
            a[2] |= m[1] | 
				
			||||
        else: | 
				
			||||
            a[0] &= m[0] | 
				
			||||
            a[1] &= m[0] | 
				
			||||
            a[2] &= m[0] | 
				
			||||
                                     | 
				
			||||
    def __repr__(self): | 
				
			||||
        return f'<PackedVectors nvectors={self.nvectors}, width={self.width}, vdim={self.vdim}>' | 
				
			||||
 | 
				
			||||
    def __str__(self): | 
				
			||||
        lst = [] | 
				
			||||
        for p in range(self.nvectors): | 
				
			||||
            lst.append(''.join(self.get_value(p, w) for w in range(len(self.bits)))) | 
				
			||||
        if len(lst) == 0: return '' | 
				
			||||
        if len(lst[0]) > 64: | 
				
			||||
            lst = [s[:32] + '...' + s[-32:] for s in lst] | 
				
			||||
        if len(lst) <= 16: | 
				
			||||
            return '\n'.join(lst) | 
				
			||||
        else: | 
				
			||||
            return '\n'.join(lst[:8]) + '\n...\n' + '\n'.join(lst[-8:]) | 
				
			||||
             | 
				
			||||
    def diff(self, other, out=None): | 
				
			||||
        if out is None: | 
				
			||||
            out = np.zeros((self.width, self.bits.shape[-1]), dtype='uint8') | 
				
			||||
        out[...] = (self.value_bits ^ other.value_bits) & self.care_bits & other.care_bits | 
				
			||||
        return out | 
				
			||||
@ -1,161 +1,96 @@
				@@ -1,161 +1,96 @@
					 | 
				
			||||
from kyupy.logic_sim import LogicSim | 
				
			||||
from kyupy import bench | 
				
			||||
from kyupy.packed_vectors import PackedVectors | 
				
			||||
from kyupy.logic import MVArray, BPArray | 
				
			||||
 | 
				
			||||
 | 
				
			||||
def test_vd1(): | 
				
			||||
def test_2v(): | 
				
			||||
    c = bench.parse('input(x, y) output(a, o, n) a=and(x,y) o=or(x,y) n=not(x)') | 
				
			||||
    s = LogicSim(c, 4) | 
				
			||||
    s = LogicSim(c, 4, m=2) | 
				
			||||
    assert len(s.interface) == 5 | 
				
			||||
    p = PackedVectors(4, len(s.interface)) | 
				
			||||
    p[0] = '00000' | 
				
			||||
    p[1] = '01000' | 
				
			||||
    p[2] = '10000' | 
				
			||||
    p[3] = '11000' | 
				
			||||
    s.assign(p) | 
				
			||||
    mva = MVArray(['00000', '01000', '10000', '11000'], m=2) | 
				
			||||
    bpa = BPArray(mva) | 
				
			||||
    s.assign(bpa) | 
				
			||||
    s.propagate() | 
				
			||||
    s.capture(p) | 
				
			||||
    assert p[0] == '00001' | 
				
			||||
    assert p[1] == '01011' | 
				
			||||
    assert p[2] == '10010' | 
				
			||||
    assert p[3] == '11110' | 
				
			||||
    s.capture(bpa) | 
				
			||||
    mva = MVArray(bpa) | 
				
			||||
    assert mva[0] == '00001' | 
				
			||||
    assert mva[1] == '01011' | 
				
			||||
    assert mva[2] == '10010' | 
				
			||||
    assert mva[3] == '11110' | 
				
			||||
 | 
				
			||||
 | 
				
			||||
def test_vd2(): | 
				
			||||
def test_4v(): | 
				
			||||
    c = bench.parse('input(x, y) output(a, o, n) a=and(x,y) o=or(x,y) n=not(x)') | 
				
			||||
    s = LogicSim(c, 16, 2) | 
				
			||||
    s = LogicSim(c, 16, m=4) | 
				
			||||
    assert len(s.interface) == 5 | 
				
			||||
    p = PackedVectors(16, len(s.interface), 2) | 
				
			||||
    p[0] = '00000' | 
				
			||||
    p[1] = '01000' | 
				
			||||
    p[2] = '0-000' | 
				
			||||
    p[3] = '0X000' | 
				
			||||
    p[4] = '10000' | 
				
			||||
    p[5] = '11000' | 
				
			||||
    p[6] = '1-000' | 
				
			||||
    p[7] = '1X000' | 
				
			||||
    p[8] = '-0000' | 
				
			||||
    p[9] = '-1000' | 
				
			||||
    p[10] = '--000' | 
				
			||||
    p[11] = '-X000' | 
				
			||||
    p[12] = 'X0000' | 
				
			||||
    p[13] = 'X1000' | 
				
			||||
    p[14] = 'X-000' | 
				
			||||
    p[15] = 'XX000' | 
				
			||||
    s.assign(p) | 
				
			||||
    mva = MVArray(['00000', '01000', '0-000', '0X000', | 
				
			||||
                   '10000', '11000', '1-000', '1X000', | 
				
			||||
                   '-0000', '-1000', '--000', '-X000', | 
				
			||||
                   'X0000', 'X1000', 'X-000', 'XX000'], m=4) | 
				
			||||
    bpa = BPArray(mva) | 
				
			||||
    s.assign(bpa) | 
				
			||||
    s.propagate() | 
				
			||||
    s.capture(p) | 
				
			||||
    assert p[0] == '00001' | 
				
			||||
    assert p[1] == '01011' | 
				
			||||
    assert p[2] == '0-0X1' | 
				
			||||
    assert p[3] == '0X0X1' | 
				
			||||
    assert p[4] == '10010' | 
				
			||||
    assert p[5] == '11110' | 
				
			||||
    assert p[6] == '1-X10' | 
				
			||||
    assert p[7] == '1XX10' | 
				
			||||
    assert p[8] == '-00XX' | 
				
			||||
    assert p[9] == '-1X1X' | 
				
			||||
    assert p[10] == '--XXX' | 
				
			||||
    assert p[11] == '-XXXX' | 
				
			||||
    assert p[12] == 'X00XX' | 
				
			||||
    assert p[13] == 'X1X1X' | 
				
			||||
    assert p[14] == 'X-XXX' | 
				
			||||
    assert p[15] == 'XXXXX' | 
				
			||||
    s.capture(bpa) | 
				
			||||
    mva = MVArray(bpa) | 
				
			||||
    assert mva[0] == '00001' | 
				
			||||
    assert mva[1] == '01011' | 
				
			||||
    assert mva[2] == '0-0X1' | 
				
			||||
    assert mva[3] == '0X0X1' | 
				
			||||
    assert mva[4] == '10010' | 
				
			||||
    assert mva[5] == '11110' | 
				
			||||
    assert mva[6] == '1-X10' | 
				
			||||
    assert mva[7] == '1XX10' | 
				
			||||
    assert mva[8] == '-00XX' | 
				
			||||
    assert mva[9] == '-1X1X' | 
				
			||||
    assert mva[10] == '--XXX' | 
				
			||||
    assert mva[11] == '-XXXX' | 
				
			||||
    assert mva[12] == 'X00XX' | 
				
			||||
    assert mva[13] == 'X1X1X' | 
				
			||||
    assert mva[14] == 'X-XXX' | 
				
			||||
    assert mva[15] == 'XXXXX' | 
				
			||||
 | 
				
			||||
     | 
				
			||||
def test_vd3(): | 
				
			||||
def test_8v(): | 
				
			||||
    c = bench.parse('input(x, y) output(a, o, n, xo) a=and(x,y) o=or(x,y) n=not(x) xo=xor(x,y)') | 
				
			||||
    s = LogicSim(c, 64, 3) | 
				
			||||
    s = LogicSim(c, 64, m=8) | 
				
			||||
    assert len(s.interface) == 6 | 
				
			||||
    p = PackedVectors(64, len(s.interface), 3) | 
				
			||||
    p[0] = '000010' | 
				
			||||
    p[1] = '010111' | 
				
			||||
    p[2] = '0-0X1X' | 
				
			||||
    p[3] = '0X0X1X' | 
				
			||||
    p[4] = '0R0R1R' | 
				
			||||
    p[5] = '0F0F1F' | 
				
			||||
    p[6] = '0P0P1P' | 
				
			||||
    p[7] = '0N0N1N' | 
				
			||||
    p[8] = '100101' | 
				
			||||
    p[9] = '111100' | 
				
			||||
    p[10] = '1-X10X' | 
				
			||||
    p[11] = '1XX10X' | 
				
			||||
    p[12] = '1RR10F' | 
				
			||||
    p[13] = '1FF10R' | 
				
			||||
    p[14] = '1PP10N' | 
				
			||||
    p[15] = '1NN10P' | 
				
			||||
    p[16] = '-00XXX' | 
				
			||||
    p[17] = '-1X1XX' | 
				
			||||
    p[18] = '--XXXX' | 
				
			||||
    p[19] = '-XXXXX' | 
				
			||||
    p[20] = '-RXXXX' | 
				
			||||
    p[21] = '-FXXXX' | 
				
			||||
    p[22] = '-PXXXX' | 
				
			||||
    p[23] = '-NXXXX' | 
				
			||||
    p[24] = 'X00XXX' | 
				
			||||
    p[25] = 'X1X1XX' | 
				
			||||
    p[26] = 'X-XXXX' | 
				
			||||
    p[27] = 'XXXXXX' | 
				
			||||
    p[28] = 'XRXXXX' | 
				
			||||
    p[29] = 'XFXXXX' | 
				
			||||
    p[30] = 'XPXXXX' | 
				
			||||
    p[31] = 'XNXXXX' | 
				
			||||
    p[32] = 'R00RFR' | 
				
			||||
    p[33] = 'R1R1FF' | 
				
			||||
    p[34] = 'R-XXFX' | 
				
			||||
    p[35] = 'RXXXFX' | 
				
			||||
    p[36] = 'RRRRFP' | 
				
			||||
    p[37] = 'RFPNFN' | 
				
			||||
    p[38] = 'RPPRFR' | 
				
			||||
    p[39] = 'RNRNFF' | 
				
			||||
    p[40] = 'F00FRF' | 
				
			||||
    p[41] = 'F1F1RR' | 
				
			||||
    p[42] = 'F-XXRX' | 
				
			||||
    p[43] = 'FXXXRX' | 
				
			||||
    p[44] = 'FRPNRN' | 
				
			||||
    p[45] = 'FFFFRP' | 
				
			||||
    p[46] = 'FPPFRF' | 
				
			||||
    p[47] = 'FNFNRR' | 
				
			||||
    p[48] = 'P00PNP' | 
				
			||||
    p[49] = 'P1P1NN' | 
				
			||||
    p[50] = 'P-XXNX' | 
				
			||||
    p[51] = 'PXXXNX' | 
				
			||||
    p[52] = 'PRPRNR' | 
				
			||||
    p[53] = 'PFPFNF' | 
				
			||||
    p[54] = 'PPPPNP' | 
				
			||||
    p[55] = 'PNPNNN' | 
				
			||||
    p[56] = 'N00NPN' | 
				
			||||
    p[57] = 'N1N1PP' | 
				
			||||
    p[58] = 'N-XXPX' | 
				
			||||
    p[59] = 'NXXXPX' | 
				
			||||
    p[60] = 'NRRNPF' | 
				
			||||
    p[61] = 'NFFNPR' | 
				
			||||
    p[62] = 'NPPNPN' | 
				
			||||
    p[63] = 'NNNNPP' | 
				
			||||
    expect = p.copy() | 
				
			||||
    s.assign(p) | 
				
			||||
    mva = MVArray(['000010', '010111', '0-0X1X', '0X0X1X', '0R0R1R', '0F0F1F', '0P0P1P', '0N0N1N', | 
				
			||||
                   '100101', '111100', '1-X10X', '1XX10X', '1RR10F', '1FF10R', '1PP10N', '1NN10P', | 
				
			||||
                   '-00XXX', '-1X1XX', '--XXXX', '-XXXXX', '-RXXXX', '-FXXXX', '-PXXXX', '-NXXXX', | 
				
			||||
                   'X00XXX', 'X1X1XX', 'X-XXXX', 'XXXXXX', 'XRXXXX', 'XFXXXX', 'XPXXXX', 'XNXXXX', | 
				
			||||
                   'R00RFR', 'R1R1FF', 'R-XXFX', 'RXXXFX', 'RRRRFP', 'RFPNFN', 'RPPRFR', 'RNRNFF', | 
				
			||||
                   'F00FRF', 'F1F1RR', 'F-XXRX', 'FXXXRX', 'FRPNRN', 'FFFFRP', 'FPPFRF', 'FNFNRR', | 
				
			||||
                   'P00PNP', 'P1P1NN', 'P-XXNX', 'PXXXNX', 'PRPRNR', 'PFPFNF', 'PPPPNP', 'PNPNNN', | 
				
			||||
                   'N00NPN', 'N1N1PP', 'N-XXPX', 'NXXXPX', 'NRRNPF', 'NFFNPR', 'NPPNPN', 'NNNNPP'], m=8) | 
				
			||||
    bpa = BPArray(mva) | 
				
			||||
    s.assign(bpa) | 
				
			||||
    s.propagate() | 
				
			||||
    s.capture(p) | 
				
			||||
    resp_bp = BPArray(bpa) | 
				
			||||
    s.capture(resp_bp) | 
				
			||||
    resp = MVArray(resp_bp) | 
				
			||||
 | 
				
			||||
    for i in range(64): | 
				
			||||
        assert p[i] == expect[i] | 
				
			||||
        assert resp[i] == mva[i] | 
				
			||||
         | 
				
			||||
 | 
				
			||||
def test_b01(mydir): | 
				
			||||
    c = bench.load(mydir / 'b01.bench') | 
				
			||||
 | 
				
			||||
    # 2-valued | 
				
			||||
    s = LogicSim(c, 8) | 
				
			||||
    s = LogicSim(c, 8, m=2) | 
				
			||||
    assert len(s.interface) == 9 | 
				
			||||
    t = PackedVectors(8, len(s.interface)) | 
				
			||||
    t.randomize() | 
				
			||||
    s.assign(t) | 
				
			||||
    mva = MVArray((len(s.interface), 8), m=2) | 
				
			||||
    # mva.randomize() | 
				
			||||
    bpa = BPArray(mva) | 
				
			||||
    s.assign(bpa) | 
				
			||||
    s.propagate() | 
				
			||||
    s.capture(t) | 
				
			||||
    s.capture(bpa) | 
				
			||||
 | 
				
			||||
    # 8-valued | 
				
			||||
    s = LogicSim(c, 8, 3) | 
				
			||||
    t = PackedVectors(8, len(s.interface), 3) | 
				
			||||
    t.randomize() | 
				
			||||
    s.assign(t) | 
				
			||||
    s = LogicSim(c, 8, m=8) | 
				
			||||
    mva = MVArray((len(s.interface), 8), m=8) | 
				
			||||
    # mva.randomize() | 
				
			||||
    bpa = BPArray(mva) | 
				
			||||
    s.assign(bpa) | 
				
			||||
    s.propagate() | 
				
			||||
    s.capture(t) | 
				
			||||
    s.capture(bpa) | 
				
			||||
				 
					 | 
				
			||||
@ -1,88 +0,0 @@
				@@ -1,88 +0,0 @@
					 | 
				
			||||
from kyupy.packed_vectors import PackedVectors | 
				
			||||
 | 
				
			||||
 | 
				
			||||
def test_basic(): | 
				
			||||
    ba = PackedVectors(8, 1, 1) | 
				
			||||
    assert '0\n0\n0\n0\n0\n0\n0\n0' == str(ba) | 
				
			||||
    ba.set_value(0, 0, 1) | 
				
			||||
    ba.set_value(1, 0, 'H') | 
				
			||||
    ba.set_value(2, 0, 'h') | 
				
			||||
    ba.set_value(3, 0, True) | 
				
			||||
    ba.set_value(4, 0, 0) | 
				
			||||
    ba.set_value(5, 0, 'L') | 
				
			||||
    ba.set_value(6, 0, 'l') | 
				
			||||
    ba.set_value(7, 0, False) | 
				
			||||
    assert '1\n1\n1\n1\n0\n0\n0\n0' == str(ba) | 
				
			||||
    ba.set_value(1, 0, '0') | 
				
			||||
    ba.set_value(5, 0, '1') | 
				
			||||
    assert '1\n0\n1\n1\n0\n1\n0\n0' == str(ba) | 
				
			||||
    ba = PackedVectors(8, 1, 2) | 
				
			||||
    assert '-\n-\n-\n-\n-\n-\n-\n-' == str(ba) | 
				
			||||
    ba.set_value(0, 0, 1) | 
				
			||||
    ba.set_value(7, 0, 0) | 
				
			||||
    ba.set_value(4, 0, 'X') | 
				
			||||
    assert '1\n-\n-\n-\nX\n-\n-\n0' == str(ba) | 
				
			||||
    ba.set_value(4, 0, '-') | 
				
			||||
    assert '1\n-\n-\n-\n-\n-\n-\n0' == str(ba) | 
				
			||||
    ba = PackedVectors(8, 2, 2) | 
				
			||||
    assert '--\n--\n--\n--\n--\n--\n--\n--' == str(ba) | 
				
			||||
    ba.set_value(0, 0, '1') | 
				
			||||
    ba.set_value(7, 1, '0') | 
				
			||||
    ba.set_values(1, 'XX') | 
				
			||||
    assert '1-\nXX\n--\n--\n--\n--\n--\n-0' == str(ba) | 
				
			||||
 | 
				
			||||
 | 
				
			||||
def test_8v(): | 
				
			||||
    ba = PackedVectors(1, 8, 3) | 
				
			||||
    assert '--------' == str(ba) | 
				
			||||
    ba.set_values(0, r'-x01^v\/') | 
				
			||||
    assert r'-X01PNFR' == str(ba) | 
				
			||||
    ba.set_values(0, '-XLHPNFR') | 
				
			||||
    assert r'-X01PNFR' == str(ba) | 
				
			||||
    ba.set_values(0, '-xlhpnfr') | 
				
			||||
    assert r'-X01PNFR' == str(ba) | 
				
			||||
    p1 = PackedVectors(1, 8, 1) | 
				
			||||
    p2 = PackedVectors(1, 8, 1) | 
				
			||||
    p1.set_values(0, '01010101') | 
				
			||||
    p2.set_values(0, '00110011') | 
				
			||||
    p = PackedVectors.from_pair(p1, p2) | 
				
			||||
    assert r'0FR10FR1' == str(p) | 
				
			||||
    p1 = PackedVectors(1, 8, 2) | 
				
			||||
    p2 = PackedVectors(1, 8, 2) | 
				
			||||
    p1.set_values(0, '0101-X-X') | 
				
			||||
    p2.set_values(0, '00110011') | 
				
			||||
    p = PackedVectors.from_pair(p1, p2) | 
				
			||||
    assert r'0FR1----' == str(p) | 
				
			||||
    p1.set_values(0, '0101-X-X') | 
				
			||||
    p2.set_values(0, '-X-X--XX') | 
				
			||||
    p = PackedVectors.from_pair(p1, p2) | 
				
			||||
    assert r'--------' == str(p) | 
				
			||||
 | 
				
			||||
 | 
				
			||||
def test_slicing(): | 
				
			||||
    lv = PackedVectors(3, 2, 1) | 
				
			||||
    assert '00\n00\n00' == str(lv) | 
				
			||||
    lv.set_value(1, 0, '1') | 
				
			||||
    lv.set_value(1, 1, '1') | 
				
			||||
    assert '00' == lv[0] | 
				
			||||
    assert '11' == lv[1] | 
				
			||||
    assert 3 == len(lv) | 
				
			||||
    lv2 = lv[1:3] | 
				
			||||
    assert 2 == len(lv2) | 
				
			||||
    assert '11' == lv2[0] | 
				
			||||
    assert '00' == lv2[1] | 
				
			||||
 | 
				
			||||
 | 
				
			||||
def test_copy(): | 
				
			||||
    lv1 = PackedVectors(8, 1, 1) | 
				
			||||
    lv1.set_values_for_position(0, '01010101') | 
				
			||||
    lv2 = PackedVectors(8, 1, 1) | 
				
			||||
    lv2.set_values_for_position(0, '00100101') | 
				
			||||
    diff = lv1.diff(lv2) | 
				
			||||
    lv3 = lv1.copy(selection_mask=diff) | 
				
			||||
    assert str(lv3) == '1\n0\n1' | 
				
			||||
    lv4 = lv1.copy(selection_mask=~diff) | 
				
			||||
    assert str(lv4) == '0\n0\n1\n0\n1' | 
				
			||||
    lv5 = lv3 + lv4 | 
				
			||||
    assert str(lv5) == '1\n0\n1\n0\n0\n1\n0\n1' | 
				
			||||
 | 
				
			||||
					Loading…
					
					
				
		Reference in new issue