diff --git a/arithmetic_circuits_generator.py b/arithmetic_circuits_generator.py index 9f8a913..2281ee7 100644 --- a/arithmetic_circuits_generator.py +++ b/arithmetic_circuits_generator.py @@ -1,425 +1,386 @@ #KOMPONENTY PROPOJU - -#todo ?? class wire(): - def __init__(self, value=0): - #todo nechat inicializaci? + def __init__(self, name : str, value : int = 0, index : int = 0): + self.name = name self.value = value - self.id=None - - def add_wire_id(self, wire_id): - self.id = wire_id + self.index = index - def get_wire_id(self): - return self.id + def get_declaration_c(self): + return f" uint8_t {self.name} = 0;\n" + + def get_wire_value(self, offset : int = 0): + return f"(({self.name} >> {offset}) & 0x01)" + + def return_wire_value(self, offset : int = 0): + return f"({self.name} & 0x01) << {offset}" class bus(): #inicializace sbernice - def __init__(self, N=1): - self.bus = [wire() for i in range(N)] + def __init__(self, prefix : str = "bus", N : int = 1): + self.bus = [wire(name=prefix, index= i) for i in range(N)] + self.prefix = prefix self.N = N - def get_wire(self, wire_index): - return self.bus[wire_index] - - def add_wire_id(self, wire_id, wire_index=0): - self.bus[wire_index].id = wire_id + def __index__(self, wire): + return self.bus.index(wire) - def get_wire_id(self, wire_index): - return self.bus[wire_index].id + #pripojeni vystupniho vodice vnitrni komponenty na vstup jine komponenty (nebo drat vystupni sbernice obvodu) + def connect(self, out_wire_index : int, inner_component_out_wire : wire): + self.bus[out_wire_index] = inner_component_out_wire - #vraci logickou hodnotu vedenou na drate s prislusnym indexem - def get_wire_value(self, wire_index): - return self.bus[wire_index].value + def get_wire_value(self, offset : int = 0): + self.bus[offset].get_wire_value(offset) - #pripojeni vstupni, vystupni hodnoty komponenty k sbernici - def connect(self, wire_index, component_output_value): - self.bus[wire_index].value = component_output_value + def return_wire_value(self, offset : int = 0): + self.bus[offset].return_wire_value(offset) + + def get_declaration_c(self): + if self.N > 8: + return f" uint64_t {self.prefix} = 0;\n" + else: + return f" uint8_t {self.prefix} = 0;\n" + + def get_wire(self, wire_index : int): + return self.bus[wire_index] + #KOMPONENTY HRADEL class logic_gate(): - def export_to_C(self, filename, main_component=True, file_object=None, wire_id=0, line_var_cnt=0, init_run=True): - if main_component == True: - with open(filename,'w') as f: - f.write('#include \n\n') + @staticmethod + def get_includes_c(): + return f"#include \n#include \n\n" - if self.gate_type == 'not_gate': - f.write('uint8_t not_gate(uint8_t a) {\n') - f.write(' uint8_t y = 0;\n') - f.write(' uint8_t n1 = (a >> 0) & 0x1;\n') - f.write(' y |= (~n1 & 0x01) << 0;\n') - elif self.gate_type == 'and_gate': - f.write('uint8_t and_gate(uint8_t a, uint8_t b) {\n') - f.write(' uint8_t y = 0;\n') - f.write(' uint8_t n1 = (a >> 0) & 0x1;\n') - f.write(' uint8_t n2 = (b >> 0) & 0x1;\n') - f.write(' y |= ((n1 & n2) & 0x01) << 0;\n') - elif self.gate_type == 'or_gate': - f.write('uint8_t or_gate(uint8_t a, uint8_t b) {\n') - f.write(' uint8_t y = 0;\n') - f.write(' uint8_t n1 = (a >> 0) & 0x1;\n') - f.write(' uint8_t n2 = (b >> 0) & 0x1;\n') - f.write(' y |= ((n1 | n2) & 0x01) << 0;\n') - elif self.gate_type == 'xor_gate': - f.write('uint8_t xor_gate(uint8_t a, uint8_t b) {\n') - f.write(' uint8_t y = 0;\n') - f.write(' uint8_t n1 = (a >> 0) & 0x1;\n') - f.write(' uint8_t n2 = (b >> 0) & 0x1;\n') - f.write(' y |= ((n1 ^ n2) & 0x01) << 0;\n') - - f.write(' return y;\n') - f.write('}\n') - else: - if init_run == True: - if line_var_cnt == 0: - file_object.write(' uint8_t ') - else: - file_object.write(', ') - file_object.write(f'w_{wire_id}=0') + def get_prototype_c(self): + return f"uint8_t {self.gate_type}(uint8_t a, uint8_t b)" + "{" + '\n' - self.y.add_wire_id(wire_id) - - else: - if self.gate_type == 'not_gate': - file_object.write(f' w_{self.y.get_wire_id()} = ~w_{self.input.get_wire_id(0)};\n') - else: - file_object.write(f' w_{self.y.get_wire_id()} = w_{self.input.get_wire_id(0)} {self.operator} w_{self.input.get_wire_id(1)};\n') + def get_declaration_c(self): + return f"{self.a.get_declaration_c()}{self.b.get_declaration_c()}{self.output.get_declaration_c()}" + + def get_initialization_c(self): + return f"{self.a.name} {self.operator} {self.b.name}" + + def get_function_c(self): + return f"{self.a.get_wire_value()} {self.operator} {self.b.get_wire_value(0)}" + + #generovani samostatneho obvodu logickeho hradla do jazyka C + def get_c_code(self, file_object): + file_object.write(self.get_includes_c()) + file_object.write(self.get_prototype_c()) + file_object.write(" return "+(self.get_function_c())+";\n}") + file_object.close() #jednovstupove class not_gate(logic_gate): - def __init__(self, input_wire_a): + def __init__(self, a : wire, prefix : str = "w", outid : int = 0): self.gate_type = 'not_gate' - self.wires_N = 2 - self.input = bus(1) + self.operator = '~' + self.a = wire(prefix+"_"+a.name.replace(prefix+"_", ''),a.value) - self.input.bus[0] = input_wire_a - - if input_wire_a.value == 1: - self.y = wire(0) + if self.a.value == 1: + self.output = wire(name=prefix+"_y"+str(outid),value=0) else: - self.y = wire(1) + self.output = wire(name=prefix+"_y"+str(outid),value=1) + + def get_prototype_c(self): + return f"uint8_t {self.gate_type}(uint8_t a)" + "{" + '\n' + def get_declaration_c(self): + return f"{self.a.get_declaration_c()}{self.output.get_declaration_c()}" + + def get_initialization_c(self): + return f"{self.operator}{self.a.name}" + + def get_function_c(self): + return f"{self.operator}{self.a.get_wire_value()} & 0x01 << 0" #dvouvstupove class and_gate(logic_gate): - def __init__(self, input_wire_a, input_wire_b): + def __init__(self, a : wire, b : wire, prefix : str = "w", outid : int = 0): self.gate_type = 'and_gate' - self.wires_N = 3 self.operator = '&' - self.input = bus(2) - - self.input.bus[0] = input_wire_a - self.input.bus[1] = input_wire_b + self.a = wire(prefix+"_"+a.name.replace(prefix+"_", ''),a.value) + self.b = wire(prefix+"_"+b.name.replace(prefix+"_", ''),a.value) - if input_wire_a.value == 1 and input_wire_b.value == 1: - self.y = wire(1) + if a.value == 1 and b.value == 1: + self.output = wire(name=prefix+"_y"+str(outid),value=1) else: - self.y = wire(0) + self.output = wire(name=prefix+"_y"+str(outid),value=0) + +class nand_gate(logic_gate): + def __init__(self, a : wire, b : wire, prefix : str = "w", outid : int = 0): + self.gate_type = 'nand_gate' + self.operator = '&' + self.a = wire(prefix+"_"+a.name.replace(prefix+"_", ''),a.value) + self.b = wire(prefix+"_"+b.name.replace(prefix+"_", ''),a.value) + + if self.a.value == 1 and self.b.value == 1: + self.output = wire(name=prefix+"_y"+str(outid),value=0) + else: + self.output = wire(name=prefix+"_y"+str(outid),value=1) + + def get_function_c(self): + return "~("+(super().get_function_c())+f") & 0x01 << 0" class or_gate(logic_gate): - def __init__(self, input_wire_a, input_wire_b): + def __init__(self, a : wire, b : wire, prefix : str = "w", outid : int = 0): self.gate_type = 'or_gate' - self.wires_N = 3 self.operator = '|' - self.input = bus(2) + self.a = wire(prefix+"_"+a.name.replace(prefix+"_", ''),a.value) + self.b = wire(prefix+"_"+b.name.replace(prefix+"_", ''),a.value) - self.input.bus[0] = input_wire_a - self.input.bus[1] = input_wire_b - - if input_wire_a.value == 1 or input_wire_b.value == 1: - self.y = wire(1) + if self.a.value == 1 or self.b.value == 1: + self.output = wire(name=prefix+"_y"+str(outid),value=1) else: - self.y = wire(0) + self.output = wire(name=prefix+"_y"+str(outid),value=0) + +class nor_gate(logic_gate): + def __init__(self, a : wire, b : wire, prefix : str = "w", outid : int = 0): + self.gate_type = 'nor_gate' + self.operator = '|' + self.a = wire(prefix+"_"+a.name.replace(prefix+"_", ''),a.value) + self.b = wire(prefix+"_"+b.name.replace(prefix+"_", ''),a.value) + + if self.a.value == 1 or self.b.value == 1: + self.output = wire(name=prefix+"_y"+str(outid),value=0) + else: + self.output = wire(name=prefix+"_y"+str(outid),value=1) + + def get_function_c(self): + return "~("+(super().get_function_c())+") & 0x01 << 0" class xor_gate(logic_gate): - def __init__(self, input_wire_a, input_wire_b): + def __init__(self, a : wire, b : wire, prefix : str = "w", outid : int = 0): self.gate_type = 'xor_gate' - self.wires_N = 3 self.operator = '^' - self.input = bus(2) + self.a = wire(prefix+"_"+a.name.replace(prefix+"_", ''),a.value) + self.b = wire(prefix+"_"+b.name.replace(prefix+"_", ''),a.value) - self.input.bus[0] = input_wire_a - self.input.bus[1] = input_wire_b - - if (input_wire_a.value == 1 and input_wire_b.value == 0) or (input_wire_a.value == 0 and input_wire_b.value == 1): - self.y = wire(1) + if (a.value == 1 and b.value == 0) or (a.value == 0 and b.value == 1): + self.output = wire(name=prefix+"_y"+str(outid),value=1) else: - self.y = wire(0) + self.output = wire(name=prefix+"_y"+str(outid),value=0) + +class xnor_gate(logic_gate): + def __init__(self, a : wire, b : wire, prefix : str = "w", outid : int = 0): + self.gate_type = 'xnor_gate' + self.operator = '^' + self.a = wire(prefix+"_"+a.name.replace(prefix+"_", ''),a.value) + self.b = wire(prefix+"_"+b.name.replace(prefix+"_", ''),a.value) + + if (self.a.value == 1 and self.b.value == 0) or (self.a.value == 0 and self.b.value == 1): + self.output = wire(name=prefix+"_y"+str(outid),value=0) + else: + self.output = wire(name=prefix+"_y"+str(outid),value=1) + + def get_function_c(self): + return "~("+(super().get_function_c())+") & 0x01 << 0" #ARITMETICKE OBVODY class arithmetic_circuit(): def __init__(self): - self.component_list = [] + self.components = [] + self.circuit_wires = [] + self.c_data_type = "uint64_t" + self.input_N = 0 self.carry_out_gate = None self.sum_out_gates = [] def add_component(self, component): - self.component_list.append(component) - - def get_component_index(self, component): - return self.component_list.index(component) + self.components.append(component) def get_previous_component(self): - return self.component_list[-1] + return self.components[-1] - #pomocna funkce - def wire_index_offset(self, index): - return index + def get_sum_wire(self): + return self.out.get_wire(0) - def get_carry_out_wire(self): - return self.carry_out_gate.y + def get_carry_wire(self): + return self.out.get_wire(1) - #todo jinak zpravidla posledni bit ve vystupnim vektoru bitu - def get_carry_out_val(self): - return self.carry_out_gate.value + @staticmethod + def get_includes_c(): + return f"#include \n#include \n\n" + + def get_prototype_c(self): + return f"{self.c_data_type} {self.prefix}({self.c_data_type} {self.a.prefix}, {self.c_data_type} {self.b.prefix})" + "{" + '\n' + + def get_declaration_c(self): + return f"".join([c.get_declaration_c() for c in self.components]) + + def get_initialization_c(self): + return "".join([c.get_initialization_c() for c in self.components]) - #todo - def get_sum_out_val(self, index): - return self.out.get_value(index) - - #Export do jinych reprezentaci - def export_to_C(self, filename, main_component=True, file_object=None, wire_id=0, line_var_cnt=0, init_run=True): - if main_component == True: - with open(filename,'w') as f: - f.write('#include \n\n') - - #DEKLARACE FUNKCE PRO DANY TYP OBVODU - ## - if self.circuit_type == 'ha': - f.write('uint8_t ha(uint8_t a, uint8_t b) {\n') - f.write(' uint8_t out = 0;\n') - elif self.circuit_type == 'fa': - f.write('uint8_t fa(uint8_t a, uint8_t b, uint8_t cin) {\n') - f.write(' uint8_t out = 0;\n') - elif self.circuit_type == 'rca_'+str(int(self.input_N/2)): - f.write('uint64_t rca(uint64_t a, uint64_t b) {\n') - f.write(' uint64_t out = 0;\n') - - #DEKLARACE DRATU - ## - #deklarace vstupu obvodu - for in_wire_index in range(self.input_N): - if line_var_cnt == 0: - f.write(' uint8_t ') - else: - f.write(', ') - - f.write(f'w_{in_wire_index}=0') - self.inputs.add_wire_id(wire_id, in_wire_index) - line_var_cnt += 1 - wire_id += 1 - - #deklarace vstupu a vystupu hradel vnitrni logiky obvodu - if self.circuit_type != 'ha' and self.circuit_type != 'fa': - for component in self.component_list: - if component.circuit_type == 'ha': - component.export_to_C(filename, False, file_object=f, wire_id=wire_id, line_var_cnt=line_var_cnt) - wire_id += 2 - line_var_cnt += 2 - elif component.circuit_type == 'fa': - component.export_to_C(filename, False, file_object=f, wire_id=wire_id, line_var_cnt=line_var_cnt) - wire_id += 5 - line_var_cnt += 5 - else: - for component in self.component_list: - #zapis 8 promennych na radek, odradkovani pro prehlednost - if line_var_cnt >= 8: - f.write(';\n') - line_var_cnt = 0 - - component.export_to_C(filename, False, file_object=f, wire_id=wire_id, line_var_cnt=line_var_cnt) - wire_id += 1 - line_var_cnt += 1 - - f.write(';\n') - - #PRIRAZENI VSTUPNICH HODNOT K DRATUM - if self.circuit_type == 'fa': - f.write(f' w_{self.inputs.get_wire_id(0)} = (a >> 0) & 0x1;\n') - f.write(f' w_{self.inputs.get_wire_id(1)} = (b >> 0) & 0x1;\n') - f.write(f' w_{self.inputs.get_wire_id(2)} = (cin >> 0) & 0x1;\n') - else: - for in_wire_index in range(0, int(self.input_N/2)): - f.write(f' w_{self.inputs.get_wire_id(in_wire_index)} = (a >> {in_wire_index}) & 0x1;\n') - - for in_wire_index in range(0, int(self.input_N/2)): - f.write(f' w_{self.inputs.get_wire_id(in_wire_index + int(self.input_N/2))} = (b >> {in_wire_index}) & 0x1;\n') - - #VYPOCTY VYSTUPNICH HODNOT HRADEL - ## - for component in self.component_list: - component.export_to_C(filename, False, file_object=f, init_run=False) - - #PRIRAZENI VYSTUPU - ## - for out_wire_index in range(self.out.N): - if self.circuit_type != 'ha' and self.circuit_type != 'fa': - if out_wire_index == (self.out.N)-1: - out_component_index = self.component_list[out_wire_index-1].get_component_index(self.carry_out_gate) - component = self.component_list[out_wire_index-1] - - else: - out_component_index = self.component_list[out_wire_index].get_component_index(self.sum_out_gates[out_wire_index]) - component = self.component_list[out_wire_index] - - if component.circuit_type == 'ha': - out_component_index = out_component_index * out_wire_index - elif component.circuit_type == 'fa': - if out_wire_index == (self.out.N)-1: - out_component_index += 5 * (out_wire_index-2) + 2 - else: - out_component_index += 5 * (out_wire_index-1) + 2 - - wire_id = self.wire_index_offset(out_component_index+self.input_N) - f.write(f' out |= (w_{wire_id} & 0x01) << {out_wire_index};\n') - else: - #Cout - if out_wire_index == (self.out.N)-1: - out_component_index = self.get_component_index(self.carry_out_gate) - #Sum - else: - out_component_index = self.get_component_index(self.sum_out_gates[out_wire_index]) - - wire_id = self.wire_index_offset(out_component_index+self.input_N) - f.write(f' out |= (w_{wire_id} & 0x01) << {out_wire_index};\n') - - - f.write(' return out;\n') - f.write('}\n') - else: - if init_run == True: - for component in self.component_list: - - #zapis 8 promennych na radek, odradkovani pro prehlednost - if line_var_cnt >= 8: - file_object.write(';\n') - line_var_cnt = 0 - - component.export_to_C(filename, False, file_object=file_object, wire_id=wire_id, line_var_cnt=line_var_cnt) - wire_id += 1 - line_var_cnt += 1 - else: - for component in self.component_list: - component.export_to_C(filename, False, file_object=file_object, init_run=False) + def get_function_sum_c(self): + return "".join([c.get_function_sum_c(self.components.index(c)) for c in self.components]) + + def get_function_carry_c(self): + return f"{self.get_previous_component().get_function_carry_c(offset=self.out.N-1)}" + #generovani aritmetickeho obvodu do jazyka C + def get_c_code(self, file_object): + file_object.write(self.get_includes_c()) + file_object.write(self.get_prototype_c()) + file_object.write(self.out.get_declaration_c()) + file_object.write(self.get_declaration_c()) + file_object.write(self.get_initialization_c()) + file_object.write(self.get_function_sum_c()) + file_object.write(self.get_function_carry_c()) + file_object.write(f" return {self.out.prefix}"+";\n}") + file_object.close() class half_adder(arithmetic_circuit): - def __init__(self, input_wire_a, input_wire_b): + def __init__(self, a : wire, b : wire, prefix : str = "ha"): super().__init__() - self.input_N = 2 - self.circuit_type = 'ha' - self.inputs = bus(self.input_N) - self.inputs.bus[0] = input_wire_a - self.inputs.bus[1] = input_wire_b - + self.c_data_type = "uint8_t" + self.prefix = prefix + self.a = a + self.b = b #2 draty pro vystupy komponenty (sum, cout) - self.out = bus(2) - + self.out = bus("out",2) + #Sum #XOR hradlo pro vypocet jednobitového souctu (sum) - obj_xor_gate = xor_gate(input_wire_a, input_wire_b) + obj_xor_gate = xor_gate(a, b, prefix, outid=0) self.add_component(obj_xor_gate) - self.out.connect(0,obj_xor_gate.y) - self.sum_out_gates.append(obj_xor_gate) + self.out.connect(0,obj_xor_gate.output) #Cout #AND hradlo pro vypocet jednobitoveho priznaku prenosu do vyssiho radu (cout)jednobitového souctu (sum) - obj_and_gate = and_gate(input_wire_a, input_wire_b) + obj_and_gate = and_gate(a, b, prefix, outid=1) self.add_component(obj_and_gate) - self.out.connect(1,obj_and_gate.y) - self.carry_out_gate = obj_and_gate + self.out.connect(1,obj_and_gate.output) + + def get_prototype_c(self): + return f"{self.c_data_type} {self.prefix}({self.c_data_type} {self.a.name}, {self.c_data_type} {self.b.name})" + "{" + '\n' - def get_sum_out_component(self): - return self.component_list[0] + # ziskani vsech unikatnich vodicu obvodu ze vsech hradel k zajisteni neopakujicich se deklaraci stejnych vodicu + def get_declaration_c(self): + for component in self.components: + if not [item for item in self.circuit_wires if item[1] == component.a.name]: + self.circuit_wires.append((component.a, component.a.name)) + + if not [item for item in self.circuit_wires if item[1] == component.b.name]: + self.circuit_wires.append((component.b, component.b.name)) + + if not [item for item in self.circuit_wires if item[1] == component.output.name]: + self.circuit_wires.append((component.output, component.output.name)) + + #unikatni deklarace vsech propoju obvodu + return "".join([c[0].get_declaration_c() for c in self.circuit_wires]) + + #inicializace hodnot vodicu polovicni scitacky + def get_initialization_c(self): + return f" {self.components[0].a.name} = {self.a.get_wire_value(offset=self.a.index)};\n" + \ + f" {self.components[0].b.name} = {self.b.get_wire_value(offset=self.b.index)};\n" + \ + f" {self.components[0].output.name} = {self.components[0].get_initialization_c()};\n" + \ + f" {self.components[1].output.name} = {self.components[1].get_initialization_c()};\n" + + def get_function_sum_c(self, offset : int = 0): + return f" {self.out.prefix} |= {self.components[0].output.return_wire_value(offset = offset)};\n" + + def get_function_carry_c(self, offset : int = 1): + return f" {self.out.prefix} |= {self.components[1].output.return_wire_value(offset = offset)};\n" - def get_sum_out_wire(self): - return self.out.get_wire(0) - class full_adder(arithmetic_circuit): - def __init__(self, input_wire_a, input_wire_b, carry_in_wire): + def __init__(self, a : wire, b : wire, c : wire, prefix : str = "fa"): super().__init__() - self.input_N = 3 - self.circuit_type = 'fa' - self.inputs = bus(self.input_N) - self.inputs.bus[0] = input_wire_a - self.inputs.bus[1] = input_wire_b - self.inputs.bus[2] = carry_in_wire - - + self.c_data_type = "uint8_t" + self.prefix = prefix + self.a = a + self.b = b + self.c = c #2 draty pro vystupy komponenty (sum, cout) - self.out = bus(2) + self.out = bus("out",2) #PG logika - propagate_xor_gate1 = xor_gate(input_wire_a, input_wire_b) + propagate_xor_gate1 = xor_gate(a, b, prefix, outid=0) self.add_component(propagate_xor_gate1) - generate_and_gate1 = and_gate(input_wire_a, input_wire_b) + generate_and_gate1 = and_gate(a, b, prefix, outid=1) self.add_component(generate_and_gate1) #Sum #XOR hradlo pro vypocet jednobitového souctu (sum) - obj_xor_gate2 = xor_gate(propagate_xor_gate1.y, carry_in_wire) + obj_xor_gate2 = xor_gate(propagate_xor_gate1.output, c, prefix, outid=2) self.add_component(obj_xor_gate2) - self.out.connect(0,obj_xor_gate2.y) - self.sum_out_gates.append(obj_xor_gate2) + self.out.connect(0,obj_xor_gate2.output) #Cout #AND hradlo pro vypocet jednobitoveho priznaku prenosu do vyssiho radu (cout)jednobitového souctu (sum) - obj_and_gate2 = and_gate(propagate_xor_gate1.y, carry_in_wire) + obj_and_gate2 = and_gate(propagate_xor_gate1.output, c, prefix, outid=3) self.add_component(obj_and_gate2) - obj_or_gate = or_gate(generate_and_gate1.y, obj_and_gate2.y) + obj_or_gate = or_gate(generate_and_gate1.output, obj_and_gate2.output, prefix, outid=4) self.add_component(obj_or_gate) - self.out.connect(1,obj_or_gate.y) - self.carry_out_gate = obj_or_gate - - #todo nechat? - self.propagate = propagate_xor_gate1.y - self.generate = generate_and_gate1.y + self.out.connect(1,obj_or_gate.output) - def get_sum_out_component(self): - return self.component_list[0] + #todo nechat do budoucna? + self.propagate = propagate_xor_gate1.output + self.generate = generate_and_gate1.output + + #3 vstupy spolu s carry in + def get_prototype_c(self): + return f"{self.c_data_type} {self.prefix}({self.c_data_type} {self.a.name}, {self.c_data_type} {self.b.name}, {self.c_data_type} {self.c.name})" + "{" + '\n' + + def get_declaration_c(self): + for component in self.components: + if not [item for item in self.circuit_wires if item[1] == component.a.name]: + self.circuit_wires.append((component.a, component.a.name)) + + if not [item for item in self.circuit_wires if item[1] == component.b.name]: + self.circuit_wires.append((component.b, component.b.name)) - def get_sum_out_wire(self): - return self.out.get_wire(0) + if not [item for item in self.circuit_wires if item[1] == component.output.name]: + self.circuit_wires.append((component.output, component.output.name)) + + #unikatni deklarace vsech propoju obvodu + return "".join([c[0].get_declaration_c() for c in self.circuit_wires]) + + #inicializace hodnot vodicu uplne scitacky + def get_initialization_c(self): + return f" {self.components[0].a.name} = {self.a.get_wire_value(offset=self.a.index)};\n" + \ + f" {self.components[0].b.name} = {self.b.get_wire_value(offset=self.b.index)};\n" + \ + f" {self.components[2].b.name} = {self.c.get_wire_value()};\n" + \ + f" {self.components[0].output.name} = {self.components[0].get_initialization_c()};\n" + \ + f" {self.components[1].output.name} = {self.components[1].get_initialization_c()};\n" + \ + f" {self.components[2].output.name} = {self.components[2].get_initialization_c()};\n" + \ + f" {self.components[3].output.name} = {self.components[3].get_initialization_c()};\n" + \ + f" {self.components[4].output.name} = {self.components[4].get_initialization_c()};\n" + + def get_function_sum_c(self, offset : int = 0): + return f" {self.out.prefix} |= {self.components[2].output.return_wire_value(offset = offset)};\n" + + def get_function_carry_c(self, offset : int = 1): + return f" {self.out.prefix} |= {self.components[4].output.return_wire_value(offset = offset)};\n" class ripple_carry_adder(arithmetic_circuit): - def __init__(self, input_bus_a, input_bus_b): + def __init__(self, a : bus, b : bus, prefix : str = "rca"): super().__init__() - N = max(input_bus_a.N,input_bus_b.N) - self.input_N = N * 2 - self.circuit_type = 'rca_'+str(N) - self.sum_out_gates= [] - - self.inputs = bus(self.input_N) - for i in range(N): - self.inputs.bus[i] = input_bus_a.get_wire(i) - for i in range(N): - self.inputs.bus[i+N] = input_bus_b.get_wire(i) + N = max(a.N,b.N) + self.prefix = prefix+str(N) + self.a = a + self.b = b #vystupni draty pro N souctu a vystupni priznak prenosu do vyssiho radu (cout) - self.out = bus(N+1) + self.out = bus("out", N+1) #postupne pridani jednobitovych scitacek for input_index in range(N): #prvni je polovicni scitacka if input_index == 0: - obj_ha = half_adder(input_bus_a.get_wire(input_index), input_bus_b.get_wire(input_index)) + obj_ha = half_adder(a.get_wire(input_index), b.get_wire(input_index), prefix=self.prefix+"_ha") self.add_component(obj_ha) self.out.connect(input_index, obj_ha) - self.sum_out_gates.append(obj_ha.sum_out_gates[0]) else: - obj_fa = full_adder(input_bus_a.get_wire(input_index), input_bus_b.get_wire(input_index), self.get_previous_component().get_carry_out_wire()) + obj_fa = full_adder(a.get_wire(input_index), b.get_wire(input_index), self.get_previous_component().get_carry_wire(), prefix=self.prefix+"_fa"+str(input_index)) self.add_component(obj_fa) - self.out.connect(input_index, obj_fa.get_sum_out_wire()) + self.out.connect(input_index, obj_fa.get_sum_wire()) - self.sum_out_gates.append(obj_fa.sum_out_gates[0]) if input_index == (N-1): - self.out.connect(N, obj_fa.get_carry_out_wire()) - self.carry_out_gate = obj_fa.carry_out_gate \ No newline at end of file + self.out.connect(N, obj_fa.get_carry_wire()) \ No newline at end of file