This repository has been archived by the owner on Jan 29, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
e04_signed_compare.py
78 lines (56 loc) · 2 KB
/
e04_signed_compare.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# Disable pylint's "your name is too short" warning.
# pylint: disable=C0103
from typing import List, Tuple
from nmigen import Signal, Module, Elaboratable
from nmigen.build import Platform
from nmigen.asserts import Assume, Assert, Cover
from nmigen.lib.coding import PriorityEncoder
from util import main
class UnsignedComparator(Elaboratable):
"""Logic for the UnsignedComparator module."""
def __init__(self):
self.a = Signal(16)
self.b = Signal(16)
self.lt = Signal()
def elaborate(self, _: Platform) -> Module:
"""Implements the logic for the UnsignedComparator module."""
m = Module()
m.d.comb += self.lt.eq(self.a < self.b)
return m
class SignedComparator(Elaboratable):
"""Logic for the SignedComparator module."""
def __init__(self):
self.a = Signal(16)
self.b = Signal(16)
self.lt = Signal()
def elaborate(self, _: Platform) -> Module:
"""Implements the logic for the SignedComparator module."""
m = Module()
m.submodules.ucmp = ucmp = UnsignedComparator()
ult = Signal() # Unsigned less than
# Hook up the submodule
m.d.comb += [
ucmp.a.eq(self.a),
ucmp.b.eq(self.b),
ult.eq(ucmp.lt),
]
is_a_neg = self.a[15]
is_b_neg = self.b[15]
with m.If(~is_a_neg & ~is_b_neg):
m.d.comb += self.lt.eq(ult)
with m.Elif(is_a_neg & ~is_b_neg):
m.d.comb += self.lt.eq(1)
with m.Elif(~is_a_neg & is_b_neg):
m.d.comb += self.lt.eq(0)
with m.Else():
m.d.comb += self.lt.eq(ult)
return m
@classmethod
def formal(cls) -> Tuple[Module, List[Signal]]:
"""Formal verification for the SignedComparator module."""
m = Module()
m.submodules.c = c = cls()
m.d.comb += Assert(c.lt == (c.a.as_signed() < c.b.as_signed()))
return m, [c.a, c.b]
if __name__ == "__main__":
main(SignedComparator)