Merge branch 'devel' of github.com:ehw-fit/ariths-gen into devel

This commit is contained in:
Vojta Mrazek 2024-07-08 11:31:30 +02:00
commit e41b4a2f2c
51 changed files with 555 additions and 1080 deletions

View File

@ -1,10 +1,7 @@
from .arithmetic_circuit import ( from .general_circuit import (
ArithmeticCircuit, GeneralCircuit
ThreeInputArithmeticCircuit
) )
from .general_circuit import (GeneralCircuit)
from .multiplier_circuit import ( from .multiplier_circuit import (
MultiplierCircuit MultiplierCircuit
) )

View File

@ -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()}"

View File

@ -1,13 +1,14 @@
from typing import Dict from ariths_gen.core.logic_gate_circuits.logic_gate_circuit import (
from ariths_gen.core.logic_gate_circuits.logic_gate_circuit import OneInputLogicGate, TwoInputLogicGate OneInputLogicGate,
TwoInputLogicGate
)
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire, Wire,
ConstantWireValue0,
ConstantWireValue1,
Bus Bus
) )
from typing import Dict
import inspect
import copy
from io import StringIO from io import StringIO
@ -17,7 +18,6 @@ class GeneralCircuit():
The __init__ method fills some mandatory attributes concerning arithmetic circuit The __init__ method fills some mandatory attributes concerning arithmetic circuit
that are later used for generation into various representations. 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): 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 == "": if prefix == "":
self.prefix = name self.prefix = name
@ -25,37 +25,28 @@ class GeneralCircuit():
self.prefix = prefix + "_" + name self.prefix = prefix + "_" + name
self.inner_component = inner_component self.inner_component = inner_component
if one_bit_circuit is False: # Dynamic input bus assignment
# Dynamic input bus assignment self.inputs = []
self.inputs = [] for i, input in enumerate(inputs):
input_names = "abcdefghijklmnopqrstuvwxyz" # This should be enough.. attr_name = chr(97+i)
assert len(input_names) >= len(inputs) full_prefix = f"{self.prefix}_{input.prefix}" if self.inner_component else f"{input.prefix}"
for i, input in enumerate(inputs): if isinstance(input, Bus) or isinstance(input, Wire):
attr_name = input_names[i] circuit_input = input
full_prefix = f"{self.prefix}_{input.prefix}" if self.inner_component else f"{input.prefix}" circuit_input.prefix = full_prefix
if isinstance(input, Bus): setattr(self, attr_name, circuit_input)
bus = Bus(prefix=full_prefix, wires_list=input.bus) self.inputs.append(circuit_input)
setattr(self, attr_name, bus) # If the input bus is an output bus, connect it
self.inputs.append(bus) if isinstance(input, Bus) and input.is_output_bus():
getattr(self, attr_name).connect_bus(connecting_bus=input)
# 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
if not outname: if not outname:
outname = self.prefix+"_out" outname = self.prefix+"_out"
self.out = Bus(outname, out_N, out_bus=True, signed=signed) self.out = Bus(outname, out_N, out_bus=True, signed=signed)
self.components = [] self.components = []
self.circuit_wires = [] self._prefixes = [] # TODO rename to fullname and add distinct attr for prefix, name, suffix
self.circuit_gates = [] self.circuit_gates = []
self.circuit_wires = []
self.signed = signed self.signed = signed
self.c_data_type = "int64_t" if self.signed is True else "uint64_t" self.c_data_type = "int64_t" if self.signed is True else "uint64_t"
self.pyc = None # Python compiled function self.pyc = None # Python compiled function
@ -74,13 +65,46 @@ class GeneralCircuit():
def __str__(self): def __str__(self):
return f"<{type(self).__name__} prefix={self.prefix} " + (", ".join([f"input={i}" for i in self.inputs])) + ">" 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) # 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]: def get_circuit_def(self) -> Dict[str, Wire]:
""" returns IDs and wires of the inputs and output""" """ 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 = {chr(97 + i): self.inputs[i] for i in range(len(self.inputs))}
r['out'] = self.get_global_prefix() + "_out" r['out'] = self.get_global_prefix() + "_out"
return r return r
@ -88,11 +112,25 @@ class GeneralCircuit():
def add_component(self, component): def add_component(self, component):
"""Adds a component into list of circuit's inner subcomponents. """Adds a component into list of circuit's inner subcomponents.
Additionally it adds all the gates of the component to the circuit's list of gates and all
sbcomponents prefixes to check for naming duplicates which could cause issues in the circuit generation.
Args: Args:
component: Subcomponent to be added into list of components composing described circuit. component: Subcomponent to be added into list of components composing described circuit.
""" """
prefixes = [c.prefix for c in self.components] # TODO should be refactored in ArithsGen rework
assert component.prefix not in prefixes, f"Component with prefix {component.prefix} already exists in the circuit." # We should probably check also wire names for especially hierarchical generation
if isinstance(component, TwoInputLogicGate):
if component.disable_generation is False:
self.circuit_gates.append(component)
else:
self.circuit_gates.extend(component.get_circuit_gates())
for prefix in component._prefixes:
assert prefix not in self._prefixes, f"Component with prefix {prefix} already exists in the circuit."
self._prefixes.extend(component._prefixes)
assert component.prefix not in self._prefixes, f"Component with prefix {component.prefix} already exists in the circuit."
self._prefixes.append(component.prefix)
self.components.append(component) self.components.append(component)
return component return component
@ -132,13 +170,13 @@ class GeneralCircuit():
gates = [] gates = []
for c in self.components: for c in self.components:
if isinstance(c, TwoInputLogicGate): if isinstance(c, TwoInputLogicGate):
if c.disable_generation is False and (verilog_output is False or ((hasattr(self, "use_verilog_instance") and self.use_verilog_instance is False) or hasattr(self, "use_verilog_instance") is False)): if (c.disable_generation is False) and (verilog_output is False or getattr(c, "use_verilog_instance", False) is False):
gates.append(c) gates.append(c)
else: else:
# Check whether it is necessary to use gates for the Verilog component # Check whether it is necessary to use gates for the Verilog component
# description (ArithsGen internally defined comp) or not (technology specific instance) # description (ArithsGen internally defined comp) or not (technology specific instance)
if verilog_output is False or ((hasattr(c, "use_verilog_instance") and c.use_verilog_instance is False) or hasattr(c, "use_verilog_instance") is False): if verilog_output is False or ((hasattr(c, "use_verilog_instance") and c.use_verilog_instance is False) or hasattr(c, "use_verilog_instance") is False):
gates.extend((c.get_circuit_gates(verilog_output))) gates.extend(c.get_circuit_gates(verilog_output))
return gates return gates
def get_one_bit_components(self): def get_one_bit_components(self):
@ -151,7 +189,7 @@ class GeneralCircuit():
for c in self.components: for c in self.components:
if isinstance(c, TwoInputLogicGate): if isinstance(c, TwoInputLogicGate):
continue continue
elif isinstance(getattr(c, 'a'), Wire): elif all(isinstance(i, Wire) for i in self.inputs):
one_bit_comps.append(c) one_bit_comps.append(c)
else: else:
one_bit_comps.extend(c.get_one_bit_components()) one_bit_comps.extend(c.get_one_bit_components())
@ -168,10 +206,11 @@ class GeneralCircuit():
for c in self.components: for c in self.components:
if isinstance(c, TwoInputLogicGate): if isinstance(c, TwoInputLogicGate):
continue continue
elif isinstance(getattr(c, 'a'), Wire): elif all(isinstance(i, Wire) for i in self.inputs):
continue continue
else: else:
multi_bit_comps.append(c) multi_bit_comps.append(c)
multi_bit_comps.extend(c.get_multi_bit_components())
return multi_bit_comps return multi_bit_comps
@staticmethod @staticmethod
@ -186,7 +225,7 @@ class GeneralCircuit():
list: List of unique composite class types. list: List of unique composite class types.
""" """
if multi_bit is True: 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: else:
return list({type(c): c for c in components}.values()) return list({type(c): c for c in components}.values())
@ -203,8 +242,8 @@ class GeneralCircuit():
gate_comps = self.get_unique_types(components=self.get_circuit_gates(verilog_output)) gate_comps = self.get_unique_types(components=self.get_circuit_gates(verilog_output))
one_bit_comps = self.get_unique_types( one_bit_comps = self.get_unique_types(
components=self.get_one_bit_components()) components=self.get_one_bit_components())
multi_bit_comps = self.get_unique_types( multi_bit_comps = self.get_unique_types(components=self.get_multi_bit_components(),
components=self.get_multi_bit_components(), multi_bit=True) multi_bit=True)
all_components = gate_comps + one_bit_comps + multi_bit_comps all_components = gate_comps + one_bit_comps + multi_bit_comps
return all_components return all_components
@ -227,14 +266,13 @@ class GeneralCircuit():
else: else:
return len(self.circuit_wires)+2 return len(self.circuit_wires)+2
def get_cgp_wires(self): def get_circuit_wires(self):
"""Gets a list of all wires in circuit along with their index position for cgp chromosome generation and stores them inside `self.circuit_wires` list. """Gets a list of all wires in circuit along with their index position for cgp chromosome generation and stores them inside `self.circuit_wires` list.
Constant wire with value 0 has constant index of 0. Constant wire with value 0 has constant index of 0.
Constant wire with value 1 has constant index of 1. Constant wire with value 1 has constant index of 1.
Other wires indexes start counting from 2 and up. Other wires indexes start counting from 2 and up.
""" """
self.circuit_wires = []
circuit_wires_names = [] circuit_wires_names = []
for input in self.inputs: for input in self.inputs:
@ -263,6 +301,7 @@ class GeneralCircuit():
(gate.out, gate.out.name, self.save_wire_id(wire=gate.out))) (gate.out, gate.out.name, self.save_wire_id(wire=gate.out)))
circuit_wires_names.append(gate.out.name) circuit_wires_names.append(gate.out.name)
def get_circuit_wire_index(self, wire: Wire): def get_circuit_wire_index(self, wire: Wire):
"""Searches for circuit's wire unique index position within the circuit. Used for cgp chromosome generation. """Searches for circuit's wire unique index position within the circuit. Used for cgp chromosome generation.
@ -313,8 +352,6 @@ class GeneralCircuit():
file_object (TextIOWrapper): Destination file object where circuit's representation will be written to. 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.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_init_python_flat()+"\n")
file_object.write(self.get_function_out_python_flat()) file_object.write(self.get_function_out_python_flat())
file_object.write(self.out.return_bus_wires_sign_extend_python_flat()) file_object.write(self.out.return_bus_wires_sign_extend_python_flat())
@ -388,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 # 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() 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]) return "".join([c.get_function_block_c() for c in self.component_types])
def get_function_block_c(self): def get_function_block_c(self):
@ -398,12 +433,7 @@ class GeneralCircuit():
Returns: Returns:
str: Hierarchical C code of multi-bit arithmetic circuit's function block description. str: Hierarchical C code of multi-bit arithmetic circuit's function block description.
""" """
# Obtain proper circuit name with its bit width return f"{self.get_hier_subcomponent_def(parent_kwargs=self.kwargs).get_circuit_c()}\n\n"
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"
def get_declarations_c_hier(self): def get_declarations_c_hier(self):
"""Generates hierarchical C code declaration of input/output circuit wires. """Generates hierarchical C code declaration of input/output circuit wires.
@ -422,8 +452,7 @@ class GeneralCircuit():
Returns: Returns:
str: Hierarchical C code of subcomponent arithmetic circuit's wires declaration. str: Hierarchical C code of subcomponent arithmetic circuit's wires declaration.
""" """
return f" {self.c_data_type} {self.a.prefix} = 0;\n" + \ return "".join([f" {self.c_data_type} {i.prefix} = 0;\n" for i in self.inputs if ((isinstance(i, Wire)) or (not all((w.is_const()) or (w.parent_bus is not None and w.prefix == i.prefix) for w in i.bus)))]) + \
f" {self.c_data_type} {self.b.prefix} = 0;\n" + \
f" {self.c_data_type} {self.out.prefix} = 0;\n" f" {self.c_data_type} {self.out.prefix} = 0;\n"
def get_init_c_hier(self): def get_init_c_hier(self):
@ -445,9 +474,12 @@ class GeneralCircuit():
str: Hierarchical C code of subcomponent's C function invocation and output assignment. 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 # 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) init_signature = inspect.signature(self.__class__.__init__)
return self.a.return_bus_wires_values_c_hier() + self.b.return_bus_wires_values_c_hier() + \ default_circuit_name = init_signature.parameters['name'].default
f" {self.out.prefix} = {circuit_type}({self.a.prefix}, {self.b.prefix});\n" 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): def get_function_out_c_hier(self):
"""Generates hierarchical C code assignment of corresponding arithmetic circuit's output bus wires. """Generates hierarchical C code assignment of corresponding arithmetic circuit's output bus wires.
@ -484,14 +516,13 @@ class GeneralCircuit():
""" VERILOG CODE GENERATION """ """ VERILOG CODE GENERATION """
# FLAT VERILOG # # FLAT VERILOG #
def get_prototype_v(self): def get_prototype_v(self):
"""Generates Verilog code module header to describe corresponding arithmetic circuit's interface in Verilog code. """Generates Verilog code module header to describe corresponding arithmetic circuit's interface in Verilog code.
Returns: Returns:
str: Module's name and parameters in Verilog code. 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): def get_declaration_v_flat(self):
"""Generates flat Verilog code declaration of input/output circuit wires. """Generates flat Verilog code declaration of input/output circuit wires.
@ -539,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 # 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) 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]) return "".join([c.get_function_block_v() for c in self.component_types])
def get_function_block_v(self): def get_function_block_v(self):
@ -550,11 +579,7 @@ class GeneralCircuit():
str: Hierarchical Verilog code of multi-bit arithmetic circuit's function block description. str: Hierarchical Verilog code of multi-bit arithmetic circuit's function block description.
""" """
# Obtain proper circuit name with its bit width # Obtain proper circuit name with its bit width
circuit_prefix = self.__class__( return f"{self.get_hier_subcomponent_def(parent_kwargs=self.kwargs).get_circuit_v()}\n\n"
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"
def get_declarations_v_hier(self): def get_declarations_v_hier(self):
"""Generates hierarchical Verilog code declaration of input/output circuit wires. """Generates hierarchical Verilog code declaration of input/output circuit wires.
@ -573,12 +598,7 @@ class GeneralCircuit():
Returns: Returns:
str: Hierarchical Verilog code of subcomponent arithmetic circuit's wires declaration. str: Hierarchical Verilog code of subcomponent arithmetic circuit's wires declaration.
""" """
return "".join(w.get_wire_declaration_v() for w in self.inputs + [self.out]) + "\n" return "".join(b.get_wire_declaration_v() for b in self.inputs + [self.out] if (b == self.out) or (not all((w.is_const()) or (w.parent_bus is not None and w.prefix == b.prefix) for w in b.bus)))
# 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"
def get_init_v_hier(self): def get_init_v_hier(self):
"""Generates hierarchical Verilog code initialization and assignment of corresponding arithmetic circuit's input/output wires. """Generates hierarchical Verilog code initialization and assignment of corresponding arithmetic circuit's input/output wires.
@ -599,12 +619,13 @@ class GeneralCircuit():
str: Hierarchical Verilog code of subcomponent's module invocation and output assignment. 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 # 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) init_signature = inspect.signature(self.__class__.__init__)
circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus( default_circuit_name = init_signature.parameters['name'].default
N=self.N, prefix="b"), name=circuit_type) 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]) + \ 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" 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"
def get_function_out_v_hier(self): def get_function_out_v_hier(self):
"""Generates hierarchical Verilog code assignment of corresponding arithmetic circuit's output bus wires. """Generates hierarchical Verilog code assignment of corresponding arithmetic circuit's output bus wires.
@ -653,7 +674,7 @@ class GeneralCircuit():
Returns: Returns:
str: Flat Blif code containing declaration of circuit's wires. 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" + \ 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".outputs{self.out.get_wire_declaration_blif()}\n" + \
f".names vdd\n1\n" + \ f".names vdd\n1\n" + \
f".names gnd\n0\n" f".names gnd\n0\n"
@ -687,6 +708,14 @@ class GeneralCircuit():
file_object.write(self.get_function_out_blif()) file_object.write(self.get_function_out_blif())
file_object.write(f".end\n") file_object.write(f".end\n")
# HIERARCHICAL BLIF # # HIERARCHICAL BLIF #
def get_invocations_blif_hier(self): def get_invocations_blif_hier(self):
"""Generates hierarchical Blif code with invocations of subcomponents function blocks. """Generates hierarchical Blif code with invocations of subcomponents function blocks.
@ -705,7 +734,21 @@ class GeneralCircuit():
str: Hierarchical Blif code of subcomponent's model invocation and output assignment. 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 # 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))
if self.out.N > 1:
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)}]" if b.N > 1 else f" {chr(97+i)}={b.prefix}" 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 if not o.is_const()]) + "\n"
else:
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)}]" if b.N > 1 else f" {chr(97+i)}={b.prefix}" for i, b in enumerate(self.inputs) for w in b.bus]) + \
"".join([f" {circuit_type}_out={o.name}" for o in self.out.bus if not o.is_const()]) + "\n"
# TODO delete
return f"{self.a.get_wire_assign_blif(output=True)}" + \ return f"{self.a.get_wire_assign_blif(output=True)}" + \
f"{self.b.get_wire_assign_blif(output=True)}" + \ f"{self.b.get_wire_assign_blif(output=True)}" + \
f".subckt {circuit_type}" + \ f".subckt {circuit_type}" + \
@ -734,8 +777,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 # 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) # (iterating backwards as opposed to other representations so the top modul is always above its subcomponents)
self.component_types = self.get_component_types() 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]]) return "\n".join([c.get_function_block_blif() for c in self.component_types[::-1]])
def get_function_block_blif(self): def get_function_block_blif(self):
@ -745,11 +786,7 @@ class GeneralCircuit():
str: Hierarchical Blif code of multi-bit arithmetic circuit's function block description. str: Hierarchical Blif code of multi-bit arithmetic circuit's function block description.
""" """
# Obtain proper circuit name with its bit width # Obtain proper circuit name with its bit width
circuit_prefix = self.__class__( return f"{self.get_hier_subcomponent_def(parent_kwargs=self.kwargs).get_circuit_blif()}"
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()}"
# Generating hierarchical BLIF code representation of circuit # Generating hierarchical BLIF code representation of circuit
def get_blif_code_hier(self, file_object): def get_blif_code_hier(self, file_object):
@ -773,7 +810,7 @@ class GeneralCircuit():
Returns: Returns:
str: CGP chromosome parameters of described arithmetic circuit. str: CGP chromosome parameters of described arithmetic circuit.
""" """
self.circuit_gates = self.get_circuit_gates() # self.circuit_gates = self.get_circuit_gates() TODO delete
return f"{{{sum(input_bus.N for input_bus in self.inputs)},{self.out.N},1,{len(self.circuit_gates)},2,1,0}}" return f"{{{sum(input_bus.N for input_bus in self.inputs)},{self.out.N},1,{len(self.circuit_gates)},2,1,0}}"
def get_triplets_cgp(self): def get_triplets_cgp(self):
@ -789,7 +826,7 @@ class GeneralCircuit():
Returns: Returns:
str: List of triplets each describing logic function of corresponding two input logic gate and as a whole describe the arithmetic circuit. str: List of triplets each describing logic function of corresponding two input logic gate and as a whole describe the arithmetic circuit.
""" """
self.get_cgp_wires() self.get_circuit_wires()
return "".join([g.get_triplet_cgp(a_id=self.get_circuit_wire_index(g.a), out_id=self.get_circuit_wire_index(g.out)) if isinstance(g, OneInputLogicGate) else return "".join([g.get_triplet_cgp(a_id=self.get_circuit_wire_index(g.a), out_id=self.get_circuit_wire_index(g.out)) if isinstance(g, OneInputLogicGate) else
g.get_triplet_cgp(a_id=self.get_circuit_wire_index(g.a), b_id=self.get_circuit_wire_index(g.b), out_id=self.get_circuit_wire_index(g.out)) for g in self.circuit_gates]) g.get_triplet_cgp(a_id=self.get_circuit_wire_index(g.a), b_id=self.get_circuit_wire_index(g.b), out_id=self.get_circuit_wire_index(g.out)) for g in self.circuit_gates])

