Ejemplo n.º 1
0
def patches_generator(bases, signatures, target_vector, target):
    patches = []

    # тривиальные случаи
    if target_vector == 'x' * len(target_vector):
        patch = sc.scheme_alt()
        patch.__outputs__ = [target]
        patch.__elements__[target] = ('GND', [])
        patches.append(patch)
        patch = sc.scheme_alt()
        patch.__outputs__ = [target]
        patch.__elements__[target] = ('VCC', [])
        patches.append(patch)
        return patches

    for basis in bases:
        # ищем таблицу истинности
        tt_dnf = u.form_tt(signatures, basis, target_vector, 'dnf')
        tt_cnf = u.form_tt(signatures, basis, target_vector, 'cnf')

        # генерируем патч для текущего таргета
        _, patch_dnf = rw.gen_patch_with_abc((basis, tt_dnf[0]), target, 'dnf')
        _, patch_cnf = rw.gen_patch_with_abc((basis, tt_cnf[0]), target, 'cnf')
        patches.append(patch_dnf)
        patches.append(patch_cnf)
    return patches
Ejemplo n.º 2
0
def create_subpart_for_outputs_v2(scheme, etalon, weights, all_tgts,
                                  needed_tgts, needed_outputs):
    from scheme import scheme_alt

    # Go for output cone and copy everything (etalon)
    new_ckt = scheme_alt()
    copy_list = needed_outputs.copy()
    new_ckt.__outputs__ = needed_outputs.copy()
    while len(copy_list) > 0:
        for c in copy_list.copy():
            if c in etalon.__elements__:
                if c not in new_ckt.__elements__:
                    new_ckt.__elements__[c] = copy.deepcopy(
                        etalon.__elements__[c])
                    copy_list += etalon.__elements__[c][1]
            elif c in etalon.__inputs__:
                if c not in new_ckt.__inputs__:
                    new_ckt.__inputs__.append(c)
            copy_list.remove(c)
    new_ckt.__inputs__ = sorted(new_ckt.__inputs__)
    new_etalon = copy.deepcopy(new_ckt)

    # Go for all valid inputs (scheme)
    new_ckt = scheme_alt()
    list_of_vdd_gnd_nodes = get_vdd_gnd_nodes(scheme)
    copy_list = u.cone_to_outs_v2(
        scheme,
        list(list_of_vdd_gnd_nodes) + list(new_etalon.__inputs__) +
        list(needed_tgts))
    for c in sorted(copy_list):
        if c in scheme.__elements__:
            if c not in new_ckt.__elements__:
                new_ckt.__elements__[c] = copy.deepcopy(scheme.__elements__[c])
    new_ckt.__outputs__ = needed_outputs.copy()
    new_ckt.__inputs__ = new_etalon.__inputs__.copy()
    # Set VCC on all non-input leaves
    for c in new_ckt.__elements__.copy():
        for el in new_ckt.__elements__[c][1]:
            if el not in new_ckt.__elements__:
                if el not in new_ckt.__inputs__ and el not in needed_tgts:
                    print(el, 'VCC')
                    new_ckt.__elements__[el] = ('VCC', [])
    new_scheme = copy.deepcopy(new_ckt)

    print('Elements reduction: {} from {}'.format(len(new_scheme.__elements__),
                                                  len(scheme.__elements__)))

    new_weights = dict()
    for el in weights:
        if el in new_ckt.__elements__ or el in new_ckt.__inputs__:
            new_weights[el] = weights[el]

    return new_scheme, new_etalon, new_weights
def createTMRCirc(ckt):
    out = sa.scheme_alt()
    out.__inputs__ = ckt.__inputs__
    out.__outputs__ = ckt.__outputs__

    # Делаем 3 копии схемы
    for copy in range(1,4):
        for el in ckt.__elements__:
            el1 = "{}_COPY_{}".format(el, copy)
            data = ckt.__elements__[el]
            eltype = data[0]
            lst = []
            for d in data[1]:
                if d not in ckt.__inputs__:
                    lst.append("{}_COPY_{}".format(d, copy))
                else:
                    lst.append(d)

            out.__elements__[el1] = (eltype, lst)

    # Элемент голосования на каждом выходе
    for o in ckt.__outputs__:
        out.__elements__["{}_AND1".format(o)] = ('AND', ["{}_COPY_1".format(o), "{}_COPY_2".format(o)])
        out.__elements__["{}_AND2".format(o)] = ('AND', ["{}_COPY_2".format(o), "{}_COPY_3".format(o)])
        out.__elements__["{}_AND3".format(o)] = ('AND', ["{}_COPY_1".format(o), "{}_COPY_3".format(o)])
        out.__elements__["{}_OR1".format(o)] = ('OR', ["{}_AND1".format(o), "{}_AND2".format(o)])
        out.__elements__[o] = ('OR', ["{}_AND3".format(o), "{}_OR1".format(o)])

    return out
Ejemplo n.º 4
0
def create_ft_analog_inv(inputs, outputs, k):
    # Функция генерации сбоеустойчивого аналога ЛЭ INV
    inv = '_{}_'

    ft_inv = sch.scheme_alt()
    ft_inv.__inputs__ = inputs
    ft_inv.__outputs__ = outputs

    ft_inv.__elements__ = {
        inv.format(k + 1): ('OR', [inputs[0], inputs[1]]),
        inv.format(k + 2): ('NAND', [inputs[0], inputs[1]]),
        inv.format(k + 3): ('NAND', [inv.format(k + 1), inputs[2]]),
        outputs[0]: ('AND', [inv.format(k + 2),
                             inv.format(k + 3)]),
        inv.format(k + 4): ('OR', [inputs[0], inputs[1]]),
        inv.format(k + 5): ('NAND', [inputs[0], inputs[1]]),
        inv.format(k + 6): ('NAND', [inv.format(k + 4), inputs[2]]),
        outputs[1]: ('AND', [inv.format(k + 5),
                             inv.format(k + 6)]),
        inv.format(k + 7): ('OR', [inputs[0], inputs[1]]),
        inv.format(k + 8): ('NAND', [inputs[0], inputs[1]]),
        inv.format(k + 9): ('NAND', [inv.format(k + 7), inputs[2]]),
        outputs[2]: ('AND', [inv.format(k + 8),
                             inv.format(k + 9)])
    }

    k += 9

    return ft_inv, k
Ejemplo n.º 5
0
def create_output_transducer(scheme_1, scheme_2, k):
    # Функция генерации входного преобразователя и добавления его в СФК на основе кодирования в трехбитном пространстве
    # Хэмминга
    # scheme_1 - основная комбинационная схема
    # scheme_2 - СФК на основе кодирования в трехбитном пространстве Хэмминга без выходных преобразователей

    # Создание словаря соединений
    con = dict()

    # Создание пустой подсхемы выходного преобразователя out_transducer
    out_transducer = sch.scheme_alt()

    # Генерация входов выходного преобразователя out_transducer
    out_transducer.__inputs__ = [
        '_{}_'.format(k), '_{}_'.format(k + 1), '_{}_'.format(k + 2)
    ]

    # Генерация выхода выходного преобразователя out_transducer
    out_transducer.__outputs__ = ['y']

    # Генерация элементов выходного преобразователя out_transducer
    out_transducer.__elements__ = {
        '_{}_'.format(k + 4): ('OR', ['_{}_'.format(k), '_{}_'.format(k + 1)]),
        '_{}_'.format(k + 5):
        ('NAND', ['_{}_'.format(k), '_{}_'.format(k + 1)]),
        '_{}_'.format(k + 6):
        ('NAND', ['_{}_'.format(k + 4), '_{}_'.format(k + 2)]),
        'y': ('NAND', ['_{}_'.format(k + 5), '_{}_'.format(k + 6)])
    }

    # Копирование выходных преобразователей out_transducer по числу выходов основной схемы
    out_transducer = sch.merge_schemes([out_transducer] *
                                       int(scheme_2.outputs() / 3))

    # Генерация словаря соединений
    for i in range(scheme_1.outputs()):
        con[(0, scheme_2.__outputs__[i])] = ([
            (1, out_transducer.__inputs__[3 * i])
        ])
        con[(0, scheme_2.__outputs__[scheme_1.outputs() + i])] = ([
            (1, out_transducer.__inputs__[3 * i + 1])
        ])
        con[(0, scheme_2.__outputs__[2 * scheme_1.outputs() + i])] = ([
            (1, out_transducer.__inputs__[3 * i + 2])
        ])

    # Генерация выходов объединенной схемы
    out = [(1, i) for i in out_transducer.__outputs__]

    # Объединение СФК и выходного преобразователя out_transducer
    scheme_2 = sch.merge_schemes([scheme_2, out_transducer], con, out)

    # Приведение выхода результирующей схемы к общему виду
    del scheme_2.__elements__['y']
    scheme_2.__elements__['y_0'] = ('NAND', [
        '_{}_'.format(k + 5), '_{}_'.format(k + 6)
    ])
    scheme_2.__outputs__[0] = 'y_0'

    return scheme_2
