| # TODO: need better coverage for different tile types |
| |
| import fasm2frame |
| |
| import unittest |
| import StringIO |
| import re |
| |
| |
| def frm2bits(txt): |
| ''' |
| Convert output .frm file text to set of (frame addr, word #, bit index) tuples |
| ''' |
| bits_out = set() |
| for l in txt.split('\n'): |
| l = l.strip() |
| if not l: |
| continue |
| # 0x00020500 0x00000000,0x00000000,0x00000000,... |
| addr, words = l.split(' ') |
| addr = int(addr, 0) |
| words = words.split(',') |
| assert (101 == len(words)) |
| for wordi, word in enumerate(words): |
| word = int(word, 0) |
| for biti in xrange(32): |
| val = word & (1 << biti) |
| if val: |
| bits_out.add((addr, wordi, biti)) |
| return bits_out |
| |
| |
| def bitread2bits(txt): |
| ''' |
| Convert .bits text file (ie bitread output) to set of (frame addr, word #, bit index) tuples |
| ''' |
| bits_ref = set() |
| for l in txt.split('\n'): |
| l = l.strip() |
| if not l: |
| continue |
| # bit_0002050b_004_14 |
| m = re.match(r'bit_(.{8})_(.{3})_(.{2})', l) |
| addr = int(m.group(1), 16) |
| word = int(m.group(2), 10) |
| bit = int(m.group(3), 10) |
| bits_ref.add((addr, word, bit)) |
| return bits_ref |
| |
| |
| class TestStringMethods(unittest.TestCase): |
| def test_lut(self): |
| '''Simple smoke test on just the LUTs''' |
| fout = StringIO.StringIO() |
| fasm2frame.run(open('test_data/lut.fasm', 'r'), fout) |
| |
| def bitread_frm_equals(self, frm_fn, bitread_fn): |
| fout = StringIO.StringIO() |
| fasm2frame.run(open(frm_fn, 'r'), fout) |
| |
| # Build a list of output used bits |
| bits_out = frm2bits(fout.getvalue()) |
| |
| # Build a list of reference used bits |
| bits_ref = bitread2bits(open(bitread_fn, 'r').read()) |
| |
| # Now check for equivilence vs reference design |
| self.assertEquals(len(bits_ref), len(bits_out)) |
| self.assertEquals(bits_ref, bits_out) |
| |
| def test_lut_int(self): |
| self.bitread_frm_equals( |
| 'test_data/lut_int.fasm', 'test_data/lut_int/design.bits') |
| |
| def test_ff_int(self): |
| self.bitread_frm_equals( |
| 'test_data/ff_int.fasm', 'test_data/ff_int/design.bits') |
| |
| def test_ff_int_op1(self): |
| '''Omitted key set to ''' |
| self.bitread_frm_equals( |
| 'test_data/ff_int_op1.fasm', 'test_data/ff_int/design.bits') |
| |
| # Same check as above, but isolated test case |
| def test_opkey_01_default(self): |
| '''Optional key with binary omitted value should produce valid result''' |
| fin = StringIO.StringIO("CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX") |
| fout = StringIO.StringIO() |
| fasm2frame.run(fin, fout) |
| |
| def test_opkey_01_1(self): |
| fin = StringIO.StringIO("CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX 1") |
| fout = StringIO.StringIO() |
| fasm2frame.run(fin, fout) |
| |
| def test_opkey_enum(self): |
| '''Optional key with enumerated value should produce syntax error''' |
| # CLBLM_L.SLICEM_X0.AMUX.O6 !30_06 !30_07 !30_08 30_11 |
| fin = StringIO.StringIO("CLBLM_L_X10Y102.SLICEM_X0.AMUX.O6") |
| fout = StringIO.StringIO() |
| try: |
| fasm2frame.run(fin, fout) |
| self.fail("Expected syntax error") |
| except fasm2frame.FASMSyntaxError: |
| pass |
| |
| def test_ff_int_0s(self): |
| '''Explicit 0 entries''' |
| self.bitread_frm_equals( |
| 'test_data/ff_int_0s.fasm', 'test_data/ff_int/design.bits') |
| |
| def test_badkey(self): |
| '''Bad key should throw syntax error''' |
| fin = StringIO.StringIO("CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX 2") |
| fout = StringIO.StringIO() |
| try: |
| fasm2frame.run(fin, fout) |
| self.fail("Expected syntax error") |
| except fasm2frame.FASMSyntaxError: |
| pass |
| |
| def test_dupkey(self): |
| '''Duplicate key should throw syntax error''' |
| fin = StringIO.StringIO( |
| """\ |
| CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX 0 |
| CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX 1 |
| """) |
| fout = StringIO.StringIO() |
| try: |
| fasm2frame.run(fin, fout) |
| self.fail("Expected syntax error") |
| except fasm2frame.FASMSyntaxError: |
| pass |
| |
| def test_sparse(self): |
| '''Verify sparse equivilent to normal encoding''' |
| frm_fn = 'test_data/lut_int.fasm' |
| |
| fout_sparse = StringIO.StringIO() |
| fasm2frame.run(open(frm_fn, 'r'), fout_sparse, sparse=True) |
| fout_sparse_txt = fout_sparse.getvalue() |
| bits_sparse = frm2bits(fout_sparse_txt) |
| |
| fout_full = StringIO.StringIO() |
| fasm2frame.run(open(frm_fn, 'r'), fout_full, sparse=False) |
| fout_full_txt = fout_full.getvalue() |
| bits_full = frm2bits(fout_full_txt) |
| |
| # Now check for equivilence vs reference design |
| self.assertEquals(len(bits_sparse), len(bits_full)) |
| self.assertEquals(bits_sparse, bits_full) |
| |
| # Verify the full ROI is way bigger description |
| # It will still be decent size though since even sparse occupies all columns in that area |
| self.assertGreaterEqual(len(fout_full_txt), len(fout_sparse_txt) * 4) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |