Skip to content

Commit

Permalink
Add DFF and Bit sequence unit
Browse files Browse the repository at this point in the history
  • Loading branch information
mlouielu committed Jul 3, 2017
1 parent f4bc9d1 commit 22f8dd7
Show file tree
Hide file tree
Showing 7 changed files with 342 additions and 0 deletions.
1 change: 1 addition & 0 deletions nand2vm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
#

from . import gate
from . import seq
from .bitarray import BitArray
9 changes: 9 additions & 0 deletions nand2vm/seq/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#
# Copyright (c) 2017 Louie Lu. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#

from .clock import ClockPhase
from .dff import DFF
from .bit import Bit
22 changes: 22 additions & 0 deletions nand2vm/seq/bit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#
# Copyright (c) 2017 Louie Lu. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#

from .clock import ClockPhase
from .dff import DFF
from .. import gate


class Bit(object):
def __init__(self):
self.d = DFF()
self.clock = ClockPhase.POSITIVE_EDGE

def update(self, source: bool, load: bool, clock: ClockPhase=None) -> bool:
if clock:
self.clock = clock
mux = gate.Mux(self.d.state, source, load)
out = self.d.update(mux, self.clock)
return out
14 changes: 14 additions & 0 deletions nand2vm/seq/clock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#
# Copyright (c) 2017 Louie Lu. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#

from enum import Enum


class ClockPhase(Enum):
LOW = 0
POSITIVE_EDGE = 1
HIGH = 2
NEGATIVE_EDGE = 3
27 changes: 27 additions & 0 deletions nand2vm/seq/dff.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#
# Copyright (c) 2017 Louie Lu. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#


from .. import gate
from .clock import ClockPhase


class DFF(object):
def __init__(self):
self._state = 0

def update(self, source: bool, clock: ClockPhase) -> bool:
prev_state = self._state
if clock == ClockPhase.POSITIVE_EDGE:
self._state = source
return prev_state

@property
def state(self) -> bool:
return self._state