Ejemplo n.º 6
0
def patch_circuit(scheme, patch):
    renamed_patch = sc.scheme_alt()
    renamed_patch.__inputs__ = copy.deepcopy(patch.__inputs__)
    renamed_patch.__outputs__ = copy.deepcopy(patch.__outputs__)
    postfix = '_' + '_'.join(patch.__outputs__)
    for elem in patch.__elements__:
        if elem in patch.__outputs__:
            element = elem
        else:
            element = elem + postfix

        type = patch.__elements__[elem][0]
        ports = []
        for port in patch.__elements__[elem][1]:
            if port in patch.__inputs__:
                ports.append(port)
            elif port in patch.__outputs__:
                ports.append(port)
            else:
                ports.append(port + postfix)
        renamed_patch.__elements__[element] = (type, ports)
    patched = copy.deepcopy(scheme)
    for gate in renamed_patch.__elements__:
        patched.__elements__[gate] = renamed_patch.__elements__[gate]
    return patched
Ejemplo n.º 7
0
def create_mux(input_1, input_2, k, n, groups=None):
    # Функция генерации подсхемы мультиплексора для СФК на основе спектрального R-кода
    outputs = []
    mux = sch.scheme_alt()
    mux.__inputs__ = input_1 + input_2

    for i in range(k):
        wire_1 = 'mux_{}'.format(n)
        n += 1

        wire_2 = 'mux_{}'.format(n)
        n += 1

        mux.__elements__[wire_1] = ('AND', [mux.__inputs__[k+i+2], 'n_s0'])
        mux.__elements__[wire_2] = ('AND', [mux.__inputs__[i], '_s0'])

        if groups is None:
            mux.__elements__['out_{}'.format(i + 1)] = ('OR', [wire_1, wire_2])
            outputs.append('out_{}'.format(i + 1))
        else:
            mux.__elements__['out_{}'.format(groups[i])] = ('OR', [wire_1, wire_2])
            outputs.append('out_{}'.format(groups[i]))

    mux.__outputs__ = outputs

    return mux, n
Ejemplo n.º 8
0
def generate_random_ckt(num_inputs, num_outputs, max_width, circ_type='comb'):
    """
    :param num_inputs: Required number of inputs for ckt.
    :param num_outputs: Required number of outputs for ckt.
    :param max_width: maximum width of ckt.
    :return: generated ckt
    """

    overall_index = 0

    if num_inputs < 3:
        print('Too small number of inputs')

    if num_outputs < 3:
        print('Too small number of outputs')

    height = num_outputs
    width = max_width
    if width < 2:
        width = 2

    numInLevel = dict()
    for i in range(width-1):
        numInLevel[i] = random.randint(round(height/2), height)
    numInLevel[width-1] = num_outputs

    current_nodes = []
    ckt = sa.scheme_alt()
    for i in range(num_inputs):
        ckt.__inputs__.append('N_' + str(overall_index))
        current_nodes.append('N_' + str(overall_index))
        overall_index += 1

    elements = ["BUFF", "NOT", "AND", "OR", "NAND", "NOR", "XOR", "NXOR"]
    if circ_type == 'seq':
        elements.append("DFF")
    for i in range(width):
        h = numInLevel[i]
        level_nodes = []
        for j in range(h):
            o_node_name = 'N_' + str(overall_index)
            overall_index += 1
            type = random.choice(elements)
            if type == 'NOT' or type == 'BUFF':
                node = random.choice(current_nodes)
                ckt.__elements__[o_node_name] = (type, [node])
            else:
                node1 = random.choice(current_nodes)
                tmpnodes = current_nodes[:]  # fastest way to copy
                tmpnodes.remove(node1)
                node2 = random.choice(tmpnodes)
                ckt.__elements__[o_node_name] = (type, [node1, node2])
            level_nodes.append(o_node_name)
        if i == width-1:
            ckt.__outputs__ = level_nodes
        current_nodes = current_nodes + level_nodes

    return ckt
Ejemplo n.º 9
0
def create_ft_analog_nand2(inputs, outputs, k):
    # Функция генерации сбоеустойчивого аналога ЛЭ NAND2
    nand2 = '_{}_'

    ft_nand2 = sch.scheme_alt()
    ft_nand2.__inputs__ = inputs
    ft_nand2.__outputs__ = outputs

    ft_nand2.__elements__ = {
        nand2.format(k + 1): ('OR', [inputs[0], inputs[1]]),
        nand2.format(k + 2): ('NAND', [inputs[0], inputs[1]]),
        nand2.format(k + 3): ('OR', [inputs[3], inputs[4]]),
        nand2.format(k + 4): ('NAND', [inputs[3], inputs[4]]),
        nand2.format(k + 5): ('NAND', [nand2.format(k + 1), inputs[2]]),
        nand2.format(k + 6): ('NAND', [nand2.format(k + 3), inputs[5]]),
        nand2.format(k + 7):
        ('NAND', [nand2.format(k + 5),
                  nand2.format(k + 2)]),
        nand2.format(k + 8):
        ('NAND', [nand2.format(k + 6),
                  nand2.format(k + 4)]),
        outputs[0]: ('NAND', [nand2.format(k + 7),
                              nand2.format(k + 8)]),
        nand2.format(k + 9): ('OR', [inputs[0], inputs[1]]),
        nand2.format(k + 10): ('NAND', [inputs[0], inputs[1]]),
        nand2.format(k + 11): ('OR', [inputs[3], inputs[4]]),
        nand2.format(k + 12): ('NAND', [inputs[3], inputs[4]]),
        nand2.format(k + 13): ('NAND', [nand2.format(k + 9), inputs[2]]),
        nand2.format(k + 14): ('NAND', [nand2.format(k + 11), inputs[5]]),
        nand2.format(k + 15):
        ('NAND', [nand2.format(k + 13),
                  nand2.format(k + 10)]),
        nand2.format(k + 16):
        ('NAND', [nand2.format(k + 14),
                  nand2.format(k + 12)]),
        outputs[1]: ('NAND', [nand2.format(k + 15),
                              nand2.format(k + 16)]),
        nand2.format(k + 17): ('OR', [inputs[0], inputs[1]]),
        nand2.format(k + 18): ('NAND', [inputs[0], inputs[1]]),
        nand2.format(k + 19): ('OR', [inputs[3], inputs[4]]),
        nand2.format(k + 20): ('NAND', [inputs[3], inputs[4]]),
        nand2.format(k + 21): ('NAND', [nand2.format(k + 17), inputs[2]]),
        nand2.format(k + 22): ('NAND', [nand2.format(k + 19), inputs[5]]),
        nand2.format(k + 23): ('NAND',
                               [nand2.format(k + 21),
                                nand2.format(k + 18)]),
        nand2.format(k + 24): ('NAND',
                               [nand2.format(k + 22),
                                nand2.format(k + 20)]),
        outputs[2]: ('NAND', [nand2.format(k + 23),
                              nand2.format(k + 24)])
    }

    k += 24

    return ft_nand2, k
