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