View File

@ -1,36 +1,24 @@
from .arithmetic_circuit import ( from .general_circuit import (
ArithmeticCircuit GeneralCircuit
) )
from ariths_gen.one_bit_circuits.logic_gates import (
AndGate,
NandGate,
OrGate,
NorGate,
XorGate,
XnorGate,
NotGate
)
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0,
ConstantWireValue1,
Bus Bus
) )
from ariths_gen.one_bit_circuits.logic_gates import (
AndGate,
NandGate
)
import math import math
class MultiplierCircuit(ArithmeticCircuit): class MultiplierCircuit(GeneralCircuit):
"""Class represents a general multiplier circuit derived from `ArithmeticCircuit` class. """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. 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: str = "", **kwargs):
def __init__(self, a, b, prefix: str, name: str, out_N: int, **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)
super().__init__(a=a, b=b, prefix=prefix, name=name, out_N=out_N, **kwargs)
# Array/approximate multipliers # Array/approximate multipliers
def get_previous_partial_product(self, a_index: int, b_index: int, mult_type=""): def get_previous_partial_product(self, a_index: int, b_index: int, mult_type=""):
@ -266,7 +254,7 @@ class MultiplierCircuit(ArithmeticCircuit):
else: else:
return self.columns[column][bit+1] 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. """Provides bit height reduction of the chosen column.
Inserts chosen column's top bits into an `adder` circuit to reduce its bit height. Inserts chosen column's top bits into an `adder` circuit to reduce its bit height.
@ -274,7 +262,7 @@ class MultiplierCircuit(ArithmeticCircuit):
Args: Args:
curr_column (int): Current pp column index. 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. next_column (int, optional): Subsequent pp column index. Defaults to 0.
""" """
if hasattr(adder, "c"): if hasattr(adder, "c"):

View File

@ -1,5 +1,4 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1, ConstantWireValue1,
Bus Bus
@ -7,14 +6,6 @@ from ariths_gen.wire_components import (
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
GeneralCircuit 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 ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, AndGate,
NandGate, NandGate,

View File

@ -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 from ariths_gen.wire_components.buses import Bus
import math import math
@ -344,7 +344,7 @@ class TwoInputLogicGate():
Returns: Returns:
str: Blif logic gate's wires declaration. str: Blif logic gate's wires declaration.
""" """
return f".inputs {self.a.get_declaration_blif()} {self.b.get_declaration_blif()}\n" + \ return f".inputs {self.a.get_wire_declaration_blif()}{self.b.get_wire_declaration_blif()}\n" + \
f".outputs" + \ f".outputs" + \
"".join([f" {self.out.name}\n" if self.disable_generation is False else f" {self.out.name}_out\n" for _ in range(1)]) + \ "".join([f" {self.out.name}\n" if self.disable_generation is False else f" {self.out.name}_out\n" for _ in range(1)]) + \
f".names vdd\n1\n" + \ f".names vdd\n1\n" + \
@ -687,7 +687,7 @@ class OneInputLogicGate(TwoInputLogicGate):
Returns: Returns:
str: Blif logic gate's wires declaration. str: Blif logic gate's wires declaration.
""" """
return f".inputs {self.a.get_declaration_blif()}\n" + \ return f".inputs {self.a.get_wire_declaration_blif()}\n" + \
f".outputs" + \ f".outputs" + \
"".join([f" {self.out.name}\n" if self.disable_generation is False else f" {self.out.name}_out\n" for _ in range(1)]) + \ "".join([f" {self.out.name}\n" if self.disable_generation is False else f" {self.out.name}_out\n" for _ in range(1)]) + \
f".names vdd\n1\n" + \ f".names vdd\n1\n" + \

View File

@ -1,11 +1,13 @@
from .two_input_one_bit_circuit import ( from .two_input_one_bit_circuit import (
TwoInputOneBitCircuit TwoInputOneBitCircuit
) )
from ariths_gen.core.arithmetic_circuits import (
GeneralCircuit
)
from ariths_gen.wire_components.wires import Wire 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. """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. Description of the __init__ method.
@ -15,16 +17,12 @@ class FourInputOneBitCircuit(TwoInputOneBitCircuit):
b (Wire): Second input wire. b (Wire): Second input wire.
c (Wire): Third input wire. c (Wire): Third input wire.
d (Wire): Fourth input wire. d (Wire): Fourth input wire.
prefix (str, optional): Prefix name of circuit. Defaults to "four_input_one_bit_circuit". prefix (str, optional): Prefix name of circuit. Defaults to "".
name (str, optional): 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"): 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 = "", name: str = "four_input_one_bit_circuit"):
super().__init__() GeneralCircuit.__init__(self, inputs=[a, b, c, d], prefix=prefix, name=name, out_N=1)
self.c_data_type = "uint8_t" self.c_data_type = "uint8_t"
self.prefix = prefix
self.a = a
self.b = b
self.c = c
self.d = d
""" C CODE GENERATION """ """ C CODE GENERATION """
# FLAT C # # FLAT C #
@ -39,7 +37,7 @@ class FourInputOneBitCircuit(TwoInputOneBitCircuit):
# HIERARCHICAL C # # HIERARCHICAL C #
# Subcomponent generation (four inputs) # Subcomponent generation (four inputs)
def get_out_invocation_c(self, *args, **kwargs): def get_out_invocation_c(self):
"""Generates hierarchical C code invocation of corresponding four input one bit circuit's generated function block. """Generates hierarchical C code invocation of corresponding four input one bit circuit's generated function block.
Assigns output values from invocation of the corresponding function block into inner wires present inside the upper Assigns output values from invocation of the corresponding function block into inner wires present inside the upper
@ -120,7 +118,7 @@ class FourInputOneBitCircuit(TwoInputOneBitCircuit):
f"" for c in self.components]) f"" for c in self.components])
# Subcomponent generation # Subcomponent generation
def get_out_invocation_v(self, *args, **kwargs): def get_out_invocation_v(self):
"""Generates hierarchical Verilog code invocation of corresponding four input one bit circuit's generated function block. """Generates hierarchical Verilog code invocation of corresponding four input one bit circuit's generated function block.
Assigns output values from invocation of the corresponding function block into inner wires present inside the upper Assigns output values from invocation of the corresponding function block into inner wires present inside the upper
@ -146,7 +144,7 @@ class FourInputOneBitCircuit(TwoInputOneBitCircuit):
""" """
unique_out_wires = [] unique_out_wires = []
[unique_out_wires.append(o.name+"_outid"+str(self.out.bus.index(o))) if o.is_const() or o.name in [self.a.name, self.b.name, self.c.name, self.d.name] else unique_out_wires.append(o.name) for o in self.out.bus] [unique_out_wires.append(o.name+"_outid"+str(self.out.bus.index(o))) if o.is_const() or o.name in [self.a.name, self.b.name, self.c.name, self.d.name] else unique_out_wires.append(o.name) for o in self.out.bus]
return f".inputs {self.a.get_declaration_blif()} {self.b.get_declaration_blif()} {self.c.get_declaration_blif()} {self.d.get_declaration_blif()}\n" + \ return f".inputs {self.a.get_wire_declaration_blif()}{self.b.get_wire_declaration_blif()}{self.c.get_wire_declaration_blif()}{self.d.get_wire_declaration_blif()}\n" + \
f".outputs" + \ f".outputs" + \
"".join([f" {o}" for o in unique_out_wires]) + "\n" + \ "".join([f" {o}" for o in unique_out_wires]) + "\n" + \
f".names vdd\n1\n" + \ f".names vdd\n1\n" + \
@ -190,7 +188,7 @@ class FourInputOneBitCircuit(TwoInputOneBitCircuit):
c.out.get_assign_blif(prefix=f"{unique_out_wires.pop(unique_out_wires.index(c.out.name+'_outid'+str(c.outid)))}", output=True) if f"{c.out.name+'_outid'+str(c.outid)}" in unique_out_wires else c.out.get_assign_blif(prefix=f"{unique_out_wires.pop(unique_out_wires.index(c.out.name+'_outid'+str(c.outid)))}", output=True) if f"{c.out.name+'_outid'+str(c.outid)}" in unique_out_wires else
"" for c in self.components]) "" for c in self.components])
def get_invocation_blif_hier(self, *args, **kwargs): def get_invocation_blif_hier(self):
"""Generates hierarchical Blif code invocation of corresponding four input one bit circuit's generated function block. """Generates hierarchical Blif code invocation of corresponding four input one bit circuit's generated function block.
Returns: Returns:

View File

@ -1,11 +1,13 @@
from .two_input_one_bit_circuit import ( from .two_input_one_bit_circuit import (
TwoInputOneBitCircuit TwoInputOneBitCircuit
) )
from ariths_gen.core.arithmetic_circuits import (
GeneralCircuit
)
from ariths_gen.wire_components.wires import Wire 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. """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. Description of the __init__ method.
@ -14,15 +16,12 @@ class ThreeInputOneBitCircuit(TwoInputOneBitCircuit):
a (Wire): First input wire. a (Wire): First input wire.
b (Wire): Second input wire. b (Wire): Second input wire.
c (Wire): Third input wire. c (Wire): Third input wire.
prefix (str, optional): Prefix name of circuit. Defaults to "three_input_one_bit_circuit". prefix (str, optional): Prefix name of circuit. Defaults to "".
name (str, optional): 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"): def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "", name: str = "three_input_one_bit_circuit"):
super().__init__() GeneralCircuit.__init__(self, inputs=[a, b, c], prefix=prefix, name=name, out_N=1)
self.c_data_type = "uint8_t" self.c_data_type = "uint8_t"
self.prefix = prefix
self.a = a
self.b = b
self.c = c
""" C CODE GENERATION """ """ C CODE GENERATION """
# FLAT C # # FLAT C #
@ -37,7 +36,7 @@ class ThreeInputOneBitCircuit(TwoInputOneBitCircuit):
# HIERARCHICAL C # # HIERARCHICAL C #
# Subcomponent generation (three inputs) # Subcomponent generation (three inputs)
def get_out_invocation_c(self, *args, **kwargs): def get_out_invocation_c(self):
"""Generates hierarchical C code invocation of corresponding three input one bit circuit's generated function block. """Generates hierarchical C code invocation of corresponding three input one bit circuit's generated function block.
Assigns output values from invocation of the corresponding function block into inner wires present inside the upper Assigns output values from invocation of the corresponding function block into inner wires present inside the upper
@ -118,7 +117,7 @@ class ThreeInputOneBitCircuit(TwoInputOneBitCircuit):
f"" for c in self.components]) f"" for c in self.components])
# Subcomponent generation # Subcomponent generation
def get_out_invocation_v(self, *args, **kwargs): def get_out_invocation_v(self):
"""Generates hierarchical Verilog code invocation of corresponding three input one bit circuit's generated function block. """Generates hierarchical Verilog code invocation of corresponding three input one bit circuit's generated function block.
Assigns output values from invocation of the corresponding function block into inner wires present inside the upper Assigns output values from invocation of the corresponding function block into inner wires present inside the upper
@ -144,7 +143,7 @@ class ThreeInputOneBitCircuit(TwoInputOneBitCircuit):
""" """
unique_out_wires = [] unique_out_wires = []
[unique_out_wires.append(o.name+"_outid"+str(self.out.bus.index(o))) if o.is_const() or o.name in [self.a.name, self.b.name, self.c.name] else unique_out_wires.append(o.name) for o in self.out.bus] [unique_out_wires.append(o.name+"_outid"+str(self.out.bus.index(o))) if o.is_const() or o.name in [self.a.name, self.b.name, self.c.name] else unique_out_wires.append(o.name) for o in self.out.bus]
return f".inputs {self.a.get_declaration_blif()} {self.b.get_declaration_blif()} {self.c.get_declaration_blif()}\n" + \ return f".inputs {self.a.get_wire_declaration_blif()}{self.b.get_wire_declaration_blif()}{self.c.get_wire_declaration_blif()}\n" + \
f".outputs" + \ f".outputs" + \
"".join([f" {o}" for o in unique_out_wires]) + "\n" + \ "".join([f" {o}" for o in unique_out_wires]) + "\n" + \
f".names vdd\n1\n" + \ f".names vdd\n1\n" + \
@ -188,7 +187,7 @@ class ThreeInputOneBitCircuit(TwoInputOneBitCircuit):
c.out.get_assign_blif(prefix=f"{unique_out_wires.pop(unique_out_wires.index(c.out.name+'_outid'+str(c.outid)))}", output=True) if f"{c.out.name+'_outid'+str(c.outid)}" in unique_out_wires else c.out.get_assign_blif(prefix=f"{unique_out_wires.pop(unique_out_wires.index(c.out.name+'_outid'+str(c.outid)))}", output=True) if f"{c.out.name+'_outid'+str(c.outid)}" in unique_out_wires else
"" for c in self.components]) "" for c in self.components])
def get_invocation_blif_hier(self, *args, **kwargs): def get_invocation_blif_hier(self):
"""Generates hierarchical Blif code invocation of corresponding three input one bit circuit's generated function block. """Generates hierarchical Blif code invocation of corresponding three input one bit circuit's generated function block.
Returns: Returns:

View File

@ -1,11 +1,11 @@
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit GeneralCircuit
) )
from ariths_gen.wire_components.wires import Wire 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. """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. Description of the __init__ method.
@ -13,14 +13,12 @@ class TwoInputOneBitCircuit(ArithmeticCircuit):
Args: Args:
a (Wire): First input wire. a (Wire): First input wire.
b (Wire): Second input wire. b (Wire): Second input wire.
prefix (str, optional): Prefix name of circuit. Defaults to "two_input_one_bit_circuit". prefix (str, optional): Prefix name of circuit. Defaults to "".
name (str, optional): 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"): def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "", name: 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=name, out_N=1, one_bit_circuit=True)
self.c_data_type = "uint8_t" self.c_data_type = "uint8_t"
self.prefix = prefix
self.a = a
self.b = b
""" C CODE GENERATION """ """ C CODE GENERATION """
# FLAT C # # FLAT C #
@ -53,7 +51,7 @@ class TwoInputOneBitCircuit(ArithmeticCircuit):
adder_block = self.__class__() adder_block = self.__class__()
return f"{adder_block.get_circuit_c()}\n\n" return f"{adder_block.get_circuit_c()}\n\n"
def get_out_invocation_c(self, *args, **kwargs): def get_out_invocation_c(self):
"""Generates hierarchical C code invocation of corresponding two input one bit circuit's generated function block. """Generates hierarchical C code invocation of corresponding two input one bit circuit's generated function block.
Assigns output values from invocation of the corresponding function block into inner wires present inside the upper Assigns output values from invocation of the corresponding function block into inner wires present inside the upper
@ -168,7 +166,7 @@ class TwoInputOneBitCircuit(ArithmeticCircuit):
adder_block = self.__class__() adder_block = self.__class__()
return f"{adder_block.get_circuit_v()}\n\n" return f"{adder_block.get_circuit_v()}\n\n"
def get_out_invocation_v(self, *args, **kwargs): def get_out_invocation_v(self):
"""Generates hierarchical Verilog code invocation of corresponding two input one bit circuit's generated function block. """Generates hierarchical Verilog code invocation of corresponding two input one bit circuit's generated function block.
Assigns output values from invocation of the corresponding function block into inner wires present inside the upper Assigns output values from invocation of the corresponding function block into inner wires present inside the upper
@ -253,7 +251,7 @@ class TwoInputOneBitCircuit(ArithmeticCircuit):
""" """
unique_out_wires = [] unique_out_wires = []
[unique_out_wires.append(o.name+"_outid"+str(self.out.bus.index(o))) if o.is_const() or o.name in [self.a.name, self.b.name] else unique_out_wires.append(o.name) for o in self.out.bus] [unique_out_wires.append(o.name+"_outid"+str(self.out.bus.index(o))) if o.is_const() or o.name in [self.a.name, self.b.name] else unique_out_wires.append(o.name) for o in self.out.bus]
return f".inputs {self.a.get_declaration_blif()} {self.b.get_declaration_blif()}\n" + \ return f".inputs {self.a.get_wire_declaration_blif()}{self.b.get_wire_declaration_blif()}\n" + \
f".outputs" + \ f".outputs" + \
"".join([f" {o}" for o in unique_out_wires]) + "\n" + \ "".join([f" {o}" for o in unique_out_wires]) + "\n" + \
f".names vdd\n1\n" + \ f".names vdd\n1\n" + \
@ -329,7 +327,7 @@ class TwoInputOneBitCircuit(ArithmeticCircuit):
c.out.get_assign_blif(prefix=f"{unique_out_wires.pop(unique_out_wires.index(c.out.name+'_outid'+str(c.outid)))}", output=True) if f"{c.out.name+'_outid'+str(c.outid)}" in unique_out_wires else c.out.get_assign_blif(prefix=f"{unique_out_wires.pop(unique_out_wires.index(c.out.name+'_outid'+str(c.outid)))}", output=True) if f"{c.out.name+'_outid'+str(c.outid)}" in unique_out_wires else
"" for c in self.components]) "" for c in self.components])
def get_invocation_blif_hier(self, *args, **kwargs): def get_invocation_blif_hier(self):
"""Generates hierarchical Blif code invocation of corresponding two input one bit circuit's generated function block. """Generates hierarchical Blif code invocation of corresponding two input one bit circuit's generated function block.
Returns: Returns:

View File