Ejemplo n.º 10
0
def generate_random_ckt(num_inputs, num_outputs, max_width):
    """
    :param num_inputs: Required number of inputs for ckt.
    :param num_outputs: Required number of outputs for ckt.
    :param max_width: maximum width of ckt.
    :return: generated ckt
    """

    if num_inputs < 3:
        print('Too small number of inputs')

    if num_outputs < 3:
        print('Too small number of outputs')

    height = num_outputs
    width = max_width
    if width < 2:
        width = 2

    numInLevel = dict()
    for i in range(width - 1):
        numInLevel[i] = random.randint(round(height / 2), height)
    numInLevel[width - 1] = num_outputs

    current_nodes = []
    ckt = sa.scheme_alt()
    for i in range(num_inputs):
        ckt.__inputs__.append('in_' + i.__str__())
        current_nodes.append('in_' + i.__str__())

    elements = ["INV", "AND", "OR", "NAND", "NOR", "XOR", "XNOR"]
    for i in range(width):
        h = numInLevel[i]
        level_nodes = []
        for j in range(h):
            if i != width - 1:
                o_node_name = 'wire_level_' + i.__str__(
                ) + '_pos_' + j.__str__()
            else:
                o_node_name = 'out_' + j.__str__()
            type = random.choice(elements)
            if type == 'INV':
                node = random.choice(current_nodes)
                ckt.__elements__[o_node_name] = (type, [node])
            else:
                node1 = random.choice(current_nodes)
                tmpnodes = current_nodes[:]  # fastest way to copy
                tmpnodes.remove(node1)
                node2 = random.choice(tmpnodes)
                ckt.__elements__[o_node_name] = (type, [node1, node2])
            level_nodes.append(o_node_name)
        if i == width - 1:
            ckt.__outputs__ = level_nodes
        current_nodes = current_nodes + level_nodes

    return ckt
Ejemplo n.º 11
0
def chromo2sch(chromo):
    (inputs, chromosome, outputs) = chromo
    scheme = sa.scheme_alt()
    name = names(inputs+len(chromosome))
    scheme.__inputs__ = [name.__next__() for _ in range(inputs)]
    order = scheme.__inputs__.copy()
    for gene in chromosome:
        label = name.__next__()
        order.append(label)
        scheme.__elements__[label] = (gene[0], [order[gene[1]], order[gene[2]]])
    scheme.__outputs__ = [order[out] for out in outputs]
    return scheme
Ejemplo n.º 12
0
def create_ced_for_group(scheme, group, num):

    k = scheme.outputs()
    m = k
    p = submatrix_p(k, m)

    coder = sch.replicate(scheme, 1)
    coder = create_coder(coder, p, k + m, num)

    renamed = {i: '{}_out'.format(i) for i in scheme.__outputs__}
    coder.rename_labels(renamed)
    coder.__outputs__ = ['{}_out'.format(i) for i in scheme.__outputs__] + coder.__outputs__

    hx = hx_with_elements(coder.__outputs__, np.hstack([p, np.eye(k, k, dtype=int)]), 2 * k, k)

    d1 = {i: [] for i in scheme.__outputs__}

    for i in range(k):
        for hx_str in hx:
            if coder.__outputs__[i] in hx_str:   d1[scheme.__outputs__[i]] += hx_str

    for i in scheme.__outputs__:
        check_eq = d1[i]
        ind_0 = scheme.__outputs__.index(i)
        for j in range(2):
            index = check_eq.index(coder.__outputs__[ind_0])
            check_eq.remove(check_eq[index])

    inputs = [d1[i] for i in d1]
    for i in range(k):  inputs[i] = [scheme.__outputs__[i]] + inputs[i]

    decoder = sch.scheme_alt()
    decoder.__outputs__ = ['out_ced_{}'.format(i) for i in group]
    decoder.__inputs__ = list(sorted(set([n3 for n2 in range(k) for n3 in inputs[n2]])))

    n = 1
    for i in range(k):  decoder, n = create_decoder(decoder, inputs[i], decoder.__outputs__[i], num, n)

    decoder.__inputs__ = scheme.__outputs__ + coder.__outputs__

    conn = {(0, i): [(1, i)] for i in coder.__outputs__}
    out = [(1, i) for i in decoder.__outputs__] + [(0, '{}_out'.format(i)) for i in scheme.__outputs__]

    ced = sch.merge_schemes([coder, decoder], conn, out)

    return ced, coder, decoder
Ejemplo n.º 13
0
def random_scheme(inputs, outputs, elements, types=None):
    if types is None:
        types = ("AND", "NAND", "OR", "NOR", "XOR", "XNOR", "INV")
    name = names(inputs+elements)
    scheme = sa.scheme_alt()
    scheme.__inputs__ = [name.__next__() for _ in range(inputs)]
    for _ in range(elements):
        a = random.choice(scheme.all_labels())
        b = random.choice(scheme.all_labels())
        while b == a:
            b = random.choice(scheme.all_labels())
        scheme.__elements__[name.__next__()] = (random.choice(types), [a, b])
    roulette = []
    levels = scheme.label_levels()
    #for label in levels:                                       # More level - more likely to be an output
    #    roulette += [label for _ in range(levels[label])]
    #scheme.__outputs__ = [random.choice(roulette) for _ in range(outputs)]
    scheme.__outputs__ = random.sample(scheme.element_labels(), outputs)
    return scheme
Ejemplo n.º 14
0
def rename_patch_internal_nodes(cir):
    global RENAME_INDEX

    ret = sc.scheme_alt()
    ret.__inputs__ = cir.__inputs__.copy()
    ret.__outputs__ = cir.__outputs__.copy()
    for el in cir.__elements__:
        elem_inp_list = []
        for i in cir.__elements__[el][1]:
            if i in cir.__inputs__ or i in cir.__outputs__:
                elem_inp_list.append(i)
            else:
                elem_inp_list.append(i + '_pp{}'.format(RENAME_INDEX))
        if el in cir.__inputs__ or el in cir.__outputs__:
            el_changed = copy.copy(el)
        else:
            el_changed = el + '_pp{}'.format(RENAME_INDEX)
        ret.__elements__[el_changed] = (cir.__elements__[el][0], elem_inp_list)

    RENAME_INDEX += 1
    return ret
