From d41c5f3c942eb741991fb8520ead257319e66b35 Mon Sep 17 00:00:00 2001 From: honzastor Date: Sun, 10 Oct 2021 22:15:13 +0200 Subject: [PATCH] Updated exportation of signed arithmetic circuits to python representation. Also unified some methods from arithmetic_circuit.py into general_circuit.py. --- .../arithmetic_circuits/arithmetic_circuit.py | 74 ++++--------------- .../arithmetic_circuits/general_circuit.py | 27 +++---- ariths_gen/wire_components/buses.py | 14 +++- tests/test_all.py | 4 +- 4 files changed, 41 insertions(+), 78 deletions(-) diff --git a/ariths_gen/core/arithmetic_circuits/arithmetic_circuit.py b/ariths_gen/core/arithmetic_circuits/arithmetic_circuit.py index 8f6ed88..04a63f2 100644 --- a/ariths_gen/core/arithmetic_circuits/arithmetic_circuit.py +++ b/ariths_gen/core/arithmetic_circuits/arithmetic_circuit.py @@ -50,22 +50,7 @@ class ArithmeticCircuit(GeneralCircuit): """ 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_function_block_c(self): - """Generates hierarchical C code representation of corresponding multi-bit arithmetic circuit used as function block in hierarchical circuit description. - - Returns: - str: Hierarchical C code of multi-bit arithmetic circuit's function block description. - """ - # Obtain proper circuit name with its bit width - circuit_prefix = self.__class__( - a=Bus("a"), b=Bus("b")).prefix + str(self.N) - circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus( - N=self.N, prefix="b"), name=circuit_prefix) - return f"{circuit_block.get_circuit_c()}\n\n" - """ VERILOG CODE GENERATION """ - # FLAT VERILOG # - def get_prototype_v(self): """Generates Verilog code module header to describe corresponding arithmetic circuit's interface in Verilog code. @@ -73,50 +58,21 @@ class ArithmeticCircuit(GeneralCircuit): str: Module's name and parameters in Verilog code. """ return f"module {self.prefix}(input [{self.N-1}:0] {self.a.prefix}, input [{self.N-1}:0] {self.b.prefix}, output [{self.out.N-1}:0] {self.out.prefix});\n" - # HIERARCHICAL VERILOG # - def get_function_block_v(self): - """Generates hierarchical Verilog code representation of corresponding multi-bit arithmetic circuit used as function block in hierarchical circuit description. + + """ BLIF CODE GENERATION """ + def get_declaration_blif(self): + """Generates flat Blif code declaration of input/output circuit wires. Returns: - str: Hierarchical Verilog code of multi-bit arithmetic circuit's function block description. + str: Flat Blif code containing declaration of circuit's wires. """ - # Obtain proper circuit name with its bit width - circuit_prefix = self.__class__( - a=Bus("a"), b=Bus("b")).prefix + str(self.N) - circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus( - N=self.N, prefix="b"), name=circuit_prefix) - return f"{circuit_block.get_circuit_v()}\n\n" - def get_out_invocation_v(self, circuit_prefix: str): - """Generates hierarchical Verilog code invocation of corresponding arithmetic circuit's generated function block. - - Assigns input values from other subcomponents into multi-bit input buses used as inputs for function block invocation. - Assigns output values from invocation of the corresponding function block into inner wires present inside - the upper component from which function block has been invoked. - - Args: - circuit_prefix (str): Prefix name of the upper component from which function block is being invoked. - - Returns: - str: Hierarchical Verilog code of subcomponent's module invocation and output assignment. - """ - # Getting name of circuit type and insitu copying out bus for proper Verilog code generation without affecting actual generated composition - circuit_type = self.prefix.replace(circuit_prefix+"_", "") - - # Obtain proper circuit name with its bit width - circuit_prefix = self.__class__( - a=Bus("a"), b=Bus("b")).prefix + str(self.N) - circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus( - N=self.N, prefix="b"), name=circuit_prefix) - return self.a.return_bus_wires_values_v_hier() + self.b.return_bus_wires_values_v_hier() + \ - f" {circuit_type} {circuit_type}_{self.out.prefix}(.{circuit_block.a.prefix}({self.a.prefix}), .{circuit_block.b.prefix}({self.b.prefix}), .{circuit_block.out.prefix}({self.out.prefix}));\n" - - def get_function_block_blif(self): - """Generates hierarchical Blif code representation of corresponding multi-bit arithmetic circuit used as function block in hierarchical circuit description. - - Returns: - str: Hierarchical Blif code of multi-bit arithmetic circuit's function block description. - """ - # Obtain proper circuit name with its bit width - circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus( - N=self.N, prefix="b")) - return f"{circuit_block.get_circuit_blif()}" + if self.N == 1: + return f".inputs {self.a.prefix} {self.b.prefix}\n" + \ + f".outputs{self.out.get_wire_declaration_blif()}\n" + \ + f".names vdd\n1\n" + \ + f".names gnd\n0\n" + else: + return f".inputs{self.a.get_wire_declaration_blif()}{self.b.get_wire_declaration_blif()}\n" + \ + f".outputs{self.out.get_wire_declaration_blif()}\n" + \ + f".names vdd\n1\n" + \ + f".names gnd\n0\n" diff --git a/ariths_gen/core/arithmetic_circuits/general_circuit.py b/ariths_gen/core/arithmetic_circuits/general_circuit.py index 912c7e2..c035307 100644 --- a/ariths_gen/core/arithmetic_circuits/general_circuit.py +++ b/ariths_gen/core/arithmetic_circuits/general_circuit.py @@ -278,6 +278,7 @@ class GeneralCircuit(): #file_object.write(self.get_declaration_python_flat()+"\n") file_object.write(self.get_init_python_flat()+"\n") file_object.write(self.get_function_out_python_flat()) + file_object.write(self.out.return_bus_wires_sign_extend_python()) file_object.write(f" return {self.out.prefix}"+"\n") """ C CODE GENERATION """ @@ -336,7 +337,7 @@ class GeneralCircuit(): file_object.write(self.get_declaration_c_flat()+"\n") file_object.write(self.get_init_c_flat()+"\n") file_object.write(self.get_function_out_c_flat()) - file_object.write(self.out.return_bus_wires_sign_extend()) + file_object.write(self.out.return_bus_wires_sign_extend_c()) file_object.write(f" return {self.out.prefix}"+";\n}") # HIERARCHICAL C # @@ -360,7 +361,7 @@ class GeneralCircuit(): circuit_prefix = self.__class__( a=Bus("a"), b=Bus("b")).prefix + str(self.N) circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus( - N=self.N, prefix="b"), prefix=circuit_prefix) + N=self.N, prefix="b"), name=circuit_prefix) return f"{circuit_block.get_circuit_c()}\n\n" def get_declarations_c_hier(self): @@ -429,7 +430,7 @@ class GeneralCircuit(): f"{self.get_declarations_c_hier()}\n" + \ f"{self.get_init_c_hier()}\n" + \ f"{self.get_function_out_c_hier()}" + \ - f"{self.out.return_bus_wires_sign_extend()}" + \ + f"{self.out.return_bus_wires_sign_extend_c()}" + \ f" return {self.out.prefix}"+";\n}" # Generating hierarchical C code representation of circuit @@ -512,7 +513,7 @@ class GeneralCircuit(): circuit_prefix = self.__class__( a=Bus("a"), b=Bus("b")).prefix + str(self.N) circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus( - N=self.N, prefix="b"), prefix=circuit_prefix) + N=self.N, prefix="b"), name=circuit_prefix) return f"{circuit_block.get_circuit_v()}\n\n" def get_declarations_v_hier(self): @@ -564,7 +565,7 @@ class GeneralCircuit(): circuit_prefix = self.__class__( a=Bus("a"), b=Bus("b")).prefix + str(self.N) circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus( - N=self.N, prefix="b"), prefix=circuit_prefix) + N=self.N, prefix="b"), name=circuit_prefix) return self.a.return_bus_wires_values_v_hier() + self.b.return_bus_wires_values_v_hier() + \ f" {circuit_type} {circuit_type}_{self.out.prefix}(.{circuit_block.a.prefix}({self.a.prefix}), .{circuit_block.b.prefix}({self.b.prefix}), .{circuit_block.out.prefix}({self.out.prefix}));\n" @@ -615,16 +616,10 @@ class GeneralCircuit(): Returns: str: Flat Blif code containing declaration of circuit's wires. """ - if self.N == 1: - return f".inputs {self.a.prefix} {self.b.prefix}\n" + \ - f".outputs{self.out.get_wire_declaration_blif()}\n" + \ - f".names vdd\n1\n" + \ - f".names gnd\n0\n" - else: - return f".inputs{self.a.get_wire_declaration_blif()}{self.b.get_wire_declaration_blif()}\n" + \ - f".outputs{self.out.get_wire_declaration_blif()}\n" + \ - f".names vdd\n1\n" + \ - f".names gnd\n0\n" + return f".inputs{''.join([w.get_wire_declaration_blif() for w in self.inputs])}\n" + \ + f".outputs{self.out.get_wire_declaration_blif()}\n" + \ + f".names vdd\n1\n" + \ + f".names gnd\n0\n" def get_function_blif_flat(self): """Generates flat Blif code with invocation of subcomponents logic gates functions via their corresponding truth tables. @@ -718,7 +713,7 @@ class GeneralCircuit(): circuit_prefix = self.__class__( a=Bus("a"), b=Bus("b")).prefix + str(self.N) circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus( - N=self.N, prefix="b"), prefix=circuit_prefix) + N=self.N, prefix="b"), name=circuit_prefix) return f"{circuit_block.get_circuit_blif()}" # Generating hierarchical BLIF code representation of circuit diff --git a/ariths_gen/wire_components/buses.py b/ariths_gen/wire_components/buses.py index 08a3d74..060caff 100644 --- a/ariths_gen/wire_components/buses.py +++ b/ariths_gen/wire_components/buses.py @@ -119,6 +119,18 @@ class Bus(): str: Python code for assigning wire values into bus represented in Python code variable. """ return "".join([f" {self.prefix} = 0\n"] + [f" {self.prefix} |= {w.return_wire_value_python_flat(offset=self.bus.index(w))}" for w in self.bus]) + + def return_bus_wires_sign_extend_python(self): + """Sign extends the bus's corresponding Python variable (object) to ensure proper Python code variable signedness. + + Returns: + str: Python code for sign extending the bus variable wire values. + """ + if self.signed is True: + last_bus_wire = self.bus[-1] + return "".join([f" {self.prefix} |= {last_bus_wire.return_wire_value_python_flat(offset=i)}" for i in range(len(self.bus), 64)]) + else: + return "" """ C CODE GENERATION """ def get_declaration_c(self): @@ -146,7 +158,7 @@ class Bus(): """ return "".join([f" {self.prefix} |= {w.return_wire_value_c_hier(offset=self.bus.index(w))}" for w in self.bus]) - def return_bus_wires_sign_extend(self): + def return_bus_wires_sign_extend_c(self): """Sign extends the bus's corresponding C variable to ensure proper C code variable signedness. Returns: diff --git a/tests/test_all.py b/tests/test_all.py index 8e78377..8e9e3eb 100644 --- a/tests/test_all.py +++ b/tests/test_all.py @@ -61,7 +61,7 @@ def test_signed_mul(): mul = c(a, b) r = mul(av, bv) - r[r >= 2**(2*N-1)] -= 2**(2*N) # hack!!! two's complement not implemented yet + # r[r >= 2**(2*N-1)] -= 2**(2*N) # hack!!! two's complement not implemented yet np.testing.assert_array_equal(expected, r) @@ -94,7 +94,7 @@ def test_signed_add(): for c in [SignedCarryLookaheadAdder, SignedPGRippleCarryAdder, SignedRippleCarryAdder, SignedCarrySkipAdder]: mul = c(a, b) r = mul(av, bv) - r[r >= 2**(N)] -= 2**(N+1) # hack!!! two's complement not implemented yet + # r[r >= 2**(N)] -= 2**(N+1) # hack!!! two's complement not implemented yet np.testing.assert_array_equal(expected, r)