mirror of
https://github.com/ehw-fit/ariths-gen.git
synced 2025-04-04 06:11:41 +01:00
Big code cleanup and some fixes. Hierarchical generation for popcount seems problematic. It seems bus connections are the issue.
This commit is contained in:
parent
739d5fafce
commit
97e79b93da
@ -1,10 +1,7 @@
|
||||
from .arithmetic_circuit import (
|
||||
ArithmeticCircuit,
|
||||
ThreeInputArithmeticCircuit
|
||||
from .general_circuit import (
|
||||
GeneralCircuit
|
||||
)
|
||||
|
||||
from .general_circuit import (GeneralCircuit)
|
||||
|
||||
from .multiplier_circuit import (
|
||||
MultiplierCircuit
|
||||
)
|
||||
|
@ -1,247 +0,0 @@
|
||||
from ariths_gen.core.logic_gate_circuits.logic_gate_circuit import OneInputLogicGate, TwoInputLogicGate
|
||||
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
|
||||
from ariths_gen.core.arithmetic_circuits.general_circuit import GeneralCircuit
|
||||
|
||||
|
||||
class ArithmeticCircuit(GeneralCircuit):
|
||||
"""Class represents a general arithmetic circuit and ensures its generation to various representations.
|
||||
|
||||
The __init__ method fills some mandatory attributes concerning arithmetic circuit
|
||||
that are later used for generation into various representations.
|
||||
"""
|
||||
|
||||
def __init__(self, a, b, prefix: str, name: str, out_N: int, inner_component: bool = False, one_bit_circuit: bool = False, signed: bool = False, **kwargs):
|
||||
super().__init__(prefix, name, out_N, inner_component, inputs=[a, b], signed=signed, one_bit_circuit=one_bit_circuit, **kwargs)
|
||||
|
||||
""" C CODE GENERATION """
|
||||
def get_prototype_c(self):
|
||||
"""Generates C code function header to describe corresponding arithmetic circuit's interface in C code.
|
||||
|
||||
Returns:
|
||||
str: Function's name and parameters in C code.
|
||||
"""
|
||||
return f"{self.c_data_type} {self.prefix}({self.c_data_type} {self.a.prefix}, {self.c_data_type} {self.b.prefix})" + "{" + "\n"
|
||||
|
||||
""" VERILOG CODE GENERATION """
|
||||
def get_prototype_v(self):
|
||||
"""Generates Verilog code module header to describe corresponding arithmetic circuit's interface in Verilog code.
|
||||
|
||||
Returns:
|
||||
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"
|
||||
|
||||
""" BLIF CODE GENERATION """
|
||||
def get_declaration_blif(self):
|
||||
"""Generates flat Blif code declaration of input/output circuit wires.
|
||||
|
||||
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"
|
||||
|
||||
|
||||
class ThreeInputArithmeticCircuit(GeneralCircuit):
|
||||
"""Class represents a general three input arithmetic circuit and ensures its generation to various representations.
|
||||
|
||||
The __init__ method fills some mandatory attributes concerning arithmetic circuit
|
||||
that are later used for generation into various representations.
|
||||
"""
|
||||
|
||||
def __init__(self, a, b, c, prefix: str, name: str, out_N: int, inner_component: bool = False, one_bit_circuit: bool = False, signed: bool = False, **kwargs):
|
||||
super().__init__(prefix, name, out_N, inner_component, inputs=[a, b, c], signed=signed, **kwargs)
|
||||
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)
|
||||
self.c = Bus(prefix=f"{self.prefix}_{c.prefix}", wires_list=c.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)
|
||||
if c.is_output_bus():
|
||||
self.c.connect_bus(connecting_bus=c)
|
||||
else:
|
||||
self.a = Bus(prefix=f"{a.prefix}", wires_list=a.bus)
|
||||
self.b = Bus(prefix=f"{b.prefix}", wires_list=b.bus)
|
||||
self.c = Bus(prefix=f"{c.prefix}", wires_list=c.bus)
|
||||
|
||||
""" C CODE GENERATION """
|
||||
def get_prototype_c(self):
|
||||
"""Generates C code function header to describe corresponding arithmetic circuit's interface in C code.
|
||||
|
||||
Returns:
|
||||
str: Function's name and parameters in C code.
|
||||
"""
|
||||
return f"{self.c_data_type} {self.prefix}({self.c_data_type} {self.a.prefix}, {self.c_data_type} {self.b.prefix}, {self.c_data_type} {self.c.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"), c=Bus("c")).prefix + str(self.N)
|
||||
circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(
|
||||
N=self.N, prefix="b"), c=Bus(
|
||||
N=self.N, prefix="c"), name=circuit_prefix, **self._parent_kwargs)
|
||||
return f"{circuit_block.get_circuit_c()}\n\n"
|
||||
|
||||
def get_declaration_c_hier(self):
|
||||
"""Generates hierarchical C code declaration of corresponding subcomponent input/output wires inside the upper component.
|
||||
|
||||
Generates wires used to connect input/output values to/from invocation of the corresponding function block into inner wires present
|
||||
inside the upper component from which function block has been invoked.
|
||||
|
||||
Returns:
|
||||
str: Hierarchical C code of subcomponent arithmetic circuit's wires declaration.
|
||||
"""
|
||||
return f" {self.c_data_type} {self.a.prefix} = 0;\n" + \
|
||||
f" {self.c_data_type} {self.b.prefix} = 0;\n" + \
|
||||
f" {self.c_data_type} {self.c.prefix} = 0;\n" + \
|
||||
f" {self.c_data_type} {self.out.prefix} = 0;\n"
|
||||
|
||||
def get_out_invocation_c(self):
|
||||
"""Generates hierarchical C 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.
|
||||
|
||||
Returns:
|
||||
str: Hierarchical C code of subcomponent's C function invocation and output assignment.
|
||||
"""
|
||||
# Getting name of circuit type for proper C code generation without affecting actual generated composition
|
||||
circuit_type = self.__class__(a=Bus("a"), b=Bus("b"), c=Bus("c")).prefix + str(self.N)
|
||||
return self.a.return_bus_wires_values_c_hier() + self.b.return_bus_wires_values_c_hier() + self.c.return_bus_wires_values_c_hier() + \
|
||||
f" {self.out.prefix} = {circuit_type}({self.a.prefix}, {self.b.prefix}, {self.c.prefix});\n"
|
||||
|
||||
""" VERILOG CODE GENERATION """
|
||||
def get_prototype_v(self):
|
||||
"""Generates Verilog code module header to describe corresponding arithmetic circuit's interface in Verilog code.
|
||||
|
||||
Returns:
|
||||
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}, input [{self.N-1}:0] {self.c.prefix}, output [{self.out.N-1}:0] {self.out.prefix});\n"
|
||||
|
||||
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.
|
||||
|
||||
Returns:
|
||||
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"), c=Bus("c")).prefix + str(self.N)
|
||||
circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(
|
||||
N=self.N, prefix="b"), c=Bus(N=self.N, prefix="c"), name=circuit_prefix, **self._parent_kwargs)
|
||||
return f"{circuit_block.get_circuit_v()}\n\n"
|
||||
|
||||
def get_declaration_v_hier(self):
|
||||
"""Generates hierarchical Verilog code declaration of corresponding subcomponent input/output wires inside the upper component.
|
||||
|
||||
Generates wires used to connect input/output values to/from invocation of the corresponding function block into inner wires present
|
||||
inside the upper component from which function block has been invoked.
|
||||
|
||||
Returns:
|
||||
str: Hierarchical Verilog code of subcomponent arithmetic circuit's wires declaration.
|
||||
"""
|
||||
return f" wire [{self.a.N-1}:0] {self.a.prefix};\n" + \
|
||||
f" wire [{self.b.N-1}:0] {self.b.prefix};\n" + \
|
||||
f" wire [{self.c.N-1}:0] {self.c.prefix};\n" + \
|
||||
f" wire [{self.out.N-1}:0] {self.out.prefix};\n"
|
||||
|
||||
def get_out_invocation_v(self):
|
||||
"""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.
|
||||
|
||||
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.__class__(a=Bus("a"), b=Bus("b"), c=Bus("c")).prefix + str(self.N)
|
||||
circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(
|
||||
N=self.N, prefix="b"), c=Bus(
|
||||
N=self.N, prefix="c"), name=circuit_type)
|
||||
return self.a.return_bus_wires_values_v_hier() + self.b.return_bus_wires_values_v_hier() + self.c.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.c.prefix}({self.c.prefix}), .{circuit_block.out.prefix}({self.out.prefix}));\n"
|
||||
|
||||
""" BLIF CODE GENERATION """
|
||||
def get_declaration_blif(self):
|
||||
"""Generates flat Blif code declaration of input/output circuit wires.
|
||||
|
||||
Returns:
|
||||
str: Flat Blif code containing declaration of circuit's wires.
|
||||
"""
|
||||
if self.N == 1:
|
||||
return f".inputs {self.a.prefix} {self.b.prefix} {self.c.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()}{self.c.get_wire_declaration_blif()}\n" + \
|
||||
f".outputs{self.out.get_wire_declaration_blif()}\n" + \
|
||||
f".names vdd\n1\n" + \
|
||||
f".names gnd\n0\n"
|
||||
|
||||
def get_invocation_blif_hier(self):
|
||||
"""Generates hierarchical Blif code invocation of corresponding arithmetic circuit's generated function block.
|
||||
|
||||
Used for multi-bit subcomponent's modul invocation.
|
||||
|
||||
Returns:
|
||||
str: Hierarchical Blif code of subcomponent's model invocation and output assignment.
|
||||
"""
|
||||
# Getting name of circuit type for proper Blif code generation without affecting actual generated composition
|
||||
circuit_type = self.__class__(a=Bus("a"), b=Bus("b"), c=Bus("c")).prefix + str(self.N)
|
||||
return f"{self.a.get_wire_assign_blif(output=True)}" + \
|
||||
f"{self.b.get_wire_assign_blif(output=True)}" + \
|
||||
f"{self.c.get_wire_assign_blif(output=True)}" + \
|
||||
f".subckt {circuit_type}" + \
|
||||
"".join([f" a[{self.a.bus.index(w)}]={self.a.prefix}[{self.a.bus.index(w)}]" for w in self.a.bus]) + \
|
||||
"".join([f" b[{self.b.bus.index(w)}]={self.b.prefix}[{self.b.bus.index(w)}]" for w in self.b.bus]) + \
|
||||
"".join([f" c[{self.c.bus.index(w)}]={self.c.prefix}[{self.c.bus.index(w)}]" for w in self.c.bus]) + \
|
||||
"".join(
|
||||
[f" {circuit_type}_out[{self.out.bus.index(o)}]={o.name}" for o in self.out.bus]) + "\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_prefix = self.__class__(
|
||||
a=Bus("a"), b=Bus("b"), c=Bus("c")).prefix + str(self.N)
|
||||
circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(
|
||||
N=self.N, prefix="b"), c=Bus(N=self.N, prefix="c"), name=circuit_prefix, **self._parent_kwargs)
|
||||
return f"{circuit_block.get_circuit_blif()}"
|
@ -1,13 +1,14 @@
|
||||
from typing import Dict
|
||||
from ariths_gen.core.logic_gate_circuits.logic_gate_circuit import OneInputLogicGate, TwoInputLogicGate
|
||||
|
||||
from ariths_gen.core.logic_gate_circuits.logic_gate_circuit import (
|
||||
OneInputLogicGate,
|
||||
TwoInputLogicGate
|
||||
)
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
|
||||
from typing import Dict
|
||||
import inspect
|
||||
import copy
|
||||
from io import StringIO
|
||||
|
||||
|
||||
@ -17,7 +18,6 @@ class GeneralCircuit():
|
||||
The __init__ method fills some mandatory attributes concerning arithmetic circuit
|
||||
that are later used for generation into various representations.
|
||||
"""
|
||||
|
||||
def __init__(self, prefix: str, name: str, out_N: int, inner_component: bool = False, inputs: list = [], one_bit_circuit: bool = False, signed: bool = False, outname=None, **kwargs):
|
||||
if prefix == "":
|
||||
self.prefix = name
|
||||
@ -25,29 +25,19 @@ class GeneralCircuit():
|
||||
self.prefix = prefix + "_" + name
|
||||
self.inner_component = inner_component
|
||||
|
||||
if one_bit_circuit is False:
|
||||
# Dynamic input bus assignment
|
||||
self.inputs = []
|
||||
input_names = "abcdefghijklmnopqrstuvwxyz" # This should be enough..
|
||||
assert len(input_names) >= len(inputs)
|
||||
for i, input in enumerate(inputs):
|
||||
attr_name = input_names[i]
|
||||
full_prefix = f"{self.prefix}_{input.prefix}" if self.inner_component else f"{input.prefix}"
|
||||
if isinstance(input, Bus):
|
||||
bus = Bus(prefix=full_prefix, wires_list=input.bus)
|
||||
setattr(self, attr_name, bus)
|
||||
self.inputs.append(bus)
|
||||
|
||||
# If the input bus is an output bus, connect it
|
||||
if input.is_output_bus():
|
||||
getattr(self, attr_name).connect_bus(connecting_bus=input)
|
||||
else:
|
||||
wire = Wire(name=input.name, prefix=full_prefix)
|
||||
setattr(self, attr_name, wire)
|
||||
self.inputs.append(wire)
|
||||
|
||||
else:
|
||||
self.inputs = inputs
|
||||
# Dynamic input bus assignment
|
||||
self.inputs = []
|
||||
for i, input in enumerate(inputs):
|
||||
attr_name = chr(97+i)
|
||||
full_prefix = f"{self.prefix}_{input.prefix}" if self.inner_component else f"{input.prefix}"
|
||||
if isinstance(input, Bus) or isinstance(input, Wire):
|
||||
circuit_input = copy.deepcopy(input)
|
||||
circuit_input.prefix = full_prefix
|
||||
setattr(self, attr_name, circuit_input)
|
||||
self.inputs.append(circuit_input)
|
||||
# If the input bus is an output bus, connect it
|
||||
if isinstance(input, Bus) and input.is_output_bus():
|
||||
getattr(self, attr_name).connect_bus(connecting_bus=input)
|
||||
|
||||
if not outname:
|
||||
outname = self.prefix+"_out"
|
||||
@ -75,17 +65,50 @@ class GeneralCircuit():
|
||||
|
||||
def __str__(self):
|
||||
return f"<{type(self).__name__} prefix={self.prefix} " + (", ".join([f"input={i}" for i in self.inputs])) + ">"
|
||||
|
||||
# super().__init__(prefix, name, out_N, inner_component, inputs=[a, b], signed=signed, **kwargs)
|
||||
|
||||
def get_hier_subcomponent_def(self, parent_kwargs: dict = {}):
|
||||
""" Creates and returns a new instance of the current circuit block used for definition of a subcomponent in a hierarchical circuit.
|
||||
|
||||
Args:
|
||||
parent_kwargs (dict): Dictionary containing all the configuration settings of the parent circuit block.
|
||||
|
||||
Returns:
|
||||
GeneralCircuit: A new instance of the current circuit block with proper prefix and input wires.
|
||||
"""
|
||||
# Obtain proper circuit name with its input bit widths
|
||||
init_signature = inspect.signature(self.__class__.__init__)
|
||||
init_params = list(init_signature.parameters.keys())
|
||||
default_circuit_name = init_signature.parameters['name'].default
|
||||
circuit_type = default_circuit_name + "x".join(str(getattr(self, chr(97+i)).N) for i, _ in enumerate(self.inputs))
|
||||
# Initialize and fill args for the new instance based on the current instance
|
||||
init_args = {}
|
||||
|
||||
for param in init_params[1:]: # Skip 'self'
|
||||
attr = getattr(self, param, None) # Get the attribute from the current instance
|
||||
|
||||
if attr is not None: # If attribute does not exist, it will use default value from the signature
|
||||
if isinstance(attr, Bus): # If the input is a Bus, create a copy of the Bus object with same length, but proper prefix
|
||||
init_args[param] = Bus(N=attr.N, prefix=param)
|
||||
elif isinstance(attr, Wire): # If the input is a Wire, create a copy of the Wire object with proper prefix
|
||||
init_args[param] = Wire(name=param)
|
||||
else: # Copy other types of attributes
|
||||
init_args[param] = copy.deepcopy(attr)
|
||||
|
||||
init_args['name'] = circuit_type
|
||||
init_args['prefix'] = ""
|
||||
|
||||
circuit_block = self.__class__(**init_args, **parent_kwargs)
|
||||
return circuit_block
|
||||
|
||||
def get_circuit_def(self) -> Dict[str, Wire]:
|
||||
""" returns IDs and wires of the inputs and output"""
|
||||
#.{circuit_block.a.prefix}({self.a.prefix}), .{circuit_block.b.prefix}({self.b.prefix}), .{circuit_block.out.prefix}({self.out.prefix}));\n"
|
||||
# TODO delete? (probably replaced by get_hier_subcomponent_def)
|
||||
#.{circuit_block.a.prefix}({self.a.prefix}), .{circuit_block.b.prefix}({self.b.prefix}), .{circuit_block.out.prefix}({self.out.prefix}));\n"
|
||||
r = {chr(97 + i): self.inputs[i] for i in range(len(self.inputs))}
|
||||
r['out'] = self.get_global_prefix() + "_out"
|
||||
return r
|
||||
|
||||
|
||||
def add_component(self, component):
|
||||
"""Adds a component into list of circuit's inner subcomponents.
|
||||
|
||||
@ -95,7 +118,7 @@ class GeneralCircuit():
|
||||
Args:
|
||||
component: Subcomponent to be added into list of components composing described circuit.
|
||||
"""
|
||||
# TODO will be redone in ArithsGen rework
|
||||
# TODO should be refactored in ArithsGen rework
|
||||
# We should probably check also wire names for especially hierarchical generation
|
||||
if isinstance(component, TwoInputLogicGate):
|
||||
if component.disable_generation is False:
|
||||
@ -166,7 +189,7 @@ class GeneralCircuit():
|
||||
for c in self.components:
|
||||
if isinstance(c, TwoInputLogicGate):
|
||||
continue
|
||||
elif isinstance(getattr(c, 'a'), Wire):
|
||||
elif all(isinstance(i, Wire) for i in self.inputs):
|
||||
one_bit_comps.append(c)
|
||||
else:
|
||||
one_bit_comps.extend(c.get_one_bit_components())
|
||||
@ -183,14 +206,15 @@ class GeneralCircuit():
|
||||
for c in self.components:
|
||||
if isinstance(c, TwoInputLogicGate):
|
||||
continue
|
||||
elif isinstance(getattr(c, 'a'), Wire):
|
||||
elif all(isinstance(i, Wire) for i in self.inputs):
|
||||
continue
|
||||
else:
|
||||
multi_bit_comps.append(c)
|
||||
multi_bit_comps.extend(c.get_multi_bit_components())
|
||||
return multi_bit_comps
|
||||
|
||||
@staticmethod
|
||||
def get_unique_types(components: list, multi_bit: bool = False):
|
||||
def get_unique_types(components: list, name="", multi_bit: bool = False):
|
||||
"""Retrieves just the unique representatives of class types present inside the provided components list.
|
||||
|
||||
Args:
|
||||
@ -201,7 +225,7 @@ class GeneralCircuit():
|
||||
list: List of unique composite class types.
|
||||
"""
|
||||
if multi_bit is True:
|
||||
return list({(type(c), c.N): c for c in components}.values())
|
||||
return list({(type(c), tuple(i.N for i in c.inputs)): c for c in components[::-1]}.values())
|
||||
else:
|
||||
return list({type(c): c for c in components}.values())
|
||||
|
||||
@ -218,7 +242,7 @@ class GeneralCircuit():
|
||||
gate_comps = self.get_unique_types(components=self.get_circuit_gates(verilog_output))
|
||||
one_bit_comps = self.get_unique_types(
|
||||
components=self.get_one_bit_components())
|
||||
multi_bit_comps = self.get_unique_types(
|
||||
multi_bit_comps = self.get_unique_types(name=self.prefix,
|
||||
components=self.get_multi_bit_components(), multi_bit=True)
|
||||
|
||||
all_components = gate_comps + one_bit_comps + multi_bit_comps
|
||||
@ -328,8 +352,6 @@ class GeneralCircuit():
|
||||
file_object (TextIOWrapper): Destination file object where circuit's representation will be written to.
|
||||
"""
|
||||
file_object.write(self.get_prototype_python())
|
||||
# file_object.write(self.out.get_declaration_python())
|
||||
# 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_flat())
|
||||
@ -403,8 +425,6 @@ class GeneralCircuit():
|
||||
"""
|
||||
# Retrieve all unique component types composing this circuit and add them kwargs from the parent circuit to allow propagatation of config settings for subcomponents
|
||||
self.component_types = self.get_component_types()
|
||||
for c in self.component_types:
|
||||
c._parent_kwargs = self.kwargs
|
||||
return "".join([c.get_function_block_c() for c in self.component_types])
|
||||
|
||||
def get_function_block_c(self):
|
||||
@ -413,12 +433,7 @@ class GeneralCircuit():
|
||||
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", self.N), b=Bus("b", self.N)).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, **self._parent_kwargs)
|
||||
return f"{circuit_block.get_circuit_c()}\n\n"
|
||||
return f"{self.get_hier_subcomponent_def(parent_kwargs=self.kwargs).get_circuit_c()}\n\n"
|
||||
|
||||
def get_declarations_c_hier(self):
|
||||
"""Generates hierarchical C code declaration of input/output circuit wires.
|
||||
@ -437,9 +452,8 @@ class GeneralCircuit():
|
||||
Returns:
|
||||
str: Hierarchical C code of subcomponent arithmetic circuit's wires declaration.
|
||||
"""
|
||||
return f" {self.c_data_type} {self.a.prefix} = 0;\n" + \
|
||||
f" {self.c_data_type} {self.b.prefix} = 0;\n" + \
|
||||
f" {self.c_data_type} {self.out.prefix} = 0;\n"
|
||||
return ";\n".join([f" {self.c_data_type} {i.prefix} = 0" for i in self.inputs]) + ";\n" + \
|
||||
f" {self.c_data_type} {self.out.prefix} = 0;\n"
|
||||
|
||||
def get_init_c_hier(self):
|
||||
"""Generates hierarchical C code initialization and assignment of corresponding arithmetic circuit's input/output wires.
|
||||
@ -460,9 +474,12 @@ class GeneralCircuit():
|
||||
str: Hierarchical C code of subcomponent's C function invocation and output assignment.
|
||||
"""
|
||||
# Getting name of circuit type for proper C code generation without affecting actual generated composition
|
||||
circuit_type = self.__class__(a=Bus("a", self.N), b=Bus("b", self.N)).prefix + str(self.N)
|
||||
return self.a.return_bus_wires_values_c_hier() + self.b.return_bus_wires_values_c_hier() + \
|
||||
f" {self.out.prefix} = {circuit_type}({self.a.prefix}, {self.b.prefix});\n"
|
||||
init_signature = inspect.signature(self.__class__.__init__)
|
||||
default_circuit_name = init_signature.parameters['name'].default
|
||||
circuit_type = default_circuit_name + "x".join(str(getattr(self, chr(97+i)).N) for i, _ in enumerate(self.inputs))
|
||||
# TODO .. now only works for input buses
|
||||
return "".join(w.return_bus_wires_values_c_hier() for w in self.inputs) + \
|
||||
f" {self.out.prefix} = {circuit_type}({', '.join(w.prefix if isinstance(w, Bus) else w.get_wire_value_c_hier() for w in self.inputs)});\n"
|
||||
|
||||
def get_function_out_c_hier(self):
|
||||
"""Generates hierarchical C code assignment of corresponding arithmetic circuit's output bus wires.
|
||||
@ -499,14 +516,13 @@ class GeneralCircuit():
|
||||
|
||||
""" 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.
|
||||
|
||||
Returns:
|
||||
str: Module's name and parameters in Verilog code.
|
||||
"""
|
||||
return f"module {self.prefix}(" + ",".join(f"input [{x.N-1}:0] {x.prefix}" for x in self.inputs) + f", output [{self.out.N-1}:0] {self.out.prefix});\n"
|
||||
return f"module {self.prefix}(" + ", ".join(f"input [{x.N-1}:0] {x.prefix}" for x in self.inputs) + f", output [{self.out.N-1}:0] {self.out.prefix});\n"
|
||||
|
||||
def get_declaration_v_flat(self):
|
||||
"""Generates flat Verilog code declaration of input/output circuit wires.
|
||||
@ -554,8 +570,6 @@ class GeneralCircuit():
|
||||
"""
|
||||
# Retrieve all unique component types composing this circuit and add them kwargs from the parent circuit to allow propagatation of config settings for subcomponents
|
||||
self.component_types = self.get_component_types(verilog_output=True)
|
||||
for c in self.component_types:
|
||||
c._parent_kwargs = self.kwargs
|
||||
return "".join([c.get_function_block_v() for c in self.component_types])
|
||||
|
||||
def get_function_block_v(self):
|
||||
@ -565,11 +579,7 @@ class GeneralCircuit():
|
||||
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", self.N), b=Bus("b", self.N)).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, **self._parent_kwargs)
|
||||
return f"{circuit_block.get_circuit_v()}\n\n"
|
||||
return f"{self.get_hier_subcomponent_def(parent_kwargs=self.kwargs).get_circuit_v()}\n\n"
|
||||
|
||||
def get_declarations_v_hier(self):
|
||||
"""Generates hierarchical Verilog code declaration of input/output circuit wires.
|
||||
@ -590,10 +600,7 @@ class GeneralCircuit():
|
||||
"""
|
||||
return "".join(w.get_wire_declaration_v() for w in self.inputs + [self.out]) + "\n"
|
||||
|
||||
# TODO del..
|
||||
return f" wire [{self.a.N-1}:0] {self.a.prefix};\n" + \
|
||||
f" wire [{self.b.N-1}:0] {self.b.prefix};\n" + \
|
||||
f" wire [{self.out.N-1}:0] {self.out.prefix};\n"
|
||||
#return "".join(b.get_wire_declaration_v() for b in self.inputs + [self.out] if not all((w.is_const()) or (w.parent_bus is not None and w.prefix == b.prefix) for w in b.bus)) + "\n"
|
||||
|
||||
def get_init_v_hier(self):
|
||||
"""Generates hierarchical Verilog code initialization and assignment of corresponding arithmetic circuit's input/output wires.
|
||||
@ -614,12 +621,13 @@ class GeneralCircuit():
|
||||
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.__class__(a=Bus("a", self.N), b=Bus("b", self.N)).prefix + str(self.N)
|
||||
circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(
|
||||
N=self.N, prefix="b"), name=circuit_type)
|
||||
init_signature = inspect.signature(self.__class__.__init__)
|
||||
default_circuit_name = init_signature.parameters['name'].default
|
||||
circuit_type = default_circuit_name + "x".join(str(getattr(self, chr(97+i)).N) for i, _ in enumerate(self.inputs))
|
||||
circuit_block = self.get_hier_subcomponent_def(parent_kwargs=self.kwargs)
|
||||
# TODO .. now only works for input buses
|
||||
return "".join([c.return_bus_wires_values_v_hier() for c in self.inputs]) + \
|
||||
f" {circuit_type} {circuit_type}_{self.out.prefix}(" + ",".join([f".{a.prefix}({b.prefix})" for a, b in zip(circuit_block.inputs, self.inputs)]) + f", .{circuit_block.out.prefix}({self.out.prefix}));\n"
|
||||
#.{circuit_block.a.prefix}({self.a.prefix}), .{circuit_block.b.prefix}({self.b.prefix}), .{circuit_block.out.prefix}({self.out.prefix}));\n"
|
||||
f" {circuit_type} {circuit_type}_{self.out.prefix}(" + ",".join([f".{a.prefix}({b.prefix})" for a, b in zip(circuit_block.inputs, self.inputs)]) + f", .{circuit_block.out.prefix}({self.out.prefix}));\n"
|
||||
|
||||
def get_function_out_v_hier(self):
|
||||
"""Generates hierarchical Verilog code assignment of corresponding arithmetic circuit's output bus wires.
|
||||
@ -668,10 +676,16 @@ class GeneralCircuit():
|
||||
Returns:
|
||||
str: Flat Blif code containing declaration of circuit's wires.
|
||||
"""
|
||||
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"
|
||||
if self.N == 1:
|
||||
return f".inputs {' '.join([w.prefix 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"
|
||||
else:
|
||||
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.
|
||||
@ -720,7 +734,15 @@ class GeneralCircuit():
|
||||
str: Hierarchical Blif code of subcomponent's model invocation and output assignment.
|
||||
"""
|
||||
# Getting name of circuit type for proper Blif code generation without affecting actual generated composition
|
||||
circuit_type = self.__class__(a=Bus("a", self.N), b=Bus("b", self.N)).prefix + str(self.N)
|
||||
init_signature = inspect.signature(self.__class__.__init__)
|
||||
default_circuit_name = init_signature.parameters['name'].default
|
||||
circuit_type = default_circuit_name + "x".join(str(getattr(self, chr(97+i)).N) for i, _ in enumerate(self.inputs))
|
||||
return "".join([w.get_wire_assign_blif(output=True) for w in self.inputs]) + \
|
||||
f".subckt {circuit_type}" + \
|
||||
"".join([f" {chr(97+i)}[{b.bus.index(w)}]={b.prefix}[{b.bus.index(w)}]" for i, b in enumerate(self.inputs) for w in b.bus]) + \
|
||||
"".join([f" {circuit_type}_out[{self.out.bus.index(o)}]={o.name}" for o in self.out.bus]) + "\n"
|
||||
|
||||
# TODO delete
|
||||
return f"{self.a.get_wire_assign_blif(output=True)}" + \
|
||||
f"{self.b.get_wire_assign_blif(output=True)}" + \
|
||||
f".subckt {circuit_type}" + \
|
||||
@ -749,8 +771,6 @@ class GeneralCircuit():
|
||||
# Retrieve all unique component types composing this circuit and add them kwargs from the parent circuit to allow propagatation of config settings for subcomponents
|
||||
# (iterating backwards as opposed to other representations so the top modul is always above its subcomponents)
|
||||
self.component_types = self.get_component_types()
|
||||
for c in self.component_types:
|
||||
c._parent_kwargs = self.kwargs
|
||||
return "\n".join([c.get_function_block_blif() for c in self.component_types[::-1]])
|
||||
|
||||
def get_function_block_blif(self):
|
||||
@ -760,11 +780,7 @@ class GeneralCircuit():
|
||||
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", self.N), b=Bus("b", self.N)).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, **self._parent_kwargs)
|
||||
return f"{circuit_block.get_circuit_blif()}"
|
||||
return f"{self.get_hier_subcomponent_def(parent_kwargs=self.kwargs).get_circuit_blif()}"
|
||||
|
||||
# Generating hierarchical BLIF code representation of circuit
|
||||
def get_blif_code_hier(self, file_object):
|
||||
|
@ -1,36 +1,24 @@
|
||||
from .arithmetic_circuit import (
|
||||
ArithmeticCircuit
|
||||
from .general_circuit import (
|
||||
GeneralCircuit
|
||||
)
|
||||
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
)
|
||||
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate
|
||||
)
|
||||
import math
|
||||
|
||||
|
||||
class MultiplierCircuit(ArithmeticCircuit):
|
||||
"""Class represents a general multiplier circuit derived from `ArithmeticCircuit` class.
|
||||
class MultiplierCircuit(GeneralCircuit):
|
||||
"""Class represents a general multiplier circuit derived from `GeneralCircuit` class.
|
||||
|
||||
The __init__ method calls parent class __init__ method which fills some mandatory attributes concerning arithmetic circuit
|
||||
The __init__ method calls parent class __init__ method which fills some mandatory attributes concerning general circuit
|
||||
that are later used for generation into various representations.
|
||||
"""
|
||||
|
||||
def __init__(self, a, b, prefix: str, name: str, out_N: int, **kwargs):
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=out_N, **kwargs)
|
||||
def __init__(self, prefix: str, name: str, out_N: int, inner_component: bool = False, inputs: list = [], one_bit_circuit: bool = False, signed: bool = False, outname: str = "", **kwargs):
|
||||
super().__init__(prefix=prefix, name=name, out_N=out_N, inner_component=inner_component, inputs=inputs, one_bit_circuit=one_bit_circuit, signed=signed, outname=outname, **kwargs)
|
||||
|
||||
# Array/approximate multipliers
|
||||
def get_previous_partial_product(self, a_index: int, b_index: int, mult_type=""):
|
||||
@ -266,7 +254,7 @@ class MultiplierCircuit(ArithmeticCircuit):
|
||||
else:
|
||||
return self.columns[column][bit+1]
|
||||
|
||||
def update_column_wires(self, curr_column: int, adder: ArithmeticCircuit, next_column: int = 0):
|
||||
def update_column_wires(self, curr_column: int, adder: GeneralCircuit, next_column: int = 0):
|
||||
"""Provides bit height reduction of the chosen column.
|
||||
|
||||
Inserts chosen column's top bits into an `adder` circuit to reduce its bit height.
|
||||
@ -274,7 +262,7 @@ class MultiplierCircuit(ArithmeticCircuit):
|
||||
|
||||
Args:
|
||||
curr_column (int): Current pp column index.
|
||||
adder (ArithmeticCircuit): Two/three input one bit adder.
|
||||
adder (GeneralCircuit): Two/three input one bit adder.
|
||||
next_column (int, optional): Subsequent pp column index. Defaults to 0.
|
||||
"""
|
||||
if hasattr(adder, "c"):
|
||||
|
@ -1,5 +1,4 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
@ -7,14 +6,6 @@ from ariths_gen.wire_components import (
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
GeneralCircuit
|
||||
)
|
||||
|
||||
from ariths_gen.core.logic_gate_circuits import (
|
||||
MultipleInputLogicGate
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
|
@ -1,4 +1,4 @@
|
||||
from ariths_gen.wire_components.wires import Wire, ConstantWireValue0, ConstantWireValue1
|
||||
from ariths_gen.wire_components.wires import Wire
|
||||
from ariths_gen.wire_components.buses import Bus
|
||||
import math
|
||||
|
||||
|
@ -1,11 +1,13 @@
|
||||
from .two_input_one_bit_circuit import (
|
||||
TwoInputOneBitCircuit
|
||||
)
|
||||
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.wire_components.wires import Wire
|
||||
|
||||
|
||||
class FourInputOneBitCircuit(TwoInputOneBitCircuit):
|
||||
class FourInputOneBitCircuit(TwoInputOneBitCircuit, GeneralCircuit):
|
||||
"""Class represents a general four input one bit circuit and implements their generation to various representations. It is derived from `TwoInputOneBitCircuit` class.
|
||||
|
||||
Description of the __init__ method.
|
||||
@ -18,13 +20,8 @@ class FourInputOneBitCircuit(TwoInputOneBitCircuit):
|
||||
prefix (str, optional): Prefix name of circuit. Defaults to "four_input_one_bit_circuit".
|
||||
"""
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="c"), d: Wire = Wire(name="d"), prefix: str = "four_input_one_bit_circuit"):
|
||||
super().__init__()
|
||||
GeneralCircuit.__init__(self, inputs=[a, b, c, d], prefix=prefix, name="", out_N=1)
|
||||
self.c_data_type = "uint8_t"
|
||||
self.prefix = prefix
|
||||
self.a = a
|
||||
self.b = b
|
||||
self.c = c
|
||||
self.d = d
|
||||
|
||||
""" C CODE GENERATION """
|
||||
# FLAT C #
|
||||
|
@ -1,11 +1,13 @@
|
||||
from .two_input_one_bit_circuit import (
|
||||
TwoInputOneBitCircuit
|
||||
)
|
||||
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.wire_components.wires import Wire
|
||||
|
||||
|
||||
class ThreeInputOneBitCircuit(TwoInputOneBitCircuit):
|
||||
class ThreeInputOneBitCircuit(TwoInputOneBitCircuit, GeneralCircuit):
|
||||
"""Class represents a general three input one bit circuit and implements their generation to various representations. It is derived from `TwoInputOneBitCircuit` class.
|
||||
|
||||
Description of the __init__ method.
|
||||
@ -17,12 +19,8 @@ class ThreeInputOneBitCircuit(TwoInputOneBitCircuit):
|
||||
prefix (str, optional): Prefix name of circuit. Defaults to "three_input_one_bit_circuit".
|
||||
"""
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "three_input_one_bit_circuit"):
|
||||
super().__init__()
|
||||
GeneralCircuit.__init__(self, inputs=[a, b, c], prefix=prefix, name="", out_N=1)
|
||||
self.c_data_type = "uint8_t"
|
||||
self.prefix = prefix
|
||||
self.a = a
|
||||
self.b = b
|
||||
self.c = c
|
||||
|
||||
""" C CODE GENERATION """
|
||||
# FLAT C #
|
||||
|
@ -1,11 +1,11 @@
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit
|
||||
GeneralCircuit
|
||||
)
|
||||
|
||||
from ariths_gen.wire_components.wires import Wire
|
||||
|
||||
|
||||
class TwoInputOneBitCircuit(ArithmeticCircuit):
|
||||
class TwoInputOneBitCircuit(GeneralCircuit):
|
||||
"""Class represents a general two input one bit circuit and implements their generation to various representations. It is derived from `ArithmeticCircuit` class.
|
||||
|
||||
Description of the __init__ method.
|
||||
@ -16,11 +16,8 @@ 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__(a=a, b=b, prefix=prefix, name="", out_N=1, one_bit_circuit=True)
|
||||
super().__init__(inputs=[a, b], prefix=prefix, name="", out_N=1, one_bit_circuit=True)
|
||||
self.c_data_type = "uint8_t"
|
||||
self.prefix = prefix
|
||||
self.a = a
|
||||
self.b = b
|
||||
|
||||
""" C CODE GENERATION """
|
||||
# FLAT C #
|
||||
|
@ -67,4 +67,4 @@ from ariths_gen.multi_bit_circuits.adders.conditional_sum_adder import (
|
||||
from ariths_gen.multi_bit_circuits.adders.carry_increment_adder import (
|
||||
UnsignedCarryIncrementAdder,
|
||||
SignedCarryIncrementAdder
|
||||
)
|
||||
)
|
||||
|
@ -1,41 +1,22 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder,
|
||||
PGSumLogic,
|
||||
GreyCell,
|
||||
BlackCell
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
)
|
||||
from ariths_gen.multi_bit_circuits.adders import (
|
||||
UnsignedCarryLookaheadAdder,
|
||||
UnsignedPGRippleCarryAdder,
|
||||
UnsignedRippleCarryAdder,
|
||||
SignedCarryLookaheadAdder,
|
||||
SignedPGRippleCarryAdder,
|
||||
SignedRippleCarryAdder
|
||||
XorGate
|
||||
)
|
||||
import math
|
||||
|
||||
|
||||
class UnsignedBrentKungAdder(ArithmeticCircuit):
|
||||
class UnsignedBrentKungAdder(GeneralCircuit):
|
||||
"""Class representing unsigned Brent-Kung adder (using valency-2 logic gates).
|
||||
|
||||
The Brent-Kung adder belongs to a type of tree (parallel-prefix) adders.
|
||||
@ -87,7 +68,7 @@ class UnsignedBrentKungAdder(ArithmeticCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_bka", **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N+1, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -155,7 +136,7 @@ class UnsignedBrentKungAdder(ArithmeticCircuit):
|
||||
self.generate_sig[i_wire+1].append(self.get_previous_component().get_generate_wire())
|
||||
|
||||
|
||||
class SignedBrentKungAdder(UnsignedBrentKungAdder, ArithmeticCircuit):
|
||||
class SignedBrentKungAdder(UnsignedBrentKungAdder, GeneralCircuit):
|
||||
"""Class representing signed Brent-Kung adder (using valency-2 logic gates).
|
||||
|
||||
The Brent-Kung adder belongs to a type of tree (parallel-prefix) adders.
|
||||
|
@ -1,13 +1,9 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus,
|
||||
wires
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.core.logic_gate_circuits import (
|
||||
MultipleInputLogicGate
|
||||
@ -15,21 +11,16 @@ from ariths_gen.core.logic_gate_circuits import (
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder,
|
||||
FullAdderP,
|
||||
TwoOneMultiplexer
|
||||
FullAdderP
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
XorGate
|
||||
)
|
||||
|
||||
|
||||
class UnsignedCarryIncrementAdder(ArithmeticCircuit):
|
||||
class UnsignedCarryIncrementAdder(GeneralCircuit):
|
||||
"""Class representing unsigned carry increment adder.
|
||||
|
||||
Carry increment adder represents a modified carry select adder that achieves about the same critical delay
|
||||
@ -71,7 +62,7 @@ class UnsignedCarryIncrementAdder(ArithmeticCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, increment_block_size: int = 4, prefix: str = "", name: str = "u_cia", **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N+1, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -115,7 +106,7 @@ class UnsignedCarryIncrementAdder(ArithmeticCircuit):
|
||||
self.out.connect(self.N, cin)
|
||||
|
||||
|
||||
class SignedCarryIncrementAdder(UnsignedCarryIncrementAdder, ArithmeticCircuit):
|
||||
class SignedCarryIncrementAdder(UnsignedCarryIncrementAdder, GeneralCircuit):
|
||||
"""Class representing signed carry increment adder.
|
||||
|
||||
Carry increment adder represents a modified carry select adder that achieves about the same critical delay
|
||||
|
@ -1,34 +1,24 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.core.logic_gate_circuits import (
|
||||
MultipleInputLogicGate
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder,
|
||||
FullAdderPG,
|
||||
PGLogicBlock
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
XorGate
|
||||
)
|
||||
|
||||
|
||||
class UnsignedCarryLookaheadAdder(ArithmeticCircuit):
|
||||
class UnsignedCarryLookaheadAdder(GeneralCircuit):
|
||||
"""Class representing unsigned carry-lookahead adder.
|
||||
|
||||
Unsigned carry-lookahead adder represents faster adder circuit which is composed
|
||||
@ -67,7 +57,7 @@ class UnsignedCarryLookaheadAdder(ArithmeticCircuit):
|
||||
"""
|
||||
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)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N+1, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -128,7 +118,7 @@ class UnsignedCarryLookaheadAdder(ArithmeticCircuit):
|
||||
self.out.connect(self.N, cin)
|
||||
|
||||
|
||||
class SignedCarryLookaheadAdder(UnsignedCarryLookaheadAdder, ArithmeticCircuit):
|
||||
class SignedCarryLookaheadAdder(UnsignedCarryLookaheadAdder, GeneralCircuit):
|
||||
"""Class representing signed carry-lookahead adder.
|
||||
|
||||
Signed carry-lookahead adder represents faster adder circuit which is composed
|
||||
|
@ -1,38 +1,20 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
ThreeInputArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
)
|
||||
from ariths_gen.multi_bit_circuits.adders import (
|
||||
UnsignedCarryLookaheadAdder,
|
||||
UnsignedPGRippleCarryAdder,
|
||||
UnsignedRippleCarryAdder,
|
||||
SignedCarryLookaheadAdder,
|
||||
SignedPGRippleCarryAdder,
|
||||
SignedRippleCarryAdder
|
||||
UnsignedCarryLookaheadAdder
|
||||
)
|
||||
|
||||
|
||||
class CarrySaveAdderComponent(ThreeInputArithmeticCircuit):
|
||||
class CarrySaveAdderComponent(GeneralCircuit):
|
||||
"""Class representing carry save adder component.
|
||||
|
||||
The carry save adder component is especially useful when constructing tree multiplier architectures to reduce the propagation delay as opposed to traditional implementation of tree multipliers with half/full adders.
|
||||
@ -70,7 +52,8 @@ class CarrySaveAdderComponent(ThreeInputArithmeticCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, c: Bus, prefix: str = "", name: str = "csa_component", signed: bool = False, **kwargs):
|
||||
self.N = max(a.N, b.N, c.N)
|
||||
super().__init__(a=a, b=b, c=c, prefix=prefix, name=name, out_N=(2*self.N)+2, signed=signed, **kwargs)
|
||||
super().__init__(inputs=[a, b, c], prefix=prefix, name=name, out_N=(2*self.N)+2, signed=signed, **kwargs)
|
||||
self.out.signed = False # CSA component has always unsigned output
|
||||
|
||||
bus_extension_wire = ConstantWireValue1() if self.signed is True else ConstantWireValue0()
|
||||
self.a.bus_extend(N=self.N, prefix=a.prefix, desired_extension_wire=bus_extension_wire)
|
||||
@ -94,7 +77,7 @@ class CarrySaveAdderComponent(ThreeInputArithmeticCircuit):
|
||||
[self.out.connect(o, self.carry_bits.get_wire(o-int(self.out.N/2))) for o in range(int(self.out.N/2), self.out.N)]
|
||||
|
||||
|
||||
class UnsignedCarrySaveAdder(ThreeInputArithmeticCircuit):
|
||||
class UnsignedCarrySaveAdder(GeneralCircuit):
|
||||
"""Class representing unsigned carry save adder.
|
||||
|
||||
Unsigned carry save adder represents 3 input N-bit unsigned adder which is composed of
|
||||
@ -132,7 +115,7 @@ class UnsignedCarrySaveAdder(ThreeInputArithmeticCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, c: Bus, prefix: str = "", name: str = "u_csa", unsigned_adder_class_name: str = UnsignedCarryLookaheadAdder, **kwargs):
|
||||
self.N = max(a.N, b.N, c.N)
|
||||
super().__init__(a=a, b=b, c=c, prefix=prefix, name=name, out_N=self.N+2, **kwargs)
|
||||
super().__init__(inputs=[a, b, c], 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)
|
||||
|
@ -1,34 +1,23 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus,
|
||||
wires
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
)
|
||||
from ariths_gen.core.logic_gate_circuits import (
|
||||
MultipleInputLogicGate
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder,
|
||||
TwoOneMultiplexer
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
XorGate
|
||||
)
|
||||
|
||||
|
||||
class UnsignedCarrySelectAdder(ArithmeticCircuit):
|
||||
class UnsignedCarrySelectAdder(GeneralCircuit):
|
||||
"""Class representing unsigned carry select adder.
|
||||
|
||||
Carry select adder's logic is divided into a number of carry select blocks.
|
||||
@ -75,7 +64,7 @@ class UnsignedCarrySelectAdder(ArithmeticCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, select_block_size: int = 4, prefix: str = "", name: str = "u_csla", **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N+1, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -125,7 +114,7 @@ class UnsignedCarrySelectAdder(ArithmeticCircuit):
|
||||
self.out.connect(self.N, cin)
|
||||
|
||||
|
||||
class SignedCarrySelectAdder(UnsignedCarrySelectAdder, ArithmeticCircuit):
|
||||
class SignedCarrySelectAdder(UnsignedCarrySelectAdder, GeneralCircuit):
|
||||
"""Class representing signed carry select adder.
|
||||
|
||||
Carry select adder's logic is divided into a number of carry select blocks.
|
||||
|
@ -1,13 +1,9 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus,
|
||||
wires
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.core.logic_gate_circuits import (
|
||||
MultipleInputLogicGate
|
||||
@ -19,16 +15,11 @@ from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
XorGate
|
||||
)
|
||||
|
||||
|
||||
class UnsignedCarrySkipAdder(ArithmeticCircuit):
|
||||
class UnsignedCarrySkipAdder(GeneralCircuit):
|
||||
"""Class representing unsigned carry skip (bypass) adder composed of smaller carry bypass blocks of chosen size to reduce propagation delay.
|
||||
|
||||
Unsigned carry skip (bypass) adder represents faster adder circuit which is composed
|
||||
@ -72,7 +63,7 @@ class UnsignedCarrySkipAdder(ArithmeticCircuit):
|
||||
"""
|
||||
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)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N+1, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -120,7 +111,7 @@ class UnsignedCarrySkipAdder(ArithmeticCircuit):
|
||||
self.out.connect(self.N, cin)
|
||||
|
||||
|
||||
class SignedCarrySkipAdder(UnsignedCarrySkipAdder, ArithmeticCircuit):
|
||||
class SignedCarrySkipAdder(UnsignedCarrySkipAdder, GeneralCircuit):
|
||||
"""Class representing signed carry skip (bypass) adder composed of smaller carry bypass blocks of chosen size to reduce propagation delay.
|
||||
|
||||
Signed carry skip (bypass) adder represents faster adder circuit which is composed
|
||||
|
@ -1,35 +1,22 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus,
|
||||
wires
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
)
|
||||
from ariths_gen.core.logic_gate_circuits import (
|
||||
MultipleInputLogicGate
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder,
|
||||
TwoOneMultiplexer
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
XorGate
|
||||
)
|
||||
import math
|
||||
|
||||
|
||||
class UnsignedConditionalSumAdder(ArithmeticCircuit):
|
||||
class UnsignedConditionalSumAdder(GeneralCircuit):
|
||||
"""Class representing unsigned conditional sum adder.
|
||||
|
||||
Conditional sum adder performs carry-select addition starting with
|
||||
@ -108,7 +95,7 @@ class UnsignedConditionalSumAdder(ArithmeticCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_cosa", **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N+1, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -191,7 +178,7 @@ class UnsignedConditionalSumAdder(ArithmeticCircuit):
|
||||
self.out.connect(self.N, self.carry_sig[i_wire+1][0][-1])
|
||||
|
||||
|
||||
class SignedConditionalSumAdder(UnsignedConditionalSumAdder, ArithmeticCircuit):
|
||||
class SignedConditionalSumAdder(UnsignedConditionalSumAdder, GeneralCircuit):
|
||||
"""Class representing signed conditional sum adder.
|
||||
|
||||
Conditional sum adder performs carry-select addition starting with
|
||||
|
@ -1,41 +1,22 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder,
|
||||
PGSumLogic,
|
||||
GreyCell,
|
||||
BlackCell
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
)
|
||||
from ariths_gen.multi_bit_circuits.adders import (
|
||||
UnsignedCarryLookaheadAdder,
|
||||
UnsignedPGRippleCarryAdder,
|
||||
UnsignedRippleCarryAdder,
|
||||
SignedCarryLookaheadAdder,
|
||||
SignedPGRippleCarryAdder,
|
||||
SignedRippleCarryAdder
|
||||
XorGate
|
||||
)
|
||||
import math
|
||||
|
||||
|
||||
class UnsignedHanCarlsonAdder(ArithmeticCircuit):
|
||||
class UnsignedHanCarlsonAdder(GeneralCircuit):
|
||||
"""Class representing unsigned Han-Carlson adder (using valency-2 logic gates).
|
||||
|
||||
The Han-Carlson adder belongs to a type of tree (parallel-prefix) adders.
|
||||
@ -88,7 +69,7 @@ class UnsignedHanCarlsonAdder(ArithmeticCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_hca", config_choice: int = 1, **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N+1, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -184,7 +165,7 @@ class UnsignedHanCarlsonAdder(ArithmeticCircuit):
|
||||
self.generate_sig[i_wire+1].append(self.get_previous_component().get_generate_wire())
|
||||
|
||||
|
||||
class SignedHanCarlsonAdder(UnsignedHanCarlsonAdder, ArithmeticCircuit):
|
||||
class SignedHanCarlsonAdder(UnsignedHanCarlsonAdder, GeneralCircuit):
|
||||
"""Class representing signed Han-Carlson adder (using valency-2 logic gates).
|
||||
|
||||
The Han-Carlson adder belongs to a type of tree (parallel-prefix) adders.
|
||||
|
@ -1,41 +1,22 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder,
|
||||
PGSumLogic,
|
||||
GreyCell,
|
||||
BlackCell
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
)
|
||||
from ariths_gen.multi_bit_circuits.adders import (
|
||||
UnsignedCarryLookaheadAdder,
|
||||
UnsignedPGRippleCarryAdder,
|
||||
UnsignedRippleCarryAdder,
|
||||
SignedCarryLookaheadAdder,
|
||||
SignedPGRippleCarryAdder,
|
||||
SignedRippleCarryAdder
|
||||
XorGate
|
||||
)
|
||||
import math
|
||||
|
||||
|
||||
class UnsignedKnowlesAdder(ArithmeticCircuit):
|
||||
class UnsignedKnowlesAdder(GeneralCircuit):
|
||||
"""Class representing unsigned Knowles adder (using valency-2 logic gates).
|
||||
|
||||
The Knowles adder belongs to a type of tree (parallel-prefix) adders.
|
||||
@ -88,7 +69,7 @@ class UnsignedKnowlesAdder(ArithmeticCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_ka", config_choice: int = 1, **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N+1, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -143,7 +124,7 @@ class UnsignedKnowlesAdder(ArithmeticCircuit):
|
||||
self.generate_sig[i_wire+1].append(self.get_previous_component().get_generate_wire())
|
||||
|
||||
|
||||
class SignedKnowlesAdder(UnsignedKnowlesAdder, ArithmeticCircuit):
|
||||
class SignedKnowlesAdder(UnsignedKnowlesAdder, GeneralCircuit):
|
||||
"""Class representing signed Knowles adder (using valency-2 logic gates).
|
||||
|
||||
The Knowles adder belongs to a type of tree (parallel-prefix) adders.
|
||||
|
@ -1,41 +1,22 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder,
|
||||
PGSumLogic,
|
||||
GreyCell,
|
||||
BlackCell
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
)
|
||||
from ariths_gen.multi_bit_circuits.adders import (
|
||||
UnsignedCarryLookaheadAdder,
|
||||
UnsignedPGRippleCarryAdder,
|
||||
UnsignedRippleCarryAdder,
|
||||
SignedCarryLookaheadAdder,
|
||||
SignedPGRippleCarryAdder,
|
||||
SignedRippleCarryAdder
|
||||
XorGate
|
||||
)
|
||||
import math
|
||||
|
||||
|
||||
class UnsignedKoggeStoneAdder(ArithmeticCircuit):
|
||||
class UnsignedKoggeStoneAdder(GeneralCircuit):
|
||||
"""Class representing unsigned Kogge-Stone adder (using valency-2 logic gates).
|
||||
|
||||
The Kogge-Stone adder belongs to a type of tree (parallel-prefix) adders.
|
||||
@ -86,7 +67,7 @@ class UnsignedKoggeStoneAdder(ArithmeticCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_ksa", **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N+1, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -129,7 +110,7 @@ class UnsignedKoggeStoneAdder(ArithmeticCircuit):
|
||||
self.generate_sig[i_wire+1].append(self.get_previous_component().get_generate_wire())
|
||||
|
||||
|
||||
class SignedKoggeStoneAdder(UnsignedKoggeStoneAdder, ArithmeticCircuit):
|
||||
class SignedKoggeStoneAdder(UnsignedKoggeStoneAdder, GeneralCircuit):
|
||||
"""Class representing signed Kogge-Stone adder (using valency-2 logic gates).
|
||||
|
||||
The Kogge-Stone adder belongs to a type of tree (parallel-prefix) adders.
|
||||
|
@ -1,41 +1,22 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder,
|
||||
PGSumLogic,
|
||||
GreyCell,
|
||||
BlackCell
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
)
|
||||
from ariths_gen.multi_bit_circuits.adders import (
|
||||
UnsignedCarryLookaheadAdder,
|
||||
UnsignedPGRippleCarryAdder,
|
||||
UnsignedRippleCarryAdder,
|
||||
SignedCarryLookaheadAdder,
|
||||
SignedPGRippleCarryAdder,
|
||||
SignedRippleCarryAdder
|
||||
XorGate
|
||||
)
|
||||
import math
|
||||
|
||||
|
||||
class UnsignedLadnerFischerAdder(ArithmeticCircuit):
|
||||
class UnsignedLadnerFischerAdder(GeneralCircuit):
|
||||
"""Class representing unsigned Ladner-Fischer adder (using valency-2 logic gates).
|
||||
|
||||
The Ladner-Fischer adder belongs to a type of tree (parallel-prefix) adders.
|
||||
@ -88,7 +69,7 @@ class UnsignedLadnerFischerAdder(ArithmeticCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_lfa", config_choice: int = 1, **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N+1, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -188,7 +169,7 @@ class UnsignedLadnerFischerAdder(ArithmeticCircuit):
|
||||
self.generate_sig[i_wire+1].append(self.get_previous_component().get_generate_wire())
|
||||
|
||||
|
||||
class SignedLadnerFischerAdder(UnsignedLadnerFischerAdder, ArithmeticCircuit):
|
||||
class SignedLadnerFischerAdder(UnsignedLadnerFischerAdder, GeneralCircuit):
|
||||
"""Class representing signed Ladner-Fischer adder (using valency-2 logic gates).
|
||||
|
||||
The Ladner-Fischer adder belongs to a type of tree (parallel-prefix) adders.
|
||||
|
@ -1,30 +1,21 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder,
|
||||
PGSumLogic
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
XorGate
|
||||
)
|
||||
|
||||
|
||||
class UnsignedPGRippleCarryAdder(ArithmeticCircuit):
|
||||
class UnsignedPGRippleCarryAdder(GeneralCircuit):
|
||||
"""Class representing unsigned ripple carry adder with propagate/generate logic.
|
||||
|
||||
Unsigned ripple carry adder with PG logic represents slightly different rca implementation
|
||||
@ -69,7 +60,7 @@ class UnsignedPGRippleCarryAdder(ArithmeticCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_pg_rca", **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N+1, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -96,7 +87,7 @@ class UnsignedPGRippleCarryAdder(ArithmeticCircuit):
|
||||
self.out.connect(self.N, obj_or.out)
|
||||
|
||||
|
||||
class SignedPGRippleCarryAdder(UnsignedPGRippleCarryAdder, ArithmeticCircuit):
|
||||
class SignedPGRippleCarryAdder(UnsignedPGRippleCarryAdder, GeneralCircuit):
|
||||
"""Class representing signed ripple carry adder with propagate/generate logic.
|
||||
|
||||
Signed ripple carry adder with PG logic represents slightly different rca implementation
|
||||
|
@ -1,29 +1,19 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
XorGate
|
||||
)
|
||||
|
||||
|
||||
class UnsignedRippleCarryAdder(ArithmeticCircuit):
|
||||
class UnsignedRippleCarryAdder(GeneralCircuit):
|
||||
"""Class representing unsigned ripple carry adder.
|
||||
|
||||
Unsigned ripple carry adder represents N-bit unsigned adder which is composed of
|
||||
@ -53,7 +43,7 @@ class UnsignedRippleCarryAdder(ArithmeticCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_rca", **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N+1, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -74,7 +64,7 @@ class UnsignedRippleCarryAdder(ArithmeticCircuit):
|
||||
self.out.connect(self.N, obj_adder.get_carry_wire())
|
||||
|
||||
|
||||
class SignedRippleCarryAdder(UnsignedRippleCarryAdder, ArithmeticCircuit):
|
||||
class SignedRippleCarryAdder(UnsignedRippleCarryAdder, GeneralCircuit):
|
||||
"""Class representing signed ripple carry adder.
|
||||
|
||||
Signed ripple carry adder represents N-bit signed adder which is composed of
|
||||
|
@ -1,40 +1,21 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder,
|
||||
PGSumLogic,
|
||||
GreyCell,
|
||||
BlackCell
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
)
|
||||
from ariths_gen.multi_bit_circuits.adders import (
|
||||
UnsignedCarryLookaheadAdder,
|
||||
UnsignedPGRippleCarryAdder,
|
||||
UnsignedRippleCarryAdder,
|
||||
SignedCarryLookaheadAdder,
|
||||
SignedPGRippleCarryAdder,
|
||||
SignedRippleCarryAdder
|
||||
XorGate
|
||||
)
|
||||
|
||||
|
||||
class UnsignedSklanskyAdder(ArithmeticCircuit):
|
||||
class UnsignedSklanskyAdder(GeneralCircuit):
|
||||
"""Class representing unsigned Sklansky (or divide-and-conquer) adder (using valency-2 logic gates).
|
||||
|
||||
The Sklansky adder belongs to a type of tree (parallel-prefix) adders.
|
||||
@ -85,7 +66,7 @@ class UnsignedSklanskyAdder(ArithmeticCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_sa", **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N+1, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -132,7 +113,7 @@ class UnsignedSklanskyAdder(ArithmeticCircuit):
|
||||
prev_stage_int_value += 2**stage
|
||||
|
||||
|
||||
class SignedSklanskyAdder(UnsignedSklanskyAdder, ArithmeticCircuit):
|
||||
class SignedSklanskyAdder(UnsignedSklanskyAdder, GeneralCircuit):
|
||||
"""Class representing signed Sklansky (or divide-and-conquer) adder (using valency-2 logic gates).
|
||||
|
||||
The Sklansky adder belongs to a type of tree (parallel-prefix) adders.
|
||||
|
@ -1 +1 @@
|
||||
from .quad import QuAdder
|
||||
from .quad import QuAdder
|
||||
|
@ -7,33 +7,20 @@ M. A. Hanif, R. Hafiz, O. Hasan and M. Shafique, "QuAd: Design and analysis of Q
|
||||
"""
|
||||
|
||||
from ...wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder
|
||||
|
||||
from ariths_gen.multi_bit_circuits.adders.ripple_carry_adder import (
|
||||
UnsignedRippleCarryAdder
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
)
|
||||
from ariths_gen.multi_bit_circuits.adders.ripple_carry_adder import UnsignedRippleCarryAdder
|
||||
import warnings
|
||||
|
||||
|
||||
class QuAdder(ArithmeticCircuit):
|
||||
class QuAdder(GeneralCircuit):
|
||||
"""
|
||||
Implementation of QuAd
|
||||
|
||||
@ -102,13 +89,13 @@ class QuAdder(ArithmeticCircuit):
|
||||
self.use_log = use_log
|
||||
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N+1, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
|
||||
#warnings.warn("QuAdder is not tested yet")
|
||||
# warnings.warn("QuAdder is not tested yet")
|
||||
|
||||
# Connect all outputs to zero
|
||||
for i in range(self.N+1):
|
||||
@ -128,7 +115,7 @@ class QuAdder(ArithmeticCircuit):
|
||||
|
||||
for i, j in zip(out_indexes, in_indexes):
|
||||
if j >= in_bus.N:
|
||||
out_bus[i] = ConstantWireValue0() # unsigned extension
|
||||
out_bus[i] = ConstantWireValue0() # unsigned extension
|
||||
else:
|
||||
out_bus.connect(i, in_bus.get_wire(j)) # [i] = in_bus[j]
|
||||
|
||||
|
@ -1,11 +1,8 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
@ -13,17 +10,7 @@ from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
FullAdder
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
)
|
||||
from ariths_gen.multi_bit_circuits.multipliers import (
|
||||
UnsignedArrayMultiplier,
|
||||
SignedArrayMultiplier
|
||||
AndGate
|
||||
)
|
||||
|
||||
|
||||
@ -107,7 +94,7 @@ class UnsignedBrokenArrayMultiplier(MultiplierCircuit):
|
||||
# Vertical cut should be greater or equal to horizontal cut
|
||||
assert vertical_cut >= horizontal_cut
|
||||
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
|
@ -1,11 +1,8 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit,
|
||||
)
|
||||
from ariths_gen.core.logic_gate_circuits import (
|
||||
@ -16,13 +13,7 @@ from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
FullAdder
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
AndGate
|
||||
)
|
||||
from ariths_gen.multi_bit_circuits.adders import (
|
||||
UnsignedCarryLookaheadAdder
|
||||
@ -114,7 +105,7 @@ class UnsignedBrokenCarrySaveMultiplier(MultiplierCircuit):
|
||||
# Vertical cut should be greater or equal to horizontal cut
|
||||
assert vertical_cut >= horizontal_cut
|
||||
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -213,7 +204,6 @@ class UnsignedBrokenCarrySaveMultiplier(MultiplierCircuit):
|
||||
adder_name = unsigned_adder_class_name(a=a, b=b).prefix + str(final_cpa_N)
|
||||
adder_a = Bus(prefix=f"a", wires_list=previous_sums)
|
||||
adder_b = Bus(prefix=f"b", wires_list=previous_carries)
|
||||
|
||||
final_adder = unsigned_adder_class_name(a=adder_a, b=adder_b, prefix=self.prefix, name=adder_name, inner_component=True)
|
||||
self.add_component(final_adder)
|
||||
[self.out.connect(o, final_adder.out.get_wire(o-max(self.N, self.vertical_cut)), inserted_wire_desired_index=o-max(self.N, self.vertical_cut)) for o in range(max(self.N, self.vertical_cut), self.out.N)]
|
||||
|
@ -11,11 +11,9 @@ from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
XorGate,
|
||||
NotGate
|
||||
)
|
||||
|
||||
from ariths_gen.multi_bit_circuits.adders import (
|
||||
UnsignedCarryLookaheadAdder
|
||||
)
|
||||
|
||||
import math
|
||||
|
||||
|
||||
@ -55,7 +53,7 @@ class UnsignedAccurateTwoBitMultiplier(MultiplierCircuit):
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_2bit_accm", **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
assert self.N == 2
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -98,14 +96,14 @@ class UnsignedApproximateTwoBitMultiplierM1(MultiplierCircuit):
|
||||
"""Class representing unsigned two-bit approximate multiplier variant M1.
|
||||
|
||||
M1 ax variant defined here: https://ieeexplore.ieee.org/document/8727537
|
||||
|
||||
|
||||
```
|
||||
A1B1 A1B0 A0B1 A0B0
|
||||
│ │ │ │ │ │ │ │
|
||||
┌▼─▼┐ ┌▼─▼┐ ┌▼─▼┐ ┌▼─▼┐
|
||||
│AND│ │AND│ │AND│ │AND│
|
||||
└─┬─┘ └─┬─┘ └─┬─┘ └─┬─┘
|
||||
│ │ └┐ │
|
||||
│ │ └┐ │
|
||||
│ └─────┐ │ │
|
||||
└──────┐ ┌▼─▼┐ │
|
||||
│ │ OR│ │
|
||||
@ -126,7 +124,7 @@ class UnsignedApproximateTwoBitMultiplierM1(MultiplierCircuit):
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_2bit_axm1", **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
assert self.N == 2
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -165,7 +163,7 @@ class UnsignedApproximateTwoBitMultiplierM2(MultiplierCircuit):
|
||||
"""Class representing unsigned two-bit approximate multiplier variant M2.
|
||||
|
||||
M2 ax variant defined here: https://ieeexplore.ieee.org/document/8727537
|
||||
|
||||
|
||||
```
|
||||
A1B1 A1B0 A0B1
|
||||
│ │ │ │ │ │
|
||||
@ -200,7 +198,7 @@ class UnsignedApproximateTwoBitMultiplierM2(MultiplierCircuit):
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_2bit_axm1", **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
assert self.N == 2
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -241,7 +239,7 @@ class UnsignedApproximateTwoBitMultiplierM3(MultiplierCircuit):
|
||||
"""Class representing unsigned two-bit approximate multiplier variant M3.
|
||||
|
||||
M3 ax variant defined here: https://ieeexplore.ieee.org/document/8727537
|
||||
|
||||
|
||||
```
|
||||
A1B1 A1B0 A0B1 A0B0
|
||||
│ │ │ │ │ │ │ │
|
||||
@ -280,7 +278,7 @@ class UnsignedApproximateTwoBitMultiplierM3(MultiplierCircuit):
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_2bit_axm3", **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
assert self.N == 2
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -330,7 +328,7 @@ class UnsignedApproximateTwoBitMultiplierM4(MultiplierCircuit):
|
||||
┌▼─▼┐ ┌▼─▼┐ ┌▼─▼┐ ┌▼─▼┐
|
||||
│AND│ │AND│ │AND│ │AND│
|
||||
└─┬─┘ └─┬─┘ └─┬─┘ └─┬─┘
|
||||
│ │ └┐ │
|
||||
│ │ └┐ │
|
||||
│ └─────┐ │ │
|
||||
└──────┐ ┌▼─▼┐ │
|
||||
│ │XOR│ │
|
||||
@ -351,7 +349,7 @@ class UnsignedApproximateTwoBitMultiplierM4(MultiplierCircuit):
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_2bit_axm4", **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
assert self.N == 2
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -390,12 +388,12 @@ class UnsignedRecursiveMultiplier(MultiplierCircuit):
|
||||
"""Class representing unsigned recursive multiplier.
|
||||
|
||||
Input bit-vector length N can be any power of two greater than 1 (e.g. 2, 4, 8, ...).
|
||||
|
||||
|
||||
The internal structure of the recursive multiplier is composed of subsequent two-bit submultipliers provided in the input `submultipliers` list.
|
||||
The `submultipliers` list should contain the classes of the two-bit submultipliers that will be used for instantiation. If None are provided, accurate two-bit submultipliers are assumed.
|
||||
|
||||
|
||||
The number of submultipliers required is equal to (N/2)² for N > 2. For N = 2, only one two-bit submultiplier is required.
|
||||
|
||||
|
||||
Description of the __init__ method.
|
||||
|
||||
Args:
|
||||
@ -410,7 +408,7 @@ class UnsignedRecursiveMultiplier(MultiplierCircuit):
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_rm", submultipliers: list = None, unsigned_adder_class_name: str = UnsignedCarryLookaheadAdder, **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
assert self.N > 1 and self.N & (self.N-1) == 0 # assure that N is a power of two greater than 1 (So allowed N is 2, 4, 8, ..)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -424,7 +422,7 @@ class UnsignedRecursiveMultiplier(MultiplierCircuit):
|
||||
|
||||
assert (self.N > 2 and len(submultipliers) == (self.N//2)**2) or (self.N == 2 and len(submultipliers) == 1)
|
||||
|
||||
if self.N == 2: # Base case for just one two-bit multiplier
|
||||
if self.N == 2: # Base case for just one two-bit multiplier
|
||||
# TODO add suffix in ariths_gen rework
|
||||
mult = submultipliers[0](Bus(prefix=self.prefix + "_a", wires_list=self.a.bus), Bus(prefix=self.prefix + "_b", wires_list=self.b.bus), prefix=self.prefix + "_" + str(self.get_instance_num(cls=submultipliers[0])), **kwargs)
|
||||
self.add_component(mult)
|
||||
@ -467,7 +465,7 @@ class UnsignedRecursiveMultiplier(MultiplierCircuit):
|
||||
|
||||
# Create wire vectors holding partial products for final summation
|
||||
pp = Bus(prefix=f"pp_{m}", N=self.out.N, wires_list=[ConstantWireValue0() for _ in range(self.out.N)])
|
||||
#[pp.connect_bus(submult.out, offset=(self.out.N-4)-(a_bus_offset+b_bus_offset))]
|
||||
# [pp.connect_bus(submult.out, offset=(self.out.N-4)-(a_bus_offset+b_bus_offset))]
|
||||
[pp.connect((self.out.N-1)-(a_bus_offset+b_bus_offset)-i, submult.out[3-i], inserted_wire_desired_index=3-i) for i in range(4)]
|
||||
partial_products.append(pp)
|
||||
|
||||
|
@ -1,11 +1,8 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
@ -13,13 +10,7 @@ from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
FullAdder
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
AndGate
|
||||
)
|
||||
|
||||
|
||||
@ -87,7 +78,7 @@ class UnsignedTruncatedArrayMultiplier(MultiplierCircuit):
|
||||
# Cut level should be: 0 <= truncation_cut < N
|
||||
assert truncation_cut < self.N
|
||||
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
|
@ -1,11 +1,8 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
@ -14,12 +11,6 @@ from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
)
|
||||
from ariths_gen.multi_bit_circuits.adders import (
|
||||
UnsignedCarryLookaheadAdder
|
||||
@ -101,7 +92,7 @@ class UnsignedTruncatedCarrySaveMultiplier(MultiplierCircuit):
|
||||
# Cut level should be: 0 <= truncation_cut < N
|
||||
assert truncation_cut < self.N
|
||||
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
|
@ -1,31 +1,20 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder,
|
||||
TwoOneMultiplexer,
|
||||
FullSubtractor
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
)
|
||||
|
||||
|
||||
class ArrayDivider(ArithmeticCircuit):
|
||||
class ArrayDivider(GeneralCircuit):
|
||||
"""Class representing array divider.
|
||||
|
||||
Array divider performs division between two N bit numbers and stores their
|
||||
@ -96,7 +85,7 @@ class ArrayDivider(ArithmeticCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "arrdiv", **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
|
@ -1,11 +1,9 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
@ -15,11 +13,8 @@ from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
XorGate
|
||||
)
|
||||
|
||||
|
||||
@ -83,7 +78,7 @@ class UnsignedArrayMultiplier(MultiplierCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_arrmul", **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -190,7 +185,7 @@ class SignedArrayMultiplier(MultiplierCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "s_arrmul", **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, signed=True, **kwargs)
|
||||
super().__init__(inputs=[a, b], prefix=prefix, name=name, out_N=self.N*2, signed=True, **kwargs)
|
||||
|
||||
# Bus sign extension in case buses have different lengths
|
||||
self.a.bus_extend(N=self.N, prefix=a.prefix)
|
||||
|
@ -1,11 +1,9 @@
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
@ -15,11 +13,7 @@ from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
NorGate
|
||||
)
|
||||
from ariths_gen.multi_bit_circuits.adders import (
|
||||
UnsignedCarryLookaheadAdder
|
||||
@ -96,7 +90,7 @@ class UnsignedCarrySaveMultiplier(MultiplierCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_csamul", unsigned_adder_class_name: str = UnsignedCarryLookaheadAdder, **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -219,7 +213,7 @@ class SignedCarrySaveMultiplier(MultiplierCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "s_csamul", unsigned_adder_class_name: str = UnsignedCarryLookaheadAdder, **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, signed=True, **kwargs)
|
||||
super().__init__(inputs=[a, b], prefix=prefix, name=name, out_N=self.N*2, signed=True, **kwargs)
|
||||
|
||||
# Bus sign extension in case buses have different lengths
|
||||
self.a.bus_extend(N=self.N, prefix=a.prefix)
|
||||
|
@ -1,12 +1,12 @@
|
||||
from ariths_gen.multi_bit_circuits.adders.carry_lookahead_adder import UnsignedCarryLookaheadAdder
|
||||
from ariths_gen.multi_bit_circuits.adders.carry_lookahead_adder import (
|
||||
UnsignedCarryLookaheadAdder
|
||||
)
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
@ -14,13 +14,7 @@ from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
FullAdder
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
XorGate
|
||||
)
|
||||
|
||||
|
||||
@ -50,7 +44,7 @@ class UnsignedDaddaMultiplier(MultiplierCircuit):
|
||||
"""
|
||||
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)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -154,7 +148,7 @@ class SignedDaddaMultiplier(MultiplierCircuit):
|
||||
"""
|
||||
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)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, signed=True, **kwargs)
|
||||
super().__init__(inputs=[a, b], prefix=prefix, name=name, out_N=self.N*2, signed=True, **kwargs)
|
||||
|
||||
# Bus sign extension in case buses have different lengths
|
||||
self.a.bus_extend(N=self.N, prefix=a.prefix)
|
||||
|
@ -1,12 +1,12 @@
|
||||
from ariths_gen.multi_bit_circuits.adders.carry_lookahead_adder import UnsignedCarryLookaheadAdder
|
||||
from ariths_gen.multi_bit_circuits.adders.carry_lookahead_adder import (
|
||||
UnsignedCarryLookaheadAdder
|
||||
)
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
MultiplierCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
@ -14,13 +14,7 @@ from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
FullAdder
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
XorGate
|
||||
)
|
||||
from ariths_gen.multi_bit_circuits.adders import (
|
||||
CarrySaveAdderComponent,
|
||||
@ -86,7 +80,7 @@ class UnsignedWallaceMultiplier(MultiplierCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_wallace_cla", use_csa: bool = True, unsigned_adder_class_name: str = UnsignedCarryLookaheadAdder, **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, **kwargs)
|
||||
super().__init__(inputs=[a, 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)
|
||||
@ -249,7 +243,7 @@ class SignedWallaceMultiplier(MultiplierCircuit):
|
||||
"""
|
||||
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "s_wallace_cla", use_csa: bool = True, unsigned_adder_class_name: str = UnsignedCarryLookaheadAdder, **kwargs):
|
||||
self.N = max(a.N, b.N)
|
||||
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=self.N*2, signed=True, **kwargs)
|
||||
super().__init__(inputs=[a, b], prefix=prefix, name=name, out_N=self.N*2, signed=True, **kwargs)
|
||||
|
||||
# Bus sign extension in case buses have different lengths
|
||||
self.a.bus_extend(N=self.N, prefix=a.prefix)
|
||||
|
@ -1,53 +1,25 @@
|
||||
"""
|
||||
|
||||
"""
|
||||
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus,
|
||||
wires
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
GeneralCircuit,
|
||||
MultiplierCircuit
|
||||
)
|
||||
from ariths_gen.core.logic_gate_circuits import (
|
||||
MultipleInputLogicGate
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder,
|
||||
FullAdderP,
|
||||
TwoOneMultiplexer
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
OrGate
|
||||
)
|
||||
from ariths_gen.core.logic_gate_circuits import (
|
||||
TwoInputLogicGate
|
||||
)
|
||||
|
||||
from ariths_gen.core.logic_gate_circuits import TwoInputLogicGate, TwoInputInvertedLogicGate, OneInputLogicGate
|
||||
from ariths_gen.multi_bit_circuits.adders import UnsignedRippleCarryAdder
|
||||
|
||||
from math import log2, ceil
|
||||
|
||||
class BitReduce(GeneralCircuit):
|
||||
"""Class representing tree reducer circuit. Doent work for NAND gate!
|
||||
"""
|
||||
|
||||
def __init__(self, a: Bus, gate : TwoInputLogicGate, prefix : str = "", name : str = "bitreduce", **kwargs):
|
||||
def __init__(self, a: Bus, gate: TwoInputLogicGate, prefix: str = "", name: str = "bitreduce", **kwargs):
|
||||
self.N = a.N
|
||||
self.a = a
|
||||
|
||||
outc = 1
|
||||
super().__init__(name=name, prefix=prefix, inputs = [self.a], out_N=outc)
|
||||
super().__init__(name=name, prefix=prefix, inputs=[a], out_N=1, **kwargs)
|
||||
|
||||
# tree reduction
|
||||
def create_tree(a: Bus, depth: int, branch="A"):
|
||||
|
@ -1,43 +1,20 @@
|
||||
"""
|
||||
|
||||
"""
|
||||
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus,
|
||||
wires
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
GeneralCircuit,
|
||||
MultiplierCircuit
|
||||
)
|
||||
|
||||
from ariths_gen.core.logic_gate_circuits import (
|
||||
MultipleInputLogicGate
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder,
|
||||
FullAdderP,
|
||||
TwoOneMultiplexer
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
)
|
||||
from ariths_gen.multi_bit_circuits.others import (
|
||||
OrReduce
|
||||
)
|
||||
|
||||
from ariths_gen.multi_bit_circuits.others import OrReduce
|
||||
|
||||
|
||||
from math import log2, ceil
|
||||
|
||||
class UnsignedCompareLT(GeneralCircuit):
|
||||
"""Class representing unsigned compare
|
||||
@ -47,12 +24,8 @@ class UnsignedCompareLT(GeneralCircuit):
|
||||
"""
|
||||
|
||||
def __init__(self, a: Bus, b: Bus, prefix : str = "", name : str = "cmp_lt", **kwargs):
|
||||
self.a = a
|
||||
self.b = b
|
||||
self.N = max(a.N, b.N)
|
||||
|
||||
super().__init__(name=name, prefix=prefix,
|
||||
inputs = [self.a, self.b], out_N=1)
|
||||
super().__init__(name=name, prefix=prefix, inputs=[a, b], out_N=1)
|
||||
|
||||
# create wires
|
||||
psum = ConstantWireValue1()
|
||||
@ -84,12 +57,8 @@ class UnsignedCompareLTE(GeneralCircuit):
|
||||
"""
|
||||
|
||||
def __init__(self, a: Bus, b: Bus, prefix : str = "", name : str = "cmp_lte", **kwargs):
|
||||
self.a = a
|
||||
self.b = b
|
||||
self.N = max(a.N, b.N)
|
||||
|
||||
super().__init__(name=name, prefix=prefix,
|
||||
inputs = [self.a, self.b], out_N=1)
|
||||
super().__init__(name=name, prefix=prefix, inputs=[a, b], out_N=1)
|
||||
|
||||
# create wires
|
||||
psum = ConstantWireValue1()
|
||||
@ -125,12 +94,8 @@ class UnsignedCompareGT(GeneralCircuit):
|
||||
"""
|
||||
|
||||
def __init__(self, a: Bus, b: Bus, prefix : str = "", name : str = "cmp_gt", **kwargs):
|
||||
self.a = a
|
||||
self.b = b
|
||||
self.N = max(a.N, b.N)
|
||||
|
||||
super().__init__(name=name, prefix=prefix,
|
||||
inputs = [self.a, self.b], out_N=1)
|
||||
super().__init__(name=name, prefix=prefix, inputs=[a, b], out_N=1)
|
||||
|
||||
# create wires
|
||||
psum = ConstantWireValue1()
|
||||
@ -162,12 +127,8 @@ class UnsignedCompareGTE(GeneralCircuit):
|
||||
"""
|
||||
|
||||
def __init__(self, a: Bus, b: Bus, prefix : str = "", name : str = "cmp_gte", **kwargs):
|
||||
self.a = a
|
||||
self.b = b
|
||||
self.N = max(a.N, b.N)
|
||||
|
||||
super().__init__(name=name, prefix=prefix,
|
||||
inputs = [self.a, self.b], out_N=1)
|
||||
super().__init__(name=name, prefix=prefix, inputs=[a, b], out_N=1)
|
||||
|
||||
# create wires
|
||||
psum = ConstantWireValue1()
|
||||
|
@ -1,43 +1,17 @@
|
||||
"""
|
||||
|
||||
"""
|
||||
from typing import Union, Optional
|
||||
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus,
|
||||
wires
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
GeneralCircuit,
|
||||
MultiplierCircuit
|
||||
GeneralCircuit
|
||||
)
|
||||
from ariths_gen.core.logic_gate_circuits import (
|
||||
MultipleInputLogicGate
|
||||
from ariths_gen.multi_bit_circuits.adders import (
|
||||
UnsignedRippleCarryAdder
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder,
|
||||
FullAdderP,
|
||||
TwoOneMultiplexer
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
)
|
||||
|
||||
from ariths_gen.multi_bit_circuits.adders import UnsignedRippleCarryAdder
|
||||
|
||||
from typing import Optional
|
||||
from math import log2, ceil
|
||||
|
||||
|
||||
class UnsignedPopCount(GeneralCircuit):
|
||||
"""Class representing unsigned popcount circuit.
|
||||
|
||||
@ -45,14 +19,11 @@ class UnsignedPopCount(GeneralCircuit):
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, a: Bus, adder : Optional[ArithmeticCircuit] = None, prefix : str = "", name : str = "popcnt", **kwargs):
|
||||
def __init__(self, a: Bus, adder : Optional[GeneralCircuit] = None, prefix : str = "", name : str = "popcnt", **kwargs):
|
||||
self.N = a.N
|
||||
self.a = a
|
||||
|
||||
outc = ceil(log2(self.N + 1))
|
||||
#print("outc", outc)
|
||||
super().__init__(name=name, prefix=prefix, inputs = [self.a], out_N=outc)
|
||||
|
||||
super().__init__(name=name, prefix=prefix, inputs=[a], out_N=outc)
|
||||
|
||||
self.a.bus_extend(2**(outc - 1), prefix=a.prefix)
|
||||
#print(self.a)
|
||||
@ -62,7 +33,6 @@ class UnsignedPopCount(GeneralCircuit):
|
||||
|
||||
# tree reduction
|
||||
def create_tree(a: Bus, depth: int, branch="A"):
|
||||
|
||||
#print(a)
|
||||
if a.N == 1:
|
||||
return a
|
||||
@ -70,17 +40,17 @@ class UnsignedPopCount(GeneralCircuit):
|
||||
half = a.N // 2
|
||||
b_in = Bus(N=half, prefix=f"b_inn_{branch}_{depth}A")
|
||||
c_in = Bus(N=a.N - half, prefix=f"b_inn_{branch}_{depth}B")
|
||||
#print(b_in.prefix)
|
||||
#print(a, half, a.N)
|
||||
|
||||
|
||||
for i, j in enumerate(range(half)):
|
||||
b_in[i] = a[j]
|
||||
|
||||
for i, j in enumerate(range(half, a.N)):
|
||||
c_in[i] = a[j]
|
||||
|
||||
b = create_tree(b_in, depth=depth + 1, branch = branch + "A")
|
||||
c = create_tree(c_in, depth= depth + 1, branch = branch + "B")
|
||||
c = create_tree(c_in, depth=depth + 1, branch = branch + "B")
|
||||
|
||||
|
||||
d = self.adder(a=b, b=c, prefix = f"{self.prefix}_add{branch}_{depth}")
|
||||
self.add_component(d)
|
||||
return d.out
|
||||
|
@ -1,45 +1,15 @@
|
||||
"""
|
||||
|
||||
"""
|
||||
|
||||
from ariths_gen.multi_bit_circuits.others import UnsignedPopCount
|
||||
from ariths_gen.multi_bit_circuits.others.compare import UnsignedCompareGTE
|
||||
from ariths_gen.wire_components import (
|
||||
Wire,
|
||||
ConstantWireValue0,
|
||||
ConstantWireValue1,
|
||||
Bus,
|
||||
wires
|
||||
Bus
|
||||
)
|
||||
from ariths_gen.core.arithmetic_circuits import (
|
||||
ArithmeticCircuit,
|
||||
GeneralCircuit,
|
||||
MultiplierCircuit
|
||||
GeneralCircuit
|
||||
)
|
||||
|
||||
from ariths_gen.core.logic_gate_circuits import (
|
||||
MultipleInputLogicGate
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||
HalfAdder,
|
||||
FullAdder,
|
||||
FullAdderP,
|
||||
TwoOneMultiplexer
|
||||
)
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
from ariths_gen.multi_bit_circuits.others import (
|
||||
UnsignedPopCount,
|
||||
UnsignedCompareGTE
|
||||
)
|
||||
|
||||
from ariths_gen.multi_bit_circuits.others import OrReduce
|
||||
|
||||
|
||||
from math import log2, ceil
|
||||
|
||||
class PopCountCompare(GeneralCircuit):
|
||||
"""Class representing a circiut
|
||||
@ -60,22 +30,21 @@ class PopCountCompare(GeneralCircuit):
|
||||
"""
|
||||
|
||||
def __init__(self, a: Bus, b: Bus, prefix : str = "", name : str = "popcnt_cmp", **kwargs):
|
||||
self.a = a
|
||||
self.b = b
|
||||
|
||||
super().__init__(name=name, prefix=prefix,
|
||||
inputs = [self.a, self.b], out_N=1)
|
||||
super().__init__(name=name, prefix=prefix, inputs=[a, b], out_N=1, **kwargs)
|
||||
|
||||
p1 = self.add_component(UnsignedPopCount(self.a,
|
||||
p1 = self.add_component(UnsignedPopCount(a=Bus(wires_list=self.a.bus, prefix=f"{prefix}_popcount1_a"),
|
||||
prefix=f"{prefix}_popcount1",
|
||||
inner_component=True)).out
|
||||
p2 = self.add_component(UnsignedPopCount(self.b,
|
||||
p2 = self.add_component(UnsignedPopCount(a=Bus(wires_list=self.b.bus, prefix=f"{prefix}_popcount2_a"),
|
||||
prefix=f"{prefix}_popcount2",
|
||||
inner_component=True)).out
|
||||
|
||||
print(p1)
|
||||
#N = max(p1.N, p2.N)
|
||||
#p1.bus_extend(N)
|
||||
#p2.bus_extend(N)
|
||||
|
||||
red = self.add_component(UnsignedCompareGTE(p1, p2, prefix=f"{prefix}_cmp", inner_component = True))
|
||||
cmp_gte_a = Bus(wires_list=p1.bus, prefix=f"{prefix}_cmp_gte_a")
|
||||
cmp_gte_a.connect_bus(p1)
|
||||
cmp_gte_b = Bus(wires_list=p2.bus, prefix=f"{prefix}_cmp_gte_b")
|
||||
cmp_gte_b.connect_bus(p2)
|
||||
red = self.add_component(UnsignedCompareGTE(cmp_gte_a, cmp_gte_b, prefix=f"{prefix}_cmp", inner_component = True))
|
||||
self.out.connect_bus(red.out)
|
||||
|
@ -74,7 +74,7 @@ class Wire():
|
||||
return f"({self.c_const})"
|
||||
# If wire is part of an input bus (where wire names are concatenated from bus prefix and their index position inside the bus in square brackets)
|
||||
# then the wire value is obtained from bitwise shifting the required wire from the parent bus ('parent_bus.prefix' is the same value as 'self.prefix')
|
||||
elif self.is_buswire():
|
||||
elif self.is_buswire() and self.name == f"{self.prefix}[{self.index}]":
|
||||
return f"(({self.prefix} >> {self.index}) & 0x01)"
|
||||
else:
|
||||
return f"(({self.name} >> 0) & 0x01)"
|
||||
|
@ -1,9 +1,8 @@
|
||||
|
||||
from ariths_gen.core.arithmetic_circuits.arithmetic_circuit import ArithmeticCircuit
|
||||
from ariths_gen.core.arithmetic_circuits import GeneralCircuit
|
||||
from ariths_gen.wire_components import Bus, Wire
|
||||
from ariths_gen.multi_bit_circuits.adders import UnsignedRippleCarryAdder
|
||||
from ariths_gen.multi_bit_circuits.multipliers import UnsignedArrayMultiplier, UnsignedDaddaMultiplier
|
||||
from ariths_gen.multi_bit_circuits.multipliers import UnsignedArrayMultiplier
|
||||
import os
|
||||
|
||||
|
||||
|
@ -8,13 +8,8 @@ DIR_PATH = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, os.path.join(DIR_PATH, '..'))
|
||||
import numpy as np
|
||||
import itertools
|
||||
|
||||
from ariths_gen.core.arithmetic_circuits.arithmetic_circuit import ArithmeticCircuit
|
||||
from ariths_gen.core.arithmetic_circuits import GeneralCircuit
|
||||
from ariths_gen.wire_components import Bus, Wire
|
||||
from ariths_gen.multi_bit_circuits.adders import UnsignedRippleCarryAdder
|
||||
from ariths_gen.wire_components import Bus
|
||||
from ariths_gen.multi_bit_circuits.approximate_adders import QuAdder
|
||||
from ariths_gen.multi_bit_circuits.multipliers import UnsignedArrayMultiplier, UnsignedDaddaMultiplier
|
||||
|
||||
|
||||
def test_quadder():
|
||||
|
Loading…
x
Reference in New Issue
Block a user