Ejemplo n.º 15
0
def create_input_transducer(scheme_1, scheme_2):
    # Функция генерации вх. преобразователя и добавления его в СФК на основе кодирования в 3битном пространстве Хэмминга
    # scheme_1 - основная комбинационная схема
    # scheme_2 - схема, в которой ЛЭ были заменены на сбоеустойчивые аналоги в 3битном пространстве Хэмминга

    # Создание словаря соединений
    con = dict()

    # Создание списка выходов объединенной схемы scheme_2
    out = list()

    # Создание пустой подсхемы входного преобразователя inp_transducer
    inp_transducer = sch.scheme_alt()

    # Добавление входов для подсхемы входного преобразователя inp_transducer
    inp_transducer.__inputs__ = ['x_0']

    for i in range(scheme_1.inputs() - 1):
        inp_transducer.__inputs__.append('x_{}'.format(i + 1))

    # Добавление выходов для подсхемы входного преобразователя inp_transducer
    inp_transducer.__outputs__ = inp_transducer.__inputs__

    # Генерация словаря соединений
    # Например:
    # {(1,'x_1'): [(0, 'a'), (0, 'a_1'), (0, 'a_2')]}, где 'x_1' - вход преобразователя,
    # 'a','a_1','a_2' - входы схемы
    for i in range(scheme_1.inputs()):
        con[(1, 'x_{}'.format(i))] = [(0, scheme_1.__inputs__[i]),
                                      (0, scheme_1.__inputs__[i] + '_1'),
                                      (0, scheme_1.__inputs__[i] + '_2')]

    # Генерация выходов объединенной схемы
    for i in range(scheme_2.outputs()):
        out.append((0, scheme_2.__outputs__[i]))

    # Объединение схемы hemming_scheme и подсхемы входного преобразователя inp_transducer
    scheme_2 = sch.merge_schemes([scheme_2, inp_transducer], con, out)

    return scheme_2
Ejemplo n.º 16
0
def remap_node_names(ckt):

    # Fill dictionary of all available nodes
    nodes = dict()
    total = 0
    for i in ckt.__inputs__:
        if i not in nodes:
            nodes[i] = str(total)
            total += 1
    for i in ckt.__outputs__:
        if i not in nodes:
            nodes[i] = str(total)
            total += 1
    for el in ckt.__elements__:
        if el not in nodes:
            nodes[el] = str(total)
            total += 1
            for l in ckt.__elements__[el][1]:
                if l not in nodes:
                    nodes[l] = str(total)
                    total += 1

    new = sa.scheme_alt()
    for i in ckt.__inputs__:
        new.__inputs__.append(nodes[i])
    for i in ckt.__outputs__:
        new.__outputs__.append(nodes[i])
    for el in ckt.__elements__:
        lst = []
        for l in ckt.__elements__[el][1]:
            lst.append(nodes[l])
        elem = ckt.__elements__[el][0]
        if elem == 'INV':
            elem = 'NOT'
        if elem == 'BUF':
            elem = 'BUFF'
        if elem == 'XNOR':
            elem = 'NXOR'
        new.__elements__[nodes[el]] = (elem, lst)
    return new
def createSubckt_method3(q, ckt):
    sckt = sa.scheme_alt()
    for i in ckt.__inputs__:
        sckt.__inputs__.append(i)
    for o in ckt.__outputs__:
        sckt.__outputs__.append(o)

    # Делаем подходящую структуру данных
    merge = createMergeStructure(q, ckt)

    # Ищем самые часто встречающиеся пары и заменяем их
    # Приоритет парам либо с отрицаниями, либо без них
    # Цикл заканчивается когда все термы сжимаются до одного элемента
    num = 0
    while (1):
        uniqueList = getUniqueNames(merge)
        total = len(uniqueList)

        # Создаем проверочный массив
        check = [0] * total
        for i in range(total):
            check[i] = [0] * total

        # Считаем пары
        for i in range(0, total):
            for j in range(i+1, total):
                n1 = uniqueList[i]
                n2 = uniqueList[j]
                check[i][j] = 0
                for o in merge:
                    for term in merge[o]:
                        if term.count(n1) > 0 and term.count(n2) > 0:
                            check[i][j] = check[i][j] + 1

        # Выбираем случайную пару
        count = 0
        for i in range(0, total):
            for j in range(i+1, total):
                if check[i][j] > 0:
                    count += 1
        if count == 0:
            break

        numPair = random.randint(0, count-1)
        count = 0
        for i in range(0, total):
            for j in range(i+1, total):
                if check[i][j] > 0:
                    if count == numPair:
                        n1 = uniqueList[i]
                        n2 = uniqueList[j]
                        break
                    count += 1

        newname = "INT_{0}".format(num)
        num = num + 1
        if (n1[0] != '!' and n2[0] != '!'):
            sckt.__elements__[newname] = ('AND', [n1, n2])
        elif (n1[0] == '!' and n2[0] == '!'):
            sckt.__elements__[newname] = ('NOR', [n1[1:], n2[1:]])
        elif (n1[0] == '!'):
            newname1 = "INT_{0}".format(num)
            num = num + 1
            if random.randint(0, 1) == 0:
                sckt.__elements__[newname1] = ('INV', [n1[1:]])
                sckt.__elements__[newname] = ('AND', [newname1, n2])
            else:
                sckt.__elements__[newname1] = ('INV', [n2])
                sckt.__elements__[newname] = ('NOR', [newname1, n1[1:]])
        elif (n2[0] == '!'):
            newname1 = "INT_{0}".format(num)
            num = num + 1
            if random.randint(0, 1) == 0:
                sckt.__elements__[newname1] = ('INV', [n2[1:]])
                sckt.__elements__[newname] = ('AND', [newname1, n1])
            else:
                sckt.__elements__[newname1] = ('INV', [n1])
                sckt.__elements__[newname] = ('NOR', [newname1, n2[1:]])

        # Заменяем пары в термах
        for o in merge:
            for term in merge[o]:
                if term.count(n1) > 0 and term.count(n2) > 0:
                    term.remove(n1)
                    term.remove(n2)
                    term.append(newname)

    # Цикл, который попарно объединяет термы в рамках каждого выхода
    while (1):
        uniqueList = getUniqueNames(merge)
        total = len(uniqueList)

        # Создаем проверочный массив
        check = [0] * total
        for i in range(total):
            check[i] = [0] * total

        # Считаем пары (надо проверить какая пара чаще встречается среди всех выходов)
        for i in range(0, total):
            for j in range(i+1, total):
                n1 = uniqueList[i]
                n2 = uniqueList[j]
                check[i][j] = 0
                for o in merge:
                    flag = 0
                    for term in merge[o]:
                        if term.count(n1) > 0:
                            flag = flag + 1
                    for term in merge[o]:
                        if term.count(n2) > 0:
                            flag = flag + 1
                    if flag == 2:
                        check[i][j] = check[i][j] + 1

        # Выбираем случайную пару
        count = 0
        for i in range(0, total):
            for j in range(i+1, total):
                if check[i][j] > 0:
                    count += 1

        if count == 0:
            break

        numPair = random.randint(0, count-1)
        count = 0
        for i in range(0, total):
            for j in range(i+1, total):
                if check[i][j] > 0:
                    if count == numPair:
                        n1 = uniqueList[i]
                        n2 = uniqueList[j]
                        break
                    count += 1

        # Если пары ещё есть добавляем элемент в схемы и заменяем пару в списке на один элемент
        newname = "INT_{0}".format(num)
        num = num + 1
        if (n1[0] != '!' and n2[0] != '!'):
            sckt.__elements__[newname] = ('OR', [n1, n2])
        elif (n1[0] == '!' and n2[0] == '!'):
            sckt.__elements__[newname] = ('NAND', [n1[1:], n2[1:]])
        elif (n1[0] == '!'):
            newname1 = "INT_{0}".format(num)
            num = num + 1
            if random.randint(0, 1) == 0:
                sckt.__elements__[newname1] = ('INV', [n1[1:]])
                sckt.__elements__[newname] = ('OR', [newname1, n2])
            else:
                sckt.__elements__[newname1] = ('INV', [n2])
                sckt.__elements__[newname] = ('NAND', [newname1, n1[1:]])
        elif (n2[0] == '!'):
            newname1 = "INT_{0}".format(num)
            num = num + 1
            if random.randint(0, 1) == 0:
                sckt.__elements__[newname1] = ('INV', [n2[1:]])
                sckt.__elements__[newname] = ('OR', [newname1, n1])
            else:
                sckt.__elements__[newname1] = ('INV', [n1])
                sckt.__elements__[newname] = ('NAND', [newname1, n2[1:]])

        # Заменяем пары в термах
        for o in merge:
            flag = 0
            for term in merge[o]:
                if term.count(n1) > 0:
                    flag = flag + 1
                if term.count(n2) > 0:
                    flag = flag + 1
            if (flag == 2):
                for term in merge[o]:
                    if term.count(n1) > 0:
                        term.remove(n1)
                        continue
                    if term.count(n2) > 0:
                        term.remove(n2)
                        continue
                merge[o].append([newname])

        # Чистим список от пустых записей
        for o in merge:
            for term in merge[o]:
                while (merge[o].count([]) > 0):
                    merge[o].remove([])

    # Теперь требуется заменить имена промежуточных узлов на имена реальных выходов
    for o in merge:
        find = merge[o][0][0]
        replace = o
        # Сначала меняем в поле ключей
        if find in sckt.__elements__:
            sckt.__elements__[replace] = sckt.__elements__[find]
            del sckt.__elements__[find]
        # Затем меняем в элементах
        for el in sckt.__elements__:
            lst = sckt.__elements__[el][1]
            for key,i in enumerate(lst):
                if i == find:
                    lst[key] = replace

    # Фикс для случая когда у нас несколько выходов имеют единую логическую функцию (и часть выходов пропала при замене)
    # В этом случае добавляем буферы
    fix_happened = 0
    for o in merge:
        if o not in sckt.__elements__:
            flag = 0
            for el in sckt.__elements__:
                lst = sckt.__elements__[el][1]
                for key,i in enumerate(lst):
                    if i == o:
                         flag += 1
            if flag == 0:
                f1 = merge[o][0][0]
                fname = ''
                for o1 in merge:
                    if o1 in sckt.__elements__:
                        f2 = merge[o1][0][0]
                        if f1 == f2:
                            fname = o1
                if fname == '':
                    print('Some unexpected error here')
                    break
                sckt.__elements__[o] = ('BUF', [fname])
                fix_happened += 1

    # Фикс для случая когда выход полностью повторяет вход или его инверсию (и он теряется)
    # Необходимо добавить буфер типа (BUF вход выход) или (INV вход выход)
    for o in merge:
        if (len(merge[o]) == 1) & (len(merge[o][0]) == 1):
            if (merge[o][0][0][0] != '!') & (merge[o][0][0] in ckt.__inputs__):
                sckt.__elements__[o] = ('BUF', merge[o][0])
            if (merge[o][0][0][0] == '!') & (merge[o][0][0][1:] in ckt.__inputs__):
                sckt.__elements__[o] = ('INV', [merge[o][0][0][1:]])

    return sckt
