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):
# 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
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)
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())
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):
(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)