@ -1,41 +1,22 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit, GeneralCircuit
MultiplierCircuit
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( from ariths_gen.one_bit_circuits.one_bit_components import (
HalfAdder,
FullAdder,
PGSumLogic, PGSumLogic,
GreyCell, GreyCell,
BlackCell BlackCell
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, XorGate
NandGate,
OrGate,
NorGate,
XorGate,
XnorGate,
NotGate
)
from ariths_gen.multi_bit_circuits.adders import (
UnsignedCarryLookaheadAdder,
UnsignedPGRippleCarryAdder,
UnsignedRippleCarryAdder,
SignedCarryLookaheadAdder,
SignedPGRippleCarryAdder,
SignedRippleCarryAdder
) )
import math import math
class UnsignedBrentKungAdder(ArithmeticCircuit): class UnsignedBrentKungAdder(GeneralCircuit):
"""Class representing unsigned Brent-Kung adder (using valency-2 logic gates). """Class representing unsigned Brent-Kung adder (using valency-2 logic gates).
The Brent-Kung adder belongs to a type of tree (parallel-prefix) adders. 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): def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_bka", **kwargs):
self.N = max(a.N, b.N) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) 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()) 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). """Class representing signed Brent-Kung adder (using valency-2 logic gates).
The Brent-Kung adder belongs to a type of tree (parallel-prefix) adders. The Brent-Kung adder belongs to a type of tree (parallel-prefix) adders.

View File

@ -1,13 +1,9 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1, Bus
Bus,
wires
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit, GeneralCircuit
MultiplierCircuit
) )
from ariths_gen.core.logic_gate_circuits import ( from ariths_gen.core.logic_gate_circuits import (
MultipleInputLogicGate MultipleInputLogicGate
@ -15,21 +11,16 @@ from ariths_gen.core.logic_gate_circuits import (
from ariths_gen.one_bit_circuits.one_bit_components import ( from ariths_gen.one_bit_circuits.one_bit_components import (
HalfAdder, HalfAdder,
FullAdder, FullAdder,
FullAdderP, FullAdderP
TwoOneMultiplexer
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, AndGate,
NandGate,
OrGate, OrGate,
NorGate, XorGate
XorGate,
XnorGate,
NotGate
) )
class UnsignedCarryIncrementAdder(ArithmeticCircuit): class UnsignedCarryIncrementAdder(GeneralCircuit):
"""Class representing unsigned carry increment adder. """Class representing unsigned carry increment adder.
Carry increment adder represents a modified carry select adder that achieves about the same critical delay 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): 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) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)
@ -115,7 +106,7 @@ class UnsignedCarryIncrementAdder(ArithmeticCircuit):
self.out.connect(self.N, cin) self.out.connect(self.N, cin)
class SignedCarryIncrementAdder(UnsignedCarryIncrementAdder, ArithmeticCircuit): class SignedCarryIncrementAdder(UnsignedCarryIncrementAdder, GeneralCircuit):
"""Class representing signed carry increment adder. """Class representing signed carry increment adder.
Carry increment adder represents a modified carry select adder that achieves about the same critical delay Carry increment adder represents a modified carry select adder that achieves about the same critical delay

View File

@ -1,34 +1,24 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit, GeneralCircuit
MultiplierCircuit
) )
from ariths_gen.core.logic_gate_circuits import ( from ariths_gen.core.logic_gate_circuits import (
MultipleInputLogicGate MultipleInputLogicGate
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( from ariths_gen.one_bit_circuits.one_bit_components import (
HalfAdder,
FullAdder,
FullAdderPG,
PGLogicBlock PGLogicBlock
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, AndGate,
NandGate,
OrGate, OrGate,
NorGate, XorGate
XorGate,
XnorGate,
NotGate
) )
class UnsignedCarryLookaheadAdder(ArithmeticCircuit): class UnsignedCarryLookaheadAdder(GeneralCircuit):
"""Class representing unsigned carry-lookahead adder. """Class representing unsigned carry-lookahead adder.
Unsigned carry-lookahead adder represents faster adder circuit which is composed 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): def __init__(self, a: Bus, b: Bus, cla_block_size: int = 4, prefix: str = "", name: str = "u_cla", **kwargs):
self.N = max(a.N, b.N) self.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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)
@ -128,7 +118,7 @@ class UnsignedCarryLookaheadAdder(ArithmeticCircuit):
self.out.connect(self.N, cin) self.out.connect(self.N, cin)
class SignedCarryLookaheadAdder(UnsignedCarryLookaheadAdder, ArithmeticCircuit): class SignedCarryLookaheadAdder(UnsignedCarryLookaheadAdder, GeneralCircuit):
"""Class representing signed carry-lookahead adder. """Class representing signed carry-lookahead adder.
Signed carry-lookahead adder represents faster adder circuit which is composed Signed carry-lookahead adder represents faster adder circuit which is composed

View File

@ -1,38 +1,20 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1, ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit, GeneralCircuit
ThreeInputArithmeticCircuit,
MultiplierCircuit
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( from ariths_gen.one_bit_circuits.one_bit_components import (
HalfAdder,
FullAdder 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 ( from ariths_gen.multi_bit_circuits.adders import (
UnsignedCarryLookaheadAdder, UnsignedCarryLookaheadAdder
UnsignedPGRippleCarryAdder,
UnsignedRippleCarryAdder,
SignedCarryLookaheadAdder,
SignedPGRippleCarryAdder,
SignedRippleCarryAdder
) )
class CarrySaveAdderComponent(ThreeInputArithmeticCircuit): class CarrySaveAdderComponent(GeneralCircuit):
"""Class representing carry save adder component. """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. 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): 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) 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() 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) 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)] [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. """Class representing unsigned carry save adder.
Unsigned carry save adder represents 3 input N-bit unsigned adder which is composed of 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): 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) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)

View File

@ -1,34 +1,23 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1, ConstantWireValue1,
Bus, Bus
wires
) )
from ariths_gen.core.arithmetic_circuits import ( 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 ( from ariths_gen.one_bit_circuits.one_bit_components import (
HalfAdder,
FullAdder, FullAdder,
TwoOneMultiplexer TwoOneMultiplexer
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, AndGate,
NandGate,
OrGate, OrGate,
NorGate, XorGate
XorGate,
XnorGate,
NotGate
) )
class UnsignedCarrySelectAdder(ArithmeticCircuit): class UnsignedCarrySelectAdder(GeneralCircuit):
"""Class representing unsigned carry select adder. """Class representing unsigned carry select adder.
Carry select adder's logic is divided into a number of carry select blocks. 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): 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) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)
@ -125,7 +114,7 @@ class UnsignedCarrySelectAdder(ArithmeticCircuit):
self.out.connect(self.N, cin) self.out.connect(self.N, cin)
class SignedCarrySelectAdder(UnsignedCarrySelectAdder, ArithmeticCircuit): class SignedCarrySelectAdder(UnsignedCarrySelectAdder, GeneralCircuit):
"""Class representing signed carry select adder. """Class representing signed carry select adder.
Carry select adder's logic is divided into a number of carry select blocks. Carry select adder's logic is divided into a number of carry select blocks.

View File

@ -1,13 +1,9 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1, Bus
Bus,
wires
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit, GeneralCircuit
MultiplierCircuit
) )
from ariths_gen.core.logic_gate_circuits import ( from ariths_gen.core.logic_gate_circuits import (
MultipleInputLogicGate MultipleInputLogicGate
@ -19,16 +15,11 @@ from ariths_gen.one_bit_circuits.one_bit_components import (
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, AndGate,
NandGate, XorGate
OrGate,
NorGate,
XorGate,
XnorGate,
NotGate
) )
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. """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 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): def __init__(self, a: Bus, b: Bus, bypass_block_size: int = 4, prefix: str = "", name: str = "u_cska", **kwargs):
self.N = max(a.N, b.N) self.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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)
@ -120,7 +111,7 @@ class UnsignedCarrySkipAdder(ArithmeticCircuit):
self.out.connect(self.N, cin) 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. """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 Signed carry skip (bypass) adder represents faster adder circuit which is composed

View File

@ -1,35 +1,22 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1, ConstantWireValue1,
Bus, Bus
wires
) )
from ariths_gen.core.arithmetic_circuits import ( 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 ( from ariths_gen.one_bit_circuits.one_bit_components import (
HalfAdder,
FullAdder, FullAdder,
TwoOneMultiplexer TwoOneMultiplexer
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, XorGate
NandGate,
OrGate,
NorGate,
XorGate,
XnorGate,
NotGate
) )
import math import math
class UnsignedConditionalSumAdder(ArithmeticCircuit): class UnsignedConditionalSumAdder(GeneralCircuit):
"""Class representing unsigned conditional sum adder. """Class representing unsigned conditional sum adder.
Conditional sum adder performs carry-select addition starting with 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): def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_cosa", **kwargs):
self.N = max(a.N, b.N) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) 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]) 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. """Class representing signed conditional sum adder.
Conditional sum adder performs carry-select addition starting with Conditional sum adder performs carry-select addition starting with

View File

@ -1,41 +1,22 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit, GeneralCircuit
MultiplierCircuit
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( from ariths_gen.one_bit_circuits.one_bit_components import (
HalfAdder,
FullAdder,
PGSumLogic, PGSumLogic,
GreyCell, GreyCell,
BlackCell BlackCell
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, XorGate
NandGate,
OrGate,
NorGate,
XorGate,
XnorGate,
NotGate
)
from ariths_gen.multi_bit_circuits.adders import (
UnsignedCarryLookaheadAdder,
UnsignedPGRippleCarryAdder,
UnsignedRippleCarryAdder,
SignedCarryLookaheadAdder,
SignedPGRippleCarryAdder,
SignedRippleCarryAdder
) )
import math import math
class UnsignedHanCarlsonAdder(ArithmeticCircuit): class UnsignedHanCarlsonAdder(GeneralCircuit):
"""Class representing unsigned Han-Carlson adder (using valency-2 logic gates). """Class representing unsigned Han-Carlson adder (using valency-2 logic gates).
The Han-Carlson adder belongs to a type of tree (parallel-prefix) adders. 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): 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) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) 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()) 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). """Class representing signed Han-Carlson adder (using valency-2 logic gates).
The Han-Carlson adder belongs to a type of tree (parallel-prefix) adders. The Han-Carlson adder belongs to a type of tree (parallel-prefix) adders.

View File

@ -1,41 +1,22 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit, GeneralCircuit
MultiplierCircuit
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( from ariths_gen.one_bit_circuits.one_bit_components import (
HalfAdder,
FullAdder,
PGSumLogic, PGSumLogic,
GreyCell, GreyCell,
BlackCell BlackCell
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, XorGate
NandGate,
OrGate,
NorGate,
XorGate,
XnorGate,
NotGate
)
from ariths_gen.multi_bit_circuits.adders import (
UnsignedCarryLookaheadAdder,
UnsignedPGRippleCarryAdder,
UnsignedRippleCarryAdder,
SignedCarryLookaheadAdder,
SignedPGRippleCarryAdder,
SignedRippleCarryAdder
) )
import math import math
class UnsignedKnowlesAdder(ArithmeticCircuit): class UnsignedKnowlesAdder(GeneralCircuit):
"""Class representing unsigned Knowles adder (using valency-2 logic gates). """Class representing unsigned Knowles adder (using valency-2 logic gates).
The Knowles adder belongs to a type of tree (parallel-prefix) adders. 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): 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) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) 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()) 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). """Class representing signed Knowles adder (using valency-2 logic gates).
The Knowles adder belongs to a type of tree (parallel-prefix) adders. The Knowles adder belongs to a type of tree (parallel-prefix) adders.

View File

@ -1,41 +1,22 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit, GeneralCircuit
MultiplierCircuit
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( from ariths_gen.one_bit_circuits.one_bit_components import (
HalfAdder,
FullAdder,
PGSumLogic, PGSumLogic,
GreyCell, GreyCell,
BlackCell BlackCell
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, XorGate
NandGate,
OrGate,
NorGate,
XorGate,
XnorGate,
NotGate
)
from ariths_gen.multi_bit_circuits.adders import (
UnsignedCarryLookaheadAdder,
UnsignedPGRippleCarryAdder,
UnsignedRippleCarryAdder,
SignedCarryLookaheadAdder,
SignedPGRippleCarryAdder,
SignedRippleCarryAdder
) )
import math import math
class UnsignedKoggeStoneAdder(ArithmeticCircuit): class UnsignedKoggeStoneAdder(GeneralCircuit):
"""Class representing unsigned Kogge-Stone adder (using valency-2 logic gates). """Class representing unsigned Kogge-Stone adder (using valency-2 logic gates).
The Kogge-Stone adder belongs to a type of tree (parallel-prefix) adders. 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): def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_ksa", **kwargs):
self.N = max(a.N, b.N) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) 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()) 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). """Class representing signed Kogge-Stone adder (using valency-2 logic gates).
The Kogge-Stone adder belongs to a type of tree (parallel-prefix) adders. The Kogge-Stone adder belongs to a type of tree (parallel-prefix) adders.

View File

@ -1,41 +1,22 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit, GeneralCircuit
MultiplierCircuit
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( from ariths_gen.one_bit_circuits.one_bit_components import (
HalfAdder,
FullAdder,
PGSumLogic, PGSumLogic,
GreyCell, GreyCell,
BlackCell BlackCell
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, XorGate
NandGate,
OrGate,
NorGate,
XorGate,
XnorGate,
NotGate
)
from ariths_gen.multi_bit_circuits.adders import (
UnsignedCarryLookaheadAdder,
UnsignedPGRippleCarryAdder,
UnsignedRippleCarryAdder,
SignedCarryLookaheadAdder,
SignedPGRippleCarryAdder,
SignedRippleCarryAdder
) )
import math import math
class UnsignedLadnerFischerAdder(ArithmeticCircuit): class UnsignedLadnerFischerAdder(GeneralCircuit):
"""Class representing unsigned Ladner-Fischer adder (using valency-2 logic gates). """Class representing unsigned Ladner-Fischer adder (using valency-2 logic gates).
The Ladner-Fischer adder belongs to a type of tree (parallel-prefix) adders. 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): 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) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) 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()) 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). """Class representing signed Ladner-Fischer adder (using valency-2 logic gates).
The Ladner-Fischer adder belongs to a type of tree (parallel-prefix) adders. The Ladner-Fischer adder belongs to a type of tree (parallel-prefix) adders.

View File

@ -1,30 +1,21 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit, GeneralCircuit
MultiplierCircuit
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( from ariths_gen.one_bit_circuits.one_bit_components import (
HalfAdder,
FullAdder,
PGSumLogic PGSumLogic
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, AndGate,
NandGate,
OrGate, OrGate,
NorGate, XorGate
XorGate,
XnorGate,
NotGate
) )
class UnsignedPGRippleCarryAdder(ArithmeticCircuit): class UnsignedPGRippleCarryAdder(GeneralCircuit):
"""Class representing unsigned ripple carry adder with propagate/generate logic. """Class representing unsigned ripple carry adder with propagate/generate logic.
Unsigned ripple carry adder with PG logic represents slightly different rca implementation 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): def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_pg_rca", **kwargs):
self.N = max(a.N, b.N) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) 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) 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. """Class representing signed ripple carry adder with propagate/generate logic.
Signed ripple carry adder with PG logic represents slightly different rca implementation Signed ripple carry adder with PG logic represents slightly different rca implementation

View File

@ -1,29 +1,19 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0,
ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit, GeneralCircuit
MultiplierCircuit
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( from ariths_gen.one_bit_circuits.one_bit_components import (
HalfAdder, HalfAdder,
FullAdder FullAdder
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, XorGate
NandGate,
OrGate,
NorGate,
XorGate,
XnorGate,
NotGate
) )
class UnsignedRippleCarryAdder(ArithmeticCircuit): class UnsignedRippleCarryAdder(GeneralCircuit):
"""Class representing unsigned ripple carry adder. """Class representing unsigned ripple carry adder.
Unsigned ripple carry adder represents N-bit unsigned adder which is composed of 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): def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_rca", **kwargs):
self.N = max(a.N, b.N) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) 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()) self.out.connect(self.N, obj_adder.get_carry_wire())
class SignedRippleCarryAdder(UnsignedRippleCarryAdder, ArithmeticCircuit): class SignedRippleCarryAdder(UnsignedRippleCarryAdder, GeneralCircuit):
"""Class representing signed ripple carry adder. """Class representing signed ripple carry adder.
Signed ripple carry adder represents N-bit signed adder which is composed of Signed ripple carry adder represents N-bit signed adder which is composed of

View File

