From: Luke Kenneth Casson Leighton Date: Tue, 5 Oct 2021 16:42:43 +0000 (+0100) Subject: add signed/unsigned functions and preliminary unit test X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=90ad7e29637c953efe536a11e55215be2d3e3d98;p=ieee754fpu.git add signed/unsigned functions and preliminary unit test --- diff --git a/src/ieee754/part/partsig.py b/src/ieee754/part/partsig.py index 5d3ba756..d2b6280d 100644 --- a/src/ieee754/part/partsig.py +++ b/src/ieee754/part/partsig.py @@ -30,7 +30,7 @@ from ieee754.part_cat.pcat import PCat from operator import or_, xor, and_, not_ from nmigen import (Signal, Const) -from nmigen.hdl.ast import UserValue +from nmigen.hdl.ast import UserValue, Shape def getsig(op1): @@ -342,9 +342,16 @@ class PartitionedSignal(UserValue): # TODO, http://bugs.libre-riscv.org/show_bug.cgi?id=716 # def __getitem__(self, key): - # TODO, http://bugs.libre-riscv.org/show_bug.cgi?id=719 - #def as_unsigned(self): - #def as_signed(self): + def __new_sign(self, signed): + shape = Shape(len(self), signed=signed) + result = PartitionedSignal.like(self, shape=shape) + self.m.d.comb += result.sig.eq(self.sig) + return result + + def as_unsigned(self): + return self.__new_sign(False) + def as_signed(self): + return self.__new_sign(True) # useful operators diff --git a/src/ieee754/part/test/test_partsig.py b/src/ieee754/part/test/test_partsig.py index 965d0eca..dff2d6ec 100644 --- a/src/ieee754/part/test/test_partsig.py +++ b/src/ieee754/part/test/test_partsig.py @@ -202,6 +202,7 @@ class TestAddMod(Elaboratable): self.add_carry_out = Signal(len(partpoints)+1) self.sub_carry_out = Signal(len(partpoints)+1) self.neg_output = Signal(width) + self.signed_output = Signal(width) self.xor_output = Signal(len(partpoints)+1) self.bool_output = Signal(len(partpoints)+1) self.all_output = Signal(len(partpoints)+1) @@ -230,8 +231,9 @@ class TestAddMod(Elaboratable): self.carry_in) comb += self.sub_output.eq(sub_out.sig) comb += self.sub_carry_out.eq(sub_carry) - # neg + # neg / signed / unsigned comb += self.neg_output.eq((-self.a).sig) + comb += self.signed_output.eq(self.a.as_signed()) # horizontal operators comb += self.xor_output.eq(self.a.xor()) comb += self.bool_output.eq(self.a.bool()) @@ -749,6 +751,9 @@ class TestPartitionedSignal(unittest.TestCase): a = (a & mask) >> pos # shift it to the beginning return ((-a) << pos) & mask, 0 # negate and shift it back + def test_signed_fn(carry_in, a, b, mask): + return a & mask, 0 + def test_op(msg_prefix, carry, test_fn, mod_attr, *mask_list): rand_data = [] for i in range(100): @@ -801,6 +806,7 @@ class TestPartitionedSignal(unittest.TestCase): (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)