def create_decoder(scheme, gx_el, one, n, k, count):
    # ФУНКЦИЯ ФОРМИРОВАНИЯ ПОДСХЕМЫ ДЕКОДЕРА

    outputs_shem = []
    for i in range(scheme.outputs()):
        outputs_shem.append(scheme.__outputs__[i])

    decoder = sch.scheme_alt()
    decoder.__inputs__ = outputs_shem

    for i in range(n):
        decoder.__inputs__.append('decoder_in_{}'.format(i))

    outputs_shem = []

    for num in range(n):
        if one[num] != 1:
            for i in range(one[num] - 1):
                if i == 0:
                    decoder.__elements__['decoder_{}'.format(count)] = (
                        'XOR', [gx_el[num][0], gx_el[num][1]])
                    count += 1
                else:
                    decoder.__elements__['decoder_{}'.format(count)] = (
                        'XOR',
                        [gx_el[num][i + 1], 'decoder_{}'.format(count - 1)])
                    count += 1
            decoder.__outputs__.append('decoder_{}'.format(count - 1))
        else:
            decoder.__outputs__.append(gx_el[num][0])

    for i in range(n):
        decoder.__outputs__.append(decoder.__inputs__[scheme.outputs() + i])

    if k != 1:

        for j in range(n):
            decoder.__elements__['_s{}'.format(j)] = ('XOR', [
                decoder.__outputs__[j], decoder.__outputs__[j + n]
            ])
            outputs_shem.append('_s{}'.format(j))
            count += 1

        decoder.__outputs__ = []
        list_1 = outputs_shem

        if (n - 1) != 1:
            for i in range(n - 1):
                if i == 0:
                    decoder.__elements__['decoder_{}'.format(count)] = ('OR', [
                        list_1[0], list_1[1]
                    ])
                    count += 1
                else:
                    if i == n - 2:
                        decoder.__elements__['flag'] = ('OR', [
                            list_1[i + 1], 'decoder_{}'.format(count - 1)
                        ])
                        decoder.__outputs__.append('flag')
                    else:
                        decoder.__elements__['decoder_{}'.format(count)] = (
                            'OR',
                            [list_1[i + 1], 'decoder_{}'.format(count - 1)])
                    count += 1
        elif (n - 1) == 1:
            for i in range(n - 1):
                if i == 0:
                    decoder.__elements__['flag'] = ('OR',
                                                    [list_1[0], list_1[1]])
                    count += 1
                    decoder.__outputs__.append('flag')
    else:
        for j in range(n):
            decoder.__elements__['flag'] = ('XOR', [
                decoder.__outputs__[j], decoder.__outputs__[j + n]
            ])
            count += 1
        decoder.__outputs__ = []
        for i in range(scheme.outputs() - 1):
            decoder.__outputs__.append(scheme.__outputs__[i])
        decoder.__outputs__.append('flag')

    return decoder, count