@ -1,40 +1,21 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit, GeneralCircuit
MultiplierCircuit
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( from ariths_gen.one_bit_circuits.one_bit_components import (
HalfAdder,
FullAdder,
PGSumLogic, PGSumLogic,
GreyCell, GreyCell,
BlackCell BlackCell
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, XorGate
NandGate,
OrGate,
NorGate,
XorGate,
XnorGate,
NotGate
)
from ariths_gen.multi_bit_circuits.adders import (
UnsignedCarryLookaheadAdder,
UnsignedPGRippleCarryAdder,
UnsignedRippleCarryAdder,
SignedCarryLookaheadAdder,
SignedPGRippleCarryAdder,
SignedRippleCarryAdder
) )
class UnsignedSklanskyAdder(ArithmeticCircuit): class UnsignedSklanskyAdder(GeneralCircuit):
"""Class representing unsigned Sklansky (or divide-and-conquer) adder (using valency-2 logic gates). """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. 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): def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_sa", **kwargs):
self.N = max(a.N, b.N) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)
@ -132,7 +113,7 @@ class UnsignedSklanskyAdder(ArithmeticCircuit):
prev_stage_int_value += 2**stage 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). """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. The Sklansky adder belongs to a type of tree (parallel-prefix) adders.

View File

@ -7,33 +7,20 @@ M. A. Hanif, R. Hafiz, O. Hasan and M. Shafique, "QuAd: Design and analysis of Q
""" """
from ...wire_components import ( from ...wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit, GeneralCircuit
MultiplierCircuit
) )
from ariths_gen.one_bit_circuits.one_bit_components import (
HalfAdder, from ariths_gen.multi_bit_circuits.adders.ripple_carry_adder import (
FullAdder 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 import warnings
class QuAdder(ArithmeticCircuit): class QuAdder(GeneralCircuit):
""" """
Implementation of QuAd Implementation of QuAd
@ -102,13 +89,13 @@ class QuAdder(ArithmeticCircuit):
self.use_log = use_log self.use_log = use_log
self.N = max(a.N, b.N) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)
self.b.bus_extend(N=self.N, prefix=b.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 # Connect all outputs to zero
for i in range(self.N+1): for i in range(self.N+1):
@ -128,7 +115,7 @@ class QuAdder(ArithmeticCircuit):
for i, j in zip(out_indexes, in_indexes): for i, j in zip(out_indexes, in_indexes):
if j >= in_bus.N: if j >= in_bus.N:
out_bus[i] = ConstantWireValue0() # unsigned extension out_bus[i] = ConstantWireValue0() # unsigned extension
else: else:
out_bus.connect(i, in_bus.get_wire(j)) # [i] = in_bus[j] out_bus.connect(i, in_bus.get_wire(j)) # [i] = in_bus[j]

View File

@ -1,11 +1,8 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit,
MultiplierCircuit MultiplierCircuit
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( 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 FullAdder
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, AndGate
NandGate,
OrGate,
NorGate,
XorGate,
XnorGate,
NotGate
)
from ariths_gen.multi_bit_circuits.multipliers import (
UnsignedArrayMultiplier,
SignedArrayMultiplier
) )
@ -107,7 +94,7 @@ class UnsignedBrokenArrayMultiplier(MultiplierCircuit):
# Vertical cut should be greater or equal to horizontal cut # Vertical cut should be greater or equal to horizontal cut
assert vertical_cut >= 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)

View File

@ -1,11 +1,8 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit,
MultiplierCircuit, MultiplierCircuit,
) )
from ariths_gen.core.logic_gate_circuits import ( from ariths_gen.core.logic_gate_circuits import (
@ -16,13 +13,7 @@ from ariths_gen.one_bit_circuits.one_bit_components import (
FullAdder FullAdder
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, AndGate
NandGate,
OrGate,
NorGate,
XorGate,
XnorGate,
NotGate
) )
from ariths_gen.multi_bit_circuits.adders import ( from ariths_gen.multi_bit_circuits.adders import (
UnsignedCarryLookaheadAdder UnsignedCarryLookaheadAdder
@ -114,7 +105,7 @@ class UnsignedBrokenCarrySaveMultiplier(MultiplierCircuit):
# Vertical cut should be greater or equal to horizontal cut # Vertical cut should be greater or equal to horizontal cut
assert vertical_cut >= 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) 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_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_a = Bus(prefix=f"a", wires_list=previous_sums)
adder_b = Bus(prefix=f"b", wires_list=previous_carries) 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) 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.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)] [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)]

View File

@ -11,17 +11,37 @@ from ariths_gen.one_bit_circuits.logic_gates import (
XorGate, XorGate,
NotGate NotGate
) )
from ariths_gen.multi_bit_circuits.adders import ( from ariths_gen.multi_bit_circuits.adders import (
UnsignedCarryLookaheadAdder UnsignedCarryLookaheadAdder
) )
import math import math
class UnsignedAccurateTwoBitMultiplier(MultiplierCircuit): class UnsignedAccurateTwoBitMultiplier(MultiplierCircuit):
"""Class representing unsigned two-bit accurate multiplier. """Class representing unsigned two-bit accurate multiplier.
```
A1B1 A1B0 A0B1 A0B0
AND AND AND AND
AND
AND XOR XOR
O3 O2 O1 O0
```
Description of the __init__ method. Description of the __init__ method.
Args: Args:
@ -33,7 +53,7 @@ class UnsignedAccurateTwoBitMultiplier(MultiplierCircuit):
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_2bit_accm", **kwargs): def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_2bit_accm", **kwargs):
self.N = max(a.N, b.N) self.N = max(a.N, b.N)
assert self.N == 2 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)
@ -77,6 +97,22 @@ class UnsignedApproximateTwoBitMultiplierM1(MultiplierCircuit):
M1 ax variant defined here: https://ieeexplore.ieee.org/document/8727537 M1 ax variant defined here: https://ieeexplore.ieee.org/document/8727537
```
A1B1 A1B0 A0B1 A0B0
AND AND AND AND
OR
O3=0 O2 O1 O0
```
Description of the __init__ method. Description of the __init__ method.
Args: Args:
@ -88,7 +124,7 @@ class UnsignedApproximateTwoBitMultiplierM1(MultiplierCircuit):
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_2bit_axm1", **kwargs): def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_2bit_axm1", **kwargs):
self.N = max(a.N, b.N) self.N = max(a.N, b.N)
assert self.N == 2 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)
@ -128,6 +164,29 @@ class UnsignedApproximateTwoBitMultiplierM2(MultiplierCircuit):
M2 ax variant defined here: https://ieeexplore.ieee.org/document/8727537 M2 ax variant defined here: https://ieeexplore.ieee.org/document/8727537
```
A1B1 A1B0 A0B1
AND AND AND
XOR AND
XOR
O3 O2 O1 O0
```
Description of the __init__ method. Description of the __init__ method.
Args: Args:
@ -139,7 +198,7 @@ class UnsignedApproximateTwoBitMultiplierM2(MultiplierCircuit):
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_2bit_axm1", **kwargs): def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_2bit_axm1", **kwargs):
self.N = max(a.N, b.N) self.N = max(a.N, b.N)
assert self.N == 2 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)
@ -181,6 +240,33 @@ class UnsignedApproximateTwoBitMultiplierM3(MultiplierCircuit):
M3 ax variant defined here: https://ieeexplore.ieee.org/document/8727537 M3 ax variant defined here: https://ieeexplore.ieee.org/document/8727537
```
A1B1 A1B0 A0B1 A0B0
AND AND AND AND
OR
NOT
AND AND
O3 O2 O1 O0
```
Description of the __init__ method. Description of the __init__ method.
Args: Args:
@ -192,7 +278,7 @@ class UnsignedApproximateTwoBitMultiplierM3(MultiplierCircuit):
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_2bit_axm3", **kwargs): def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_2bit_axm3", **kwargs):
self.N = max(a.N, b.N) self.N = max(a.N, b.N)
assert self.N == 2 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)
@ -236,6 +322,22 @@ class UnsignedApproximateTwoBitMultiplierM4(MultiplierCircuit):
M4 ax variant defined here: https://ieeexplore.ieee.org/document/8727537 M4 ax variant defined here: https://ieeexplore.ieee.org/document/8727537
```
A1B1 A1B0 A0B1 A0B0
AND AND AND AND
XOR
O3=0 O2 O1 O0
```
Description of the __init__ method. Description of the __init__ method.
Args: Args:
@ -247,7 +349,7 @@ class UnsignedApproximateTwoBitMultiplierM4(MultiplierCircuit):
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_2bit_axm4", **kwargs): def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_2bit_axm4", **kwargs):
self.N = max(a.N, b.N) self.N = max(a.N, b.N)
assert self.N == 2 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)
@ -285,7 +387,13 @@ class SignedApproximateTwoBitMultiplierM4(MultiplierCircuit):
class UnsignedRecursiveMultiplier(MultiplierCircuit): class UnsignedRecursiveMultiplier(MultiplierCircuit):
"""Class representing unsigned recursive multiplier. """Class representing unsigned recursive multiplier.
TODO 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. Description of the __init__ method.
Args: Args:
@ -300,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): 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) 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, ..) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)
@ -314,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) 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 # 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) 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) self.add_component(mult)
@ -357,7 +465,7 @@ class UnsignedRecursiveMultiplier(MultiplierCircuit):
# Create wire vectors holding partial products for final summation # 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 = 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)] [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) partial_products.append(pp)

View File

@ -1,11 +1,8 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit,
MultiplierCircuit MultiplierCircuit
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( 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 FullAdder
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, AndGate
NandGate,
OrGate,
NorGate,
XorGate,
XnorGate,
NotGate
) )
@ -87,7 +78,7 @@ class UnsignedTruncatedArrayMultiplier(MultiplierCircuit):
# Cut level should be: 0 <= truncation_cut < N # Cut level should be: 0 <= truncation_cut < N
assert truncation_cut < self.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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)

View File

@ -1,11 +1,8 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit,
MultiplierCircuit MultiplierCircuit
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( 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 ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, AndGate,
NandGate,
OrGate,
NorGate,
XorGate,
XnorGate,
NotGate
) )
from ariths_gen.multi_bit_circuits.adders import ( from ariths_gen.multi_bit_circuits.adders import (
UnsignedCarryLookaheadAdder UnsignedCarryLookaheadAdder
@ -101,7 +92,7 @@ class UnsignedTruncatedCarrySaveMultiplier(MultiplierCircuit):
# Cut level should be: 0 <= truncation_cut < N # Cut level should be: 0 <= truncation_cut < N
assert truncation_cut < self.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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)

View File

@ -1,31 +1,20 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit, GeneralCircuit
MultiplierCircuit
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( from ariths_gen.one_bit_circuits.one_bit_components import (
HalfAdder,
FullAdder,
TwoOneMultiplexer, TwoOneMultiplexer,
FullSubtractor FullSubtractor
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate,
NandGate,
OrGate,
NorGate,
XorGate,
XnorGate,
NotGate NotGate
) )
class ArrayDivider(ArithmeticCircuit): class ArrayDivider(GeneralCircuit):
"""Class representing array divider. """Class representing array divider.
Array divider performs division between two N bit numbers and stores their 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): def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "arrdiv", **kwargs):
self.N = max(a.N, b.N) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)

View File

@ -1,11 +1,9 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1, ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit,
MultiplierCircuit MultiplierCircuit
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( 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 ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, AndGate,
NandGate, NandGate,
OrGate,
NorGate, NorGate,
XorGate, XorGate
XnorGate,
NotGate
) )
@ -83,7 +78,7 @@ class UnsignedArrayMultiplier(MultiplierCircuit):
""" """
def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_arrmul", **kwargs): def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_arrmul", **kwargs):
self.N = max(a.N, b.N) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) 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): def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "s_arrmul", **kwargs):
self.N = max(a.N, b.N) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)

View File

@ -1,11 +1,9 @@
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1, ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit,
MultiplierCircuit MultiplierCircuit
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( 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 ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, AndGate,
NandGate, NandGate,
OrGate, NorGate
NorGate,
XorGate,
XnorGate,
NotGate
) )
from ariths_gen.multi_bit_circuits.adders import ( from ariths_gen.multi_bit_circuits.adders import (
UnsignedCarryLookaheadAdder 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): 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) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) 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): 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) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)

View File

@ -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 ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1, ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit,
MultiplierCircuit MultiplierCircuit
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( 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 FullAdder
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, XorGate
NandGate,
OrGate,
NorGate,
XorGate,
XnorGate,
NotGate
) )
@ -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): def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "u_dadda_cla", unsigned_adder_class_name: str = UnsignedCarryLookaheadAdder, **kwargs):
self.N = max(a.N, b.N) self.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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) 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): def __init__(self, a: Bus, b: Bus, prefix: str = "", name: str = "s_dadda_cla", unsigned_adder_class_name: str = UnsignedCarryLookaheadAdder, **kwargs):
self.N = max(a.N, b.N) self.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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)

View File

@ -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 ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1, ConstantWireValue1,
Bus Bus
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit,
MultiplierCircuit MultiplierCircuit
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( 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 FullAdder
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, XorGate
NandGate,
OrGate,
NorGate,
XorGate,
XnorGate,
NotGate
) )
from ariths_gen.multi_bit_circuits.adders import ( from ariths_gen.multi_bit_circuits.adders import (
CarrySaveAdderComponent, 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): 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) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) 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): 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) 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 # Bus sign extension in case buses have different lengths
self.a.bus_extend(N=self.N, prefix=a.prefix) self.a.bus_extend(N=self.N, prefix=a.prefix)

View File

@ -4,11 +4,18 @@ from ariths_gen.multi_bit_circuits.others.popcount import (
) )
from ariths_gen.multi_bit_circuits.others.bit_reduce import ( from ariths_gen.multi_bit_circuits.others.bit_reduce import (
BitReduce, AndReduce, OrReduce BitReduce,
AndReduce,
OrReduce
) )
from ariths_gen.multi_bit_circuits.others.compare import ( from ariths_gen.multi_bit_circuits.others.compare import (
UnsignedCompareLT, UnsignedCompareLTE, UnsignedCompareGT, UnsignedCompareGTE UnsignedCompareLT,
UnsignedCompareLTE,
UnsignedCompareGT,
UnsignedCompareGTE
) )
from ariths_gen.multi_bit_circuits.others.popcount_compare import PopCountCompare from ariths_gen.multi_bit_circuits.others.popcount_compare import (
PopCountCompare
)

View File

@ -1,53 +1,25 @@
"""
"""
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire, Bus
ConstantWireValue0,
ConstantWireValue1,
Bus,
wires
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit, GeneralCircuit
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
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, AndGate,
NandGate, OrGate
OrGate, )
NorGate, from ariths_gen.core.logic_gate_circuits import (
XorGate, TwoInputLogicGate
XnorGate,
NotGate
) )
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 BitReduce(GeneralCircuit):
"""Class representing tree reducer circuit. Doent work for NAND gate! """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.N = a.N
self.a = a super().__init__(name=name, prefix=prefix, inputs=[a], out_N=1, **kwargs)
outc = 1
super().__init__(name=name, prefix=prefix, inputs = [self.a], out_N=outc)
# tree reduction # tree reduction
def create_tree(a: Bus, depth: int, branch="A"): def create_tree(a: Bus, depth: int, branch="A"):
@ -80,10 +52,10 @@ class BitReduce(GeneralCircuit):
class OrReduce(BitReduce): class OrReduce(BitReduce):
def __init__(self, a: Bus, prefix : str = "", name : str = "orreduce", **kwargs): def __init__(self, a: Bus, prefix: str = "", name: str = "orreduce", **kwargs):
super().__init__(a=a, gate=OrGate, prefix=prefix, name=name, **kwargs) super().__init__(a=a, gate=OrGate, prefix=prefix, name=name, **kwargs)
class AndReduce(BitReduce): class AndReduce(BitReduce):
def __init__(self, a: Bus, prefix : str = "", name : str = "orreduce", **kwargs): def __init__(self, a: Bus, prefix: str = "", name: str = "andreduce", **kwargs):
super().__init__(a=a, gate=AndGate, prefix=prefix, name=name, **kwargs) super().__init__(a=a, gate=AndGate, prefix=prefix, name=name, **kwargs)

View File

@ -1,43 +1,20 @@
"""
"""
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire,
ConstantWireValue0, ConstantWireValue0,
ConstantWireValue1, ConstantWireValue1,
Bus, Bus
wires
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit, GeneralCircuit
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
) )
from ariths_gen.one_bit_circuits.logic_gates import ( from ariths_gen.one_bit_circuits.logic_gates import (
AndGate, AndGate,
NandGate,
OrGate,
NorGate,
XorGate,
XnorGate, XnorGate,
NotGate 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 UnsignedCompareLT(GeneralCircuit):
"""Class representing unsigned compare """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): 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) self.N = max(a.N, b.N)
super().__init__(name=name, prefix=prefix, inputs=[a, b], out_N=1)
super().__init__(name=name, prefix=prefix,
inputs = [self.a, self.b], out_N=1)
# create wires # create wires
psum = ConstantWireValue1() psum = ConstantWireValue1()
@ -83,13 +56,9 @@ class UnsignedCompareLTE(GeneralCircuit):
Returns true if a <= b Returns true if a <= b
""" """
def __init__(self, a: Bus, b: Bus, prefix : str = "", name : str = "cmp_lt", **kwargs): 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) self.N = max(a.N, b.N)
super().__init__(name=name, prefix=prefix, inputs=[a, b], out_N=1)
super().__init__(name=name, prefix=prefix,
inputs = [self.a, self.b], out_N=1)
# create wires # create wires
psum = ConstantWireValue1() psum = ConstantWireValue1()
@ -125,12 +94,8 @@ class UnsignedCompareGT(GeneralCircuit):
""" """
def __init__(self, a: Bus, b: Bus, prefix : str = "", name : str = "cmp_gt", **kwargs): 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) self.N = max(a.N, b.N)
super().__init__(name=name, prefix=prefix, inputs=[a, b], out_N=1)
super().__init__(name=name, prefix=prefix,
inputs = [self.a, self.b], out_N=1)
# create wires # create wires
psum = ConstantWireValue1() psum = ConstantWireValue1()
@ -162,12 +127,8 @@ class UnsignedCompareGTE(GeneralCircuit):
""" """
def __init__(self, a: Bus, b: Bus, prefix : str = "", name : str = "cmp_gte", **kwargs): 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) self.N = max(a.N, b.N)
super().__init__(name=name, prefix=prefix, inputs=[a, b], out_N=1)
super().__init__(name=name, prefix=prefix,
inputs = [self.a, self.b], out_N=1)
# create wires # create wires
psum = ConstantWireValue1() psum = ConstantWireValue1()

View File

@ -1,43 +1,17 @@
"""
"""
from typing import Union, Optional
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire, Bus
ConstantWireValue0,
ConstantWireValue1,
Bus,
wires
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit,
GeneralCircuit, GeneralCircuit,
MultiplierCircuit GeneralCircuit
) )
from ariths_gen.core.logic_gate_circuits import ( from ariths_gen.multi_bit_circuits.adders import (
MultipleInputLogicGate UnsignedRippleCarryAdder
) )
from ariths_gen.one_bit_circuits.one_bit_components import ( from typing import Optional
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 math import log2, ceil from math import log2, ceil
class UnsignedPopCount(GeneralCircuit): class UnsignedPopCount(GeneralCircuit):
"""Class representing unsigned popcount circuit. """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.N = a.N
self.a = a
outc = ceil(log2(self.N + 1)) outc = ceil(log2(self.N + 1))
#print("outc", outc) #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) self.a.bus_extend(2**(outc - 1), prefix=a.prefix)
#print(self.a) #print(self.a)
@ -62,7 +33,6 @@ class UnsignedPopCount(GeneralCircuit):
# tree reduction # tree reduction
def create_tree(a: Bus, depth: int, branch="A"): def create_tree(a: Bus, depth: int, branch="A"):
#print(a) #print(a)
if a.N == 1: if a.N == 1:
return a return a
@ -71,13 +41,10 @@ class UnsignedPopCount(GeneralCircuit):
b_in = Bus(N=half, prefix=f"b_inn{branch}_{depth}A") b_in = Bus(N=half, prefix=f"b_inn{branch}_{depth}A")
c_in = Bus(N=a.N - half, prefix=f"c_inn{branch}_{depth}B") c_in = Bus(N=a.N - half, prefix=f"c_inn{branch}_{depth}B")
#print(a, half, a.N) #print(a, half, a.N)
for i, j in enumerate(range(half)): for i, j in enumerate(range(half)):
b_in[i] = a[j] b_in.connect(i, a.get_wire(j))
for i, j in enumerate(range(half, a.N)): for i, j in enumerate(range(half, a.N)):
c_in[i] = a[j] c_in.connect(i, a.get_wire(j))
b = create_tree(b_in, depth=depth + 1, branch = branch + "A") 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")
@ -89,4 +56,4 @@ class UnsignedPopCount(GeneralCircuit):
sumbus = create_tree(self.a,0, "X") sumbus = create_tree(self.a,0, "X")
#print(sumbus) #print(sumbus)
self.out.connect_bus(sumbus ) self.out.connect_bus(sumbus)

View File

@ -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 ( from ariths_gen.wire_components import (
Wire, Bus
ConstantWireValue0,
ConstantWireValue1,
Bus,
wires
) )
from ariths_gen.core.arithmetic_circuits import ( from ariths_gen.core.arithmetic_circuits import (
ArithmeticCircuit, GeneralCircuit
GeneralCircuit,
MultiplierCircuit
) )
from ariths_gen.core.logic_gate_circuits import ( from ariths_gen.multi_bit_circuits.others import (
MultipleInputLogicGate UnsignedPopCount,
) UnsignedCompareGTE
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 OrReduce
from math import log2, ceil
class PopCountCompare(GeneralCircuit): class PopCountCompare(GeneralCircuit):
"""Class representing a circiut """Class representing a circiut
@ -59,23 +29,17 @@ class PopCountCompare(GeneralCircuit):
""" """
def __init__(self, a: Bus, b: Bus, prefix : str = "", name : str = "cmp_lt", **kwargs): def __init__(self, a: Bus, b: Bus, prefix : str = "", name : str = "popcnt_cmp", **kwargs):
self.a = a super().__init__(name=name, prefix=prefix, inputs=[a, b], out_N=1, **kwargs)
self.b = b
super().__init__(name=name, prefix=prefix, p1 = self.add_component(UnsignedPopCount(a=Bus(wires_list=self.a.bus, prefix=f"{prefix}_popcount1_a"),
inputs = [self.a, self.b], out_N=1)
p1 = self.add_component(UnsignedPopCount(self.a,
prefix=f"{prefix}_popcount1", prefix=f"{prefix}_popcount1",
inner_component=True)).out 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", prefix=f"{prefix}_popcount2",
inner_component=True)).out inner_component=True)).out
#N = max(p1.N, p2.N) #N = max(p1.N, p2.N)
#p1.bus_extend(N) #p1.bus_extend(N)
#p2.bus_extend(N) #p2.bus_extend(N)
red = self.add_component(UnsignedCompareGTE(p1, p2, prefix=f"{prefix}_cmp", inner_component = True)) red = self.add_component(UnsignedCompareGTE(p1, p2, prefix=f"{prefix}_cmp", inner_component = True))
self.out.connect_bus(red.out) self.out.connect_bus(red.out)

View File

@ -24,10 +24,11 @@ class BlackCell(FourInputOneBitCircuit):
b (Wire, optional): Second input wire, represents propagate signal from the current stage. Defaults to Wire(name="p1"). b (Wire, optional): Second input wire, represents propagate signal from the current stage. Defaults to Wire(name="p1").
c (Wire, optional): Third input wire, represents generate signal from a preceding stage. Defaults to Wire(name="g0"). c (Wire, optional): Third input wire, represents generate signal from a preceding stage. Defaults to Wire(name="g0").
d (Wire, optional): Fourth input wire, represents propagate signal from a preceding stage. Defaults to Wire(name="p0"). d (Wire, optional): Fourth input wire, represents propagate signal from a preceding stage. Defaults to Wire(name="p0").
prefix (str, optional): Prefix name of grey cell. Defaults to "gc". prefix (str, optional): Prefix name of grey cell. Defaults to "".
name (str, optional): Name of grey cell. Defaults to "gc".
""" """
def __init__(self, a: Wire = Wire(name="g1"), b: Wire = Wire(name="p1"), c: Wire = Wire(name="g0"), d: Wire = Wire(name="p0"), prefix: str = "bc"): def __init__(self, a: Wire = Wire(name="g1"), b: Wire = Wire(name="p1"), c: Wire = Wire(name="g0"), d: Wire = Wire(name="p0"), prefix: str = "", name: str = "bc"):
super().__init__(a, b, c, d, prefix) super().__init__(a, b, c, d, prefix=prefix, name=name)
# 2 wires for component's bus output (generate, propagate) # 2 wires for component's bus output (generate, propagate)
self.out = Bus(self.prefix+"_out", 2) self.out = Bus(self.prefix+"_out", 2)

View File

@ -21,12 +21,13 @@ class FullAdder(ThreeInputOneBitCircuit):
a (Wire, optional): First input wire. Defaults to Wire(name="a"). a (Wire, optional): First input wire. Defaults to Wire(name="a").
b (Wire, optional): Second input wire. Defaults to Wire(name="b"). b (Wire, optional): Second input wire. Defaults to Wire(name="b").
c (Wire, optional): Carry input wire. Defaults to Wire(name="cin"). c (Wire, optional): Carry input wire. Defaults to Wire(name="cin").
prefix (str, optional): Prefix name of full adder. Defaults to "fa". prefix (str, optional): Prefix name of full adder. Defaults to "".
name (str, optional): Name of full adder. Defaults to "fa".
""" """
use_verilog_instance = False use_verilog_instance = False
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "fa"): def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "", name: str = "fa"):
super().__init__(a, b, c, prefix) super().__init__(a, b, c, prefix=prefix, name=name)
# 2 wires for component's bus output (sum, cout) # 2 wires for component's bus output (sum, cout)
self.out = Bus(self.prefix+"_out", 2) self.out = Bus(self.prefix+"_out", 2)
@ -129,10 +130,11 @@ class FullAdderP(FullAdder, ThreeInputOneBitCircuit):
a (Wire, optional): First input wire. Defaults to Wire(name="a"). a (Wire, optional): First input wire. Defaults to Wire(name="a").
b (Wire, optional): Second input wire. Defaults to Wire(name="b"). b (Wire, optional): Second input wire. Defaults to Wire(name="b").
c (Wire, optional): Carry input wire. Defaults to Wire(name="cin"). c (Wire, optional): Carry input wire. Defaults to Wire(name="cin").
prefix (str, optional): Prefix name of full adder with p logic. Defaults to "fa_p". prefix (str, optional): Prefix name of full adder with p logic. Defaults to "".
name (str, optional): Name of full adder with p logic. Defaults to "fa_p".
""" """
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "fa_p"): def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "", name: str = "fa_p"):
super().__init__(a, b, c, prefix) super().__init__(a, b, c, prefix=prefix, name=name)
# 3 wires for component's bus output (sum, cout, propagate) # 3 wires for component's bus output (sum, cout, propagate)
self.out.bus_extend(3) self.out.bus_extend(3)
self.out.connect(2, self.get_previous_component(5).out) self.out.connect(2, self.get_previous_component(5).out)
@ -164,10 +166,11 @@ class FullAdderPG(FullAdder, ThreeInputOneBitCircuit):
a (Wire, optional): First input wire. Defaults to Wire(name="a"). a (Wire, optional): First input wire. Defaults to Wire(name="a").
b (Wire, optional): Second input wire. Defaults to Wire(name="b"). b (Wire, optional): Second input wire. Defaults to Wire(name="b").
c (Wire, optional): Carry input wire. Defaults to Wire(name="cin"). c (Wire, optional): Carry input wire. Defaults to Wire(name="cin").
prefix (str, optional): Prefix name of full adder with pg logic. Defaults to "fa_pg". prefix (str, optional): Prefix name of full adder with pg logic. Defaults to "".
name (str, optional): Name of full adder with pg logic. Defaults to "fa_pg".
""" """
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "fa_pg"): def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "", name: str = "fa_pg"):
super().__init__(a, b, c, prefix) super().__init__(a, b, c, prefix=prefix, name=name)
# 4 wires for component's bus output (sum, cout, propagate, generate) # 4 wires for component's bus output (sum, cout, propagate, generate)
self.out.bus_extend(4) self.out.bus_extend(4)
self.out.connect(2, self.get_previous_component(5).out) self.out.connect(2, self.get_previous_component(5).out)
@ -207,10 +210,11 @@ class PGSumLogic(ThreeInputOneBitCircuit):
a (Wire, optional): First input wire. Defaults to Wire(name="a"). a (Wire, optional): First input wire. Defaults to Wire(name="a").
b (Wire, optional): Second input wire. Defaults to Wire(name="b"). b (Wire, optional): Second input wire. Defaults to Wire(name="b").
c (Wire, optional): Carry input wire. Defaults to Wire(name="cin"). c (Wire, optional): Carry input wire. Defaults to Wire(name="cin").
prefix (str, optional): Prefix name of pg sum logic. Defaults to "pg_sum". prefix (str, optional): Prefix name of pg sum logic. Defaults to "".
name (str, optional): Name of pg sum logic. Defaults to "pg_sum".
""" """
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "pg_sum"): def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "", name: str = "pg_sum"):
super().__init__(a, b, c, prefix) super().__init__(a, b, c, prefix=prefix, name=name)
# 3 wires for component's bus output (sum, propagate, generate) # 3 wires for component's bus output (sum, propagate, generate)
self.out = Bus(self.prefix+"_out", 3) self.out = Bus(self.prefix+"_out", 3)
@ -271,12 +275,13 @@ class TwoOneMultiplexer(ThreeInputOneBitCircuit):
a (Wire, optional): First input wire. Defaults to Wire(name="d0"). a (Wire, optional): First input wire. Defaults to Wire(name="d0").
b (Wire, optional): Second input wire. Defaults to Wire(name="d1"). b (Wire, optional): Second input wire. Defaults to Wire(name="d1").
c (Wire, optional): Select signal. Defaults to Wire(name="sel"). c (Wire, optional): Select signal. Defaults to Wire(name="sel").
prefix (str, optional): Prefix name of two to one multiplexer. Defaults to "mux2to1". prefix (str, optional): Prefix name of two to one multiplexer. Defaults to "".
name (str, optional): Name of two to one multiplexer. Defaults to "mux2to1".
""" """
use_verilog_instance = False use_verilog_instance = False
def __init__(self, a: Wire = Wire(name="d0"), b: Wire = Wire(name="d1"), c: Wire = Wire(name="sel"), prefix: str = "mux2to1"): def __init__(self, a: Wire = Wire(name="d0"), b: Wire = Wire(name="d1"), c: Wire = Wire(name="sel"), prefix: str = "", name: str = "mux2to1"):
super().__init__(a, b, c, prefix) super().__init__(a, b, c, prefix=prefix, name=name)
# Represents select signal (self.c naming for proper unified generation) # Represents select signal (self.c naming for proper unified generation)
self.c = c self.c = c
# 1 wire for component's output bus # 1 wire for component's output bus
@ -371,10 +376,11 @@ class FullSubtractor(ThreeInputOneBitCircuit):
a (Wire, optional): First input wire. Defaults to Wire(name="a"). a (Wire, optional): First input wire. Defaults to Wire(name="a").
b (Wire, optional): Second input wire. Defaults to Wire(name="b"). b (Wire, optional): Second input wire. Defaults to Wire(name="b").
c (Wire, optional): Input borrow wire. Defaults to Wire(name="bin"). c (Wire, optional): Input borrow wire. Defaults to Wire(name="bin").
prefix (str, optional): Prefix name of full subtractor. Defaults to "fs". prefix (str, optional): Prefix name of full subtractor. Defaults to "".
name (str, optional): Name of full subtractor. Defaults to "fs".
""" """
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="bin"), prefix: str = "fs"): def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="bin"), prefix: str = "", name: str = "fs"):
super().__init__(a, b, c, prefix) super().__init__(a, b, c, prefix=prefix, name=name)
# 2 wires for component's bus output (difference, bout) # 2 wires for component's bus output (difference, bout)
self.out = Bus(self.prefix+"_out", 2) self.out = Bus(self.prefix+"_out", 2)
@ -438,10 +444,11 @@ class GreyCell(ThreeInputOneBitCircuit):
a (Wire, optional): First input wire, represents generate signal from the current stage. Defaults to Wire(name="g1"). a (Wire, optional): First input wire, represents generate signal from the current stage. Defaults to Wire(name="g1").
b (Wire, optional): Second input wire, represents propagate signal from the current stage. Defaults to Wire(name="p1"). b (Wire, optional): Second input wire, represents propagate signal from the current stage. Defaults to Wire(name="p1").
c (Wire, optional): Third input wire, represents generate signal from a preceding stage. Defaults to Wire(name="g0"). c (Wire, optional): Third input wire, represents generate signal from a preceding stage. Defaults to Wire(name="g0").
prefix (str, optional): Prefix name of grey cell. Defaults to "gc". prefix (str, optional): Prefix name of grey cell. Defaults to "".
name (str, optional): Name of grey cell. Defaults to "gc".
""" """
def __init__(self, a: Wire = Wire(name="g1"), b: Wire = Wire(name="p1"), c: Wire = Wire(name="g0"), prefix: str = "gc"): def __init__(self, a: Wire = Wire(name="g1"), b: Wire = Wire(name="p1"), c: Wire = Wire(name="g0"), prefix: str = "", name: str = "gc"):
super().__init__(a, b, c, prefix) super().__init__(a, b, c, prefix=prefix, name=name)
# 1 wire for component's bus output (output generate) # 1 wire for component's bus output (output generate)
self.out = Bus(self.prefix+"_out", 1) self.out = Bus(self.prefix+"_out", 1)

View File

@ -19,12 +19,13 @@ class HalfAdder(TwoInputOneBitCircuit):
Args: Args:
a (Wire, optional): First input wire. Defaults to Wire(name="a"). a (Wire, optional): First input wire. Defaults to Wire(name="a").
b (Wire, optional): Second input wire. Defaults to Wire(name="b"). b (Wire, optional): Second input wire. Defaults to Wire(name="b").
prefix (str, optional): Prefix name of half adder. Defaults to "ha". prefix (str, optional): Prefix name of half adder. Defaults to "".
name (str, optional): Name of half adder. Defaults to "ha".
""" """
use_verilog_instance = False use_verilog_instance = False
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "ha"): def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "", name: str = "ha"):
super().__init__(a, b, prefix) super().__init__(a, b, prefix=prefix, name=name)
# 2 wires for component's bus output (sum, cout) # 2 wires for component's bus output (sum, cout)
self.out = Bus(self.prefix+"_out", 2) self.out = Bus(self.prefix+"_out", 2)
@ -114,10 +115,11 @@ class PGLogicBlock(TwoInputOneBitCircuit):
Args: Args:
a (Wire, optional): First input wire. Defaults to Wire(name="a"). a (Wire, optional): First input wire. Defaults to Wire(name="a").
b (Wire, optional): Second input wire. Defaults to Wire(name="b"). b (Wire, optional): Second input wire. Defaults to Wire(name="b").
prefix (str, optional): Prefix name of pg logic block. Defaults to "pg_logic". prefix (str, optional): Prefix name of pg logic block. Defaults to "".
name (str, optional): Name of pg logic block. Defaults to "pg_logic".
""" """
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "pg_logic"): def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "", name: str = "pg_logic"):
super().__init__(a, b, prefix) super().__init__(a, b, prefix=prefix, name=name)
# 3 wires for component's bus output (propagate, generate, sum) # 3 wires for component's bus output (propagate, generate, sum)
self.out = Bus(self.prefix+"_out", 3) self.out = Bus(self.prefix+"_out", 3)
@ -174,10 +176,11 @@ class HalfSubtractor(TwoInputOneBitCircuit):
Args: Args:
a (Wire, optional): First input wire. Defaults to Wire(name="a"). a (Wire, optional): First input wire. Defaults to Wire(name="a").
b (Wire, optional): Second input wire. Defaults to Wire(name="b"). b (Wire, optional): Second input wire. Defaults to Wire(name="b").
prefix (str, optional): Prefix name of half subtractor adder. Defaults to "hs". prefix (str, optional): Prefix name of half subtractor adder. Defaults to "".
name (str, optional): Name of half subtractor adder. Defaults to "hs".
""" """
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "hs"): def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "", name: str = "hs"):
super().__init__(a, b, prefix) super().__init__(a, b, prefix=prefix, name=name)
# 2 wires for component's bus output (difference, bout) # 2 wires for component's bus output (difference, bout)
self.out = Bus(self.prefix+"_out", 2) self.out = Bus(self.prefix+"_out", 2)

View File

@ -18,7 +18,7 @@ class Bus():
if wires_list is None: if wires_list is None:
self.prefix = prefix self.prefix = prefix
# Adding wires into current bus's wires list (wire names are concatenated from bus prefix and their index position inside the bus in square brackets) # Adding wires into current bus's wires list (wire names are concatenated from bus prefix and their index position inside the bus in square brackets)
self.bus = [Wire(name=prefix+f"[{i}]", prefix=prefix, index=i, parent_bus=self) for i in range(N)] self.bus = [Wire(name=prefix+f"[{i}]" if N != 1 else prefix, prefix=prefix, index=i, parent_bus=self) for i in range(N)]
self.N = N self.N = N
else: else:
self.prefix = prefix self.prefix = prefix
@ -179,7 +179,7 @@ class Bus():
""" """
# Ensures correct binding between the bus wire index and the wire itself # Ensures correct binding between the bus wire index and the wire itself
# It is used for the case when multiple of the same wire (e.g. `ContantWireValue0()`) are present in the bus (its id would otherwise be incorrect when using `self.bus.index(_)`) # It is used for the case when multiple of the same wire (e.g. `ContantWireValue0()`) are present in the bus (its id would otherwise be incorrect when using `self.bus.index(_)`)
mapped_positions = [(w_id, self.bus[w_id]) for w_id in range(self.N)] mapped_positions = [(w_id, w) for w_id, w in enumerate(self.bus) if ((w.parent_bus is None) or (w.parent_bus is not None and w.prefix != self.prefix) or (w.is_const()))]
return "".join([f" {self.prefix} |= {w[1].return_wire_value_c_hier(offset=w[0])}" for w in mapped_positions]) return "".join([f" {self.prefix} |= {w[1].return_wire_value_c_hier(offset=w[0])}" for w in mapped_positions])
def return_bus_wires_sign_extend_c_flat(self): def return_bus_wires_sign_extend_c_flat(self):
@ -226,7 +226,7 @@ class Bus():
""" """
# Ensures correct binding between the bus wire index and the wire itself # Ensures correct binding between the bus wire index and the wire itself
# It is used for the case when multiple of the same wire (e.g. `ContantWireValue0()`) are present in the bus (its id would otherwise be incorrect when using `self.bus.index(_)`) # It is used for the case when multiple of the same wire (e.g. `ContantWireValue0()`) are present in the bus (its id would otherwise be incorrect when using `self.bus.index(_)`)
mapped_positions = [(w_id, self.bus[w_id]) for w_id in range(self.N)] mapped_positions = [(w_id, w) for w_id, w in enumerate(self.bus) if ((w.parent_bus is None) or (w.parent_bus is not None and w.prefix != self.prefix) or (w.is_const()))]
return "".join([f" assign {self.prefix}[{w[0]}] = {w[1].return_wire_value_v_hier()}" for w in mapped_positions]) return "".join([f" assign {self.prefix}[{w[0]}] = {w[1].return_wire_value_v_hier()}" for w in mapped_positions])
def get_unique_assign_out_wires_v(self, circuit_block: object): def get_unique_assign_out_wires_v(self, circuit_block: object):
@ -250,20 +250,17 @@ class Bus():
""" """
return f" wire [{self.N-1}:0] {self.prefix};\n" return f" wire [{self.N-1}:0] {self.prefix};\n"
""" BLIF CODE GENERATION """ """ BLIF CODE GENERATION """
def get_wire_declaration_blif(self, array: bool = True): def get_wire_declaration_blif(self):
"""Declare each wire from the bus independently in Blif code representation. """Declare each wire from the bus independently in Blif code representation.
Args:
array (bool, optional): Specifies whether to declare wires from bus by their offset e.g. out[0] or by their wire name e.g. out_0. Defaults to True.
Returns: Returns:
str: Blif code for declaration of individual bus wires. str: Blif code for declaration of individual bus wires.
""" """
# Ensures correct binding between the bus wire index and the wire itself # Ensures correct binding between the bus wire index and the wire itself
# It is used for the case when multiple of the same wire (e.g. `ContantWireValue0()`) are present in the bus (its id would otherwise be incorrect when using `self.bus.index(_)`) # It is used for the case when multiple of the same wire (e.g. `ContantWireValue0()`) are present in the bus (its id would otherwise be incorrect when using `self.bus.index(_)`)
mapped_positions = [(w_id, self.bus[w_id]) for w_id in range(self.N)] mapped_positions = [(w_id, self.bus[w_id]) for w_id in range(self.N)]
array = True if self.N > 1 else False
return "".join([f" {w[1].get_declaration_blif(prefix=self.prefix, offset=w[0], array=array)}" for w in mapped_positions]) return "".join([f" {w[1].get_declaration_blif(prefix=self.prefix, offset=w[0], array=array)}" for w in mapped_positions])
def get_wire_assign_blif(self, output: bool = False): def get_wire_assign_blif(self, output: bool = False):
@ -278,7 +275,10 @@ class Bus():
# Ensures correct binding between the bus wire index and the wire itself # Ensures correct binding between the bus wire index and the wire itself
# It is used for the case when multiple of the same wire (e.g. `ContantWireValue0()`) are present in the bus (its id would otherwise be incorrect when using `self.bus.index(_)`) # It is used for the case when multiple of the same wire (e.g. `ContantWireValue0()`) are present in the bus (its id would otherwise be incorrect when using `self.bus.index(_)`)
mapped_positions = [(w_id, self.bus[w_id]) for w_id in range(self.N)] mapped_positions = [(w_id, self.bus[w_id]) for w_id in range(self.N)]
return "".join([w[1].get_assign_blif(prefix=self.prefix+f"[{w[0]}]", output=output) for w in mapped_positions]) if self.N > 1:
return "".join([w[1].get_assign_blif(prefix=self.prefix+f"[{w[0]}]", output=output) for w in mapped_positions])
else:
return "".join([w[1].get_assign_blif(prefix=self.prefix, output=output) for w in mapped_positions])
def get_unique_assign_out_wires_blif(self, function_block_out_bus: object): def get_unique_assign_out_wires_blif(self, function_block_out_bus: object):
"""Assigns unique output wires to their respective outputs of subcomponent's function block modul in hierarchical Blif subcomponent's invocation. """Assigns unique output wires to their respective outputs of subcomponent's function block modul in hierarchical Blif subcomponent's invocation.

View File

@ -74,7 +74,7 @@ class Wire():
return f"({self.c_const})" 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) # 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') # 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)" return f"(({self.prefix} >> {self.index}) & 0x01)"
else: else:
return f"(({self.name} >> 0) & 0x01)" return f"(({self.name} >> 0) & 0x01)"
@ -189,7 +189,7 @@ class Wire():
""" BLIF CODE GENERATION """ """ BLIF CODE GENERATION """
def get_declaration_blif(self, prefix: str = "", offset: int = 0, array: bool = False): def get_declaration_blif(self, prefix: str = "", offset: int = 0, array: bool = False):
"""Wire declaration in Blif code. """Declaration of wire which is part of a bus in Blif code.
Declares basic wire name if wire is not part of a bus Declares basic wire name if wire is not part of a bus
or declares wire by an offset of its position within the bus. or declares wire by an offset of its position within the bus.
@ -205,7 +205,17 @@ class Wire():
if array is True: if array is True:
return f"{prefix}[{offset}]" return f"{prefix}[{offset}]"
else: else:
return f"{self.name}" return f"{prefix}"
def get_wire_declaration_blif(self):
"""Declaration of a single wire in Blif code.
Used for declaration of modul inputs.
Returns:
str: Blif code for declaration of a wire.
"""
return f"{self.prefix} "
def get_assign_blif(self, prefix: str, output: bool = False): def get_assign_blif(self, prefix: str, output: bool = False):
"""Assignment of wire value to another desired wire in Blif code. """Assignment of wire value to another desired wire in Blif code.
@ -245,10 +255,8 @@ class Wire():
""" """
if self.is_const(): if self.is_const():
return self.blif_const return self.blif_const
elif self.parent_bus is not None and self.parent_bus.N > 1:
return self.name
else: else:
return self.prefix return self.name
def __str__(self): def __str__(self):
if self.is_const(): if self.is_const():

View File

@ -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.core.arithmetic_circuits import GeneralCircuit
from ariths_gen.wire_components import Bus, Wire from ariths_gen.wire_components import Bus, Wire
from ariths_gen.multi_bit_circuits.adders import UnsignedRippleCarryAdder 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 import os
@ -13,8 +12,8 @@ class MAC(GeneralCircuit):
assert a.N == b.N assert a.N == b.N
assert r.N == 2 * a.N assert r.N == 2 * a.N
self.mul = self.add_component(UnsignedArrayMultiplier(a=a, b=b, prefix=self.prefix, name=f"u_arrmul{a.N}", inner_component=True)) self.mul = self.add_component(UnsignedArrayMultiplier(a=Bus(wires_list=a.bus, prefix=a.prefix), b=Bus(wires_list=b.bus, prefix=b.prefix), prefix=self.prefix, name=f"u_arrmul{a.N}", inner_component=True))
self.add = self.add_component(UnsignedRippleCarryAdder(a=r, b=self.mul.out, prefix=self.prefix, name=f"u_rca{r.N}", inner_component=True)) self.add = self.add_component(UnsignedRippleCarryAdder(a=Bus(wires_list=r.bus, prefix=r.prefix), b=self.mul.out, prefix=self.prefix, name=f"u_rca{r.N}", inner_component=True))
self.out.connect_bus(connecting_bus=self.add.out) self.out.connect_bus(connecting_bus=self.add.out)

View File

@ -319,8 +319,8 @@ def test_mac():
assert a.N == b.N assert a.N == b.N
assert r.N == 2 * a.N assert r.N == 2 * a.N
self.mul = self.add_component(UnsignedArrayMultiplier(a=a, b=b, prefix=self.prefix, name=f"u_arrmul{a.N}", inner_component=True)) self.mul = self.add_component(UnsignedArrayMultiplier(a=Bus(wires_list=a.bus, prefix=a.prefix), b=Bus(wires_list=b.bus, prefix=b.prefix), prefix=self.prefix, name=f"u_arrmul{a.N}", inner_component=True))
self.add = self.add_component(UnsignedRippleCarryAdder(a=r, b=self.mul.out, prefix=self.prefix, name=f"u_rca{r.N}", inner_component=True)) self.add = self.add_component(UnsignedRippleCarryAdder(a=Bus(wires_list=r.bus, prefix=r.prefix), b=self.mul.out, prefix=self.prefix, name=f"u_rca{r.N}", inner_component=True))
self.out.connect_bus(connecting_bus=self.add.out) self.out.connect_bus(connecting_bus=self.add.out)
# usage # usage

View File

@ -8,13 +8,8 @@ DIR_PATH = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.join(DIR_PATH, '..')) sys.path.insert(0, os.path.join(DIR_PATH, '..'))
import numpy as np import numpy as np
import itertools import itertools
from ariths_gen.wire_components import Bus
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.approximate_adders import QuAdder from ariths_gen.multi_bit_circuits.approximate_adders import QuAdder
from ariths_gen.multi_bit_circuits.multipliers import UnsignedArrayMultiplier, UnsignedDaddaMultiplier
def test_quadder(): def test_quadder():

View File

@ -1,3 +1,9 @@
import os
import sys
# Add the parent directory to the system path
DIR_PATH = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.join(DIR_PATH, '..'))
from io import StringIO from io import StringIO
from ariths_gen.core.cgp_circuit import UnsignedCGPCircuit from ariths_gen.core.cgp_circuit import UnsignedCGPCircuit
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (

View File

@ -1,3 +1,9 @@
import os
import sys
# Add the parent directory to the system path
DIR_PATH = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.join(DIR_PATH, '..'))
from ariths_gen.wire_components import ( from ariths_gen.wire_components import (
Wire, Wire,
ConstantWireValue0, ConstantWireValue0,