From e16de78c2b376686b1c3a82ed146a9d69661ad65 Mon Sep 17 00:00:00 2001 From: honzastor Date: Tue, 7 Sep 2021 17:39:39 +0200 Subject: [PATCH] Updated logic behind generating export representations, mainly focused around circuit and its buses and subcomponents namings. --- .../arithmetic_circuits/arithmetic_circuit.py | 41 ++++++++++------ .../arithmetic_circuits/general_circuit.py | 8 +++- .../arithmetic_circuits/multiplier_circuit.py | 4 +- .../two_input_one_bit_circuit.py | 2 +- .../adders/carry_lookahead_adder.py | 20 ++++---- .../adders/carry_skip_adder.py | 20 ++++---- .../adders/pg_ripple_carry_adder.py | 22 ++++----- .../adders/ripple_carry_adder.py | 20 ++++---- .../dividers/array_divider.py | 13 ++--- .../multipliers/array_multiplier.py | 28 ++++------- .../multipliers/dadda_multiplier.py | 48 +++++++------------ .../multipliers/wallace_multiplier.py | 46 +++++++----------- ariths_gen/wire_components/buses.py | 20 +++++++- 13 files changed, 134 insertions(+), 158 deletions(-) diff --git a/ariths_gen/core/arithmetic_circuits/arithmetic_circuit.py b/ariths_gen/core/arithmetic_circuits/arithmetic_circuit.py index 4c2e8e2..1fb1aa1 100644 --- a/ariths_gen/core/arithmetic_circuits/arithmetic_circuit.py +++ b/ariths_gen/core/arithmetic_circuits/arithmetic_circuit.py @@ -15,12 +15,33 @@ class ArithmeticCircuit(): that are later used for generation into various representations. """ - def __init__(self): + def __init__(self, a, b, prefix: str, name: str, out_N: int, inner_component: bool = False, one_bit_circuit: bool = False): + if one_bit_circuit is False: + if prefix == "": + self.prefix = name + else: + self.prefix = prefix + "_" + name + + self.inner_component = inner_component + if self.inner_component is True: + self.a = Bus(prefix=f"{self.prefix}_{a.prefix}", wires_list=a.bus) + self.b = Bus(prefix=f"{self.prefix}_{b.prefix}", wires_list=b.bus) + + if a.is_output_bus(): + self.a.connect_bus(connecting_bus=a) + if b.is_output_bus(): + self.b.connect_bus(connecting_bus=b) + else: + self.a = Bus(prefix=f"{a.prefix}", wires_list=a.bus) + self.b = Bus(prefix=f"{b.prefix}", wires_list=b.bus) + + # N output wires for given circuit + self.out = Bus(self.prefix+"_out", out_N, out_bus=True) + self.components = [] self.circuit_wires = [] self.circuit_gates = [] self.c_data_type = "uint64_t" - self.N = 1 def add_component(self, component): """Adds a component into list of circuit's inner subcomponents. @@ -294,10 +315,8 @@ class ArithmeticCircuit(): 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"), prefix=circuit_prefix) + N=self.N, prefix="b")) return f"{circuit_block.get_circuit_c()}\n\n" def get_declarations_c_hier(self): @@ -447,10 +466,8 @@ class ArithmeticCircuit(): str: Hierarchical Verilog 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"), prefix=circuit_prefix) + N=self.N, prefix="b")) return f"{circuit_block.get_circuit_v()}\n\n" def get_declarations_v_hier(self): @@ -499,10 +516,8 @@ class ArithmeticCircuit(): 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"), prefix=circuit_prefix) + N=self.N, prefix="b")) 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" @@ -655,10 +670,8 @@ class ArithmeticCircuit(): str: Hierarchical Blif 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"), prefix=circuit_prefix) + N=self.N, prefix="b")) return f"{circuit_block.get_circuit_blif()}" # Generating hierarchical BLIF code representation of circuit diff --git a/ariths_gen/core/arithmetic_circuits/general_circuit.py b/ariths_gen/core/arithmetic_circuits/general_circuit.py index 4de1a58..9f7a68e 100644 --- a/ariths_gen/core/arithmetic_circuits/general_circuit.py +++ b/ariths_gen/core/arithmetic_circuits/general_circuit.py @@ -15,12 +15,16 @@ class GeneralCircuit(): that are later used for generation into various representations. """ - def __init__(self, inputs): + def __init__(self, prefix: str, out_N: int, inner_component: bool = False, inputs: list=[]): + self.prefix = prefix + self.inner_component = inner_component + self.inputs = inputs + self.out = Bus(self.prefix+"_out", out_N, out_bus=True) + self.components = [] self.circuit_wires = [] self.circuit_gates = [] self.c_data_type = "uint64_t" - self.inputs = inputs def add_component(self, component): """Adds a component into list of circuit's inner subcomponents. diff --git a/ariths_gen/core/arithmetic_circuits/multiplier_circuit.py b/ariths_gen/core/arithmetic_circuits/multiplier_circuit.py index af46fe4..e565ed6 100644 --- a/ariths_gen/core/arithmetic_circuits/multiplier_circuit.py +++ b/ariths_gen/core/arithmetic_circuits/multiplier_circuit.py @@ -29,8 +29,8 @@ class MultiplierCircuit(ArithmeticCircuit): that are later used for generation into various representations. """ - def __init__(self): - super().__init__() + def __init__(self, a, b, prefix, name, out_N, **kwargs): + super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=out_N, **kwargs) # Array multipliers def get_previous_partial_product(self, a_index: int, b_index: int): diff --git a/ariths_gen/core/one_bit_circuits/two_input_one_bit_circuit.py b/ariths_gen/core/one_bit_circuits/two_input_one_bit_circuit.py index 8331d13..b13106d 100644 --- a/ariths_gen/core/one_bit_circuits/two_input_one_bit_circuit.py +++ b/ariths_gen/core/one_bit_circuits/two_input_one_bit_circuit.py @@ -16,7 +16,7 @@ class TwoInputOneBitCircuit(ArithmeticCircuit): prefix (str, optional): Prefix name of circuit. Defaults to "two_input_one_bit_circuit". """ def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "two_input_one_bit_circuit"): - super().__init__() + super().__init__(a=a, b=b, prefix=prefix, name="", out_N=1, one_bit_circuit = True) self.c_data_type = "uint8_t" self.prefix = prefix self.a = a diff --git a/ariths_gen/multi_bit_circuits/adders/carry_lookahead_adder.py b/ariths_gen/multi_bit_circuits/adders/carry_lookahead_adder.py index d4d664f..ccd8aa4 100644 --- a/ariths_gen/multi_bit_circuits/adders/carry_lookahead_adder.py +++ b/ariths_gen/multi_bit_circuits/adders/carry_lookahead_adder.py @@ -62,22 +62,17 @@ class UnsignedCarryLookaheadAdder(ArithmeticCircuit): a (Bus): First input bus. b (Bus): Second input bus. cla_block_size (int, optional): Size of each composite cla adder block size. Defaults to 4. - prefix (str, optional): Prefix name of unsigned cla. Defaults to "u_cla". + prefix (str, optional): Prefix name of unsigned cla. Defaults to "". + name (str, optional): Name of unsigned cla. Defaults to "u_cla". """ - def __init__(self, a: Bus, b: Bus, cla_block_size: int = 4, prefix: str = "u_cla"): - super().__init__() + def __init__(self, a: Bus, b: Bus, cla_block_size: int = 4, prefix: str = "", name: str = "u_cla", **kwargs): self.N = max(a.N, b.N) - self.prefix = prefix - self.a = Bus(prefix=a.prefix, wires_list=a.bus) - self.b = Bus(prefix=b.prefix, wires_list=b.bus) + super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N+1, **kwargs) # Bus sign extension in case buses have different lengths self.a.bus_extend(N=self.N, prefix=a.prefix) self.b.bus_extend(N=self.N, prefix=b.prefix) - # Output wires for N sum bits and additional cout bit - self.out = Bus(self.prefix+"_out", self.N+1) - # To signify current number of blocks and number of bits that remain to be added into function blocks N_blocks = 0 N_wires = self.N @@ -185,10 +180,11 @@ class SignedCarryLookaheadAdder(UnsignedCarryLookaheadAdder, ArithmeticCircuit): a (Bus): First input bus. b (Bus): Second input bus. cla_block_size (int, optional): Size of each composite cla adder block size. Defaults to 4. - prefix (str, optional): Prefix name of signed cla. Defaults to "s_cla". + prefix (str, optional): Prefix name of signed cla. Defaults to "". + name (str, optional): Name of signed cla. Defaults to "s_cla". """ - def __init__(self, a: Bus, b: Bus, cla_block_size: int = 4, prefix: str = "s_cla"): - super().__init__(a=a, b=b, cla_block_size=cla_block_size, prefix=prefix) + def __init__(self, a: Bus, b: Bus, cla_block_size: int = 4, prefix: str = "", name: str = "s_cla", **kwargs): + super().__init__(a=a, b=b, cla_block_size=cla_block_size, prefix=prefix, name=name, **kwargs) self.c_data_type = "int64_t" # Additional XOR gates to ensure correct sign extension in case of sign addition diff --git a/ariths_gen/multi_bit_circuits/adders/carry_skip_adder.py b/ariths_gen/multi_bit_circuits/adders/carry_skip_adder.py index 1fa3be2..b033dcd 100644 --- a/ariths_gen/multi_bit_circuits/adders/carry_skip_adder.py +++ b/ariths_gen/multi_bit_circuits/adders/carry_skip_adder.py @@ -69,22 +69,17 @@ class UnsignedCarrySkipAdder(ArithmeticCircuit): a (Bus): First input bus. b (Bus): Second input bus. bypass_block_size (int, optional): Size of each composite bypass adder block size. Defaults to 4. - prefix (str, optional): Prefix name of unsigned cska. Defaults to "u_cska". + prefix (str, optional): Prefix name of unsigned cska. Defaults to "". + name (str, optional): Name of unsigned cska. Defaults to "u_cska". """ - def __init__(self, a: Bus, b: Bus, bypass_block_size: int = 4, prefix: str = "u_cska"): - super().__init__() + def __init__(self, a: Bus, b: Bus, bypass_block_size: int = 4, prefix: str = "", name: str = "u_cska", **kwargs): self.N = max(a.N, b.N) - self.prefix = prefix - self.a = Bus(prefix=a.prefix, wires_list=a.bus) - self.b = Bus(prefix=b.prefix, wires_list=b.bus) + super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N+1, **kwargs) # Bus sign extension in case buses have different lengths self.a.bus_extend(N=self.N, prefix=a.prefix) self.b.bus_extend(N=self.N, prefix=b.prefix) - # Output wires for N sum bits and additional cout bit - self.out = Bus(self.prefix+"_out", self.N+1) - # To signify current number of blocks and number of bits that remain to be added into function blocks N_blocks = 0 N_wires = self.N @@ -168,10 +163,11 @@ class SignedCarrySkipAdder(UnsignedCarrySkipAdder, ArithmeticCircuit): a (Bus): First input bus. b (Bus): Second input bus. bypass_block_size (int, optional): Size of each composite bypass adder block size. Defaults to 4. - prefix (str, optional): Prefix name of signed cska. Defaults to "s_cska". + prefix (str, optional): Prefix name of signed cska. Defaults to "". + name (str, optional): Name of signed cska. Defaults to "s_cska". """ - def __init__(self, a: Bus, b: Bus, bypass_block_size: int = 4, prefix: str = "s_cska"): - super().__init__(a=a, b=b, bypass_block_size=bypass_block_size, prefix=prefix) + def __init__(self, a: Bus, b: Bus, bypass_block_size: int = 4, prefix: str = "", name: str = "s_cska", **kwargs): + super().__init__(a=a, b=b, bypass_block_size=bypass_block_size, prefix=prefix, name=name, **kwargs) self.c_data_type = "int64_t" # Additional XOR gates to ensure correct sign extension in case of sign addition diff --git a/ariths_gen/multi_bit_circuits/adders/pg_ripple_carry_adder.py b/ariths_gen/multi_bit_circuits/adders/pg_ripple_carry_adder.py index 5988a0e..5e99a1c 100644 --- a/ariths_gen/multi_bit_circuits/adders/pg_ripple_carry_adder.py +++ b/ariths_gen/multi_bit_circuits/adders/pg_ripple_carry_adder.py @@ -59,22 +59,17 @@ class UnsignedPGRippleCarryAdder(ArithmeticCircuit): Args: a (Bus): First input bus. b (Bus): Second input bus. - prefix (str, optional): Prefix name of unsigned P/G rca. Defaults to "u_pg_rca". + prefix (str, optional): Prefix name of unsigned P/G rca. Defaults to "". + name (str, optional): Name of unsigned P/G rca. Defaults to "u_pg_rca". """ - def __init__(self, a: Bus, b: Bus, prefix: str = "u_pg_rca"): - super().__init__() + def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_pg_rca", **kwargs): self.N = max(a.N, b.N) - self.prefix = prefix - self.a = Bus(prefix=a.prefix, wires_list=a.bus) - self.b = Bus(prefix=b.prefix, wires_list=b.bus) - + super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N+1, **kwargs) + # Bus sign extension in case buses have different lengths self.a.bus_extend(N=self.N, prefix=a.prefix) self.b.bus_extend(N=self.N, prefix=b.prefix) - # Output wires for N sum bits and additional cout bit - self.out = Bus(self.prefix+"_out", self.N+1) - # Gradual addition of 1-bit adder components for input_index in range(self.N): if input_index == 0: @@ -131,10 +126,11 @@ class SignedPGRippleCarryAdder(UnsignedPGRippleCarryAdder, ArithmeticCircuit): Args: a (Bus): First input bus. b (Bus): Second input bus. - prefix (str, optional): Prefix name of signed P/G rca. Defaults to "s_pg_rca". + prefix (str, optional): Prefix name of signed P/G rca. Defaults to "". + name (str, optional): Name of signed P/G rca. Defaults to "s_pg_rca". """ - def __init__(self, a: Bus, b: Bus, prefix: str = "s_pg_rca"): - super().__init__(a=a, b=b, prefix=prefix) + def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "s_pg_rca", **kwargs): + super().__init__(a=a, b=b, prefix=prefix, name=name, **kwargs) self.c_data_type = "int64_t" # Additional XOR gates to ensure correct sign extension in case of sign addition diff --git a/ariths_gen/multi_bit_circuits/adders/ripple_carry_adder.py b/ariths_gen/multi_bit_circuits/adders/ripple_carry_adder.py index 48a3df6..35af939 100644 --- a/ariths_gen/multi_bit_circuits/adders/ripple_carry_adder.py +++ b/ariths_gen/multi_bit_circuits/adders/ripple_carry_adder.py @@ -50,22 +50,17 @@ class UnsignedRippleCarryAdder(ArithmeticCircuit): Args: a (Bus): First input bus. b (Bus): Second input bus. - prefix (str, optional): Prefix name of unsigned rca. Defaults to "u_rca". + prefix (str, optional): Prefix name of unsigned rca. Defaults to "". + name (str, optional): Name of unsigned rca. Defaults to "u_rca". """ - def __init__(self, a: Bus, b: Bus, prefix: str = "u_rca"): - super().__init__() + def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_rca", **kwargs): self.N = max(a.N, b.N) - self.prefix = prefix - self.a = Bus(prefix=a.prefix, wires_list=a.bus) - self.b = Bus(prefix=b.prefix, wires_list=b.bus) + super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N+1, **kwargs) # Bus sign extension in case buses have different lengths self.a.bus_extend(N=self.N, prefix=a.prefix) self.b.bus_extend(N=self.N, prefix=b.prefix) - # Output wires for N sum bits and additional cout bit - self.out = Bus(self.prefix+"_out", self.N+1) - # Gradual addition of 1-bit adder components for input_index in range(self.N): # First adder is a half adder @@ -107,10 +102,11 @@ class SignedRippleCarryAdder(UnsignedRippleCarryAdder, ArithmeticCircuit): Args: a (Bus): First input bus. b (Bus): Second input bus. - prefix (str, optional): Prefix name of signed rca. Defaults to "s_rca". + prefix (str, optional): Prefix name of signed rca. Defaults to "". + name (str, optional): Name of signed rca. Defaults to "s_rca". """ - def __init__(self, a: Bus, b: Bus, prefix: str = "s_rca"): - super().__init__(a=a, b=b, prefix=prefix) + def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "s_rca", **kwargs): + super().__init__(a=a, b=b, prefix=prefix, name=name, **kwargs) self.c_data_type = "int64_t" # Additional XOR gates to ensure correct sign extension in case of sign addition diff --git a/ariths_gen/multi_bit_circuits/dividers/array_divider.py b/ariths_gen/multi_bit_circuits/dividers/array_divider.py index 0c9f71b..4c31ac1 100644 --- a/ariths_gen/multi_bit_circuits/dividers/array_divider.py +++ b/ariths_gen/multi_bit_circuits/dividers/array_divider.py @@ -92,22 +92,17 @@ class ArrayDivider(ArithmeticCircuit): Args: a (Bus): First input bus. b (Bus): Second input bus. - prefix (str, optional): Prefix name of array divider. Defaults to "arrdiv". + prefix (str, optional): Prefix name of array divider. Defaults to "". + name (str, optional): Name of array divider. Defaults to "arrdiv". """ - def __init__(self, a: Bus, b: Bus, prefix: str = "arrdiv"): - super().__init__() + def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "arrdiv", **kwargs): self.N = max(a.N, b.N) - self.prefix = prefix - self.a = Bus(prefix=a.prefix, wires_list=a.bus) - self.b = Bus(prefix=b.prefix, wires_list=b.bus) + super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N, **kwargs) # Bus sign extension in case buses have different lengths self.a.bus_extend(N=self.N, prefix=a.prefix) self.b.bus_extend(N=self.N, prefix=b.prefix) - # Output wires for quotient result - self.out = Bus(self.prefix+"_out", self.N) - # Performing series of iterative subtractions # Gradually shifting the divisor for a_index in reversed(range(self.N)): diff --git a/ariths_gen/multi_bit_circuits/multipliers/array_multiplier.py b/ariths_gen/multi_bit_circuits/multipliers/array_multiplier.py index 6e74694..92b0666 100644 --- a/ariths_gen/multi_bit_circuits/multipliers/array_multiplier.py +++ b/ariths_gen/multi_bit_circuits/multipliers/array_multiplier.py @@ -79,22 +79,17 @@ class UnsignedArrayMultiplier(MultiplierCircuit): Args: a (Bus): First input bus. b (Bus): Second input bus. - prefix (str, optional): Prefix name of unsigned array multiplier. Defaults to "u_arrmul". + prefix (str, optional): Prefix name of unsigned array multiplier. Defaults to "". + name (str, optional): Name of unsigned array multiplier. Defaults to "u_arrmul". """ - def __init__(self, a: Bus, b: Bus, prefix: str = "u_arrmul"): - super().__init__() + def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_arrmul", **kwargs): self.N = max(a.N, b.N) - self.prefix = prefix - self.a = Bus(prefix=a.prefix, wires_list=a.bus) - self.b = Bus(prefix=b.prefix, wires_list=b.bus) + super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs) # Bus sign extension in case buses have different lengths self.a.bus_extend(N=self.N, prefix=a.prefix) self.b.bus_extend(N=self.N, prefix=b.prefix) - # Output wires for multiplication product - self.out = Bus(self.prefix+"_out", self.N*2) - # Gradual generation of partial products for b_multiplier_index in range(self.N): for a_multiplicand_index in range(self.N): @@ -191,23 +186,18 @@ class SignedArrayMultiplier(MultiplierCircuit): Args: a (Bus): First input bus. b (Bus): Second input bus. - prefix (str, optional): Prefix name of signed array multiplier. Defaults to "s_arrmul". + prefix (str, optional): Prefix name of signed array multiplier. Defaults to "". + name (str, optional): Name of signed array multiplier. Defaults to "s_arrmul". """ - def __init__(self, a: Bus, b: Bus, prefix: str = "s_arrmul"): - super().__init__() - self.c_data_type = "int64_t" + def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "s_arrmul", **kwargs): self.N = max(a.N, b.N) - self.prefix = prefix - self.a = Bus(prefix=a.prefix, wires_list=a.bus) - self.b = Bus(prefix=b.prefix, wires_list=b.bus) + super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs) + self.c_data_type = "int64_t" # Bus sign extension in case buses have different lengths self.a.bus_extend(N=self.N, prefix=a.prefix) self.b.bus_extend(N=self.N, prefix=b.prefix) - # Output wires for multiplication product - self.out = Bus(self.prefix+"_out", self.N*2) - # Gradual generation of partial products for b_multiplier_index in range(self.N): for a_multiplicand_index in range(self.N): diff --git a/ariths_gen/multi_bit_circuits/multipliers/dadda_multiplier.py b/ariths_gen/multi_bit_circuits/multipliers/dadda_multiplier.py index af7f182..e932c9f 100644 --- a/ariths_gen/multi_bit_circuits/multipliers/dadda_multiplier.py +++ b/ariths_gen/multi_bit_circuits/multipliers/dadda_multiplier.py @@ -45,23 +45,18 @@ class UnsignedDaddaMultiplier(MultiplierCircuit): Args: a (Bus): First input bus. b (Bus): Second input bus. - prefix (str, optional): Prefix name of unsigned dadda multiplier. Defaults to "u_dadda_cla". + prefix (str, optional): Prefix name of unsigned dadda multiplier. Defaults to "". + name (str, optional): Name of unsigned dadda multiplier. Defaults to "u_dadda_cla". unsigned_adder_class_name (str, optional): Unsigned multi bit adder used to obtain final sums of products. Defaults to UnsignedCarryLookaheadAdder. """ - def __init__(self, a: Bus, b: Bus, prefix: str = "u_dadda_cla", unsigned_adder_class_name: str = UnsignedCarryLookaheadAdder): - super().__init__() + def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_dadda_cla", unsigned_adder_class_name: str = UnsignedCarryLookaheadAdder, **kwargs): self.N = max(a.N, b.N) - self.prefix = prefix - self.a = Bus(prefix=a.prefix, wires_list=a.bus) - self.b = Bus(prefix=b.prefix, wires_list=b.bus) + super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs) # Bus sign extension in case buses have different lengths self.a.bus_extend(N=self.N, prefix=a.prefix) self.b.bus_extend(N=self.N, prefix=b.prefix) - # Output wires for multiplication product - self.out = Bus(self.prefix+"_out", self.N*2) - # Get starting stage and maximum possible column height self.stage, self.d = self.get_maximum_height(initial_value=min(self.a.N, self.b.N)) # Initialize all columns partial products forming AND gates matrix @@ -122,12 +117,10 @@ class UnsignedDaddaMultiplier(MultiplierCircuit): self.out.connect(3, obj_ha.get_carry_wire()) # Final addition of remaining bits using chosen unsigned multi bit adder else: - # Obtain proper adder name with its bit width (columns bit pairs minus the first alone bit) - adder_prefix = self.prefix + "_" + unsigned_adder_class_name(a=a, b=b).prefix + str(len(self.columns)-1) - - adder_a = Bus(prefix=f"{adder_prefix}_a", wires_list=[self.add_column_wire(column=col, bit=0) for col in range(1, len(self.columns))]) - adder_b = Bus(prefix=f"{adder_prefix}_b", wires_list=[self.add_column_wire(column=col, bit=1) for col in range(1, len(self.columns))]) - final_adder = unsigned_adder_class_name(a=adder_a, b=adder_b, prefix=adder_prefix) + # Create adder of final PP pairs + adder_a = Bus(prefix=f"a", wires_list=[self.add_column_wire(column=col, bit=0) for col in range(1, len(self.columns))]) + adder_b = Bus(prefix=f"b", wires_list=[self.add_column_wire(column=col, bit=1) for col in range(1, len(self.columns))]) + final_adder = unsigned_adder_class_name(a=adder_a, b=adder_b, prefix=self.prefix, inner_component=True) self.add_component(final_adder) [self.out.connect(o, final_adder.out.get_wire(o-1), inserted_wire_desired_index=o-1) for o in range(1, len(self.out.bus))] @@ -155,24 +148,19 @@ class SignedDaddaMultiplier(MultiplierCircuit): Args: a (Bus): First input bus. b (Bus): Second input bus. - prefix (str, optional): Prefix name of signed dadda multiplier. Defaults to "s_dadda_cla". + prefix (str, optional): Prefix name of signed dadda multiplier. Defaults to "". + name (str, optional): Name of signed dadda multiplier. Defaults to "s_dadda_cla". unsigned_adder_class_name (str, optional): Unsigned multi bit adder used to obtain final sums of products. Defaults to UnsignedCarryLookaheadAdder. """ - def __init__(self, a: Bus, b: Bus, prefix: str = "s_dadda_cla", unsigned_adder_class_name: str = UnsignedCarryLookaheadAdder): - super().__init__() - self.c_data_type = "int64_t" + def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "s_dadda_cla", unsigned_adder_class_name: str = UnsignedCarryLookaheadAdder, **kwargs): self.N = max(a.N, b.N) - self.prefix = prefix - self.a = Bus(prefix=a.prefix, wires_list=a.bus) - self.b = Bus(prefix=b.prefix, wires_list=b.bus) + super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs) + self.c_data_type = "int64_t" # Bus sign extension in case buses have different lengths self.a.bus_extend(N=self.N, prefix=a.prefix) self.b.bus_extend(N=self.N, prefix=b.prefix) - # Output wires for multiplication product - self.out = Bus(self.prefix+"_out", self.N*2) - # Get starting stage and maximum possible column height self.stage, self.d = self.get_maximum_height(initial_value=min(self.a.N, self.b.N)) # Initialize all columns partial products forming AND/NAND gates matrix based on Baugh-Wooley multiplication @@ -240,12 +228,10 @@ class SignedDaddaMultiplier(MultiplierCircuit): # Final addition of remaining bits using chosen unsigned multi bit adder else: - # Obtain proper adder name with its bit width (columns bit pairs minus the first alone bit) - adder_prefix = self.prefix + "_" + unsigned_adder_class_name(a=a, b=b).prefix + str(len(self.columns)-1) - - adder_a = Bus(prefix=f"{adder_prefix}_a", wires_list=[self.add_column_wire(column=col, bit=0) for col in range(1, len(self.columns))]) - adder_b = Bus(prefix=f"{adder_prefix}_b", wires_list=[self.add_column_wire(column=col, bit=1) for col in range(1, len(self.columns))]) - final_adder = unsigned_adder_class_name(a=adder_a, b=adder_b, prefix=adder_prefix) + # Create adder of final PP pairs + adder_a = Bus(prefix=f"a", wires_list=[self.add_column_wire(column=col, bit=0) for col in range(1, len(self.columns))]) + adder_b = Bus(prefix=f"b", wires_list=[self.add_column_wire(column=col, bit=1) for col in range(1, len(self.columns))]) + final_adder = unsigned_adder_class_name(a=adder_a, b=adder_b, prefix=self.prefix, inner_component=True) self.add_component(final_adder) [self.out.connect(o, final_adder.out.get_wire(o-1), inserted_wire_desired_index=o-1) for o in range(1, len(self.out.bus))] diff --git a/ariths_gen/multi_bit_circuits/multipliers/wallace_multiplier.py b/ariths_gen/multi_bit_circuits/multipliers/wallace_multiplier.py index cfabf4c..d05eeff 100644 --- a/ariths_gen/multi_bit_circuits/multipliers/wallace_multiplier.py +++ b/ariths_gen/multi_bit_circuits/multipliers/wallace_multiplier.py @@ -44,23 +44,18 @@ class UnsignedWallaceMultiplier(MultiplierCircuit): Args: a (Bus): First input bus. b (Bus): Second input bus. - prefix (str, optional): Prefix name of unsigned wallace multiplier. Defaults to "u_wallace_cla". + prefix (str, optional): Prefix name of unsigned wallace multiplier. Defaults to "". + name (str, optional): Name of unsigned wallace multiplier. Defaults to "u_wallace_cla". unsigned_adder_class_name (str, optional): Unsigned multi bit adder used to obtain final sums of products. Defaults to UnsignedCarryLookaheadAdder. """ - def __init__(self, a: Bus, b: Bus, prefix: str = "u_wallace_cla", unsigned_adder_class_name: str = UnsignedCarryLookaheadAdder): - super().__init__() + def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_wallace_cla", unsigned_adder_class_name: str = UnsignedCarryLookaheadAdder, **kwargs): self.N = max(a.N, b.N) - self.prefix = prefix - self.a = Bus(prefix=a.prefix, wires_list=a.bus) - self.b = Bus(prefix=b.prefix, wires_list=b.bus) + super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs) # Bus sign extension in case buses have different lengths self.a.bus_extend(N=self.N, prefix=a.prefix) self.b.bus_extend(N=self.N, prefix=b.prefix) - # Output wires for multiplication product - self.out = Bus(self.prefix+"_out", self.N*2) - # Initialize all columns partial products forming AND gates matrix self.columns = self.init_column_heights() @@ -116,12 +111,10 @@ class UnsignedWallaceMultiplier(MultiplierCircuit): self.out.connect(3, obj_ha.get_carry_wire()) # Final addition of remaining bits using chosen unsigned multi bit adder else: - # Obtain proper adder name with its bit width (columns bit pairs minus the first alone bit) - adder_prefix = self.prefix + "_" + unsigned_adder_class_name(a=a, b=b).prefix + str(len(self.columns)-1) - - adder_a = Bus(prefix=f"{adder_prefix}_a", wires_list=[self.add_column_wire(column=col, bit=0) for col in range(1, len(self.columns))]) - adder_b = Bus(prefix=f"{adder_prefix}_b", wires_list=[self.add_column_wire(column=col, bit=1) for col in range(1, len(self.columns))]) - final_adder = unsigned_adder_class_name(a=adder_a, b=adder_b, prefix=adder_prefix) + # Create adder of final PP pairs + adder_a = Bus(prefix=f"a", wires_list=[self.add_column_wire(column=col, bit=0) for col in range(1, len(self.columns))]) + adder_b = Bus(prefix=f"b", wires_list=[self.add_column_wire(column=col, bit=1) for col in range(1, len(self.columns))]) + final_adder = unsigned_adder_class_name(a=adder_a, b=adder_b, prefix=self.prefix, inner_component=True) self.add_component(final_adder) [self.out.connect(o, final_adder.out.get_wire(o-1), inserted_wire_desired_index=o-1) for o in range(1, len(self.out.bus))] @@ -148,24 +141,19 @@ class SignedWallaceMultiplier(MultiplierCircuit): Args: a (Bus): First input bus. b (Bus): Second input bus. - prefix (str, optional): Prefix name of signed wallace multiplier. Defaults to "s_wallace_cla". + prefix (str, optional): Prefix name of signed wallace multiplier. Defaults to "". + name (str, optional): Name of signed wallace multiplier. Defaults to "s_wallace_cla". unsigned_adder_class_name (str, optional): Unsigned multi bit adder used to obtain final sums of products. Defaults to UnsignedCarryLookaheadAdder. """ - def __init__(self, a: Bus, b: Bus, prefix: str = "s_wallace_cla", unsigned_adder_class_name: str = UnsignedCarryLookaheadAdder): - super().__init__() + def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "s_wallace_cla", unsigned_adder_class_name: str = UnsignedCarryLookaheadAdder, **kwargs): self.N = max(a.N, b.N) - self.prefix = prefix + super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs) self.c_data_type = "int64_t" - self.a = Bus(prefix=a.prefix, wires_list=a.bus) - self.b = Bus(prefix=b.prefix, wires_list=b.bus) # Bus sign extension in case buses have different lengths self.a.bus_extend(N=self.N, prefix=a.prefix) self.b.bus_extend(N=self.N, prefix=b.prefix) - # Output wires for multiplication product - self.out = Bus(self.prefix+"_out", self.N*2) - # Initialize all columns partial products forming AND/NAND gates matrix based on Baugh-Wooley multiplication self.columns = self.init_column_heights(signed=True) @@ -230,12 +218,10 @@ class SignedWallaceMultiplier(MultiplierCircuit): # Final addition of remaining bits using chosen unsigned multi bit adder else: - # Obtain proper adder name with its bit width (columns bit pairs minus the first alone bit) - adder_prefix = self.prefix + "_" + unsigned_adder_class_name(a=a, b=b).prefix + str(len(self.columns)-1) - - adder_a = Bus(prefix=f"{adder_prefix}_a", wires_list=[self.add_column_wire(column=col, bit=0) for col in range(1, len(self.columns))]) - adder_b = Bus(prefix=f"{adder_prefix}_b", wires_list=[self.add_column_wire(column=col, bit=1) for col in range(1, len(self.columns))]) - final_adder = unsigned_adder_class_name(a=adder_a, b=adder_b, prefix=adder_prefix) + # Create adder of final PP pairs + adder_a = Bus(prefix=f"a", wires_list=[self.add_column_wire(column=col, bit=0) for col in range(1, len(self.columns))]) + adder_b = Bus(prefix=f"b", wires_list=[self.add_column_wire(column=col, bit=1) for col in range(1, len(self.columns))]) + final_adder = unsigned_adder_class_name(a=adder_a, b=adder_b, prefix=self.prefix, inner_component=True) self.add_component(final_adder) [self.out.connect(o, final_adder.out.get_wire(o-1), inserted_wire_desired_index=o-1) for o in range(1, len(self.out.bus))] diff --git a/ariths_gen/wire_components/buses.py b/ariths_gen/wire_components/buses.py index 9d707bb..50b263e 100644 --- a/ariths_gen/wire_components/buses.py +++ b/ariths_gen/wire_components/buses.py @@ -10,8 +10,10 @@ class Bus(): prefix (str, optional): Prefix name of the bus. Defaults to "bus". N (int, optional): Number of wires in the bus. Defaults to 1. wires_list (list, optional): List of Wire objects used to clone one bus to another. Defaults to 0. + out_bus (bool, optional): Specifies whether this Bus is an output bus of some previous component. Defaults to False. """ - def __init__(self, prefix: str = "bus", N: int = 1, wires_list: list = None): + def __init__(self, prefix: str = "bus", N: int = 1, wires_list: list = None, out_bus: bool = False): + self.out_bus = out_bus if wires_list is None: self.prefix = prefix # Adding wires into current bus's wires list (wire names are concatenated from bus prefix and their index position inside the bus in square brackets) @@ -22,6 +24,14 @@ class Bus(): self.bus = wires_list self.N = len(self.bus) + def is_output_bus(self): + """Tells whether this Bus is an output bus. + + Returns: + bool: Returns True if it is an output bus of some component. + """ + return self.out_bus + def bus_extend(self, N: int, prefix: str = "bus"): """Provides bus extension to contain more wires. @@ -69,6 +79,14 @@ class Bus(): elif inserted_wire_desired_index != -1: self.bus[bus_wire_index] = Wire(name=inner_component_out_wire.name, prefix=inner_component_out_wire.parent_bus.prefix, index=inserted_wire_index, value=inner_component_out_wire.value, parent_bus=self) + # TODO + def connect_bus(self, connecting_bus, start_connection_pos: int = 0, end_connection_pos: int = -1): + if end_connection_pos == -1: + end_connection_pos = self.N + + # Nakonec je potřeba napojit výstup adderu na výstup mac + [self.connect(o, connecting_bus.get_wire(o), inserted_wire_desired_index=o) for o in range(start_connection_pos, end_connection_pos)] + """ C CODE GENERATION """ def get_declaration_c(self): """Bus declaration in C code.