def create_ced(scheme, count):
    #ОСНОВНАЯ ФУНКЦИЯ ГЕНЕРАЦИИ СФК НА ОСНОВЕ МОДИФИЦИРОВАННОГО КОДА ХЭММИНГА

    SWC_ced = sch.scheme_alt()
    # ВЫЧИСЛЕНИЕ ОСНОВНЫХ ПАРАМЕТРОВ СХЕМЫ
    k = scheme.outputs()  # КОЛ-ВО ИНФОРМАЦИОННЫХ РАЗРЯДОВ/ВЫХОДОВ СХЕМЫ
    n = int(np.ceil(np.log2(k + 1)))  # КОЛ-ВО ПРОВЕРОЧНЫХ РАЗРЯДОВ
    gx = matrix_gx(n, k)  # ГЕНЕРАЦИЯ ПОРОЖДАЮЩЕЙ МАТРИЦЫ
    gx_elements = gx_with_elements(
        scheme, gx, k, n)  # СПИСОК ЭЛ-ОВ, ДЛЯ ВЫЧИСЛЕНИЯ ПРОВЕРОЧНЫХ РАЗРЯДОВ
    gx_one_line = np.sum(
        gx, 1)  # КОЛ-ВО ЭЛ-ОВ, ДЛЯ ВЫЧИСЛЕНИЯ ПРОВЕРОЧНЫХ РАЗРЯДОВ
    scheme_1 = sch.replicate(scheme, 1)  # КОПИЯ О.С. ДЛЯ ФОРМИРОВАНИЯ КОДЕРА
    coder, count = create_coder(scheme_1, gx_elements, gx_one_line, n,
                                count)  # ФОРМИРОВАНИЕ ПОДСХЕМЫ КОДЕРА
    #coder_min = create_circuit_external_yosys(coder)                                # МИНИМИЗАЦИЯ КОДЕРА С ПОМОЩЬЮ YOSYS
    decoder, count = create_decoder(scheme, gx_elements, gx_one_line, n, k,
                                    count)  # ФОРМИРОВАНИЕ ПОДСХЕМЫ ДЕКОДЕРА
    #decoder_min = create_circuit_external_yosys(decoder)                            # МИНИМИЗАЦИЯ ДЭКОДЕРА С ПОМОЩЬЮ YOSYS

    # ОБЪЕДИНЕНИЕ ОСНОВНОЙ СХЕМЫ И ПОДСХЕМЫ КОДЕРА
    conn = dict()  # СОЕДИНЕНИЯ ОС И КОДЕРА
    conn_min = dict()  # СОЕДИНЕНИЯ ОС И МИНИМИЗИРОВАННОГО КОДЕРА
    out = list()  # ВЫХОДЫ ОС И КОДЕРА
    out_min = list()  # ВЫХОДЫ ОС И МИН. КОДЕРА

    for i in range(scheme.inputs()):  # ЗАПОЛНЕНИЕ СЛОВОРЕЙ СОЕДИНЕНИЙ
        conn[(0, scheme.__inputs__[i])] = [(1, coder.__inputs__[i])]
        #conn_min[(0, scheme.__inputs__[i])] = [(1, coder_min.__inputs__[i])]

    for j in range(scheme.outputs()):  # ЗАПОЛНЕНИЕ СПИСКА ВЫХОДОВ
        out.append((0, scheme.__outputs__[j]))
        out_min.append((0, scheme.__outputs__[j]))

    for i in range(coder.outputs()):
        out.append((1, coder.__outputs__[i]))
    # for i in range(coder_min.outputs()):
    #     out_min.append((1, coder_min.__outputs__[i]))

    scheme_2 = sch.merge_schemes([scheme, coder], conn,
                                 out)  # ОБЪЕДИНЕНИЕ ОС И КОДЕРА
    #scheme_3 = sch.merge_schemes([scheme, coder_min], conn_min, out_min)        # ОБЪЕДИНЕНИЕ ОС И МИН. КОДЕРА

    # ОБЪЕДИНЕНИЕ scheme_3/scheme_3 И ДЕКОДЕРА
    conn = dict()  # СОЕДИНЕНИЯ scheme_3/scheme_3 И ДЕКОДЕРА
    conn_min = dict()  # СОЕДИНЕНИЯ scheme_3/scheme_3 И МИН. ДЕКОДЕРА
    out = list()  # ВЫХОДЫ scheme_3/scheme_3 И ДЕКОДЕРА
    out_min = list()  # ВЫХОДЫ scheme_3/scheme_3 И МИН. ДЕКОДЕРА

    for i in range(decoder.inputs()):  # ЗАПОЛНЕНИЕ СЛОВОРЕЙ СОЕДИНЕНИЙ
        conn[(0, scheme_2.__outputs__[i])] = [(1, decoder.__inputs__[i])]
    # for i in range(decoder_min.inputs()):
    #     conn_min[(0, scheme_2.__outputs__[i])] = [(1, decoder_min.__inputs__[i])]

    for j in range(scheme.outputs()):  # ЗАПОЛНЕНИЕ СПИСКА ВЫХОДОВ
        out.append((0, scheme_2.__outputs__[j]))
        out_min.append((0, scheme_2.__outputs__[j]))

    for i in range(decoder.outputs()):
        out.append((1, decoder.__outputs__[i]))
    # for i in range(decoder_min.outputs()):
    #     out_min.append((1, decoder_min.__outputs__[i]))

    SWC_ced = sch.merge_schemes([scheme_2, decoder], conn,
                                out)  # ФОРМИРОВАНИЕ СФК
    #SWC_ced = sch.merge_schemes([scheme_2, decoder_min], conn, out)             # ФОРМИРОВАНИЕ СФК С МИН. ДЕКОДЕРОМ
    #SWC_ced = sch.merge_schemes([scheme_3, decoder], conn, out)                # ФОРМИРОВАНИЕ СФК С МИН. КОДЕРОМ
    #SWC_ced = sch.merge_schemes([scheme_3, decoder_min], conn_min, out_min)    # ФОРМИР СФК С МИН. КОДЕРОМ И МИН. ДЕКОДЕРОМ

    return SWC_ced
Ejemplo n.º 20
0
def read_verilog(filename):
    """
    verilog parser
    :param filename: filename
    :return: scheme in scheme_alt format
    """
    scheme = sc.scheme_alt()
    f = open(filename)
    file = f.read()
    # парсинг модуля и портов
    m = re.match(r"\s*module\s+(\S+)\s*\(((\s*\S+\s*,)*\s*\S+\s*)\)\s*;\s*",
                 file)
    if m:
        ports = m.group(2)
        ports = ports.replace(' ', '')
        ports = ports.split(',')
        module_name = m.group(1)
        rest = file[0:m.start()] + file[m.end():len(file)]

    # парсинг входов
    m = re.match(r"\s*input\s+((\s*\S+\s*,)*\s*\S+\s*)\s*;\s*", rest)
    if m:
        inputs = m.group(1)
        inputs = inputs.replace(' ', '')
        inputs = inputs.split(',')
        rest = rest[0:m.start()] + rest[m.end():len(rest)]
    else:
        print('ERROR IN READING VERILOG: no inputs')
        return 0

    # парсинг выходов
    m = re.match(r"\s*output\s+((\s*\S+\s*,)*\s*\S+\s*)\s*;\s*", rest)
    if m:
        outputs = m.group(1)
        outputs = outputs.replace(' ', '')
        outputs = outputs.split(',')
        rest = rest[0:m.start()] + rest[m.end():len(rest)]
    else:
        print('ERROR IN READING VERILOG: no outputs')
        return 0

    # парсинг проводов
    m = re.match(r"\s*wire\s+((\s*\S+\s*,)*\s*\S+\s*)\s*;\s*", rest)
    if m:
        wires = m.group(1)
        wires = wires.replace(' ', '')
        wires = wires.split(',')
        rest = rest[0:m.start()] + rest[m.end():len(rest)]
    else:
        wires = []

    # парсинг тестовых проводов
    m = re.match(r"\s*wire\s+((\s*\S+\s*,)*\s*\S+\s*)\s*;\s*", rest)
    if m:
        targets = m.group(1)
        targets = targets.replace(' ', '')
        targets = targets.split(',')
        rest = rest[0:m.start()] + rest[m.end():len(rest)]
    else:
        targets = []

    # генерируем имя для VCC
    while 1:
        VCC_name = gen_name(scheme)
        if VCC_name not in wires + inputs + outputs + targets:
            break

    # генерируем имя для GND
    while 1:
        GND_name = gen_name(scheme)
        if GND_name not in wires + inputs + outputs + targets:
            break
    VCC_name += '_VCC'
    GND_name += '_GND'
    # парсинг элементов
    lines = rest.splitlines()

    for line in lines:
        m = re.match(r"\s*(\S+)\s*\(((\s*\S+\s*,)*\s*\S+\s*)\)\s*;\s*", line)
        if m:
            elt = m.group(1)
            elt = elt.upper()
            if elt == 'NOT':
                elt = 'INV'
            pts = m.group(2)
            pts = pts.replace(' ', '')
            pts = pts.split(',')
            # проверка не являются ли сигналы - нулями/единицами
            scheme.__elements__[VCC_name] = ('VCC', [])
            scheme.__elements__[GND_name] = ('GND', [])
            k = 0
            for inp in pts[1:]:
                k += 1
                if (inp == '1\'b1' or inp == '1'):
                    #name = gen_name(scheme)
                    #scheme.__elements__[name] = ('VCC', [])
                    #pts[k] = name
                    pts[k] = VCC_name
                if (inp == '1\'b0' or inp == '0'):
                    #name = gen_name(scheme)
                    #scheme.__elements__[name] = ('GND', [])
                    #pts[k] = name
                    pts[k] = GND_name
            scheme.__elements__[pts[0]] = (elt, pts[1:])

    scheme.__inputs__ = inputs
    scheme.__outputs__ = outputs

    return scheme
