diff --git a/.gitignore b/.gitignore index cdb10ee..b642747 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ __pycache__/ test.py Makefile *.c +*.v t.py \ No newline at end of file diff --git a/arithmetic_circuits_generator.py b/arithmetic_circuits_generator.py index d2cb9bb..11a410e 100644 --- a/arithmetic_circuits_generator.py +++ b/arithmetic_circuits_generator.py @@ -12,6 +12,7 @@ class arithmetic_circuit(): self.components = [] self.circuit_wires = [] self.c_data_type = "uint64_t" + self.N = 1 # TODO delete? self.carry_out_gate = None @@ -39,7 +40,19 @@ class arithmetic_circuit(): def get_carry_wire(self): return self.out.get_wire(1) - # FLAT C GENERATION # + def get_circuit_wires(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)) + + """ C CODE GENERATION """ + # FLAT C # @staticmethod def get_includes_c(): return f"#include \n#include \n\n" @@ -71,7 +84,7 @@ class arithmetic_circuit(): file_object.write(f" return {self.out.prefix}"+";\n}") file_object.close() - # HIERARCHICAL C GENERATION # + # HIERARCHICAL C # def get_function_blocks_c(self): # Add unique 1-bit adder components (ha, fa) self.component_types = self.get_component_types() @@ -116,6 +129,36 @@ class arithmetic_circuit(): file_object.write(self.get_circuit_c()) file_object.close() + """ VERILOG CODE GENERATION """ + # FLAT VERILOG # + def get_prototype_v(self): + return f"module {self.prefix}(input [{self.N-1}:0] {self.a.prefix}, input [{self.N-1}:0] {self.b.prefix}, output [{self.N}:0] {self.out.prefix});\n" + + def get_declaration_v_flat(self): + return f"".join([c.get_declaration_v_flat() for c in self.components]) + + def get_init_v_flat(self, offset: int = 0, array: bool = False): + return "".join([c.get_init_v_flat(offset=self.components.index(c), array=True) for c in self.components]) + + def get_function_sum_cout_v_flat(self): + return "".join([c.get_function_sum_cout_v_flat(offset=self.components.index(c)) for c in self.components]) + + def get_function_sum_v_flat(self): + return "".join([c.get_function_sum_v_flat(offset=self.components.index(c)) for c in self.components]) + + def get_function_carry_v_flat(self): + return f"{self.get_previous_component().get_function_carry_v_flat(offset=self.out.N-1)}" + + # Generating flat V code representation of circuit + def get_v_code_flat(self, file_object): + file_object.write(self.get_prototype_v()) + file_object.write(self.get_declaration_v_flat()+"\n") + file_object.write(self.get_init_v_flat(array=False)+"\n") + file_object.write(self.get_function_sum_v_flat()) + file_object.write(self.get_function_carry_v_flat()) + file_object.write(f"endmodule") + file_object.close() + class half_adder(arithmetic_circuit): def __init__(self, a: wire, b: wire, prefix: str = "ha"): @@ -125,7 +168,7 @@ class half_adder(arithmetic_circuit): self.a = a self.b = b # 2 wires for component's bus output (sum, cout) - self.out = bus("out", 2) + self.out = bus("out", self.N+1) # Sum # XOR gate for calculation of 1-bit sum @@ -139,7 +182,8 @@ class half_adder(arithmetic_circuit): self.add_component(obj_and_gate) self.out.connect(1, obj_and_gate.output) - # FLAT C GENERATION # + """ C CODE GENERATION """ + # FLAT C # # Half adder function prototype with two inputs 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" @@ -147,23 +191,14 @@ class half_adder(arithmetic_circuit): # Obtaining list of all the unique circuit wires from all contained logic gates # to ensure non-recurring declaration of same wires def get_declaration_c_flat(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)) - + self.get_circuit_wires() # Unique declaration of all circuit's interconnections return "".join([c[0].get_declaration_c() for c in self.circuit_wires]) # Half adder wires values initialization def get_init_c_flat(self): - self.a.prefix = self.a.name if self.a.prefix == "" else self.a.prefix - self.b.prefix = self.b.name if self.b.prefix == "" else self.b.prefix + # self.a.prefix = self.a.name if self.a.prefix == "" else self.a.prefix + # self.b.prefix = self.b.name if self.b.prefix == "" else self.b.prefix 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_init_c_flat()};\n" + \ @@ -175,7 +210,7 @@ class half_adder(arithmetic_circuit): def get_function_carry_c_flat(self, offset: int = 1): return f" {self.out.prefix} |= {self.components[1].output.return_wire_value_c(offset=offset)};\n" - # HIERARCHICAL C GENERATION # + # HIERARCHICAL C # def get_function_block_c(self): self.component_types = self.get_component_types() self.prefix = "ha" @@ -208,6 +243,31 @@ class half_adder(arithmetic_circuit): f"{self.get_function_carry_c_hier()}" + \ f" return {self.out.prefix}"+";\n}" + """ VERILOG CODE GENERATION """ + # FLAT VERILOG # + def get_prototype_v(self): + return f"module {self.prefix}(input {self.a.name}, input {self.b.name}, output [{self.N}:0]{self.out.prefix});\n" + + def get_declaration_v_flat(self): + self.get_circuit_wires() + # Unique declaration of all circuit's interconnections + return "".join([c[0].get_declaration_v() for c in self.circuit_wires]) + + # Half adder wires values initialization + def get_init_v_flat(self, offset: int = 0, array: bool = False, ): + self.a.prefix = self.a.name if self.a.prefix == "" else self.a.prefix + self.b.prefix = self.b.name if self.b.prefix == "" else self.b.prefix + return f" assign {self.components[0].a.name} = {self.a.get_wire_value_v(offset=offset, array=array)};\n" + \ + f" assign {self.components[0].b.name} = {self.b.get_wire_value_v(offset=offset, array=array)};\n" + \ + f" assign {self.components[0].output.name} = {self.components[0].get_init_v_flat()};\n" + \ + f" assign {self.components[1].output.name} = {self.components[1].get_init_v_flat()};\n" + + def get_function_sum_v_flat(self, offset: int = 0): + return f" assign {self.out.prefix}[{offset}] = {self.components[0].output.name};\n" + + def get_function_carry_v_flat(self, offset: int = 1): + return f" assign {self.out.prefix}[{offset}] = {self.components[1].output.name};\n" + class full_adder(arithmetic_circuit): def __init__(self, a: wire, b: wire, c: wire, prefix: str = "fa"): @@ -218,7 +278,7 @@ class full_adder(arithmetic_circuit): self.b = b self.c = c # 2 wires for component's bus output (sum, cout) - self.out = bus("out", 2) + self.out = bus("out", self.N+1) # PG logic propagate_xor_gate1 = xor_gate(a, b, prefix, outid=0) @@ -246,7 +306,8 @@ class full_adder(arithmetic_circuit): self.propagate = propagate_xor_gate1.output self.generate = generate_and_gate1.output - # FLAT C GENERATION # + """ C CODE GENERATION """ + # FLAT C # # Full adder function prototype with three inputs 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" @@ -254,16 +315,7 @@ class full_adder(arithmetic_circuit): # Obtaining list of all the unique circuit wires from all contained logic gates # to ensure non-recurring declaration of same wires def get_declaration_c_flat(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)) - + self.get_circuit_wires() # Unique declaration of all circuit's interconnections return "".join([c[0].get_declaration_c() for c in self.circuit_wires]) @@ -287,7 +339,7 @@ class full_adder(arithmetic_circuit): def get_function_carry_c_flat(self, offset: int = 1): return f" {self.out.prefix} |= {self.components[4].output.return_wire_value_c(offset=offset)};\n" - # HIERARCHICAL C GENERATION # + # HIERARCHICAL C # def get_function_block_c(self): self.component_types = self.get_component_types() self.prefix = "fa" @@ -340,6 +392,36 @@ class full_adder(arithmetic_circuit): f"{self.get_function_carry_c_hier()}" + \ f" return {self.out.prefix}"+";\n}" + """ VERILOG CODE GENERATION """ + # FLAT VERILOG # + def get_prototype_v(self): + return f"module {self.prefix}(input {self.a.name}, input {self.b.name}, input {self.c.name}, output [{self.N}:0]{self.out.prefix});\n" + + def get_declaration_v_flat(self): + self.get_circuit_wires() + # Unique declaration of all circuit's interconnections + return "".join([c[0].get_declaration_v() for c in self.circuit_wires]) + + # Full adder wires values initialization + def get_init_v_flat(self, offset: int = 0, array: bool = False): + self.a.prefix = self.a.name if self.a.prefix == "" else self.a.prefix + self.b.prefix = self.b.name if self.b.prefix == "" else self.b.prefix + self.c.prefix = self.c.name + return f" assign {self.components[0].a.name} = {self.a.get_wire_value_v(offset=offset, array=array)};\n" + \ + f" assign {self.components[0].b.name} = {self.b.get_wire_value_v(offset=offset, array=array)};\n" + \ + f" assign {self.components[2].b.name} = {self.c.get_wire_value_v(offset=offset, array=array)};\n" + \ + f" assign {self.components[0].output.name} = {self.components[0].get_init_v_flat()};\n" + \ + f" assign {self.components[1].output.name} = {self.components[1].get_init_v_flat()};\n" + \ + f" assign {self.components[2].output.name} = {self.components[2].get_init_v_flat()};\n" + \ + f" assign {self.components[3].output.name} = {self.components[3].get_init_v_flat()};\n" + \ + f" assign {self.components[4].output.name} = {self.components[4].get_init_v_flat()};\n" + + def get_function_sum_v_flat(self, offset: int = 0): + return f" assign {self.out.prefix}[{offset}] = {self.components[2].output.name};\n" + + def get_function_carry_v_flat(self, offset: int = 1): + return f" assign {self.out.prefix}[{offset}] = {self.components[4].output.name};\n" + class signed_ripple_carry_adder(arithmetic_circuit): def __init__(self, a: bus, b: bus, prefix: str = "s_rca"): @@ -381,7 +463,8 @@ class signed_ripple_carry_adder(arithmetic_circuit): self.add_component(sign_xor_1) self.add_component(sign_xor_2) - # FLAT C GENERATION # + """ VERILOG CODE GENERATION """ + # FLAT C # # Initialization of 1-bit adders and sign extension XOR gates def get_init_c_flat(self): self.components[-2].output.prefix = self.components[-2].output.name @@ -400,7 +483,7 @@ class signed_ripple_carry_adder(arithmetic_circuit): def get_function_carry_c_flat(self): return f" {self.out.prefix} |= {self.get_previous_component().output.return_wire_value_c(offset = self.N)};\n" - # HIERARCHICAL C GENERATION # + # HIERARCHICAL C # def get_declaration_c_hier(self): self.cout = bus(N=self.N, prefix="cout") return "".join(self.a.get_wire_declaration_c()) + \ @@ -418,6 +501,26 @@ class signed_ripple_carry_adder(arithmetic_circuit): def get_function_carry_c_hier(self): return f" {self.out.prefix} |= {self.get_previous_component().get_gate_output_c(a=self.components[-2].output, b=self.cout.bus[-1], offset=self.out.N-1)};\n" + """ VERILOG CODE GENERATION """ + # FLAT C # + # Initialization of 1-bit adders and sign extension XOR gates + def get_init_v_flat(self, offset: int = 0, array: bool = False): + self.components[-2].output.prefix = self.components[-2].output.name + self.components[-3].get_carry_wire().prefix = self.components[-3].get_carry_wire().name + return f"".join([c.get_init_v_flat(offset=self.components.index(c), array=True) for c in self.components[:-2]]) + \ + f" assign {self.components[-2].a.name} = {self.a.get_wire_value_v(offset=self.N-1, array=True)};\n" + \ + f" assign {self.components[-2].b.name} = {self.b.get_wire_value_v(offset=self.N-1, array=True)};\n" + \ + f" assign {self.components[-2].output.name} = {self.components[-2].get_init_v_flat()};\n" + \ + f" assign {self.components[-1].a.name} = {self.components[-2].output.get_wire_value_v(offset=offset, array=array)};\n" + \ + f" assign {self.components[-1].b.name} = {self.components[-3].get_carry_wire().get_wire_value_v()};\n" + \ + f" assign {self.components[-1].output.name} = {self.components[-1].get_init_v_flat()};\n" + + def get_function_sum_v_flat(self, offset: int = 0): + return "".join([c.get_function_sum_v_flat(offset=self.components.index(c)) for c in self.components[:-2]]) + + def get_function_carry_v_flat(self): + return f" assign {self.out.prefix}[{self.N}] = {self.get_previous_component().output.return_wire_value_v(offset=self.N)};\n" + class unsigned_ripple_carry_adder(arithmetic_circuit): def __init__(self, a: bus, b: bus, prefix: str = "u_rca"): @@ -456,14 +559,22 @@ class unsigned_ripple_carry_adder(arithmetic_circuit): if __name__ == "__main__": a = bus(N=8, prefix="a") b = bus(N=8, prefix="b") - rca = unsigned_ripple_carry_adder(a, b) - - # rca.get_c_code_hier(open("h_u_rca8.c", "w")) + rca = unsigned_ripple_carry_adder(a, b, prefix="u_rca8") + # rca.get_c_code_hier(open("h_u_rca4.c", "w")) + # rca.get_c_code_flat(open("f_u_rca8.c", "w")) + rca.get_v_code_flat(open("f_u_rca8.v", "w")) w1 = wire(name="a") w2 = wire(name="b") w3 = wire(name="cout") - fa = full_adder(w1, w2, w3, prefix="h_fa") - ha = half_adder(w1, w2, prefix="h_ha") + fa = full_adder(w1, w2, w3, prefix="f_fa") + ha = half_adder(w1, w2, prefix="f_ha") - # ha.get_c_code_hier(open("h_ha.c","w")) + # ha.get_c_code_flat(open("f_ha.c","w")) + # ha.get_v_code_flat(open("f_ha.v","w")) + # fa.get_c_code_flat(open("f_fa.c","w")) + # fa.get_v_code_flat(open("f_fa.v","w")) + + gate = not_gate(w1) + # gate.get_c_code(open("not_gate.c","w")) + # gate.get_v_code(open("not_gate.v","w")) diff --git a/logic_gates_generator.py b/logic_gates_generator.py index 8c5b281..e078b83 100644 --- a/logic_gates_generator.py +++ b/logic_gates_generator.py @@ -5,7 +5,7 @@ from wire_components import wire class logic_gate(): - def __init__(self, a: wire, b: wire, prefix: str = "w"): + def __init__(self, a: wire, b: wire, prefix: str = "gate"): self.a = wire(name=prefix+"_"+a.name.replace(prefix+"_", ""), value=a.value) self.b = wire(name=prefix+"_"+b.name.replace(prefix+"_", ""), value=b.value) self.prefix = prefix @@ -13,15 +13,19 @@ class logic_gate(): def get_component_types(self): return list([self]) - # FLAT C GENERATION # + """ C CODE GENERATION """ + # FLAT C # @staticmethod def get_includes_c(): return f"#include \n#include \n\n" def get_prototype_c(self): - self.a.name = self.a.name.replace(self.prefix+"_", "") - self.b.name = self.b.name.replace(self.prefix+"_", "") - return f"uint8_t {self.gate_type}(uint8_t {self.a.name}, uint8_t {self.b.name})" + "{" + "\n" + self.a.name = self.a.name.replace(self.prefix, "", 1) + self.b.name = self.b.name.replace(self.prefix, "", 1) + return f"uint8_t {self.prefix}_{self.gate_type}(uint8_t {self.a.name}, uint8_t {self.b.name})" + "{" + "\n" + + def get_function_c(self): + return f"{self.a.get_wire_value_c()} {self.operator} {self.b.get_wire_value_c()}" def get_declaration_c_flat(self): return f"{self.a.get_declaration_c()}{self.b.get_declaration_c()}{self.output.get_declaration_c()}" @@ -29,12 +33,7 @@ class logic_gate(): def get_init_c_flat(self): return f"{self.a.name} {self.operator} {self.b.name}" - def get_function_c(self): - self.a.prefix = self.a.name.replace(self.prefix+"_", "") - self.b.prefix = self.b.name.replace(self.prefix+"_", "") - return f"{self.a.get_wire_value_c()} {self.operator} {self.b.get_wire_value_c()}" - - # Generating flat C code representation of separate logic gate + # Generating flat C code representation of the logic gate itself # (i.e. not as a component of bigger circuit) def get_c_code(self, file_object): file_object.write(self.get_includes_c()) @@ -55,13 +54,38 @@ class logic_gate(): def get_gate_output_c(self, a: wire, b: wire, offset: int = 0): return f"({self.gate_type}({a.name}, {b.name}) & 0x01) << {offset}" + """ VERILOG CODE GENERATION """ + # FLAT VERILOG # + def get_prototype_v(self): + self.a.name = self.a.name.replace(self.prefix, "", 1) + self.b.name = self.b.name.replace(self.prefix, "", 1) + self.output.name = self.output.name.replace(self.prefix, "", 1) + return f"module {self.prefix}_{self.gate_type}(input {self.a.name}, input {self.b.name}, output {self.output.name});\n" + + def get_declaration_v_flat(self): + return f"{self.a.get_declaration_v()}{self.b.get_declaration_v()}{self.output.get_declaration_v()}" + + def get_function_v(self): + return f"{self.a.name} {self.operator} {self.b.name}" + + def get_init_v_flat(self): + return f"{self.a.name} {self.operator} {self.b.name}" + + # Generating flat Verilog code representation of the logic gate itself + # (i.e. not as a component of bigger circuit) + def get_v_code(self, file_object): + file_object.write(self.get_prototype_v()) + file_object.write(f" assign {self.output.name} = {self.get_function_v()};\n") + file_object.write(f"endmodule") + file_object.close() + # Single-input class not_gate(logic_gate): - def __init__(self, a: wire, prefix: str = "w", outid: int = 0): + def __init__(self, a: wire, prefix: str = "", outid: int = 0): self.gate_type = "not_gate" self.operator = "~" - self.a = wire(prefix+"_"+a.name.replace(prefix+"_", ""), a.value) + self.a = wire(name=prefix+"_"+a.name.replace(prefix+"_", ""), value=a.value) self.prefix = prefix if self.a.value == 1: @@ -69,9 +93,14 @@ class not_gate(logic_gate): else: self.output = wire(name=prefix+"_y"+str(outid), value=1) - # FLAT C GENERATION # + """ C CODE GENERATION """ + # FLAT C # def get_prototype_c(self): - return f"uint8_t {self.gate_type}(uint8_t a)" + "{" + "\n" + self.a.name = self.a.name.replace(self.prefix, "", 1) + return f"uint8_t {self.prefix}_{self.gate_type}(uint8_t {self.a.name})" + "{" + "\n" + + def get_function_c(self): + return f"{self.operator}{self.a.get_wire_value_c()} & 0x01 << 0" def get_declaration_c(self): return f"{self.a.get_declaration_c()}{self.output.get_declaration_c()}" @@ -79,11 +108,7 @@ class not_gate(logic_gate): def get_init_c_flat(self): return f"{self.operator}{self.a.name}" - def get_function_c(self): - self.a.prefix = self.a.name.replace(self.prefix+"_", "") - return f"{self.operator}{self.a.get_wire_value_c()} & 0x01 << 0" - - # HIERARCHICAL C GENERATION # + # HIERARCHICAL C # def get_function_block_c(self): self.a.name = "a" return f"{self.get_prototype_c()}" + \ @@ -95,10 +120,27 @@ class not_gate(logic_gate): def get_gate_output_c(self, a: wire, offset: int = 0): return f"({self.gate_type}({a.name}) & 0x01) << {offset}" + """ VERILOG CODE GENERATION """ + # FLAT VERILOG # + def get_prototype_v(self): + self.a.name = self.a.name.replace(self.prefix, "", 1) + self.output.name = self.output.name.replace(self.prefix, "", 1) + return f"module {self.prefix}_{self.gate_type}(input {self.a.name}, output {self.output.name});\n" + + def get_declaration_v_flat(self): + return f"{self.a.get_declaration_v()}{self.output.get_declaration_v()}" + + def get_function_v(self): + # self.a.name = self.a.name.replace(self.prefix+"_", "") + return f" {self.operator}{self.a.name}" + + def get_init_v_flat(self): + return f"{self.a.name} {self.operator} {self.b.name}" + # Two-input class and_gate(logic_gate): - def __init__(self, a: wire, b: wire, prefix: str = "w", outid: int = 0): + def __init__(self, a: wire, b: wire, prefix: str = "", outid: int = 0): super().__init__(a, b, prefix) self.gate_type = "and_gate" self.operator = "&" @@ -110,7 +152,7 @@ class and_gate(logic_gate): class nand_gate(logic_gate): - def __init__(self, a: wire, b: wire, prefix: str = "w", outid: int = 0): + def __init__(self, a: wire, b: wire, prefix: str = "", outid: int = 0): super().__init__(a, b, prefix) self.gate_type = "nand_gate" self.operator = "&" @@ -120,12 +162,17 @@ class nand_gate(logic_gate): else: self.output = wire(name=prefix+"_y"+str(outid), value=1) + """ C CODE GENERATION """ def get_function_c(self): return "~("+(super().get_function_c())+f") & 0x01 << 0" + """ VERILOG CODE GENERATION """ + def get_function_v(self): + return "~("+(super().get_function_v())+f")" + class or_gate(logic_gate): - def __init__(self, a: wire, b: wire, prefix: str = "w", outid: int = 0): + def __init__(self, a: wire, b: wire, prefix: str = "", outid: int = 0): super().__init__(a, b, prefix) self.gate_type = "or_gate" self.operator = "|" @@ -137,7 +184,7 @@ class or_gate(logic_gate): class nor_gate(logic_gate): - def __init__(self, a: wire, b: wire, prefix: str = "w", outid: int = 0): + def __init__(self, a: wire, b: wire, prefix: str = "", outid: int = 0): super().__init__(a, b, prefix) self.gate_type = "nor_gate" self.operator = "|" @@ -147,12 +194,17 @@ class nor_gate(logic_gate): else: self.output = wire(name=prefix+"_y"+str(outid), value=1) + """ C CODE GENERATION """ def get_function_c(self): return "~("+(super().get_function_c())+") & 0x01 << 0" + """ VERILOG CODE GENERATION """ + def get_function_v(self): + return "~("+(super().get_function_v())+f")" + class xor_gate(logic_gate): - def __init__(self, a: wire, b: wire, prefix: str = "w", outid: int = 0): + def __init__(self, a: wire, b: wire, prefix: str = "", outid: int = 0): super().__init__(a, b, prefix) self.gate_type = "xor_gate" self.operator = "^" @@ -164,7 +216,7 @@ class xor_gate(logic_gate): class xnor_gate(logic_gate): - def __init__(self, a: wire, b: wire, prefix: str = "w", outid: int = 0): + def __init__(self, a: wire, b: wire, prefix: str = "", outid: int = 0): super().__init__(a, b, prefix) self.gate_type = "xnor_gate" self.operator = "^" @@ -174,5 +226,10 @@ class xnor_gate(logic_gate): else: self.output = wire(name=prefix+"_y"+str(outid), value=1) + """ C CODE GENERATION """ def get_function_c(self): return "~("+(super().get_function_c())+") & 0x01 << 0" + + """ VERILOG CODE GENERATION """ + def get_function_v(self): + return "~("+(super().get_function_v())+f")" diff --git a/wire_components.py b/wire_components.py index 1a4a1bc..cb69b21 100644 --- a/wire_components.py +++ b/wire_components.py @@ -8,16 +8,31 @@ class wire(): self.value = value self.index = index - # C GENERATION # + # C CODE GENERATION # 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.prefix} >> {offset}) & 0x01)" + name = self.name if self.prefix == "" else self.prefix + return f"(({name} >> {offset}) & 0x01)" def return_wire_value_c(self, offset: int = 0): return f"({self.name} & 0x01) << {offset}" + # VERILOG CODE GENERATION # + def get_declaration_v(self): + return f" wire {self.name};\n" + + def get_wire_value_v(self, offset: int = 0, array: bool = False): + name = self.name if self.prefix == "" else self.prefix + if array is True: + return f"{name}[{offset}]" + else: + return f"{name}" + + def return_wire_value_v(self, offset: int = 0): + return f"{self.name}" + class bus(): def __init__(self, prefix: str = "bus", N: int = 1): @@ -40,7 +55,7 @@ class bus(): self.bus = [wire(name=prefix+"_"+str(i), index=i) for i in range(N)] self.N = N - # C GENERATION # + # C CODE GENERATION # def get_wire_value_c(self, offset: int = 0): return self.bus[offset].get_wire_value_c(offset=offset) @@ -55,3 +70,7 @@ class bus(): return f" uint64_t {self.prefix} = 0;\n" else: return f" uint8_t {self.prefix} = 0;\n" + + # VERILOG CODE GENERATION # + def get_wire_value_v(self, offset: int = 0, array: bool = False): + return self.bus[offset].get_wire_value_v(offset=offset, array=array)