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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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