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
コード例 #2
0
def subscheme_by_inputs(scheme, nodes):
    sub = sa.scheme_alt()
    sub.__inputs__ = copy.copy(nodes)
    interarr = copy.copy(nodes)
    input_nodes = []

    while interarr != []:
        label = interarr.pop()
        if (label in scheme.__outputs__) & (label not in sub.__outputs__):
            sub.__outputs__.append(label)
        for element in scheme.__elements__:
            if label in scheme.__elements__[element][1]:
                sub.__elements__[element] = copy.deepcopy(scheme.__elements__[element])
                input_nodes.append(sub.__elements__[element][1][0])
                if sub.__elements__[element][0] not in ["INV", "BUF", "VCC", "GND"]:
                    input_nodes.append(sub.__elements__[element][1][1])
                interarr.append(element)

    for input in input_nodes:
        if input not in sub.all_labels():
            sub.__inputs__.append(input)

    return sub
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
コード例 #4
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