popcount and compare
This commit is contained in:
parent
7e1112cf81
commit
2e1694ccd5
@ -1,3 +1,4 @@
|
|||||||
|
from typing import Dict
|
||||||
from ariths_gen.core.logic_gate_circuits.logic_gate_circuit import OneInputLogicGate, TwoInputLogicGate
|
from ariths_gen.core.logic_gate_circuits.logic_gate_circuit import OneInputLogicGate, TwoInputLogicGate
|
||||||
|
|
||||||
from ariths_gen.wire_components import (
|
from ariths_gen.wire_components import (
|
||||||
@ -52,12 +53,22 @@ class GeneralCircuit():
|
|||||||
|
|
||||||
# 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_circuit_def(self) -> Dict[str, Wire]:
|
||||||
|
""" returns IDs and wires of the inputs and output"""
|
||||||
|
#.{circuit_block.a.prefix}({self.a.prefix}), .{circuit_block.b.prefix}({self.b.prefix}), .{circuit_block.out.prefix}({self.out.prefix}));\n"
|
||||||
|
r = {chr(97 + i): self.inputs[i] for i in range(len(self.inputs))}
|
||||||
|
r['out'] = self.get_global_prefix() + "_out"
|
||||||
|
return r
|
||||||
|
|
||||||
def add_component(self, component):
|
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.
|
||||||
|
|
||||||
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]
|
||||||
|
#assert component.prefix not in prefixes, f"Component with prefix {component.prefix} already exists in the circuit."
|
||||||
self.components.append(component)
|
self.components.append(component)
|
||||||
return component
|
return component
|
||||||
|
|
||||||
@ -550,6 +561,8 @@ 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 f" wire [{self.a.N-1}:0] {self.a.prefix};\n" + \
|
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.b.N-1}:0] {self.b.prefix};\n" + \
|
||||||
f" wire [{self.out.N-1}:0] {self.out.prefix};\n"
|
f" wire [{self.out.N-1}:0] {self.out.prefix};\n"
|
||||||
@ -576,8 +589,9 @@ class GeneralCircuit():
|
|||||||
circuit_type = self.__class__(a=Bus("a"), b=Bus("b")).prefix + str(self.N)
|
circuit_type = self.__class__(a=Bus("a"), b=Bus("b")).prefix + str(self.N)
|
||||||
circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(
|
circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(
|
||||||
N=self.N, prefix="b"), name=circuit_type)
|
N=self.N, prefix="b"), name=circuit_type)
|
||||||
return self.a.return_bus_wires_values_v_hier() + self.b.return_bus_wires_values_v_hier() + \
|
return "".join([c.return_bus_wires_values_v_hier() for c in self.inputs]) + \
|
||||||
f" {circuit_type} {circuit_type}_{self.out.prefix}(.{circuit_block.a.prefix}({self.a.prefix}), .{circuit_block.b.prefix}({self.b.prefix}), .{circuit_block.out.prefix}({self.out.prefix}));\n"
|
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.
|
||||||
|
@ -67,4 +67,4 @@ from ariths_gen.multi_bit_circuits.adders.conditional_sum_adder import (
|
|||||||
from ariths_gen.multi_bit_circuits.adders.carry_increment_adder import (
|
from ariths_gen.multi_bit_circuits.adders.carry_increment_adder import (
|
||||||
UnsignedCarryIncrementAdder,
|
UnsignedCarryIncrementAdder,
|
||||||
SignedCarryIncrementAdder
|
SignedCarryIncrementAdder
|
||||||
)
|
)
|
12
ariths_gen/multi_bit_circuits/others/__init__.py
Normal file
12
ariths_gen/multi_bit_circuits/others/__init__.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
from ariths_gen.multi_bit_circuits.others.popcount import (
|
||||||
|
UnsignedPopCount
|
||||||
|
)
|
||||||
|
|
||||||
|
from ariths_gen.multi_bit_circuits.others.bit_reduce import (
|
||||||
|
BitReduce, AndReduce, OrReduce
|
||||||
|
)
|
||||||
|
|
||||||
|
from ariths_gen.multi_bit_circuits.others.compare import (
|
||||||
|
UnsignedCompareLT
|
||||||
|
)
|
89
ariths_gen/multi_bit_circuits/others/bit_reduce.py
Normal file
89
ariths_gen/multi_bit_circuits/others/bit_reduce.py
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
"""
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from ariths_gen.wire_components import (
|
||||||
|
Wire,
|
||||||
|
ConstantWireValue0,
|
||||||
|
ConstantWireValue1,
|
||||||
|
Bus,
|
||||||
|
wires
|
||||||
|
)
|
||||||
|
from ariths_gen.core.arithmetic_circuits import (
|
||||||
|
ArithmeticCircuit,
|
||||||
|
GeneralCircuit,
|
||||||
|
MultiplierCircuit
|
||||||
|
)
|
||||||
|
from ariths_gen.core.logic_gate_circuits import (
|
||||||
|
MultipleInputLogicGate
|
||||||
|
)
|
||||||
|
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||||
|
HalfAdder,
|
||||||
|
FullAdder,
|
||||||
|
FullAdderP,
|
||||||
|
TwoOneMultiplexer
|
||||||
|
)
|
||||||
|
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||||
|
AndGate,
|
||||||
|
NandGate,
|
||||||
|
OrGate,
|
||||||
|
NorGate,
|
||||||
|
XorGate,
|
||||||
|
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 representing tree reducer circuit. Doent work for NAND gate!
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, a: Bus, gate : TwoInputLogicGate, prefix : str = "", name : str = "bitreduce", **kwargs):
|
||||||
|
self.N = a.N
|
||||||
|
self.a = a
|
||||||
|
|
||||||
|
outc = 1
|
||||||
|
super().__init__(name=name, prefix=prefix, inputs = [self.a], out_N=outc)
|
||||||
|
|
||||||
|
# tree reduction
|
||||||
|
def create_tree(a: Bus, depth: int, branch="A"):
|
||||||
|
|
||||||
|
#print(a)
|
||||||
|
if a.N == 1:
|
||||||
|
return a[0]
|
||||||
|
else:
|
||||||
|
half = a.N // 2
|
||||||
|
b_in = Bus(N=half, prefix=f"b_inn{depth}A")
|
||||||
|
c_in = Bus(N=a.N - half, prefix=f"b_inn{depth}B")
|
||||||
|
#print(a, half, a.N)
|
||||||
|
|
||||||
|
|
||||||
|
for i, j in enumerate(range(half)):
|
||||||
|
b_in[i] = a[j]
|
||||||
|
|
||||||
|
for i, j in enumerate(range(half, a.N)):
|
||||||
|
c_in[i] = a[j]
|
||||||
|
|
||||||
|
b = create_tree(b_in, depth=depth + 1, branch = "A")
|
||||||
|
c = create_tree(c_in, depth= depth + 1, branch = "B")
|
||||||
|
d = gate(a=b, b=c, prefix = f"{self.prefix}_red_{branch}_{depth}")
|
||||||
|
self.add_component(d)
|
||||||
|
return d.out
|
||||||
|
|
||||||
|
sumwire = create_tree(self.a, 0, "X")
|
||||||
|
#print(sumbus)
|
||||||
|
self.out[0] = sumwire
|
||||||
|
|
||||||
|
|
||||||
|
class OrReduce(BitReduce):
|
||||||
|
def __init__(self, a: Bus, prefix : str = "", name : str = "orreduce", **kwargs):
|
||||||
|
super().__init__(a=a, gate=OrGate, prefix=prefix, name=name, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class AndReduce(BitReduce):
|
||||||
|
def __init__(self, a: Bus, prefix : str = "", name : str = "orreduce", **kwargs):
|
||||||
|
super().__init__(a=a, gate=AndGate, prefix=prefix, name=name, **kwargs)
|
83
ariths_gen/multi_bit_circuits/others/compare.py
Normal file
83
ariths_gen/multi_bit_circuits/others/compare.py
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
"""
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from ariths_gen.wire_components import (
|
||||||
|
Wire,
|
||||||
|
ConstantWireValue0,
|
||||||
|
ConstantWireValue1,
|
||||||
|
Bus,
|
||||||
|
wires
|
||||||
|
)
|
||||||
|
from ariths_gen.core.arithmetic_circuits import (
|
||||||
|
ArithmeticCircuit,
|
||||||
|
GeneralCircuit,
|
||||||
|
MultiplierCircuit
|
||||||
|
)
|
||||||
|
|
||||||
|
from ariths_gen.core.logic_gate_circuits import (
|
||||||
|
MultipleInputLogicGate
|
||||||
|
)
|
||||||
|
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||||
|
HalfAdder,
|
||||||
|
FullAdder,
|
||||||
|
FullAdderP,
|
||||||
|
TwoOneMultiplexer
|
||||||
|
)
|
||||||
|
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 UnsignedCompareLT(GeneralCircuit):
|
||||||
|
"""Class representing unsigned compare
|
||||||
|
|
||||||
|
|
||||||
|
Returns true if a < b
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
#print("outc", outc)
|
||||||
|
super().__init__(name=name, prefix=prefix,
|
||||||
|
inputs = [self.a, self.b], out_N=1)
|
||||||
|
|
||||||
|
|
||||||
|
self.a.bus_extend(self.N, prefix=a.prefix)
|
||||||
|
self.b.bus_extend(self.N, prefix=b.prefix)
|
||||||
|
|
||||||
|
|
||||||
|
# create wires
|
||||||
|
psum = ConstantWireValue1()
|
||||||
|
|
||||||
|
res = Bus(N = self.N, prefix=self.prefix + "res")
|
||||||
|
|
||||||
|
|
||||||
|
for i in reversed(range(self.N)):
|
||||||
|
|
||||||
|
i1 = self.add_component(NotGate(self.a[i], f"{self.prefix}_i1_{i}")).out
|
||||||
|
i2 = self.b[i]
|
||||||
|
|
||||||
|
and1 = self.add_component(AndGate(i1, i2, f"{self.prefix}_and1_{i}")).out
|
||||||
|
res[i] = self.add_component(AndGate(and1, psum, f"{self.prefix}_and2_{i}")).out
|
||||||
|
|
||||||
|
pi = self.add_component(XnorGate(self.a[i], self.b[i], f"{self.prefix}_pi_{i}")).out
|
||||||
|
psum = self.add_component(AndGate(pi, psum, f"{self.prefix}_psum_{i}")).out
|
||||||
|
|
||||||
|
|
||||||
|
self.out = self.add_component(OrReduce(res, prefix=f"{self.prefix}_orred")).out
|
||||||
|
#self.out.connect_bus(sumbus )
|
89
ariths_gen/multi_bit_circuits/others/popcount.py
Normal file
89
ariths_gen/multi_bit_circuits/others/popcount.py
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
"""
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from ariths_gen.wire_components import (
|
||||||
|
Wire,
|
||||||
|
ConstantWireValue0,
|
||||||
|
ConstantWireValue1,
|
||||||
|
Bus,
|
||||||
|
wires
|
||||||
|
)
|
||||||
|
from ariths_gen.core.arithmetic_circuits import (
|
||||||
|
ArithmeticCircuit,
|
||||||
|
GeneralCircuit,
|
||||||
|
MultiplierCircuit
|
||||||
|
)
|
||||||
|
from ariths_gen.core.logic_gate_circuits import (
|
||||||
|
MultipleInputLogicGate
|
||||||
|
)
|
||||||
|
from ariths_gen.one_bit_circuits.one_bit_components import (
|
||||||
|
HalfAdder,
|
||||||
|
FullAdder,
|
||||||
|
FullAdderP,
|
||||||
|
TwoOneMultiplexer
|
||||||
|
)
|
||||||
|
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
|
||||||
|
|
||||||
|
class UnsignedPopCount(GeneralCircuit):
|
||||||
|
"""Class representing unsigned popcount circuit.
|
||||||
|
|
||||||
|
Popcount circuit is a circuit that counts the number of 1s in a binary number.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, a: Bus, adder : ArithmeticCircuit|None = None, prefix : str = "", name : str = "popcnt", **kwargs):
|
||||||
|
self.N = a.N
|
||||||
|
self.a = a
|
||||||
|
|
||||||
|
outc = ceil(log2(self.N + 1))
|
||||||
|
#print("outc", outc)
|
||||||
|
super().__init__(name=name, prefix=prefix, inputs = [self.a], out_N=outc)
|
||||||
|
|
||||||
|
|
||||||
|
self.a.bus_extend(2**(outc - 1), prefix=a.prefix)
|
||||||
|
#print(self.a)
|
||||||
|
self.adder = adder
|
||||||
|
if not self.adder:
|
||||||
|
self.adder = UnsignedRippleCarryAdder
|
||||||
|
|
||||||
|
# tree reduction
|
||||||
|
def create_tree(a: Bus, depth: int, branch="A"):
|
||||||
|
|
||||||
|
#print(a)
|
||||||
|
if a.N == 1:
|
||||||
|
return a
|
||||||
|
else:
|
||||||
|
half = a.N // 2
|
||||||
|
b_in = Bus(N=half, prefix=f"b_inn{depth}A")
|
||||||
|
c_in = Bus(N=a.N - half, prefix=f"b_inn{depth}B")
|
||||||
|
#print(a, half, a.N)
|
||||||
|
|
||||||
|
|
||||||
|
for i, j in enumerate(range(half)):
|
||||||
|
b_in[i] = a[j]
|
||||||
|
|
||||||
|
for i, j in enumerate(range(half, a.N)):
|
||||||
|
c_in[i] = a[j]
|
||||||
|
|
||||||
|
b = create_tree(b_in, depth=depth + 1, branch = "A")
|
||||||
|
c = create_tree(c_in, depth= depth + 1, branch = "B")
|
||||||
|
d = self.adder(a=b, b=c, prefix = f"{self.prefix}_add{branch}_{depth}")
|
||||||
|
self.add_component(d)
|
||||||
|
return d.out
|
||||||
|
|
||||||
|
sumbus = create_tree(self.a,0, "X")
|
||||||
|
#print(sumbus)
|
||||||
|
self.out.connect_bus(sumbus )
|
@ -242,6 +242,15 @@ class Bus():
|
|||||||
[unique_out_wires.append(w.prefix) if w.prefix not in unique_out_wires else None for w in self.bus]
|
[unique_out_wires.append(w.prefix) if w.prefix not in unique_out_wires else None for w in self.bus]
|
||||||
return "".join([f", .{circuit_block.out.get_wire(self.bus.index(o)).prefix}({unique_out_wires.pop(unique_out_wires.index(o.prefix))})" if o.prefix in unique_out_wires else f", .{circuit_block.out.get_wire(self.bus.index(o)).prefix}()" for o in self.bus])
|
return "".join([f", .{circuit_block.out.get_wire(self.bus.index(o)).prefix}({unique_out_wires.pop(unique_out_wires.index(o.prefix))})" if o.prefix in unique_out_wires else f", .{circuit_block.out.get_wire(self.bus.index(o)).prefix}()" for o in self.bus])
|
||||||
|
|
||||||
|
def get_wire_declaration_v(self):
|
||||||
|
"""Declare the wire in Verilog code representation.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Verilog code for declaration of individual bus wires.
|
||||||
|
"""
|
||||||
|
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, array: bool = True):
|
||||||
"""Declare each wire from the bus independently in Blif code representation.
|
"""Declare each wire from the bus independently in Blif code representation.
|
||||||
|
50
tests/test_compare.py
Normal file
50
tests/test_compare.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
from ariths_gen.wire_components import (
|
||||||
|
Wire,
|
||||||
|
ConstantWireValue0,
|
||||||
|
ConstantWireValue1,
|
||||||
|
Bus
|
||||||
|
)
|
||||||
|
|
||||||
|
from ariths_gen.core.arithmetic_circuits import GeneralCircuit
|
||||||
|
|
||||||
|
from ariths_gen.multi_bit_circuits.others import (
|
||||||
|
UnsignedCompareLT
|
||||||
|
)
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import math
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
|
|
||||||
|
def test_compare():
|
||||||
|
""" Test unsigned comparator """
|
||||||
|
N = 8
|
||||||
|
|
||||||
|
a = Bus(N=N, prefix="a")
|
||||||
|
b = Bus(N=N, prefix="b")
|
||||||
|
av = np.arange(2**N).reshape(1, -1)
|
||||||
|
bv = np.arange(2**N).reshape(-1, 1)
|
||||||
|
|
||||||
|
|
||||||
|
cmp = UnsignedCompareLT(a=a, b=b)
|
||||||
|
o = StringIO()
|
||||||
|
cmp.get_v_code_hier(open("tmp.verilog", "w"))
|
||||||
|
print(o.getvalue())
|
||||||
|
|
||||||
|
# av = 0
|
||||||
|
# bv = 5
|
||||||
|
|
||||||
|
|
||||||
|
v = cmp(av, bv)
|
||||||
|
print("ret = ", v)
|
||||||
|
|
||||||
|
expected = np.array(av < bv).astype(int)
|
||||||
|
|
||||||
|
print("expected = ", expected)
|
||||||
|
|
||||||
|
#expected = np.sum(r, axis=1)
|
||||||
|
|
||||||
|
np.testing.assert_array_equal(v, expected)
|
||||||
|
|
||||||
|
|
||||||
|
|
50
tests/test_popcnt.py
Normal file
50
tests/test_popcnt.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
from ariths_gen.wire_components import (
|
||||||
|
Wire,
|
||||||
|
ConstantWireValue0,
|
||||||
|
ConstantWireValue1,
|
||||||
|
Bus
|
||||||
|
)
|
||||||
|
|
||||||
|
from ariths_gen.core.arithmetic_circuits import GeneralCircuit
|
||||||
|
|
||||||
|
from ariths_gen.multi_bit_circuits.others import (
|
||||||
|
UnsignedPopCount
|
||||||
|
)
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import math
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
|
|
||||||
|
def test_popcount():
|
||||||
|
""" Test unsigned adders """
|
||||||
|
N = 7
|
||||||
|
|
||||||
|
for N in [3, 7, 8, 9, 16]:
|
||||||
|
a = Bus(N=N, prefix="a")
|
||||||
|
av = np.arange(2**N)
|
||||||
|
|
||||||
|
|
||||||
|
popcnt = UnsignedPopCount(a=a)
|
||||||
|
#o = StringIO()
|
||||||
|
#popcnt.get_v_code_hier(o)
|
||||||
|
#print(o.getvalue())
|
||||||
|
|
||||||
|
|
||||||
|
print(popcnt(av))
|
||||||
|
|
||||||
|
|
||||||
|
# conv to binary
|
||||||
|
r = []
|
||||||
|
a_s = av.copy()
|
||||||
|
for i in range(N):
|
||||||
|
r.append(a_s % 2)
|
||||||
|
a_s = a_s // 2
|
||||||
|
r = np.dstack(r).reshape(-1, N)
|
||||||
|
print("r = ", r)
|
||||||
|
expected = np.sum(r, axis=1)
|
||||||
|
|
||||||
|
np.testing.assert_array_equal(popcnt(av), expected)
|
||||||
|
|
||||||
|
|
||||||
|
|
78
tests/test_reduce.py
Normal file
78
tests/test_reduce.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
from ariths_gen.wire_components import (
|
||||||
|
Wire,
|
||||||
|
ConstantWireValue0,
|
||||||
|
ConstantWireValue1,
|
||||||
|
Bus
|
||||||
|
)
|
||||||
|
|
||||||
|
from ariths_gen.core.arithmetic_circuits import GeneralCircuit
|
||||||
|
|
||||||
|
from ariths_gen.multi_bit_circuits.others import (
|
||||||
|
BitReduce, AndReduce, OrReduce
|
||||||
|
)
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import math
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
|
|
||||||
|
def test_orreduce():
|
||||||
|
""" Test unsigned adders """
|
||||||
|
N = 7
|
||||||
|
|
||||||
|
for N in [3, 7, 8, 9, 16]:
|
||||||
|
a = Bus(N=N, prefix="a")
|
||||||
|
av = np.arange(2**N)
|
||||||
|
|
||||||
|
|
||||||
|
reduce = OrReduce(a=a)
|
||||||
|
o = StringIO()
|
||||||
|
reduce.get_v_code_hier(o)
|
||||||
|
print(o.getvalue())
|
||||||
|
|
||||||
|
|
||||||
|
#print(reduce(av))
|
||||||
|
|
||||||
|
# conv to binary
|
||||||
|
r = []
|
||||||
|
a_s = av.copy()
|
||||||
|
for i in range(N):
|
||||||
|
r.append(a_s % 2)
|
||||||
|
a_s = a_s // 2
|
||||||
|
r = np.dstack(r).reshape(-1, N)
|
||||||
|
print("r = ", r)
|
||||||
|
expected = np.bitwise_or.reduce(r, axis=1)
|
||||||
|
|
||||||
|
np.testing.assert_array_equal(reduce(av), expected)
|
||||||
|
|
||||||
|
|
||||||
|
def test_andreduce():
|
||||||
|
""" Test unsigned adders """
|
||||||
|
N = 7
|
||||||
|
|
||||||
|
for N in [3, 7, 8, 9, 16]:
|
||||||
|
a = Bus(N=N, prefix="a")
|
||||||
|
av = np.arange(2**N)
|
||||||
|
|
||||||
|
|
||||||
|
reduce = AndReduce(a=a)
|
||||||
|
o = StringIO()
|
||||||
|
reduce.get_v_code_hier(o)
|
||||||
|
print(o.getvalue())
|
||||||
|
|
||||||
|
|
||||||
|
#print(reduce(av))
|
||||||
|
|
||||||
|
# conv to binary
|
||||||
|
r = []
|
||||||
|
a_s = av.copy()
|
||||||
|
for i in range(N):
|
||||||
|
r.append(a_s % 2)
|
||||||
|
a_s = a_s // 2
|
||||||
|
r = np.dstack(r).reshape(-1, N)
|
||||||
|
print("r = ", r)
|
||||||
|
expected = np.bitwise_and.reduce(r, axis=1)
|
||||||
|
|
||||||
|
np.testing.assert_array_equal(reduce(av), expected)
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user