dut.p.data_i.a.eq(z),
dut.p.valid_i.eq(z_valid),
dut.n.ready_i.eq(ready),
- ]
+ ]
sim = Simulator(m)
sim.add_clock(1e-6)
yield
for i in range(40):
yield
+
def reader_process():
counter = 200
while True:
counter -= 1
- if counter == 0: # some indication of progress
- print (".", sep="", end="", flush=True)
+ if counter == 0: # some indication of progress
+ print(".", sep="", end="", flush=True)
counter = 200
yield
vld = yield dut.n.valid_o
except StopIteration:
break
- print() # newline after end of progress-indicator
+ print() # newline after end of progress-indicator
sim.add_sync_process(writer_process)
sim.add_sync_process(reader_process)
sim.add_sync_process(process)
with sim.write_vcd("fpsin_cos.vcd", "fpsin_cos.gtkw", traces=[
- cos, sin, ready, start]):
+ cos, sin, ready, start]):
sim.run()
def run_test_assert(self, z, bits=64):
def get_frac(self, value, bits):
return value/(1 << bits)
+
if __name__ == "__main__":
unittest.main()
""" test of FPClassMuxInOut
"""
-from ieee754.fclass.pipeline import (FPClassMuxInOut,)
+from ieee754.fclass.pipeline import FPClassMuxInOut
from ieee754.fpcommon.test.fpmux import runfp
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_half
"""
x = x.bits
fmt = FPFormat.standard(wid)
- print (hex(x), "exp", fmt.get_exponent(x), fmt.e_max,
- "m", hex(fmt.get_mantissa_field(x)),
- fmt.get_mantissa_field(x) & (1<<fmt.m_width-1))
+ print(hex(x), "exp", fmt.get_exponent(x), fmt.e_max,
+ "m", hex(fmt.get_mantissa_field(x)),
+ fmt.get_mantissa_field(x) & (1 << fmt.m_width-1))
if fmt.is_inf(x):
if fmt.get_sign_field(x):
- return 1<<0
+ return 1 << 0
else:
- return 1<<7
+ return 1 << 7
if fmt.is_zero(x):
if fmt.get_sign_field(x):
- return 1<<3
+ return 1 << 3
else:
- return 1<<4
+ return 1 << 4
if fmt.get_exponent(x) == fmt.e_max and fmt.get_mantissa_field(x) != 0:
if fmt.is_nan_signaling(x):
- return 1<<8
+ return 1 << 8
else:
- return 1<<9
+ return 1 << 9
if fmt.is_subnormal(x) and fmt.get_mantissa_field(x) != 0:
if fmt.get_sign_field(x):
- return 1<<2
+ return 1 << 2
else:
- return 1<<5
+ return 1 << 5
if fmt.get_sign_field(x):
- return 1<<1
+ return 1 << 1
else:
- return 1<<6
+ return 1 << 6
def fclass_16(x):
def test_class_pipe_f16(self):
dut = FPClassMuxInOut(16, 16, 4, op_wid=1)
runfp(dut, 16, "test_fclass_pipe_f16", Float16, fclass_16,
- True, n_vals=100)
+ True, n_vals=100)
def test_class_pipe_f32(self):
dut = FPClassMuxInOut(32, 32, 4, op_wid=1)
runfp(dut, 32, "test_fclass_pipe_f32", Float32, fclass_32,
- True, n_vals=100)
+ True, n_vals=100)
def test_class_pipe_f64(self):
dut = FPClassMuxInOut(64, 64, 4, op_wid=1)
runfp(dut, 64, "test_fclass_pipe_f64", Float64, fclass_64,
- True, n_vals=100)
+ True, n_vals=100)
class TestFClassPipeCoverage(unittest.TestCase):
""" test of FPCVTMuxInOut
"""
-from ieee754.fcvt.pipeline import (FPCVTF2IntMuxInOut,)
+from ieee754.fcvt.pipeline import FPCVTF2IntMuxInOut
from ieee754.fpcommon.test.fpmux import (runfp, create_random)
from ieee754.fcvt.test.rangelimited import create_int
import sfpy
from sfpy import Float64, Float32, Float16
+
def fcvt_f64_ui32(x):
return sfpy.float.f64_to_ui32(x)
+
def fcvt_f64_i32(x):
return sfpy.float.f64_to_i32(x) & 0xffffffff
+
def fcvt_i16_f32(x):
- print ("fcvt i16_f32", hex(x))
- return sfpy.float.i32_to_f32(x) # XXX no i16_to_f32, it's ok though
+ print("fcvt i16_f32", hex(x))
+ return sfpy.float.i32_to_f32(x) # XXX no i16_to_f32, it's ok though
+
def fcvt_i32_f32(x):
- print ("fcvt i32_f32", hex(x))
+ print("fcvt i32_f32", hex(x))
return sfpy.float.i32_to_f32(x)
+
def fcvt_i32_f64(x):
- print ("fcvt i32_f64", hex(x))
+ print("fcvt i32_f64", hex(x))
return sfpy.float.i32_to_f64(x)
+
def fcvt_f32_ui32(x):
return sfpy.float.f32_to_ui32(x)
+
def fcvt_64_to_32(x):
return sfpy.float.ui64_to_f32(x)
+
def fcvt_f64_ui64(x):
return sfpy.float.f64_to_ui64(x)
+
def fcvt_f64_ui16(x):
x = sfpy.float.f64_to_ui32(x)
if x >= 0xffff:
return 0xffff
return x
+
def fcvt_f16_ui32(x):
return sfpy.float.f16_to_ui32(x)
+
def fcvt_f16_ui16(x):
return sfpy.float.f16_to_ui32(x) & 0xffff
+
def fcvt_f16_i16(x):
x = sfpy.float.f16_to_i32(x)
if x >= 0x7fff:
return 0x8000
return x & 0xffff
+
def fcvt_f64_i16(x):
x = sfpy.float.f64_to_i32(x)
if x >= 0x7fff:
return 0x8000
return x & 0xffff
+
def fcvt_f32_i32(x):
return sfpy.float.f32_to_i32(x) & 0xffffffff
+
def fcvt_f64_i64(x):
return sfpy.float.f64_to_i64(x) & 0xffffffffffffffff
runfp(dut, 16, "test_fcvt_int_pipe_i16_f32", to_int16, fcvt_i16_f32, True,
n_vals=100, opcode=0x1)
+
def test_int_pipe_i32_f64():
dut = FPCVTIntMuxInOut(32, 64, 4, op_wid=1)
runfp(dut, 32, "test_fcvt_int_pipe_i32_f64", to_int32, fcvt_i32_f64, True,
n_vals=100, opcode=0x1)
+
def test_int_pipe_i32_f32():
dut = FPCVTIntMuxInOut(32, 32, 4, op_wid=1)
runfp(dut, 32, "test_fcvt_int_pipe_i32_f32", to_int32, fcvt_i32_f32, True,
n_vals=100, opcode=0x1)
+
def test_int_pipe_f64_i64():
dut = FPCVTF2IntMuxInOut(64, 64, 4, op_wid=1)
vals = []
vals.append(create_int(Float64, 64))
vals += create_random(dut.num_rows, 64, True, 10)
runfp(dut, 64, "test_fcvt_f2int_pipe_f64_i64", Float64, fcvt_f64_i64,
- True, vals=vals, opcode=0x1)
+ True, vals=vals, opcode=0x1)
+
def test_int_pipe_f64_i32():
# XXX TODO: reduce range of FP num to actually fit (almost) into I32
vals.append(create_int(Float64, 32))
vals += create_random(dut.num_rows, 32, True, 10)
runfp(dut, 64, "test_fcvt_f2int_pipe_f64_i32", Float64, fcvt_f64_i32,
- True, vals=vals, opcode=0x1)
+ True, vals=vals, opcode=0x1)
+
def test_int_pipe_f64_i16():
# XXX TODO: reduce range of FP num to actually fit (almost) into I16
vals.append(create_int(Float64, 16))
vals += create_random(dut.num_rows, 16, True, 10)
runfp(dut, 64, "test_fcvt_f2int_pipe_f64_i16", Float64, fcvt_f64_i16,
- True, vals=vals, opcode=0x1)
+ True, vals=vals, opcode=0x1)
+
def test_int_pipe_f32_i32():
dut = FPCVTF2IntMuxInOut(32, 32, 4, op_wid=1)
runfp(dut, 32, "test_fcvt_f2int_pipe_f32_i32", Float32, fcvt_f32_i32,
- True, n_vals=100, opcode=0x1)
+ True, n_vals=100, opcode=0x1)
+
def test_int_pipe_f16_i16():
dut = FPCVTF2IntMuxInOut(16, 16, 4, op_wid=1)
runfp(dut, 16, "test_fcvt_f2int_pipe_f16_i16", Float16, fcvt_f16_i16,
- True, n_vals=100, opcode=0x1)
+ True, n_vals=100, opcode=0x1)
######################
-# fp to unsigned int
+# fp to unsigned int
######################
+
def test_int_pipe_f16_ui16():
# XXX softfloat-3 doesn't have ui16_to_xxx so use ui32 instead.
# should be fine.
dut = FPCVTF2IntMuxInOut(16, 16, 4, op_wid=1)
runfp(dut, 16, "test_fcvt_f2int_pipe_f16_ui16", Float16, fcvt_f16_ui16,
- True, n_vals=100)
+ True, n_vals=100)
+
def test_int_pipe_ui16_f64():
dut = FPCVTIntMuxInOut(16, 64, 4, op_wid=1)
runfp(dut, 16, "test_fcvt_int_pipe_ui16_f64", to_uint16, fcvt_64, True,
n_vals=100)
+
def test_int_pipe_f32_ui32():
dut = FPCVTF2IntMuxInOut(32, 32, 4, op_wid=1)
vals = []
vals.append(create_int(Float32, 32))
vals += create_random(dut.num_rows, 32, True, 10)
runfp(dut, 32, "test_fcvt_f2int_pipe_f32_ui32", Float32, fcvt_f32_ui32,
- True, vals=vals)
+ True, vals=vals)
+
def test_int_pipe_ui32_f64():
dut = FPCVTIntMuxInOut(32, 64, 4, op_wid=1)
runfp(dut, 32, "test_fcvt_int_pipe_ui32_64", to_uint32, fcvt_64, True,
n_vals=100)
+
def test_int_pipe_ui64_f32():
# ok, doing 33 bits here because it's pretty pointless (not entirely)
# to do random numbers statistically likely 99.999% of the time to be
runfp(dut, 33, "test_fcvt_int_pipe_ui64_32", to_uint64, fcvt_64_to_32, True,
n_vals=100)
+
def test_int_pipe_ui64_f16():
# ok, doing 17 bits here because it's pretty pointless (not entirely)
# to do random numbers statistically likely 99.999% of the time to be
runfp(dut, 17, "test_fcvt_int_pipe_ui64_16", to_uint64, fcvt_16, True,
n_vals=100)
+
def test_int_pipe_ui32_f16():
# ok, doing 17 bits here because it's pretty pointless (not entirely)
# to do random numbers statistically likely 99.999% of the time to be
runfp(dut, 17, "test_fcvt_int_pipe_ui32_16", to_uint32, fcvt_16, True,
n_vals=100)
+
def test_int_pipe_f64_ui64():
dut = FPCVTF2IntMuxInOut(64, 64, 4, op_wid=1)
vals = []
vals.append(create_int(Float64, 64))
vals += create_random(dut.num_rows, 64, True, 10)
runfp(dut, 64, "test_fcvt_f2int_pipe_f64_ui64", Float64, fcvt_f64_ui64,
- True, vals=vals)
+ True, vals=vals)
+
def test_int_pipe_f64_ui32():
dut = FPCVTF2IntMuxInOut(64, 32, 4, op_wid=1)
vals.append(create_int(Float64, 32))
vals += create_random(dut.num_rows, 32, True, 10)
runfp(dut, 64, "test_fcvt_f2int_pipe_f64_ui32", Float64, fcvt_f64_ui32,
- True, vals=vals)
+ True, vals=vals)
+
def test_int_pipe_f64_ui16():
dut = FPCVTF2IntMuxInOut(64, 16, 4, op_wid=1)
vals.append(create_int(Float64, 16))
vals += create_random(dut.num_rows, 16, True, 10)
runfp(dut, 64, "test_fcvt_f2int_pipe_f64_ui16", Float64, fcvt_f64_ui16,
- True, vals=vals)
+ True, vals=vals)
+
if __name__ == '__main__':
for i in range(200):
""" test of FPCVTMuxInOut
"""
-from ieee754.fcvt.pipeline import (FPCVTIntMuxInOut,)
+from ieee754.fcvt.pipeline import FPCVTIntMuxInOut
from ieee754.fpcommon.test.fpmux import runfp
import sfpy
from sfpy import Float64, Float32, Float16
+
def to_int16(x):
""" input: an unsigned int in the range 0..65535
output: a signed int in the range -32768..32767
return x-0x10000
return x
+
def to_int32(x):
""" input: an unsigned int in the range 0..2^32-1
output: a signed int in the range -2^31..2^31-1
"""
- if x > ((1<<31)-1):
- return x-(1<<32)
+ if x > ((1 << 31)-1):
+ return x-(1 << 32)
return x
+
def to_uint16(x):
return x
+
def to_uint32(x):
return x
+
def to_uint64(x):
return x
+
def fcvt_64(x):
return sfpy.float.ui32_to_f64(x)
+
def fcvt_i16_f32(x):
- print ("fcvt i16_f32", hex(x))
- return sfpy.float.i32_to_f32(x) # XXX no i16_to_f32, it's ok though
+ print("fcvt i16_f32", hex(x))
+ return sfpy.float.i32_to_f32(x) # XXX no i16_to_f32, it's ok though
+
def fcvt_i32_f32(x):
- print ("fcvt i32_f32", hex(x))
+ print("fcvt i32_f32", hex(x))
return sfpy.float.i32_to_f32(x)
+
def fcvt_i32_f64(x):
- print ("fcvt i32_f64", hex(x))
+ print("fcvt i32_f64", hex(x))
return sfpy.float.i32_to_f64(x)
+
def fcvt_32(x):
return sfpy.float.ui32_to_f32(x)
+
def fcvt_64_to_32(x):
return sfpy.float.ui64_to_f32(x)
+
def fcvt_16(x):
return sfpy.float.ui32_to_f16(x)
# signed int to fp
######################
+
def test_int_pipe_i16_f32():
# XXX softfloat-3 doesn't have i16_to_xxx so use ui32 instead.
# should be fine.
runfp(dut, 16, "test_fcvt_int_pipe_i16_f32", to_int16, fcvt_i16_f32, True,
n_vals=20, opcode=0x1)
+
def test_int_pipe_i32_f64():
dut = FPCVTIntMuxInOut(32, 64, 4, op_wid=1)
runfp(dut, 32, "test_fcvt_int_pipe_i32_f64", to_int32, fcvt_i32_f64, True,
n_vals=20, opcode=0x1)
+
def test_int_pipe_i32_f32():
dut = FPCVTIntMuxInOut(32, 32, 4, op_wid=1)
runfp(dut, 32, "test_fcvt_int_pipe_i32_f32", to_int32, fcvt_i32_f32, True,
# unsigned int to fp
######################
+
def test_int_pipe_ui16_f32():
# XXX softfloat-3 doesn't have ui16_to_xxx so use ui32 instead.
# should be fine.
runfp(dut, 16, "test_fcvt_int_pipe_ui16_f32", to_uint16, fcvt_32, True,
n_vals=20)
+
def test_int_pipe_ui16_f64():
dut = FPCVTIntMuxInOut(16, 64, 4, op_wid=1)
runfp(dut, 16, "test_fcvt_int_pipe_ui16_f64", to_uint16, fcvt_64, True,
n_vals=20)
+
def test_int_pipe_ui32_f32():
dut = FPCVTIntMuxInOut(32, 32, 4, op_wid=1)
runfp(dut, 32, "test_fcvt_int_pipe_ui32_32", to_uint32, fcvt_32, True,
n_vals=20)
+
def test_int_pipe_ui32_f64():
dut = FPCVTIntMuxInOut(32, 64, 4, op_wid=1)
runfp(dut, 32, "test_fcvt_int_pipe_ui32_64", to_uint32, fcvt_64, True,
n_vals=20)
+
def test_int_pipe_ui64_f32():
# ok, doing 33 bits here because it's pretty pointless (not entirely)
# to do random numbers statistically likely 99.999% of the time to be
runfp(dut, 33, "test_fcvt_int_pipe_ui64_32", to_uint64, fcvt_64_to_32, True,
n_vals=20)
+
def test_int_pipe_ui64_f16():
# ok, doing 17 bits here because it's pretty pointless (not entirely)
# to do random numbers statistically likely 99.999% of the time to be
runfp(dut, 17, "test_fcvt_int_pipe_ui64_16", to_uint64, fcvt_16, True,
n_vals=20)
+
def test_int_pipe_ui32_f16():
# ok, doing 17 bits here because it's pretty pointless (not entirely)
# to do random numbers statistically likely 99.999% of the time to be
runfp(dut, 17, "test_fcvt_int_pipe_ui32_16", to_uint32, fcvt_16, True,
n_vals=20)
+
if __name__ == '__main__':
for i in range(200):
test_int_pipe_i16_f32()
test_int_pipe_ui64_f16()
test_int_pipe_ui16_f64()
test_int_pipe_ui32_f64()
-
of sense, but hey.
"""
-from ieee754.fcvt.pipeline import (FPCVTIntMuxInOut,)
+from ieee754.fcvt.pipeline import FPCVTIntMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_half
from ieee754.fcvt.test.up_fcvt_data_16_32 import regressions
import sfpy
from sfpy import Float64, Float32, Float16
+
def to_uint16(x):
return x
+
def to_uint32(x):
return x
+
def fcvt_64(x):
return sfpy.float.ui32_to_f64(x)
+
def fcvt_32(x):
return sfpy.float.ui32_to_f32(x)
+
def test_int_pipe_fp16_32():
dut = FPCVTIntMuxInOut(16, 32, 4)
run_pipe_fp(dut, 16, "int_16_32", unit_test_half, to_uint16,
regressions, fcvt_32, 100, True)
+
if __name__ == '__main__':
for i in range(200):
test_int_pipe_fp16_32()
-
""" test of FPCVTMuxInOut
"""
-from ieee754.fcvt.pipeline import (FPCVTDownMuxInOut,)
+from ieee754.fcvt.pipeline import FPCVTDownMuxInOut
from ieee754.fpcommon.test.fpmux import runfp
from sfpy import Float64, Float32, Float16
import unittest
+
def fcvt_16(x):
return Float16(x)
+
def fcvt_32(x):
return Float32(x)
+
def test_down_pipe_fp32_16():
# XXX TODO: this has too great a dynamic range as input
# http://bugs.libre-riscv.org/show_bug.cgi?id=113
dut = FPCVTDownMuxInOut(32, 16, 4)
runfp(dut, 32, "test_fcvt_down_pipe_fp32_16", Float32, fcvt_16, True,
- n_vals=100)
+ n_vals=100)
+
def test_down_pipe_fp64_16():
# XXX TODO: this has too great a dynamic range as input
# http://bugs.libre-riscv.org/show_bug.cgi?id=113
dut = FPCVTDownMuxInOut(64, 16, 4)
runfp(dut, 64, "test_fcvt_down_pipe_fp64_16", Float64, fcvt_16, True,
- n_vals=100)
+ n_vals=100)
+
def test_down_pipe_fp64_32():
# XXX TODO: this has too great a dynamic range as input
# http://bugs.libre-riscv.org/show_bug.cgi?id=113
dut = FPCVTDownMuxInOut(64, 32, 4)
runfp(dut, 64, "test_fcvt_down_pipe_fp64_32", Float64, fcvt_32, True,
- n_vals=100)
+ n_vals=100)
+
if __name__ == '__main__':
for i in range(200):
test_down_pipe_fp64_16()
test_down_pipe_fp32_16()
test_down_pipe_fp64_32()
-
""" test of FPCVTMuxInOut
"""
-from ieee754.fcvt.pipeline import (FPCVTDownMuxInOut,)
+from ieee754.fcvt.pipeline import FPCVTDownMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_single
from ieee754.fcvt.test.fcvt_data_32_16 import regressions
import unittest
+
def fcvt_16(x):
return Float16(x)
+
class TestFClassPipe(unittest.TestCase):
def test_pipe_fp32_16(self):
dut = FPCVTDownMuxInOut(32, 16, 4)
run_pipe_fp(dut, 32, "fcvt", unit_test_single, Float32,
regressions, fcvt_16, 100, True)
+
if __name__ == '__main__':
unittest.main()
-
""" test of FPCVTMuxInOut
"""
-from ieee754.fcvt.pipeline import (FPCVTDownMuxInOut,)
+from ieee754.fcvt.pipeline import FPCVTDownMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_single
from ieee754.fcvt.test.fcvt_data_64_16 import regressions
import unittest
+
def fcvt_16(x):
return Float16(x)
+
class TestFClassPipe(unittest.TestCase):
def test_pipe_fp64_16(self):
dut = FPCVTDownMuxInOut(64, 16, 4)
run_pipe_fp(dut, 64, "fcvt", unit_test_single, Float64,
regressions, fcvt_16, 100, True)
+
if __name__ == '__main__':
unittest.main()
-
""" test of FPCVTMuxInOut
"""
-from ieee754.fcvt.pipeline import (FPCVTMuxInOut,)
+from ieee754.fcvt.pipeline import FPCVTMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_single
from ieee754.fcvt.test.fcvt_data_64_32 import regressions
import unittest
+
def fcvt_32(x):
return Float32(x)
+
class TestFClassPipe(unittest.TestCase):
def test_pipe_fp64_32(self):
dut = FPCVTMuxInOut(64, 32, 4)
run_pipe_fp(dut, 64, "fcvt", unit_test_single, Float64,
regressions, fcvt_32, 100, True)
+
if __name__ == '__main__':
unittest.main()
-
""" test of FPCVTMuxInOut
"""
-from ieee754.fcvt.pipeline import (FPCVTUpMuxInOut,)
+from ieee754.fcvt.pipeline import FPCVTUpMuxInOut
from ieee754.fpcommon.test.fpmux import runfp
from sfpy import Float64, Float32, Float16
+
def fcvt_64(x):
return Float64(x)
+
def fcvt_32(x):
return Float32(x)
+
def test_up_pipe_fp16_32():
dut = FPCVTUpMuxInOut(16, 32, 4)
runfp(dut, 16, "test_fcvt_up_pipe_fp16_32", Float16, fcvt_32, True,
n_vals=100)
+
def test_up_pipe_fp16_64():
dut = FPCVTUpMuxInOut(16, 64, 4)
runfp(dut, 16, "test_fcvt_up_pipe_fp16_64", Float16, fcvt_64, True,
n_vals=100)
+
def test_up_pipe_fp32_64():
dut = FPCVTUpMuxInOut(32, 64, 4)
runfp(dut, 32, "test_fcvt_up_pipe_fp32_64", Float32, fcvt_64, True,
n_vals=100)
+
if __name__ == '__main__':
for i in range(200):
test_up_pipe_fp16_32()
test_up_pipe_fp16_64()
test_up_pipe_fp32_64()
-
""" test of FPCVTMuxInOut
"""
-from ieee754.fcvt.pipeline import (FPCVTUpMuxInOut,)
+from ieee754.fcvt.pipeline import FPCVTUpMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_half
from ieee754.fcvt.test.up_fcvt_data_16_32 import regressions
from sfpy import Float32, Float16
+
def fcvt_32(x):
return Float32(x)
+
def test_pipe_fp16_32():
dut = FPCVTUpMuxInOut(16, 32, 4)
run_pipe_fp(dut, 16, "upfcvt", unit_test_half, Float16,
regressions, fcvt_32, 10, True)
+
if __name__ == '__main__':
test_pipe_fp16_32()
-
""" test of FPCVTMuxInOut
"""
-from ieee754.fcvt.pipeline import (FPCVTUpMuxInOut,)
+from ieee754.fcvt.pipeline import FPCVTUpMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_half
from ieee754.fcvt.test.up_fcvt_data_16_32 import regressions
from sfpy import Float64, Float16
+
def fcvt_64(x):
return Float64(x)
+
def test_pipe_fp16_64():
dut = FPCVTUpMuxInOut(16, 64, 4)
run_pipe_fp(dut, 16, "upfcvt", unit_test_half, Float16,
regressions, fcvt_64, 10, True)
+
if __name__ == '__main__':
test_pipe_fp16_64()
-
""" test of FPCVTMuxInOut
"""
-from ieee754.fcvt.pipeline import (FPCVTUpMuxInOut,)
+from ieee754.fcvt.pipeline import FPCVTUpMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_single
from ieee754.fcvt.test.up_fcvt_data_32_64 import regressions
from sfpy import Float64, Float32
+
def fcvt_64(x):
return Float64(x)
+
def test_pipe_fp32_64():
dut = FPCVTUpMuxInOut(32, 64, 4)
run_pipe_fp(dut, 32, "upfcvt", unit_test_single, Float32,
regressions, fcvt_64, 10, True)
+
if __name__ == '__main__':
test_pipe_fp32_64()
-
""" test of FPADDMuxInOut
"""
-from ieee754.fpadd.pipeline import (FPADDMuxInOut,)
+from ieee754.fpadd.pipeline import FPADDMuxInOut
from ieee754.fpcommon.test.fpmux import runfp
from sfpy import Float64, Float32, Float16
from operator import add
+
def test_pipe_fp16():
dut = FPADDMuxInOut(16, 4)
runfp(dut, 16, "test_fpadd_pipe_fp16", Float16, add)
+
def test_pipe_fp32():
dut = FPADDMuxInOut(32, 4)
runfp(dut, 32, "test_fpadd_pipe_fp32", Float32, add)
+
def test_pipe_fp64():
dut = FPADDMuxInOut(64, 4)
runfp(dut, 64, "test_fpadd_pipe_fp64", Float64, add)
+
if __name__ == '__main__':
test_pipe_fp16()
test_pipe_fp32()
test_pipe_fp64()
-
""" test of FPADDMuxInOut
"""
-from ieee754.fpadd.pipeline import (FPADDMuxInOut,)
+from ieee754.fpadd.pipeline import FPADDMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_half
from ieee754.fpadd.test.add_data16 import regressions
def test_pipe_fp16():
dut = FPADDMuxInOut(16, 4)
run_pipe_fp(dut, 16, "add", unit_test_half, Float16,
- regressions, add, 10)
+ regressions, add, 10)
if __name__ == '__main__':
""" test of FPADDMuxInOut
"""
-from ieee754.fpadd.pipeline import (FPADDMuxInOut,)
+from ieee754.fpadd.pipeline import FPADDMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_single
from ieee754.fpadd.test.add_data32 import regressions
def test_pipe_fp32():
dut = FPADDMuxInOut(32, 4)
run_pipe_fp(dut, 32, "add", unit_test_single, Float32,
- regressions, add, 10)
+ regressions, add, 10)
if __name__ == '__main__':
""" test of FPADDMuxInOut
"""
-from ieee754.fpadd.pipeline import (FPADDMuxInOut,)
+from ieee754.fpadd.pipeline import FPADDMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_double
from ieee754.fpadd.test.add_data64 import regressions
def test_pipe_fp64():
dut = FPADDMuxInOut(64, 4)
run_pipe_fp(dut, 64, "add", unit_test_double, Float64,
- regressions, add, 10)
+ regressions, add, 10)
if __name__ == '__main__':
class MuxInOut:
def __init__(self, dut, width, fpkls, fpop, vals, single_op, opcode,
- cancel=False, feedback_width=None):
- self.cancel = cancel # allow (test) cancellation
+ cancel=False, feedback_width=None):
+ self.cancel = cancel # allow (test) cancellation
self.dut = dut
self.fpkls = fpkls
self.fpop = fpop
if hasattr(res, "bits"):
self.do[muxid_out][i] = res.bits
else:
- self.do[muxid_out][i] = res # for FP to INT
+ self.do[muxid_out][i] = res # for FP to INT
def send(self, muxid):
rs = self.dut.p[muxid]
yield rs.data_i.b.eq(op2)
yield rs.data_i.muxid.eq(muxid)
if hasattr(rs, "mask_i"):
- yield rs.mask_i.eq(1) # TEMPORARY HACK
+ yield rs.mask_i.eq(1) # TEMPORARY HACK
yield
o_p_ready = yield rs.ready_o
while not o_p_ready:
else:
r = res
print("send", muxid, i, hex(op1), hex(r),
- fop1, res)
+ fop1, res)
else:
fop1 = self.fpkls(op1)
fop2 = self.fpkls(op2)
res = self.fpop(fop1, fop2)
print("send", muxid, i, hex(op1), hex(op2), hex(res.bits),
- fop1, fop2, res)
+ fop1, fop2, res)
self.sent[muxid].append(i)
yield rs.valid_i.eq(0)
if hasattr(rs, "mask_i"):
- yield rs.mask_i.eq(0) # TEMPORARY HACK
+ yield rs.mask_i.eq(0) # TEMPORARY HACK
# wait until it's received
while i in self.sent[muxid]:
yield
print("send ended", muxid)
- ## wait random period of time before queueing another value
- #for i in range(randint(0, 3)):
+ # wait random period of time before queueing another value
+ # for i in range(randint(0, 3)):
# yield
#send_range = randint(0, 3)
- #if send_range == 0:
+ # if send_range == 0:
# send = True
- #else:
+ # else:
# send = randint(0, send_range) != 0
def rcv(self, muxid):
cancel = self.cancel and (randint(0, 2) == 0)
if hasattr(rs, "mask_i") and len(self.sent[muxid]) > 0 and cancel:
todel = self.sent[muxid].pop()
- print ("to delete", muxid, self.sent[muxid], todel)
+ print("to delete", muxid, self.sent[muxid], todel)
if todel in self.do[muxid]:
del self.do[muxid][todel]
yield rs.stop_i.eq(1)
- print ("left", muxid, self.do[muxid])
+ print("left", muxid, self.do[muxid])
if len(self.do[muxid]) == 0:
break
#stall_range = randint(0, 3)
- #for j in range(randint(1,10)):
+ # for j in range(randint(1,10)):
# stall = randint(0, stall_range) != 0
# yield self.dut.n[0].ready_i.eq(stall)
# yield
yield n.ready_i.eq(1)
yield
if hasattr(rs, "mask_i"):
- yield rs.stop_i.eq(0) # resets cancel mask
+ yield rs.stop_i.eq(0) # resets cancel mask
o_n_valid = yield n.valid_o
i_n_ready = yield n.ready_i
out_z = yield n.data_o.z
if not self.sent[muxid]:
- print ("cancelled/recv", muxid, hex(out_z))
+ print("cancelled/recv", muxid, hex(out_z))
continue
out_i = self.sent[muxid].pop()
assert self.do[muxid][out_i] == out_z
- print ("senddel", muxid, out_i, self.sent[muxid])
+ print("senddel", muxid, out_i, self.sent[muxid])
del self.do[muxid][out_i]
# check if there's any more outputs
#op1 = 0x3449f9a9
#op1 = 0x1ba94baa
- #if i % 2:
+ # if i % 2:
# op1 = 0x0001
- #else:
+ # else:
# op1 = 0x3C00
# FRSQRT
""" test of FPDIVMuxInOut
"""
-from ieee754.fpdiv.pipeline import (FPDIVMuxInOut,)
+from ieee754.fpdiv.pipeline import FPDIVMuxInOut
from ieee754.fpcommon.test.fpmux import runfp
from ieee754.div_rem_sqrt_rsqrt.core import DivPipeCoreOperation
""" test of FPDIVMuxInOut
"""
-from ieee754.fpdiv.pipeline import (FPDIVMuxInOut,)
+from ieee754.fpdiv.pipeline import FPDIVMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_half
from ieee754.fpdiv.test.div_data16 import regressions
""" test of FPDIVMuxInOut
"""
-from ieee754.fpdiv.pipeline import (FPDIVMuxInOut,)
+from ieee754.fpdiv.pipeline import FPDIVMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_single
from ieee754.fpdiv.test.div_data32 import regressions
""" test of FPDIVMuxInOut
"""
-from ieee754.fpdiv.pipeline import (FPDIVMuxInOut,)
+from ieee754.fpdiv.pipeline import FPDIVMuxInOut
from ieee754.fpcommon.test.fpmux import runfp
from ieee754.div_rem_sqrt_rsqrt.core import DivPipeCoreOperation
""" test of FPDIVMuxInOut
"""
-from ieee754.fpdiv.pipeline import (FPDIVMuxInOut,)
+from ieee754.fpdiv.pipeline import FPDIVMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_half
#from ieee754.fpdiv.test.rsqrt_data16 import regressions
run_pipe_fp(dut, 16, "rsqrt16", unit_test_half, Float16, None,
rsqrt, 100, single_op=True, opcode=opcode)
+
if __name__ == '__main__':
unittest.main()
""" test of FPDIVMuxInOut
"""
-from ieee754.fpdiv.pipeline import (FPDIVMuxInOut,)
+from ieee754.fpdiv.pipeline import FPDIVMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_single
#from ieee754.fpdiv.test.rsqrt_data32 import regressions
run_pipe_fp(dut, 32, "rsqrt32", unit_test_single, Float32, None,
rsqrt, 100, single_op=True, opcode=opcode)
+
if __name__ == '__main__':
unittest.main()
""" test of FPDIVMuxInOut
"""
-from ieee754.fpdiv.pipeline import (FPDIVMuxInOut,)
+from ieee754.fpdiv.pipeline import FPDIVMuxInOut
from ieee754.fpcommon.test.fpmux import runfp
from ieee754.div_rem_sqrt_rsqrt.core import DivPipeCoreOperation
""" test of FPDIVMuxInOut
"""
-from ieee754.fpdiv.pipeline import (FPDIVMuxInOut,)
+from ieee754.fpdiv.pipeline import FPDIVMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_half
from ieee754.fpdiv.test.sqrt_data16 import regressions
run_pipe_fp(dut, 16, "sqrt16", unit_test_half, Float16, regressions,
sqrt, 100, single_op=True, opcode=opcode)
+
if __name__ == '__main__':
unittest.main()
""" test of FPDIVMuxInOut
"""
-from ieee754.fpdiv.pipeline import (FPDIVMuxInOut,)
+from ieee754.fpdiv.pipeline import FPDIVMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_single
from ieee754.fpdiv.test.sqrt_data32 import regressions
run_pipe_fp(dut, 32, "sqrt32", unit_test_single, Float32, regressions,
sqrt, 100, single_op=True, opcode=opcode)
+
if __name__ == '__main__':
unittest.main()
""" test of FPDIVMuxInOut
"""
-from ieee754.fpdiv.pipeline import (FPDIVMuxInOut,)
+from ieee754.fpdiv.pipeline import FPDIVMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_double
#from ieee754.fpdiv.test.sqrt_data64 import regressions
run_pipe_fp(dut, 64, "sqrt64", unit_test_double, Float64, None,
sqrt, 100, single_op=True, opcode=opcode)
+
if __name__ == '__main__':
unittest.main()
""" test of FPMULMuxInOut
"""
-from ieee754.fpmul.pipeline import (FPMULMuxInOut,)
+from ieee754.fpmul.pipeline import FPMULMuxInOut
from ieee754.fpcommon.test.fpmux import runfp
from sfpy import Float64, Float32, Float16
from operator import mul
+
def test_pipe_fp16():
dut = FPMULMuxInOut(16, 4)
runfp(dut, 16, "test_fpmul_pipe_fp16", Float16, mul, n_vals=50)
+
def test_pipe_fp32():
dut = FPMULMuxInOut(32, 4)
runfp(dut, 32, "test_fpmul_pipe_fp32", Float32, mul, n_vals=50)
+
def test_pipe_fp64():
dut = FPMULMuxInOut(64, 4)
runfp(dut, 64, "test_fpmul_pipe_fp64", Float64, mul, n_vals=50)
+
if __name__ == '__main__':
for i in range(1000):
test_pipe_fp16()
""" test of FPMULMuxInOut
"""
-from ieee754.fpmul.pipeline import (FPMULMuxInOut,)
+from ieee754.fpmul.pipeline import FPMULMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_half
from ieee754.fpmul.test.mul_data16 import regressions
def test_pipe_fp16():
dut = FPMULMuxInOut(16, 4)
run_pipe_fp(dut, 16, "mul", unit_test_half, Float16,
- regressions, mul, 10)
+ regressions, mul, 10)
if __name__ == '__main__':
""" test of FPMULMuxInOut
"""
-from ieee754.fpmul.pipeline import (FPMULMuxInOut,)
+from ieee754.fpmul.pipeline import FPMULMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_single
from ieee754.fpmul.test.mul_data32 import regressions
def test_pipe_fp32():
dut = FPMULMuxInOut(32, 4)
run_pipe_fp(dut, 32, "mul", unit_test_single, Float32,
- regressions, mul, 10)
+ regressions, mul, 10)
if __name__ == '__main__':
""" test of FPMULMuxInOut
"""
-from ieee754.fpmul.pipeline import (FPMULMuxInOut,)
+from ieee754.fpmul.pipeline import FPMULMuxInOut
from ieee754.fpcommon.test.case_gen import run_pipe_fp
from ieee754.fpcommon.test import unit_test_double
from ieee754.fpmul.test.mul_data64 import regressions
def test_pipe_fp64():
dut = FPMULMuxInOut(64, 4)
run_pipe_fp(dut, 64, "mul", unit_test_double, Float64,
- regressions, mul, 10)
+ regressions, mul, 10)
if __name__ == '__main__':
def first_zero(x):
res = 0
for i in range(16):
- if x & (1<<i):
+ if x & (1 << i):
return res
res += 1
+
def count_bits(x):
res = 0
for i in range(16):
- if x & (1<<i):
+ if x & (1 << i):
res += 1
return res
self.b = SimdSignal(partpoints, width)
self.bsig = Signal(width)
self.add_output = Signal(width)
- self.ls_output = Signal(width) # left shift
- self.ls_scal_output = Signal(width) # left shift
- self.rs_output = Signal(width) # right shift
- self.rs_scal_output = Signal(width) # right shift
+ self.ls_output = Signal(width) # left shift
+ self.ls_scal_output = Signal(width) # left shift
+ self.rs_output = Signal(width) # right shift
+ self.rs_scal_output = Signal(width) # right shift
self.sub_output = Signal(width)
self.eq_output = Signal(len(partpoints)+1)
self.gt_output = Signal(len(partpoints)+1)
self.b = SimdSignal(partpoints, width)
self.bsig = Signal(width)
self.add_output = Signal(width)
- self.ls_output = Signal(width) # left shift
- self.ls_scal_output = Signal(width) # left shift
- self.rs_output = Signal(width) # right shift
- self.rs_scal_output = Signal(width) # right shift
+ self.ls_output = Signal(width) # left shift
+ self.ls_scal_output = Signal(width) # left shift
+ self.rs_output = Signal(width) # right shift
+ self.rs_scal_output = Signal(width) # right shift
self.sub_output = Signal(width)
self.eq_output = Signal(len(partpoints)+1)
self.gt_output = Signal(len(partpoints)+1)
apart, bpart = [], []
ajump, bjump = alen // 4, blen // 4
for i in range(4):
- apart.append((a >> (ajump*i) & ((1<<ajump)-1)))
- bpart.append((b >> (bjump*i) & ((1<<bjump)-1)))
+ apart.append((a >> (ajump*i) & ((1 << ajump)-1)))
+ bpart.append((b >> (bjump*i) & ((1 << bjump)-1)))
- print ("apart bpart", hex(a), hex(b),
- list(map(hex, apart)), list(map(hex, bpart)))
+ print("apart bpart", hex(a), hex(b),
+ list(map(hex, apart)), list(map(hex, bpart)))
yield module.a.lower().eq(a)
yield module.b.lower().eq(b)
for i in runlengths:
# a first
for _ in range(i):
- print ("runlength", i,
- "ai", ai,
- "apart", hex(apart[ai]),
- "j", j)
+ print("runlength", i,
+ "ai", ai,
+ "apart", hex(apart[ai]),
+ "j", j)
y |= apart[ai] << j
- print (" y", hex(y))
+ print(" y", hex(y))
j += ajump
ai += 1
# now b
for _ in range(i):
- print ("runlength", i,
- "bi", bi,
- "bpart", hex(bpart[bi]),
- "j", j)
+ print("runlength", i,
+ "bi", bi,
+ "bpart", hex(bpart[bi]),
+ "j", j)
y |= bpart[bi] << j
- print (" y", hex(y))
+ print(" y", hex(y))
j += bjump
bi += 1
alen = 16
# test values a
for a in [0x0000,
- 0xDCBA,
- 0x1234,
- 0xABCD,
- 0xFFFF,
- 0x0000,
- 0x1F1F,
- 0xF1F1,
- ]:
+ 0xDCBA,
+ 0x1234,
+ 0xABCD,
+ 0xFFFF,
+ 0x0000,
+ 0x1F1F,
+ 0xF1F1,
+ ]:
# convert a to partitions
apart = []
ajump = alen // 4
for i in range(4):
- apart.append((a >> (ajump*i) & ((1<<ajump)-1)))
+ apart.append((a >> (ajump*i) & ((1 << ajump)-1)))
- print ("apart", hex(a), list(map(hex, apart)))
+ print("apart", hex(a), list(map(hex, apart)))
yield module.a.lower().eq(a)
yield Delay(0.1e-6)
# a twice because the test is Repl(a, 2)
for aidx in range(2):
for _ in range(i):
- print ("runlength", i,
- "ai", ai,
- "apart", hex(apart[ai[aidx]]),
- "j", j)
+ print("runlength", i,
+ "ai", ai,
+ "apart", hex(apart[ai[aidx]]),
+ "j", j)
y |= apart[ai[aidx]] << j
- print (" y", hex(y))
+ print(" y", hex(y))
j += ajump
ai[aidx] += 1
part_mask, scalar)
test_name = "part_sig_ass_%d_%d_%s_%s" % (in_width, out_width,
- "signed" if out_signed else "unsigned",
- "scalar" if scalar else "partitioned")
+ "signed" if out_signed else "unsigned",
+ "scalar" if scalar else "partitioned")
traces = [part_mask,
module.ass_out.lower()]
0x00c0,
0x0c00,
0xc000,
- 0x1234,
- 0xDCBA,
- 0xABCD,
- 0x0000,
- 0xFFFF,
- ] + randomvals:
+ 0x1234,
+ 0xDCBA,
+ 0xABCD,
+ 0x0000,
+ 0xFFFF,
+ ] + randomvals:
# work out the runlengths for this mask.
# 0b011 returns [1,1,2] (for a mask of length 3)
mval = yield part_mask
runlengths = get_runlengths(mval, 3)
- print ("test a", hex(a), "mask", bin(mval), "widths",
- in_width, out_width,
- "signed", out_signed,
- "scalar", scalar)
+ print("test a", hex(a), "mask", bin(mval), "widths",
+ in_width, out_width,
+ "signed", out_signed,
+ "scalar", scalar)
# convert a to runlengths sub-sections
apart = []
ajump = alen // 4
ai = 0
for i in runlengths:
- subpart = (a >> (ajump*ai) & ((1<<(ajump*i))-1))
- msb = (subpart >> ((ajump*i)-1)) # will contain the sign
+ subpart = (a >> (ajump*ai) & ((1 << (ajump*i))-1))
+ # will contain the sign
+ msb = (subpart >> ((ajump*i)-1))
apart.append((subpart, msb))
- print ("apart", ajump*i, hex(a), hex(subpart), msb)
+ print("apart", ajump*i, hex(a), hex(subpart), msb)
if not scalar:
ai += i
signext = 0
if out_signed and ojump > ajump:
if amsb:
- signext = (-1 << ajump*i) & ((1<<(ojump*i))-1)
+ signext = (-1 << ajump *
+ i) & ((1 << (ojump*i))-1)
av |= signext
# truncate if needed
if ojump < ajump:
- av &= ((1<<(ojump*i))-1)
- print ("runlength", i,
- "ai", ai,
- "apart", hex(av), amsb,
- "signext", hex(signext),
- "j", j)
+ av &= ((1 << (ojump*i))-1)
+ print("runlength", i,
+ "ai", ai,
+ "apart", hex(av), amsb,
+ "signext", hex(signext),
+ "j", j)
y |= av << j
- print (" y", hex(y))
+ print(" y", hex(y))
j += ojump*i
ai += 1
- y &= (1<<out_width)-1
+ y &= (1 << out_width)-1
# check the result
outval = (yield module.ass_out.lower())
- outval &= (1<<out_width)-1
+ outval &= (1 << out_width)-1
msg = f"{msg_prefix}: assign " + \
f"mask 0x{mval:X} input 0x{a:X}" + \
f" => expected 0x{y:X} != actual 0x{outval:X}"
# run the actual tests, here - 16/8/4 bit partitions
for (mask, name) in ((0, "16-bit"),
- (0b10, "8-bit"),
- (0b111, "4-bit")):
+ (0b10, "8-bit"),
+ (0b111, "4-bit")):
with self.subTest(name + " " + test_name):
yield part_mask.eq(mask)
yield Settle()
0xF000,
0x00FF,
0xFF00,
- 0x1234,
- 0xABCD,
- 0xFFFF,
- 0x8000,
- 0xBEEF, 0xFEED,
- ]+randomvals:
+ 0x1234,
+ 0xABCD,
+ 0xFFFF,
+ 0x8000,
+ 0xBEEF, 0xFEED,
+ ]+randomvals:
with self.subTest("%s %s %s" % (msg_prefix,
- test_fn.__name__, hex(a))):
+ test_fn.__name__, hex(a))):
yield module.a.lower().eq(a)
yield Delay(0.1e-6)
# convert to mask_list
for (test_fn, mod_attr) in ((test_xor_fn, "xor"),
(test_all_fn, "all"),
- (test_bool_fn, "any"), # same as bool
+ (test_bool_fn, "any"), # same as bool
(test_bool_fn, "bool"),
#(test_ne_fn, "ne"),
):
yield from test_horizop("16-bit", test_fn, mod_attr, 0b1111)
yield part_mask.eq(0b10)
yield from test_horizop("8-bit", test_fn, mod_attr,
- 0b1100, 0b0011)
+ 0b1100, 0b0011)
yield part_mask.eq(0b1111)
yield from test_horizop("4-bit", test_fn, mod_attr,
- 0b1000, 0b0100, 0b0010, 0b0001)
+ 0b1000, 0b0100, 0b0010, 0b0001)
def test_ls_scal_fn(carry_in, a, b, mask):
# reduce range of b
bits = count_bits(mask)
newb = b & ((bits-1))
- print ("%x %x %x bits %d trunc %x" % \
- (a, b, mask, bits, newb))
+ print("%x %x %x bits %d trunc %x" %
+ (a, b, mask, bits, newb))
b = newb
# TODO: carry
carry_in = 0
# reduce range of b
bits = count_bits(mask)
newb = b & ((bits-1))
- print ("%x %x %x bits %d trunc %x" % \
- (a, b, mask, bits, newb))
+ print("%x %x %x bits %d trunc %x" %
+ (a, b, mask, bits, newb))
b = newb
# TODO: carry
carry_in = 0
# reduce range of b
bits = count_bits(mask)
fz = first_zero(mask)
- newb = b & ((bits-1)<<fz)
- print ("%x %x %x bits %d zero %d trunc %x" % \
- (a, b, mask, bits, fz, newb))
+ newb = b & ((bits-1) << fz)
+ print("%x %x %x bits %d zero %d trunc %x" %
+ (a, b, mask, bits, fz, newb))
b = newb
# TODO: carry
carry_in = 0
lsb = mask & ~(mask-1) if carry_in else 0
b = (b & mask)
- b = b >>fz
+ b = b >> fz
sum = ((a & mask) << b)
result = mask & sum
carry = (sum & mask) != sum
# reduce range of b
bits = count_bits(mask)
fz = first_zero(mask)
- newb = b & ((bits-1)<<fz)
- print ("%x %x %x bits %d zero %d trunc %x" % \
- (a, b, mask, bits, fz, newb))
+ newb = b & ((bits-1) << fz)
+ print("%x %x %x bits %d zero %d trunc %x" %
+ (a, b, mask, bits, fz, newb))
b = newb
# TODO: carry
carry_in = 0
lsb = mask & ~(mask-1) if carry_in else 0
b = (b & mask)
- b = b >>fz
+ b = b >> fz
sum = ((a & mask) >> b)
result = mask & sum
carry = (sum & mask) != sum
y = 0
carry_result = 0
for i, mask in enumerate(mask_list):
- print ("i/mask", i, hex(mask))
+ print("i/mask", i, hex(mask))
res, c = test_fn(carry, a, b, mask)
y |= res
lsb = mask & ~(mask - 1)
# output attribute (mod_attr) will contain the result to be
# compared against the expected output from test_fn
for (test_fn, mod_attr) in (
- (test_ls_scal_fn, "ls_scal"),
- (test_ls_fn, "ls"),
- (test_rs_scal_fn, "rs_scal"),
- (test_rs_fn, "rs"),
- (test_add_fn, "add"),
- (test_sub_fn, "sub"),
- (test_neg_fn, "neg"),
- (test_signed_fn, "signed"),
- ):
+ (test_ls_scal_fn, "ls_scal"),
+ (test_ls_fn, "ls"),
+ (test_rs_scal_fn, "rs_scal"),
+ (test_rs_fn, "rs"),
+ (test_add_fn, "add"),
+ (test_sub_fn, "sub"),
+ (test_neg_fn, "neg"),
+ (test_signed_fn, "signed"),
+ ):
yield part_mask.eq(0)
yield from test_op("16-bit", 1, test_fn, mod_attr, 0xFFFF)
yield from test_op("16-bit", 0, test_fn, mod_attr, 0xFFFF)
FULL_ADDER_INPUT_COUNT = 3
+
class AddReduceData:
def __init__(self, part_pts, n_inputs, output_width, n_parts):
self.part_ops = [Signal(2, name=f"part_ops_{i}", reset_less=True)
- for i in range(n_parts)]
+ for i in range(n_parts)]
self.terms = [Signal(output_width, name=f"terms_{i}",
- reset_less=True)
- for i in range(n_inputs)]
+ reset_less=True)
+ for i in range(n_inputs)]
self.part_pts = part_pts.like()
def eq_from(self, part_pts, inputs, part_ops):
return [self.part_pts.eq(part_pts)] + \
[self.terms[i].eq(inputs[i])
- for i in range(len(self.terms))] + \
+ for i in range(len(self.terms))] + \
[self.part_ops[i].eq(part_ops[i])
- for i in range(len(self.part_ops))]
+ for i in range(len(self.part_ops))]
def eq(self, rhs):
return self.eq_from(rhs.part_pts, rhs.terms, rhs.part_ops)
def __init__(self, part_pts, output_width, n_parts):
self.part_ops = [Signal(2, name=f"part_ops_{i}", reset_less=True)
- for i in range(n_parts)]
+ for i in range(n_parts)]
self.output = Signal(output_width, reset_less=True)
self.part_pts = part_pts.like()
return [self.part_pts.eq(part_pts)] + \
[self.output.eq(output)] + \
[self.part_ops[i].eq(part_ops[i])
- for i in range(len(self.part_ops))]
+ for i in range(len(self.part_ops))]
def eq(self, rhs):
return self.eq_from(rhs.part_pts, rhs.output, rhs.part_ops)
"""
def __init__(self, pspec, lidx, n_inputs, partition_points,
- partition_step=1):
+ partition_step=1):
self.lidx = lidx
self.partition_step = partition_step
self.output_width = pspec.width * 2
def ospec(self):
return FinalReduceData(self.partition_points,
- self.output_width, self.n_parts)
+ self.output_width, self.n_parts)
def elaborate(self, platform):
"""Elaborate this module."""
"""
def __init__(self, pspec, lidx, n_inputs, partition_points,
- partition_step=1):
+ partition_step=1):
"""Create an ``AddReduce``.
:param inputs: input ``Signal``s to be summed.
# copy reg part points and part ops to output
m.d.comb += self.o.part_pts.eq(self.i.part_pts)
m.d.comb += [self.o.part_ops[i].eq(self.i.part_ops[i])
- for i in range(len(self.i.part_ops))]
+ for i in range(len(self.i.part_ops))]
# set up the partition mask (for the adders)
part_mask = Signal(self.output_width, reset_less=True)
"""
def __init__(self, inputs, output_width, register_levels, part_pts,
- part_ops, partition_step=1):
+ part_ops, partition_step=1):
"""Create an ``AddReduce``.
:param inputs: input ``Signal``s to be summed.
self._part_ops = part_ops
n_parts = len(part_ops)
self.i = AddReduceData(part_pts, len(inputs),
- output_width, n_parts)
+ output_width, n_parts)
AddReduceInternal.__init__(self, pspec, n_inputs, part_pts,
partition_step)
self.o = FinalReduceData(part_pts, output_width, n_parts)
"""Elaborate this module."""
m = Module()
- m.d.comb += self.i.eq_from(self._part_pts, self._inputs, self._part_ops)
+ m.d.comb += self.i.eq_from(self._part_pts,
+ self._inputs, self._part_ops)
for i, next_level in enumerate(self.levels):
setattr(m.submodules, "next_level%d" % i, next_level)
m.d.sync += mcur.i.eq(i)
else:
m.d.comb += mcur.i.eq(i)
- i = mcur.o # for next loop
+ i = mcur.o # for next loop
# output comes from last module
m.d.comb += self.o.eq(i)
else:
term_enabled = None
self.enabled = term_enabled
- self.term.name = "term_%d_%d" % (a_index, b_index) # rename
+ self.term.name = "term_%d_%d" % (a_index, b_index) # rename
def elaborate(self, platform):
this class is to be wrapped with a for-loop on the "a" operand.
it creates a second-level for-loop on the "b" operand.
"""
+
def __init__(self, width, twidth, pbwid, a_index, blen):
self.a_index = a_index
self.blen = blen
self.a = Signal(twidth//2, reset_less=True)
self.b = Signal(twidth//2, reset_less=True)
self.pb_en = Signal(pbwid, reset_less=True)
- self.terms = [Signal(twidth, name="term%d"%i, reset_less=True) \
- for i in range(blen)]
+ self.terms = [Signal(twidth, name="term%d" % i, reset_less=True)
+ for i in range(blen)]
def elaborate(self, platform):
m = Module()
comb = m.d.comb
bit_wid = self.bit_width
- ext = Repl(0, bit_wid) # extend output to HI part
+ ext = Repl(0, bit_wid) # extend output to HI part
# determine sign of each incoming number *in this partition*
enabled = Signal(reset_less=True)
the extra terms - as separate terms - are then thrown at the
AddReduce alongside the multiplication part-results.
"""
+
def __init__(self, part_pts, width, n_parts, pbwid):
self.pbwid = pbwid
self.a = Signal(64, reset_less=True)
self.b = Signal(64, reset_less=True)
self.a_signed = [Signal(name=f"a_signed_{i}", reset_less=True)
- for i in range(8)]
+ for i in range(8)]
self.b_signed = [Signal(name=f"_b_signed_{i}", reset_less=True)
- for i in range(8)]
+ for i in range(8)]
self.pbs = Signal(pbwid, reset_less=True)
# outputs
self.parts = [Signal(name=f"part_{i}", reset_less=True)
- for i in range(n_parts)]
+ for i in range(n_parts)]
self.not_a_term = Signal(width, reset_less=True)
self.neg_lsb_a_term = Signal(width, reset_less=True)
byte_count = 8 // len(parts)
not_a_term, neg_lsb_a_term, not_b_term, neg_lsb_b_term = (
- self.not_a_term, self.neg_lsb_a_term,
- self.not_b_term, self.neg_lsb_b_term)
+ self.not_a_term, self.neg_lsb_a_term,
+ self.not_b_term, self.neg_lsb_b_term)
- byte_width = 8 // len(parts) # byte width
+ byte_width = 8 // len(parts) # byte width
bit_wid = 8 * byte_width # bit width
nat, nbt, nla, nlb = [], [], [], []
for i in range(len(parts)):
setattr(m.submodules, "lnt_%d_a_%d" % (bit_wid, i), pa)
m.d.comb += pa.part.eq(parts[i])
m.d.comb += pa.op.eq(self.a.bit_select(bit_wid * i, bit_wid))
- m.d.comb += pa.signed.eq(self.b_signed[i * byte_width]) # yes b
- m.d.comb += pa.msb.eq(self.b[(i + 1) * bit_wid - 1]) # really, b
+ m.d.comb += pa.signed.eq(self.b_signed[i * byte_width]) # yes b
+ m.d.comb += pa.msb.eq(self.b[(i + 1) * bit_wid - 1]) # really, b
nat.append(pa.nt)
nla.append(pa.nl)
setattr(m.submodules, "lnt_%d_b_%d" % (bit_wid, i), pb)
m.d.comb += pb.part.eq(parts[i])
m.d.comb += pb.op.eq(self.b.bit_select(bit_wid * i, bit_wid))
- m.d.comb += pb.signed.eq(self.a_signed[i * byte_width]) # yes a
- m.d.comb += pb.msb.eq(self.a[(i + 1) * bit_wid - 1]) # really, a
+ m.d.comb += pb.signed.eq(self.a_signed[i * byte_width]) # yes a
+ m.d.comb += pb.msb.eq(self.a[(i + 1) * bit_wid - 1]) # really, a
nbt.append(pb.nt)
nlb.append(pb.nl)
not_b_term.eq(Cat(*nbt)),
neg_lsb_a_term.eq(Cat(*nla)),
neg_lsb_b_term.eq(Cat(*nlb)),
- ]
+ ]
return m
""" selects the HI/LO part of the multiplication, for a given bit-width
the output is also reconstructed in its SIMD (partition) lanes.
"""
+
def __init__(self, width, out_wid, n_parts):
self.width = width
self.n_parts = n_parts
self.part_ops = [Signal(2, name="dpop%d" % i, reset_less=True)
- for i in range(8)]
+ for i in range(8)]
self.intermed = Signal(out_wid, reset_less=True)
self.output = Signal(out_wid//2, reset_less=True)
that some partitions requested 8-bit computation whilst others
requested 16 or 32 bit.
"""
+
def __init__(self, pspec, part_pts):
self.part_pts = part_pts
m.d.comb += op.eq(
Mux(d8[i] | d16[i // 2],
Mux(d8[i], i8.bit_select(i * 8, 8),
- i16.bit_select(i * 8, 8)),
+ i16.bit_select(i * 8, 8)),
Mux(d32[i // 4], i32.bit_select(i * 8, 8),
- i64.bit_select(i * 8, 8))))
+ i64.bit_select(i * 8, 8))))
ol.append(op)
# create outputs
class OrMod(Elaboratable):
""" ORs four values together in a hierarchical tree
"""
+
def __init__(self, wid):
self.wid = wid
self.orin = [Signal(wid, name="orin%d" % i, reset_less=True)
asig = self.part_ops != OP_MUL_UNSIGNED_HIGH
bsig = (self.part_ops == OP_MUL_LOW) \
- | (self.part_ops == OP_MUL_SIGNED_HIGH)
+ | (self.part_ops == OP_MUL_SIGNED_HIGH)
m.d.comb += self.a_signed.eq(asig)
m.d.comb += self.b_signed.eq(bsig)
def __init__(self, part_pts, output_width, n_parts):
self.part_ops = [Signal(2, name=f"part_ops_{i}", reset_less=True)
- for i in range(n_parts)]
+ for i in range(n_parts)]
self.part_pts = part_pts.like()
self.outputs = [Signal(output_width, name="io%d" % i, reset_less=True)
- for i in range(4)]
+ for i in range(4)]
# intermediates (needed for unit tests)
self.intermediate_output = Signal(output_width)
def eq_from(self, part_pts, outputs, intermediate_output,
- part_ops):
+ part_ops):
return [self.part_pts.eq(part_pts)] + \
[self.intermediate_output.eq(intermediate_output)] + \
[self.outputs[i].eq(outputs[i])
- for i in range(4)] + \
+ for i in range(4)] + \
[self.part_ops[i].eq(part_ops[i])
- for i in range(len(self.part_ops))]
+ for i in range(len(self.part_ops))]
def eq(self, rhs):
return self.eq_from(rhs.part_pts, rhs.outputs,
return [self.part_pts.eq(part_pts)] + \
[self.a.eq(a), self.b.eq(b)] + \
[self.part_ops[i].eq(part_ops[i])
- for i in range(len(self.part_ops))]
+ for i in range(len(self.part_ops))]
def eq(self, rhs):
return self.eq_from(rhs.part_pts, rhs.a, rhs.b, rhs.part_ops)
class OutputData:
def __init__(self):
- self.intermediate_output = Signal(128) # needed for unit tests
+ self.intermediate_output = Signal(128) # needed for unit tests
self.output = Signal(64)
def eq(self, rhs):
m.submodules.nla_or = nla_or = OrMod(128)
m.submodules.nlb_or = nlb_or = OrMod(128)
for l, mod in [(nat_l, nat_or),
- (nbt_l, nbt_or),
- (nla_l, nla_or),
- (nlb_l, nlb_or)]:
+ (nbt_l, nbt_or),
+ (nla_l, nla_or),
+ (nlb_l, nlb_or)]:
for i in range(len(l)):
m.d.comb += mod.orin[i].eq(l[i])
terms.append(mod.orout)
# copy reg part points and part ops to output
m.d.comb += self.o.part_pts.eq(eps)
m.d.comb += [self.o.part_ops[i].eq(self.i.part_ops[i])
- for i in range(len(self.i.part_ops))]
+ for i in range(len(self.i.part_ops))]
return m
flip-flops are to be inserted.
"""
- self.id_wid = 0 # num_bits(num_rows)
+ self.id_wid = 0 # num_bits(num_rows)
self.op_wid = 0
self.pspec = PipelineSpec(64, self.id_wid, self.op_wid, n_ops=3)
self.pspec.n_parts = 8
terms = t.o.terms
- at = AddReduceInternal(self.pspec, n_inputs, part_pts, partition_step=2)
+ at = AddReduceInternal(self.pspec, n_inputs,
+ part_pts, partition_step=2)
i = t.o
for idx in range(len(at.levels)):
m.d.sync += o.eq(mcur.process(i))
else:
m.d.comb += o.eq(mcur.process(i))
- i = o # for next loop
+ i = o # for next loop
interm = Intermediates(self.pspec, part_pts)
interm.setup(m, i)
# See Notices.txt for copyright information
from ieee754.part_mul_add.multiply import \
- (PartitionPoints, PartitionedAdder, AddReduce,
- Mul8_16_32_64, OP_MUL_LOW, OP_MUL_SIGNED_HIGH,
- OP_MUL_SIGNED_UNSIGNED_HIGH, OP_MUL_UNSIGNED_HIGH)
+ (PartitionPoints, PartitionedAdder, AddReduce,
+ Mul8_16_32_64, OP_MUL_LOW, OP_MUL_SIGNED_HIGH,
+ OP_MUL_SIGNED_UNSIGNED_HIGH, OP_MUL_UNSIGNED_HIGH)
from nmigen import Signal, Module
from nmigen.back.pysim import Simulator, Delay, Tick, Passive
from nmigen.hdl.ast import Assign, Value
shift += lane.bit_width
return output, intermediate_output
+
class TestMul8_16_32_64(unittest.TestCase):
@staticmethod
def get_tst_cases(lanes: List[SIMDMulLane],
- keys: Iterable[int]) -> Iterable[Tuple[int, int]]:
+ keys: Iterable[int]) -> Iterable[Tuple[int, int]]:
mask = (1 << 64) - 1
for i in range(8):
hash_input = f"{i} {lanes} {list(keys)}"
def test_0_10(self) -> None:
self.subtest_register_levels([0, 10])
+
if __name__ == '__main__':
unittest.main()