def __eq__(self, other):
return self._state == other
215 changes: 215 additions & 0 deletions test/data/Bit.cmp
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
time|source|load|out
0+|0|0|0
1|0|0|0
1+|0|1|0
2|0|1|0
2+|1|0|0
3|1|0|0
3+|1|1|0
4|1|1|1
4+|0|0|1
5|0|0|1
5+|1|0|1
6|1|0|1
6+|0|1|1
7|0|1|0
7+|1|1|0
8|1|1|1
8+|0|0|1
9|0|0|1
9+|0|0|1
10|0|0|1
10+|0|0|1
11|0|0|1
11+|0|0|1
12|0|0|1
12+|0|0|1
13|0|0|1
13+|0|0|1
14|0|0|1
14+|0|0|1
15|0|0|1
15+|0|0|1
16|0|0|1
16+|0|0|1
17|0|0|1
17+|0|0|1
18|0|0|1
18+|0|0|1
19|0|0|1
19+|0|0|1
20|0|0|1
20+|0|0|1
21|0|0|1
21+|0|0|1
22|0|0|1
22+|0|0|1
23|0|0|1
23+|0|0|1
24|0|0|1
24+|0|0|1
25|0|0|1
25+|0|0|1
26|0|0|1
26+|0|0|1
27|0|0|1
27+|0|0|1
28|0|0|1
28+|0|0|1
29|0|0|1
29+|0|0|1
30|0|0|1
30+|0|0|1
31|0|0|1
31+|0|0|1
32|0|0|1
32+|0|0|1
33|0|0|1
33+|0|0|1
34|0|0|1
34+|0|0|1
35|0|0|1
35+|0|0|1
36|0|0|1
36+|0|0|1
37|0|0|1
37+|0|0|1
38|0|0|1
38+|0|0|1
39|0|0|1
39+|0|0|1
40|0|0|1
40+|0|0|1
41|0|0|1
41+|0|0|1
42|0|0|1
42+|0|0|1
43|0|0|1
43+|0|0|1
44|0|0|1
44+|0|0|1
45|0|0|1
45+|0|0|1
46|0|0|1
46+|0|0|1
47|0|0|1
47+|0|0|1
48|0|0|1
48+|0|0|1
49|0|0|1
49+|0|0|1
50|0|0|1
50+|0|0|1
51|0|0|1
51+|0|0|1
52|0|0|1
52+|0|0|1
53|0|0|1
53+|0|0|1
54|0|0|1
54+|0|0|1
55|0|0|1
55+|0|0|1
56|0|0|1
56+|0|0|1
57|0|0|1
57+|0|1|1
58|0|1|0
58+|1|0|0
59|1|0|0
59+|1|0|0
60|1|0|0
60+|1|0|0
61|1|0|0
61+|1|0|0
62|1|0|0
62+|1|0|0
63|1|0|0
63+|1|0|0
64|1|0|0
64+|1|0|0
65|1|0|0
65+|1|0|0
66|1|0|0
66+|1|0|0
67|1|0|0
67+|1|0|0
68|1|0|0
68+|1|0|0
69|1|0|0
69+|1|0|0
70|1|0|0
70+|1|0|0
71|1|0|0
71+|1|0|0
72|1|0|0
72+|1|0|0
73|1|0|0
73+|1|0|0
74|1|0|0
74+|1|0|0
75|1|0|0
75+|1|0|0
76|1|0|0
76+|1|0|0
77|1|0|0
77+|1|0|0
78|1|0|0
78+|1|0|0
79|1|0|0
79+|1|0|0
80|1|0|0
80+|1|0|0
81|1|0|0
81+|1|0|0
82|1|0|0
82+|1|0|0
83|1|0|0
83+|1|0|0
84|1|0|0
84+|1|0|0
85|1|0|0
85+|1|0|0
86|1|0|0
86+|1|0|0
87|1|0|0
87+|1|0|0
88|1|0|0
88+|1|0|0
89|1|0|0
89+|1|0|0
90|1|0|0
90+|1|0|0
91|1|0|0
91+|1|0|0
92|1|0|0
92+|1|0|0
93|1|0|0
93+|1|0|0
94|1|0|0
94+|1|0|0
95|1|0|0
95+|1|0|0
96|1|0|0
96+|1|0|0
97|1|0|0
97+|1|0|0
98|1|0|0
98+|1|0|0
99|1|0|0
99+|1|0|0
100|1|0|0
100+|1|0|0
101|1|0|0
101+|1|0|0
102|1|0|0
102+|1|0|0
103|1|0|0
103+|1|0|0
104|1|0|0
104+|1|0|0
105|1|0|0
105+|1|0|0
106|1|0|0
106+|1|0|0
107|1|0|0
54 changes: 54 additions & 0 deletions test/test_seq.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#
# Copyright (c) 2017 Louie Lu. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#

import os
import unittest
from collections import namedtuple
from nand2vm import seq


PACKAGE_DIRECTORY = os.path.dirname(os.path.abspath(__file__))
DATA_DIRECTORY = os.path.join(PACKAGE_DIRECTORY, 'data')


class DFFTest(unittest.TestCase):
def setUp(self):
self.d = seq.DFF()

def test_dff(self):
self.assertEqual(self.d.update(True, seq.ClockPhase.LOW), False)
self.assertEqual(self.d.update(True, seq.ClockPhase.POSITIVE_EDGE), False)
self.assertEqual(self.d.update(False, seq.ClockPhase.NEGATIVE_EDGE), True)
self.assertEqual(self.d.update(False, seq.ClockPhase.HIGH), True)
self.assertEqual(self.d.update(False, seq.ClockPhase.POSITIVE_EDGE), True)
self.assertEqual(self.d.update(True, seq.ClockPhase.HIGH), False)
self.assertEqual(self.d.state, False)


class BitTest(unittest.TestCase):
DATA = namedtuple('Data', ['time', 'source', 'load', 'out'])

def prepare_data(self, path):
data = []
with open(path) as f:
f.readline()
for row in f.readlines():
row = row.strip('\n').split('|')
row[0] = seq.ClockPhase.POSITIVE_EDGE if row[0].endswith('+') else seq.ClockPhase.HIGH
row[1] = bool(int(row[1]))
row[2] = bool(int(row[2]))
row[3] = bool(int(row[3]))
data.append(self.DATA(*row))
return data

def setUp(self):
self.bit = seq.Bit()

def test_bit(self):
data = self.prepare_data(os.path.join(DATA_DIRECTORY, 'Bit.cmp'))
for d in data:
out = self.bit.update(d.source, d.load, clock=d.time)
self.assertEqual(out, d.out)

0 comments on commit 22f8dd7

Please sign in to comment.