Changed implementaion of generating C code from circuits.

This commit is contained in:
root 2020-12-28 01:30:52 +01:00
parent e15fa5aed5
commit 6fe6d2c3d6

View File

@ -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 <stdint.h>\n\n')
@staticmethod
def get_includes_c():
return f"#include <stdio.h>\n#include <stdint.h>\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 <stdio.h>\n#include <stdint.h>\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 <stdint.h>\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
self.out.connect(N, obj_fa.get_carry_wire())