diff --git a/.gitignore b/.gitignore index 5069057..ac94c67 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ __pycache__/ test.py Makefile *.c - +t.py \ No newline at end of file diff --git a/arithmetic_circuits_generator.py b/arithmetic_circuits_generator.py index 3293e90..359fb2c 100644 --- a/arithmetic_circuits_generator.py +++ b/arithmetic_circuits_generator.py @@ -1,187 +1,9 @@ -#KOMPONENTY PROPOJU -class wire(): - def __init__(self, name : str, value : int = 0, index : int = 0): - self.name = name - self.value = value - self.index = index - - def get_declaration_c(self): - return f" uint8_t {self.name} = 0;\n" - - def get_wire_value_c(self, offset : int = 0): - return f"(({self.name} >> {offset}) & 0x01)" - - def return_wire_value_c(self, offset : int = 0): - return f"({self.name} & 0x01) << {offset}" - -class bus(): - #inicializace sbernice - 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 __index__(self, wire): - return self.bus.index(wire) - - #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 - - def get_wire_value_c(self, offset : int = 0): - self.bus[offset].get_wire_value_c(offset) - - def return_wire_value_c(self, offset : int = 0): - self.bus[offset].return_wire_value_c(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 __init__(self, a : wire, b : wire, prefix : str = "w"): - self.a = wire(prefix+"_"+a.name.replace(prefix+"_", ''),a.value) - self.b = wire(prefix+"_"+b.name.replace(prefix+"_", ''),b.value) - self.prefix = prefix - - @staticmethod - def get_includes_c(): - return f"#include \n#include \n\n" - - def get_prototype_c(self): - return f"uint8_t {self.gate_type}(uint8_t a, uint8_t b)" + "{" + '\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): - self.a.name = self.a.name.replace(self.prefix+"_", '') - self.b.name = self.b.name.replace(self.prefix+"_", '') - return f"{self.a.get_wire_value_c()} {self.operator} {self.b.get_wire_value_c(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, a : wire, prefix : str = "w", outid : int = 0): - self.gate_type = 'not_gate' - self.operator = '~' - self.a = wire(prefix+"_"+a.name.replace(prefix+"_", ''),a.value) - self.prefix = prefix - - if self.a.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_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): - self.a.name = self.a.name.replace(self.prefix+"_", '') - return f"{self.operator}{self.a.get_wire_value_c()} & 0x01 << 0" - -#dvouvstupove -class and_gate(logic_gate): - def __init__(self, a : wire, b : wire, prefix : str = "w", outid : int = 0): - super().__init__(a,b,prefix) - self.gate_type = 'and_gate' - self.operator = '&' - - if a.value == 1 and b.value == 1: - self.output = wire(name=prefix+"_y"+str(outid),value=1) - else: - 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): - super().__init__(a,b,prefix) - self.gate_type = 'nand_gate' - self.operator = '&' - - 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" +from wire_components import wire, bus +from logic_gates_generator import and_gate, xor_gate, or_gate +import sys -class or_gate(logic_gate): - def __init__(self, a : wire, b : wire, prefix : str = "w", outid : int = 0): - super().__init__(a,b,prefix) - self.gate_type = 'or_gate' - self.operator = '|' - - if self.a.value == 1 or self.b.value == 1: - self.output = wire(name=prefix+"_y"+str(outid),value=1) - else: - 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): - super().__init__(a,b,prefix) - self.gate_type = 'nor_gate' - self.operator = '|' - - 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, a : wire, b : wire, prefix : str = "w", outid : int = 0): - super().__init__(a,b,prefix) - self.gate_type = 'xor_gate' - self.operator = '^' - - 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.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): - super().__init__(a,b,prefix) - self.gate_type = 'xnor_gate' - self.operator = '^' - - 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 +# ARITMETICKE OBVODY class arithmetic_circuit(): def __init__(self): self.components = [] @@ -216,135 +38,136 @@ class arithmetic_circuit(): def get_initialization_c(self): return "".join([c.get_initialization_c() for c in self.components]) - + 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 + # 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_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, a : wire, b : wire, prefix : str = "ha"): + def __init__(self, a: wire, b: wire, prefix: str = "ha"): super().__init__() 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("out",2) - - #Sum - #XOR hradlo pro vypocet jednobitového souctu (sum) + # 2 draty pro vystupy komponenty (sum, cout) + self.out = bus("out", 2) + + # Sum + # XOR hradlo pro vypocet jednobitového souctu (sum) obj_xor_gate = xor_gate(a, b, prefix, outid=0) self.add_component(obj_xor_gate) - self.out.connect(0,obj_xor_gate.output) + self.out.connect(0, obj_xor_gate.output) - #Cout - #AND hradlo pro vypocet jednobitoveho priznaku prenosu do vyssiho radu (cout)jednobitového souctu (sum) + # Cout + # AND hradlo pro vypocet jednobitoveho priznaku prenosu do vyssiho radu (cout)jednobitového souctu (sum) obj_and_gate = and_gate(a, b, prefix, outid=1) self.add_component(obj_and_gate) - self.out.connect(1,obj_and_gate.output) - + 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' - # ziskani vsech unikatnich vodicu obvodu ze vsech hradel k zajisteni neopakujicich se deklaraci stejnych vodicu - def get_declaration_c(self): + # 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 + # Unikatni deklarace vsech propoju obvodu return "".join([c[0].get_declaration_c() for c in self.circuit_wires]) - #inicializace hodnot vodicu polovicni scitacky + # Inicializace hodnot vodicu polovicni scitacky def get_initialization_c(self): return f" {self.components[0].a.name} = {self.a.get_wire_value_c(offset=self.a.index)};\n" + \ f" {self.components[0].b.name} = {self.b.get_wire_value_c(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): + 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_c(offset = offset)};\n" - - def get_function_carry_c(self, offset : int = 1): + + def get_function_carry_c(self, offset: int = 1): return f" {self.out.prefix} |= {self.components[1].output.return_wire_value_c(offset = offset)};\n" class full_adder(arithmetic_circuit): - def __init__(self, a : wire, b : wire, c : wire, prefix : str = "fa"): + def __init__(self, a: wire, b: wire, c: wire, prefix: str = "fa"): super().__init__() 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("out",2) + # 2 draty pro vystupy komponenty (sum, cout) + self.out = bus("out", 2) - #PG logika + # PG logika propagate_xor_gate1 = xor_gate(a, b, prefix, outid=0) self.add_component(propagate_xor_gate1) 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) + + # Sum + # XOR hradlo pro vypocet jednobitového souctu (sum) 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.output) + self.out.connect(0, obj_xor_gate2.output) - #Cout - #AND hradlo pro vypocet jednobitoveho priznaku prenosu do vyssiho radu (cout)jednobitového souctu (sum) + # Cout + # AND hradlo pro vypocet jednobitoveho priznaku prenosu do vyssiho radu (cout)jednobitového souctu (sum) 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.output, obj_and_gate2.output, prefix, outid=4) self.add_component(obj_or_gate) - self.out.connect(1,obj_or_gate.output) - - #todo nechat do budoucna? + self.out.connect(1, obj_or_gate.output) + + # TODO nechat do budoucna? self.propagate = propagate_xor_gate1.output self.generate = generate_and_gate1.output - - #3 vstupy spolu s carry in + + # 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)) 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 + # Unikatni deklarace vsech propoju obvodu return "".join([c[0].get_declaration_c() for c in self.circuit_wires]) - - #inicializace hodnot vodicu uplne scitacky + + # Inicializace hodnot vodicu uplne scitacky def get_initialization_c(self): return f" {self.components[0].a.name} = {self.a.get_wire_value_c(offset=self.a.index)};\n" + \ f" {self.components[0].b.name} = {self.b.get_wire_value_c(offset=self.b.index)};\n" + \ @@ -354,28 +177,28 @@ class full_adder(arithmetic_circuit): 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): + + def get_function_sum_c(self, offset: int = 0): return f" {self.out.prefix} |= {self.components[2].output.return_wire_value_c(offset = offset)};\n" - def get_function_carry_c(self, offset : int = 1): + def get_function_carry_c(self, offset: int = 1): return f" {self.out.prefix} |= {self.components[4].output.return_wire_value_c(offset = offset)};\n" class ripple_carry_adder(arithmetic_circuit): - def __init__(self, a : bus, b : bus, prefix : str = "rca"): + def __init__(self, a: bus, b: bus, prefix: str = "rca"): super().__init__() - N = max(a.N,b.N) + 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) + # Vystupni draty pro N souctu a vystupni priznak prenosu do vyssiho radu (cout) self.out = bus("out", N+1) - #postupne pridani jednobitovych scitacek + # Postupne pridani jednobitovych scitacek for input_index in range(N): - #prvni je polovicni scitacka + # Prvni je polovicni scitacka if input_index == 0: obj_ha = half_adder(a.get_wire(input_index), b.get_wire(input_index), prefix=self.prefix+"_ha") self.add_component(obj_ha) @@ -384,6 +207,21 @@ class ripple_carry_adder(arithmetic_circuit): 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_wire()) - + if input_index == (N-1): - self.out.connect(N, obj_fa.get_carry_wire()) \ No newline at end of file + self.out.connect(N, obj_fa.get_carry_wire()) + +if __name__ == "__main__": + # Vytvoreni obvodu 8 bitove postupne scitacky + a = bus(N=8, prefix="a") + b = bus(N=8, prefix="b") + rca = ripple_carry_adder(a, b) + # Export do jazyka C (flat) + rca.get_c_code(open("rca_8.c", "w")) + + # Vytvoreni logickeho hradla OR + a1 = wire("a", 1) + b1 = wire("b", 0) + xor_gate = xor_gate(a1, b1) + # Export do jazyka C (flat) + xor_gate.get_c_code(sys.stdout) diff --git a/logic_gates_generator.py b/logic_gates_generator.py new file mode 100644 index 0000000..7ff29ae --- /dev/null +++ b/logic_gates_generator.py @@ -0,0 +1,143 @@ +from wire_components import wire + + +# KOMPONENTY HRADEL +class logic_gate(): + def __init__(self, a: wire, b: wire, prefix: str = "w"): + self.a = wire(prefix+"_"+a.name.replace(prefix+"_", ''), a.value) + self.b = wire(prefix+"_"+b.name.replace(prefix+"_", ''), b.value) + self.prefix = prefix + + @staticmethod + def get_includes_c(): + return f"#include \n#include \n\n" + + def get_prototype_c(self): + return f"uint8_t {self.gate_type}(uint8_t a, uint8_t b)" + "{" + '\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): + self.a.name = self.a.name.replace(self.prefix+"_", '') + self.b.name = self.b.name.replace(self.prefix+"_", '') + return f"{self.a.get_wire_value_c()} {self.operator} {self.b.get_wire_value_c(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() + + +# Jednovstupa +class not_gate(logic_gate): + def __init__(self, a: wire, prefix: str = "w", outid: int = 0): + self.gate_type = 'not_gate' + self.operator = '~' + self.a = wire(prefix+"_"+a.name.replace(prefix+"_", ''), a.value) + self.prefix = prefix + + if self.a.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_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): + self.a.name = self.a.name.replace(self.prefix+"_", '') + return f"{self.operator}{self.a.get_wire_value_c()} & 0x01 << 0" + + +# Dvouvstupa +class and_gate(logic_gate): + def __init__(self, a: wire, b: wire, prefix: str = "w", outid: int = 0): + super().__init__(a, b, prefix) + self.gate_type = 'and_gate' + self.operator = '&' + + if a.value == 1 and b.value == 1: + self.output = wire(name=prefix+"_y"+str(outid), value=1) + else: + 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): + super().__init__(a, b, prefix) + self.gate_type = 'nand_gate' + self.operator = '&' + + 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, a: wire, b: wire, prefix: str = "w", outid: int = 0): + super().__init__(a, b, prefix) + self.gate_type = 'or_gate' + self.operator = '|' + + if self.a.value == 1 or self.b.value == 1: + self.output = wire(name=prefix+"_y"+str(outid), value=1) + else: + 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): + super().__init__(a, b, prefix) + self.gate_type = 'nor_gate' + self.operator = '|' + + 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, a: wire, b: wire, prefix: str = "w", outid: int = 0): + super().__init__(a, b, prefix) + self.gate_type = 'xor_gate' + self.operator = '^' + + 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.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): + super().__init__(a, b, prefix) + self.gate_type = 'xnor_gate' + self.operator = '^' + + 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" diff --git a/wire_components.py b/wire_components.py new file mode 100644 index 0000000..8f4e004 --- /dev/null +++ b/wire_components.py @@ -0,0 +1,48 @@ +# KOMPONENTY PROPOJU + + +class wire(): + def __init__(self, name: str, value: int = 0, index: int = 0): + self.name = name + self.value = value + self.index = index + + def get_declaration_c(self): + return f" uint8_t {self.name} = 0;\n" + + def get_wire_value_c(self, offset: int = 0): + return f"(({self.name} >> {offset}) & 0x01)" + + def return_wire_value_c(self, offset: int = 0): + return f"({self.name} & 0x01) << {offset}" + + +class bus(): + # Inicializace sbernice + 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 __index__(self, wire): + return self.bus.index(wire) + + # 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 + + def get_wire_value_c(self, offset: int = 0): + self.bus[offset].get_wire_value_c(offset) + + def return_wire_value_c(self, offset: int = 0): + self.bus[offset].return_wire_value_c(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]