Ejemplo n.º 21
0
def create_hemming_circuit(scheme):
    # Функция переименования узлов схемы
    renamed_scheme = sch.replicate(scheme, 1)
    n = renamed_elements_in_scheme(renamed_scheme, 'inp_', 'wire_', 0)

    # "Утроение" основной схемы
    scheme_2 = sch.merge_schemes([renamed_scheme] * 3)
    scheme_3 = sch.scheme_alt()
    inputs = list()

    # Вычисление числа ЛЭ основной схемы
    k = scheme.elements()

    # Для каждого ЛЭ основной схемы создается сбоеустойчивый аналог данного ЛЭ в базисе 3битоного пространства Хэмминга
    # Определение выходов сбоеустойчивого аналога ЛЭ
    for element in sorted(renamed_scheme.__elements__.keys()):
        outputs = [element, element + '_1', element + '_2']

        # Определение входов аналога, если ЛЭ основной схемы является двувходовым
        if len(renamed_scheme.__elements__[element][1]) == 2:
            inputs = [
                renamed_scheme.__elements__[element][1][0],
                renamed_scheme.__elements__[element][1][0] + '_1',
                renamed_scheme.__elements__[element][1][0] + '_2',
                renamed_scheme.__elements__[element][1][1],
                renamed_scheme.__elements__[element][1][1] + '_1',
                renamed_scheme.__elements__[element][1][1] + '_2'
            ]

        # Если ЛЭ основной схемы - одновходовой
        elif len(renamed_scheme.__elements__[element][1]) == 1:
            inputs = [
                renamed_scheme.__elements__[element][1][0],
                renamed_scheme.__elements__[element][1][0] + '_1',
                renamed_scheme.__elements__[element][1][0] + '_2'
            ]

        # Определение типа (выполняемой функции) ЛЭ основной схемы
        node_type = renamed_scheme.__elements__[element][0]

        # Генерация подсхемы subscheme сбоеустойчивого аналога ЛЭ основной схемы
        if node_type == 'INV':
            subscheme, k = create_ft_analog_inv(
                inputs, outputs, k)  # Сбоеустойчивый аналог ЛЭ INV
        elif node_type == 'BUF':
            subscheme, k = create_ft_analog_buf(
                inputs, outputs, k)  # Сбоеустойчивый аналог ЛЭ BUF
        elif node_type == 'AND':
            subscheme, k = create_ft_analog_and2(
                inputs, outputs, k)  # Сбоеустойчивый аналог ЛЭ AND2
        elif node_type == 'OR':
            subscheme, k = create_ft_analog_or2(
                inputs, outputs, k)  # Сбоеустойчивый аналог ЛЭ OR2
        elif node_type == 'XOR':
            subscheme, k = create_ft_analog_xor2(
                inputs, outputs, k)  # Сбоеустойчивый аналог ЛЭ XOR2
        elif node_type == 'NAND':
            subscheme, k = create_ft_analog_nand2(
                inputs, outputs, k)  # Сбоеустойчивый аналог ЛЭ NAND2
        elif node_type == 'NOR':
            subscheme, k = create_ft_analog_nor2(
                inputs, outputs, k)  # Сбоеустойчивый аналог ЛЭ NOR2
        elif node_type == 'XNOR':
            subscheme, k = create_ft_analog_xnor2(
                inputs, outputs, k)  # Сбоеустойчивый аналог ЛЭ XNOR2
        elif node_type == 'GND':
            subscheme = {element: renamed_scheme.__elements__[element]}  # GND
        else:
            subscheme = 0

        if node_type == 'GND': scheme_3.__elements__.update(subscheme)
        else: scheme_3.__elements__.update(subscheme.__elements__)

    scheme_3.__inputs__ = scheme_2.__inputs__
    scheme_3.__outputs__ = scheme_2.__outputs__

    # Добавление подсхемы входного преобразователя
    scheme_4 = create_input_transducer(renamed_scheme, scheme_3)

    # Добавление подсхемы выходного преобразователя
    hem_ced = create_output_transducer(renamed_scheme, scheme_4, k)

    return hem_ced
Ejemplo n.º 22
0
def get_random_subcircuit(cir, limit=3, type=0):
    new = sa.scheme_alt()

    # Выбираем начальный элемент с которого начнем ветвление
    start = random.randint(0, cir.elements() - 1)
    node = cir.element_labels()[start]
    cell = cir.__elements__[node]

    # Добавляем элемент в схему
    new.__outputs__.append(copy.deepcopy(node))
    new.__inputs__ = copy.deepcopy(cell[1])
    new.__elements__[node] = copy.deepcopy(cell)

    # Цикл пока не закончится ветвление
    while 1:
        # Выбираем случайный вход в схему (узел и ячейку подключенные к нему)
        inpnum = random.randint(0, new.inputs() - 1)
        node = new.__inputs__[inpnum]

        # Если выбранный вход является входным в схему, то завершаем цикл
        if cir.__inputs__.count(node) > 0:
            break

        cell = cir.__elements__[node]
        # Удаляем из списка входов текущий и добавляем все входы от Cell
        try:
            new.__inputs__.remove(node)
        except:
            new.print_circuit_in_file(
                os.path.join(get_project_directory(), "temp", "debug1.txt"))
            cir.print_circuit_in_file(
                os.path.join(get_project_directory(), "temp", "debug2.txt"))
            exit(0)
        for inp in cell[1]:
            if new.__inputs__.count(inp) == 0:
                new.__inputs__.append(copy.deepcopy(inp))

        # Добавляем ячейку в список элементов
        new.__elements__[node] = copy.deepcopy(cell)

        # Поскольку к узлу могут быть привязаны входы других элементов,
        # мы также должны добавить эти элементы в нашу подсхему
        for el in cir.__elements__:
            val = cir.__elements__[el]
            for i in val[1]:
                if i == node:
                    if (el not in new.__elements__):
                        # добавляем входы найденного элемента которых ещё не было
                        v1 = cir.__elements__[el]
                        for j in v1[1]:
                            if new.__inputs__.count(j) == 0:
                                if new.__outputs__.count(j) == 0:
                                    if j not in new.__elements__:
                                        new.__inputs__.append(copy.copy(j))
                        # добавляем выходы найденного элемента которых ещё не было
                        if new.__outputs__.count(el) == 0:
                            new.__outputs__.append(copy.deepcopy(el))
                        # добавляем сам найденный элемент
                        new.__elements__[el] = copy.deepcopy(val)
                        # если в списке входов оказался выход добавленного элемента удаляем
                        if new.__inputs__.count(el) > 0:
                            new.__inputs__.remove(el)

        # В некоторых условиях вход и выход могут стать рядовыми узлами подсхемы
        # Удаляем элемент из списка входов если он является выходом одного из элементов
        for i in new.__inputs__:
            if i in new.__elements__:
                new.__inputs__.remove(i)

        # Удаляем элемент из списка выходов если он является входом одного из элементов
        # Так делать нельзя так как от него могут идти связи к другим элементам большой схемы!
        if 0:
            for o in new.__outputs__:
                flag = 0
                for el in new.__elements__:
                    val = new.__elements__[el]
                    for i in val[1]:
                        if i == o:
                            new.__outputs__.remove(o)
                            flag = 1
                            break
                    if flag == 1:
                        break

        if type == 0:
            if new.elements() >= limit:
                break
        else:
            if new.inputs() >= limit:
                break

    # В некоторых условиях промежуточные узлы могут оказаться выходами основной схемы.
    # В этом случае их надо добавить в список выходов для подсхемы
    for o in cir.__outputs__:
        if o not in new.__outputs__:
            if o in new.__elements__:
                new.__outputs__.append(copy.deepcopy(o))

    return new
