Updated logic behind generating export representations, mainly focused around circuit and its buses and subcomponents namings.
This commit is contained in:
parent
bfc806081e
commit
e16de78c2b
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)):
|
||||
|
@ -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):
|
||||
|
@ -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))]
|
||||
|
@ -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))]
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user