Skip to content

Commit

Permalink
Add register with test cases (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
mlouielu committed Jul 3, 2017
1 parent 0f5d656 commit 34f572a
Show file tree
Hide file tree
Showing 6 changed files with 257 additions and 34 deletions.
3 changes: 3 additions & 0 deletions nand2vm/bitarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ def __setitem__(self, key, value):

def __repr__(self):
"""Display big endian for debugging"""
if not isinstance(self.data[0], bool):
# Assume this is a Bit
return ''.join('1' if b.state else '0' for b in self.data[::-1])
return ''.join(['1' if s else '0' for s in self.data[::-1]])

def __len__(self) -> int:
Expand Down
1 change: 1 addition & 0 deletions nand2vm/seq/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
from .clock import ClockPhase
from .dff import DFF
from .bit import Bit
from .register import Register
1 change: 1 addition & 0 deletions nand2vm/seq/bit.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
class Bit(object):
def __init__(self):
self.d = DFF()
self.state = self.d.state
self.clock = ClockPhase.POSITIVE_EDGE

def update(self, source: bool, load: bool, clock: ClockPhase=None) -> bool:
Expand Down
43 changes: 43 additions & 0 deletions nand2vm/seq/register.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#
# 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 .bit import Bit
from .clock import ClockPhase
from .. import gate
from ..bitarray import BitArray


class Register(object):
def __init__(self):
self.bits = BitArray([Bit(), Bit(), Bit(), Bit(),
Bit(), Bit(), Bit(), Bit(),
Bit(), Bit(), Bit(), Bit(),
Bit(), Bit(), Bit(), Bit()])
self.clock = ClockPhase.HIGH

def update(self, source: BitArray, load: bool, clock: ClockPhase=None) -> BitArray:
if clock:
self.clock = clock
o1 = self.bits[0].update(source[0], load, clock=self.clock)
o2 = self.bits[1].update(source[1], load, clock=self.clock)
o3 = self.bits[2].update(source[2], load, clock=self.clock)
o4 = self.bits[3].update(source[3], load, clock=self.clock)
o5 = self.bits[4].update(source[4], load, clock=self.clock)
o6 = self.bits[5].update(source[5], load, clock=self.clock)
o7 = self.bits[6].update(source[6], load, clock=self.clock)
o8 = self.bits[7].update(source[7], load, clock=self.clock)
o9 = self.bits[8].update(source[8], load, clock=self.clock)
o10 = self.bits[9].update(source[9], load, clock=self.clock)
o11 = self.bits[10].update(source[10], load, clock=self.clock)
o12 = self.bits[11].update(source[11], load, clock=self.clock)
o13 = self.bits[12].update(source[12], load, clock=self.clock)
o14 = self.bits[13].update(source[13], load, clock=self.clock)
o15 = self.bits[14].update(source[14], load, clock=self.clock)
o16 = self.bits[15].update(source[15], load, clock=self.clock)

return BitArray([o1, o2, o3, o4, o5, o6, o7, o8,
o9, o10, o11, o12, o13, o14, o15, o16],
endian=False)
149 changes: 149 additions & 0 deletions test/data/Register.cmp
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
time|in|load|out
0+|0|0|0
1|0|0|0
1+|0|1|0
2|0|1|0
2+|-32123|0|0
3|-32123|0|0
3+|11111|0|0
4|11111|0|0
4+|-32123|1|0
5|-32123|1|-32123
5+|-32123|1|-32123
6|-32123|1|-32123
6+|-32123|0|-32123
7|-32123|0|-32123
7+|12345|1|-32123
8|12345|1|12345
8+|0|0|12345
9|0|0|12345
9+|0|1|12345
10|0|1|0
10+|1|0|0
11|1|0|0
11+|1|1|0
12|1|1|1
12+|2|0|1
13|2|0|1
13+|2|1|1
14|2|1|2
14+|4|0|2
15|4|0|2
15+|4|1|2
16|4|1|4
16+|8|0|4
17|8|0|4
17+|8|1|4
18|8|1|8
18+|16|0|8
19|16|0|8
19+|16|1|8
20|16|1|16
20+|32|0|16
21|32|0|16
21+|32|1|16
22|32|1|32
22+|64|0|32
23|64|0|32
23+|64|1|32
24|64|1|64
24+|128|0|64
25|128|0|64
25+|128|1|64
26|128|1|128
26+|256|0|128
27|256|0|128
27+|256|1|128
28|256|1|256
28+|512|0|256
29|512|0|256
29+|512|1|256
30|512|1|512
30+|1024|0|512
31|1024|0|512
31+|1024|1|512
32|1024|1|1024
32+|2048|0|1024
33|2048|0|1024
33+|2048|1|1024
34|2048|1|2048
34+|4096|0|2048
35|4096|0|2048
35+|4096|1|2048
36|4096|1|4096
36+|8192|0|4096
37|8192|0|4096
37+|8192|1|4096
38|8192|1|8192
38+|16384|0|8192
39|16384|0|8192
39+|16384|1|8192
40|16384|1|16384
40+|-32768|0|16384
41|-32768|0|16384
41+|-32768|1|16384
42|-32768|1|-32768
42+|-2|0|-32768
43|-2|0|-32768
43+|-2|1|-32768
44|-2|1|-2
44+|-3|0|-2
45|-3|0|-2
45+|-3|1|-2
46|-3|1|-3
46+|-5|0|-3
47|-5|0|-3
47+|-5|1|-3
48|-5|1|-5
48+|-9|0|-5
49|-9|0|-5
49+|-9|1|-5
50|-9|1|-9
50+|-17|0|-9
51|-17|0|-9
51+|-17|1|-9
52|-17|1|-17
52+|-33|0|-17
53|-33|0|-17
53+|-33|1|-17
54|-33|1|-33
54+|-65|0|-33
55|-65|0|-33
55+|-65|1|-33
56|-65|1|-65
56+|-129|0|-65
57|-129|0|-65
57+|-129|1|-65
58|-129|1|-129
58+|-257|0|-129
59|-257|0|-129
59+|-257|1|-129
60|-257|1|-257
60+|-513|0|-257
61|-513|0|-257
61+|-513|1|-257
62|-513|1|-513
62+|-1025|0|-513
63|-1025|0|-513
63+|-1025|1|-513
64|-1025|1|-1025
64+|-2049|0|-1025
65|-2049|0|-1025
65+|-2049|1|-1025
66|-2049|1|-2049
66+|-4097|0|-2049
67|-4097|0|-2049
67+|-4097|1|-2049
68|-4097|1|-4097
68+|-8193|0|-4097
69|-8193|0|-4097
69+|-8193|1|-4097
70|-8193|1|-8193
70+|-16385|0|-8193
71|-16385|0|-8193
71+|-16385|1|-8193
72|-16385|1|-16385
72+|32767|0|-16385
73|32767|0|-16385
73+|32767|1|-16385
74|32767|1|32767
94 changes: 60 additions & 34 deletions test/test_seq.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,48 +7,74 @@
import os
import unittest
from collections import namedtuple
from nand2vm import seq
from nand2vm import seq, BitArray


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 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)
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)
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)


class RegisterTest(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] = BitArray(int(row[1]))
row[2] = bool(int(row[2]))
row[3] = BitArray(int(row[3]))
data.append(self.DATA(*row))
return data

def setUp(self):
self.register = seq.Register()

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

0 comments on commit 34f572a

Please sign in to comment.