Ejemplo n.º 23
0
def create_ced_for_group(scheme, group, cone=None, n=0):
    if cone is None:    cone = []
    spectral_ced = sch.scheme_alt()

    if scheme.outputs() != 1:
        # Вычисление основных параметров спектрального R-кода
        k = scheme.outputs()

        m = int(np.ceil(np.log2(k)))+1

        gx = matrix_gx(k, m-1)
        gx_elements = gx_with_elements(scheme, gx, k, m)
        gx_count_one = gx_with_count_one(gx)

        outputs = []

        for i in range(scheme.outputs()): outputs.append(scheme.__outputs__[i])

        # Создание копии основной схемы для кодера
        scheme_1 = sch.replicate(scheme, 1)

        # Генерирование подсхемы кодера для СФК на основе спектрального R-кода
        coder, n = create_coder(scheme_1, gx_elements, gx_count_one, m, n)

        # Минимизирование подсхемы кодера для СФК на основе спектрального R-кода с помощью Yosys
        # coder_min = create_circuit_external_yosys(coder)

        # Генерирование подсхемы декодера для СФК на основе спектрального R-кода
        decoder, n = create_decoder(scheme, gx_elements, outputs, gx_count_one, m, k, n)

        # Минимизирование подсхемы декодера для СФК на основе спектрального R-кода с помощью Yosys
        # decoder_min = create_circuit_external_yosys(decoder)

        # n_decoder_out = len(decoder_min.__outputs__)
        n_decoder_out = len(decoder.__outputs__)

        # Генерирование подсхемы мультиплексора для СФК на основе спектрального R-кода
        # mux_inputs = decoder_min.__outputs__[:(n_decoder_out-1)]
        mux_inputs = decoder.__outputs__[:(n_decoder_out - 1)]

        mux, n = create_mux(mux_inputs, scheme.__outputs__, k, n, group)

        # cone += mux.__elements__

        # Объединение подсхем декодера и мультиплексора
        conn = dict()
        out = list()

        # for n1 in range(k): conn[(0, decoder_min.__outputs__[n1])] = [(1, decoder_min.__outputs__[n1])]
        for n1 in range(k): conn[(0, decoder.__outputs__[n1])] = [(1, decoder.__outputs__[n1])]
        for n2 in range(k): conn[(0, scheme.__outputs__[n2])] = [(1, scheme.__outputs__[n2])]

        conn[(0, '_s0')] = [(1, '_s0')]
        conn[(0, 'n_s0')] = [(1, 'n_s0')]

        for n3 in range(k):     out.append((1, mux.__outputs__[n3]))

        out.append((0, '_s0'))
        out.append((0, 'flag'))

        # scheme_2 = sch.merge_schemes([decoder_min, mux], conn, out)
        scheme_2 = sch.merge_schemes([decoder, mux], conn, out)

        # Объединение подсхем кодера и scheme_2
        conn = dict()
        out = list()

        # for n4 in range(m):   conn[(0, coder_min.__outputs__[n4])] = [(1, scheme_2.__inputs__[k+n4])]
        # for n5 in range(scheme_2.outputs()):    out.append((1, scheme_2.__outputs__[n5]))
        # spectral_ced = sch.merge_schemes([coder_min, scheme_2], conn, out)

        for n4 in range(m):                     conn[(0, coder.__outputs__[n4])] = [(1, scheme_2.__inputs__[k+n4])]
        for n5 in range(scheme_2.outputs()):    out.append((1, scheme_2.__outputs__[n5]))
        spectral_ced = sch.merge_schemes([coder, scheme_2], conn, out)

    return spectral_ced, cone, n, coder, decoder
Ejemplo n.º 24
0
def create_decoder(scheme, gx2, input1, one, m, k, n):
    # Функция генерации подсхемы декодера для СФК на основе спектрального R-кода
    decoder = sch.scheme_alt()
    decoder.__inputs__ = input1
    dc = list()

    for i in range(m):  decoder.__inputs__.append('decoder_in_{}'.format(i))

    outputs = []

    for num in range(m):
        if one[num] != 1:
            for i in range(one[num]-1):
                if i == 0:
                    decoder.__elements__['decoder_{}'.format(n)] = ('XOR', [gx2[num][0], gx2[num][1]])
                    n += 1
                else:
                    decoder.__elements__['decoder_{}'.format(n)] = ('XOR', [gx2[num][i + 1], 'decoder_{}'.format(n-1)])
                    n += 1
            decoder.__outputs__.append('decoder_{}'.format(n-1))
        else:   decoder.__outputs__.append(gx2[num][0])

    for i in range(m):  decoder.__outputs__.append(decoder.__inputs__[scheme.outputs() + i])
    for j in range(m):
        decoder.__elements__['_s{}'.format(j)] = ('XOR', [decoder.__outputs__[j], decoder.__outputs__[j+m]])
        outputs.append('_s{}'.format(j))

    decoder.__outputs__ = outputs
    list_1 = outputs[1:]
    outputs = []

    for n_inv in range(len(decoder.__outputs__)):
        decoder.__elements__['n' + decoder.__outputs__[n_inv]] = ('INV', [decoder.__outputs__[n_inv]])
        outputs.append('n' + decoder.__outputs__[n_inv])

    decoder.__outputs__ += outputs
    list_0 = outputs[1:]

    if m - 1 != 1:
        dc = list()

        for vector in it.product((0, 1), repeat=(m-1)): dc.append(list(vector))

        dc = dc[:k]

        for i in range(k):
            for j in range(m-1):
                if dc[i][j] == 0:   dc[i][j] = list_0[j]
                else:               dc[i][j] = list_1[j]

        outputs = []

    if k != 2:
        for i in range(k):
            for j in range(m-2):
                if j == 0:
                    decoder.__elements__['decoder_{}'.format(n)] = ('AND', [dc[i][0], dc[i][1]])
                    decoder.__outputs__ = ['decoder_{}'.format(n)]
                    if (m-1) == 2:  outputs.append('decoder_{}'.format(n))
                    n += 1
                else:
                    decoder.__elements__['decoder_{}'.format(n)] = ('AND', [decoder.__outputs__[j - 1], dc[i][j+1]])
                    decoder.__outputs__.append('decoder_{}'.format(n))
                    if j == m-3:    outputs.append('decoder_{}'.format(n))
                    n += 1

        decoder.__outputs__ = outputs
    else:   decoder.__outputs__ = ['n_s1', '_s1']

    for i in range(k):
        decoder.__elements__['decoder_{}'.format(n)] = ('XOR', [decoder.__inputs__[i], decoder.__outputs__[i]])
        n += 1
        if i == 0:  outputs = ['decoder_{}'.format(n-1)]
        else:       outputs.append('decoder_{}'.format(n-1))

    decoder.__outputs__ = outputs

    if (m-1) != 1:
        for i in range(m-2):
            if i == 0:
                decoder.__elements__['decoder_{}'.format(n)] = ('OR', [list_1[0], list_1[1]])
                n += 1
            else:
                decoder.__elements__['decoder_{}'.format(n)] = ('OR', [list_1[i+1], 'decoder_{}'.format(n-1)])
                n += 1

    if k != 2:  out = 'decoder_{}'.format(n-1)
    else:       out = '_s1'

    in1 = 'decoder_{}'.format(n)
    n += 1
    in2 = 'decoder_{}'.format(n)
    n += 1

    decoder.__outputs__.append('_s0')
    decoder.__outputs__.append('n_s0')

    decoder.__elements__[in1] = ('AND', [out, 'n_s0'])
    decoder.__elements__[in2] = ('AND', ['decoder_0', '_s0'])
    decoder.__elements__['flag'] = ('OR', [in1, in2])
    decoder.__outputs__.append('flag')
    decoder.__elements__['decoder_0'] = ('GND', [])

    return decoder, n