1 # This is the proof for Regfile class from regfile/regfile.py
3 from nmigen
import (Module
, Signal
, Elaboratable
, Mux
, Cat
, Repl
,
5 from nmigen
.asserts
import (Assert
, AnySeq
, Assume
, Cover
, Initial
,
6 Rose
, Fell
, Stable
, Past
)
7 from nmutil
.formaltest
import FHDLTestCase
8 from nmigen
.cli
import rtlil
11 from soc
.regfile
.regfile
import Register
14 class Driver(Register
):
15 def __init__(self
, writethru
=True):
16 super().__init
__(8, writethru
)
17 for i
in range(1): # just do one for now
18 self
.read_port(f
"{i}")
19 self
.write_port(f
"{i}")
21 def elaborate(self
, platform
):
22 m
= super().elaborate(platform
)
27 writethru
= self
.writethru
28 _rdports
= self
._rdports
29 _wrports
= self
._wrports
32 comb
+= _wrports
[0].data_i
.eq(AnySeq(8))
33 comb
+= _wrports
[0].wen
.eq(AnySeq(1))
34 comb
+= _rdports
[0].ren
.eq(AnySeq(1))
40 # Most likely incorrect 4-way truth table
42 # rp.ren wp.wen rp.data_o reg
43 # 0 0 zero should be previous value
45 # 1 0 reg should be previous value
46 # 1 1 wp.data_i wp.data_i
48 # Holds the value written to the register when a write happens
49 register_data
= Signal(self
.width
)
50 register_written
= Signal()
52 # Make sure we're actually hitting a read and write
53 comb
+= Cover(_rdports
[0].ren
& register_written
)
56 comb
+= Assume(rst
== 1)
58 comb
+= Assume(port
.ren
== 0)
60 comb
+= Assume(port
.wen
== 0)
62 comb
+= Assume(register_written
== 0)
65 comb
+= Assume(rst
== 0)
67 # If there is no read, then data_o should be 0
68 with m
.If(_rdports
[0].ren
== 0):
69 comb
+= Assert(_rdports
[0].data_o
== 0)
71 # If there is a read request
74 # Since writethrough is enabled, we need to check
75 # if we're writing while reading. If so, then the
76 # data from the read port should be the same as
77 # that of the write port
78 with m
.If(_wrports
[0].wen
):
79 comb
+= Assert(_rdports
[0].data_o
==
82 # Otherwise, check to make sure the register has
83 # been written to at some point, and make sure the
84 # data output matches the data that was written
87 with m
.If(register_written
):
88 comb
+= Assert(_rdports
[0].data_o
== register_data
)
91 # Same as the Else branch above, make sure the
92 # read port data matches the previously written
94 with m
.If(register_written
):
95 comb
+= Assert(_rdports
[0].data_o
== register_data
)
97 # If there is a write, store the data to be written to our
98 # copy of the register and mark it as written
99 with m
.If(_wrports
[0].wen
):
100 sync
+= register_data
.eq(_wrports
[0].data_i
)
101 sync
+= register_written
.eq(1)
106 class TestCase(FHDLTestCase
):
107 def test_formal(self
):
108 for writethrough
in [False, True]:
109 module
= Driver(writethrough
)
110 self
.assertFormal(module
, mode
="bmc", depth
=10)
111 self
.assertFormal(module
, mode
="cover", depth
=10)
113 def test_ilang(self
):
115 vl
= rtlil
.convert(dut
, ports
=[])
116 with
open("regfile.il", "w") as f
:
120 if __name__
== '__main__':