ariths-gen/tests/test_all.py
2022-04-17 13:06:46 +02:00

166 lines
5.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from ariths_gen.wire_components import (
Wire,
ConstantWireValue0,
ConstantWireValue1,
Bus
)
from ariths_gen.core.arithmetic_circuits import GeneralCircuit
from ariths_gen.multi_bit_circuits.adders import (
UnsignedCarryLookaheadAdder,
UnsignedPGRippleCarryAdder,
UnsignedRippleCarryAdder,
SignedCarryLookaheadAdder,
SignedPGRippleCarryAdder,
SignedRippleCarryAdder,
UnsignedCarrySkipAdder,
SignedCarrySkipAdder,
)
from ariths_gen.multi_bit_circuits.multipliers import (
UnsignedDaddaMultiplier,
UnsignedArrayMultiplier,
UnsignedWallaceMultiplier,
UnsignedCarrySaveMultiplier,
SignedArrayMultiplier,
SignedDaddaMultiplier,
SignedWallaceMultiplier,
SignedCarrySaveMultiplier
)
from ariths_gen.multi_bit_circuits.approximate_multipliers import (
UnsignedTruncatedArrayMultiplier,
UnsignedTruncatedCarrySaveMultiplier,
UnsignedBrokenArrayMultiplier,
UnsignedBrokenCarrySaveMultiplier
)
import numpy as np
def test_unsigned_approxmul(values = False):
""" Test unsigned approximate multipliers """
N = 7
a = Bus(N=N, prefix="a")
b = Bus(N=N, prefix="b")
av = np.arange(2**N)
bv = av.reshape(-1, 1)
expected = av * bv
for c in [UnsignedBrokenArrayMultiplier, UnsignedBrokenCarrySaveMultiplier, UnsignedTruncatedArrayMultiplier, UnsignedTruncatedCarrySaveMultiplier]:
if c == UnsignedTruncatedArrayMultiplier or c == UnsignedTruncatedCarrySaveMultiplier:
mul = c(a=a, b=b, truncation_cut=2)
elif c == UnsignedBrokenArrayMultiplier or c == UnsignedBrokenCarrySaveMultiplier:
mul = c(a=a, b=b, horizontal_cut=1, vertical_cut=2)
r = mul(av, bv)
# WCE worst case error; used for approximate multiplier error measurement
WCE = np.amax(abs(np.subtract(r, expected)))
# WCRE worst case relative error; used for approximate multiplier error measurement
np.seterr(divide='ignore', invalid='ignore')
WCRE = np.max(np.nan_to_num(abs(np.subtract(r, expected)) / expected))
if isinstance(mul, UnsignedTruncatedArrayMultiplier) or isinstance(mul, UnsignedTruncatedCarrySaveMultiplier):
# WCE_TM(n,k) = (2^k - 1) * (2^(n+1) - 2^k - 1)
expected_WCE = (2 ** mul.truncation_cut - 1) * (2 ** (mul.a.N+1) - 2 ** mul.truncation_cut - 1)
elif isinstance(mul, UnsignedBrokenArrayMultiplier) or isinstance(mul, UnsignedBrokenCarrySaveMultiplier):
# WCE_BAM(n,h,v) = (2^n - 1) * {SUM_i0_to_h-1}(2^i) + 2^h * {SUM_i0_to_v-h-1}(2^(v-h) - 2^i)
sum_1 = sum([2**i for i in range(0, mul.horizontal_cut)])
sum_2 = sum([2**(mul.vertical_cut-mul.horizontal_cut) - 2**i for i in range(0, mul.vertical_cut-mul.horizontal_cut)])
expected_WCE = (2 ** mul.N - 1) * sum_1 + 2 ** mul.horizontal_cut * sum_2
# Test expected result
assert expected_WCE == WCE
if values is True:
np.testing.assert_array_equal(expected, r)
def test_unsigned_mul():
""" Test unsigned multipliers """
N = 7
a = Bus(N=N, prefix="a")
b = Bus(N=N, prefix="b")
av = np.arange(2**N)
bv = av.reshape(-1, 1)
expected = av * bv
for c in [UnsignedDaddaMultiplier, UnsignedArrayMultiplier, UnsignedCarrySaveMultiplier, UnsignedWallaceMultiplier]:
mul = c(a, b)
assert mul(0, 0) == 0
r = mul(av, bv)
np.testing.assert_array_equal(expected, r)
# For array wallace tree implementation
mul = UnsignedWallaceMultiplier(a, b, use_csa=False)
assert mul(0, 0) == 0
r = mul(av, bv)
np.testing.assert_array_equal(expected, r)
def test_signed_mul():
""" Test signed multipliers """
N = 7
a = Bus(N=N, prefix="a")
b = Bus(N=N, prefix="b")
av = np.arange(-(2**(N-1)), 2**(N-1))
bv = av.reshape(-1, 1)
expected = av * bv
for c in [SignedDaddaMultiplier, SignedArrayMultiplier, SignedWallaceMultiplier, SignedCarrySaveMultiplier]:
mul = c(a, b)
r = mul(av, bv)
assert mul(0, 0) == 0
np.testing.assert_array_equal(expected, r)
# For array wallace tree implementation
mul = SignedWallaceMultiplier(a, b, use_csa=False)
r = mul(av, bv)
assert mul(0, 0) == 0
np.testing.assert_array_equal(expected, r)
def test_unsigned_add():
""" Test unsigned adders """
N = 7
a = Bus(N=N, prefix="a")
b = Bus(N=N, prefix="b")
av = np.arange(2**N)
bv = av.reshape(-1, 1)
expected = av + bv
for c in [UnsignedCarryLookaheadAdder, UnsignedPGRippleCarryAdder, UnsignedRippleCarryAdder, UnsignedCarrySkipAdder]:
mul = c(a, b)
r = mul(av, bv)
np.testing.assert_array_equal(expected, r)
def test_signed_add():
""" Test signed adders """
N = 7
a = Bus(N=N, prefix="a")
b = Bus(N=N, prefix="b")
av = np.arange(-(2**(N-1)), 2**(N-1))
bv = av.reshape(-1, 1)
expected = av + bv
for c in [SignedCarryLookaheadAdder, SignedPGRippleCarryAdder, SignedRippleCarryAdder, SignedCarrySkipAdder]:
mul = c(a, b)
r = mul(av, bv)
np.testing.assert_array_equal(expected, r)
def test_mac():
class MAC(GeneralCircuit):
def __init__(self, a: Bus, b: Bus, r: Bus, prefix: str = "", name: str = "mac", **kwargs):
super().__init__(prefix=prefix, name=name, out_N=2*a.N+1, inputs=[a, b, r], **kwargs)
assert a.N == b.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.add = self.add_component(UnsignedRippleCarryAdder(a=r, 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)
# usage
mymac = MAC(Bus("a", 4), Bus("b", 4), Bus("acc", 8))
av = np.arange(2**4)
bv = np.arange(2**4).reshape(-1, 1)
cv = np.arange(2**8).reshape(-1, 1, 1)
r = mymac(av, bv, cv)
expected = (av * bv) + cv
np.testing.assert_array_equal(r, expected)