Files
prjxray/utils/test_fasm2frames.py
T

192 lines
5.8 KiB
Python
Raw Normal View History

2018-10-16 23:47:19 -07:00
#!/usr/bin/env python3
2020-04-16 09:29:20 +02:00
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2020 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
# TODO: need better coverage for different tile types
2018-10-16 23:47:19 -07:00
from io import StringIO
import os
import os.path
import re
import unittest
import tempfile
2020-06-15 17:28:42 -07:00
import prjxray
import utils.fasm2frames as fasm2frames
2022-03-15 10:47:58 +01:00
from prjxray.util import OpenSafeFile
from textx.exceptions import TextXSyntaxError
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)
2018-10-16 23:47:19 -07:00
for biti in range(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 filename_test_data(self, fname):
return os.path.join(os.path.dirname(__file__), 'test_data', fname)
def get_test_data(self, fname):
2022-03-15 10:47:58 +01:00
with OpenSafeFile(self.filename_test_data(fname)) as f:
return f.read()
def fasm2frames(self, fin_data, **kw):
with tempfile.NamedTemporaryFile(suffix='.fasm') as fin:
fin.write(fin_data.encode('utf-8'))
fin.flush()
fout = StringIO()
fasm2frames.run(
2021-01-09 21:11:45 +01:00
self.filename_test_data('db'), "xc7a200tffg1156-1", fin.name,
fout, **kw)
return fout.getvalue()
def test_lut(self):
'''Simple smoke test on just the LUTs'''
self.fasm2frames(self.get_test_data('lut.fasm'))
def bitread_frm_equals(self, frm_fn, bitread_fn):
fout = self.fasm2frames(self.get_test_data(frm_fn))
# Build a list of output used bits
bits_out = frm2bits(fout)
# Build a list of reference used bits
bits_ref = bitread2bits(self.get_test_data(bitread_fn))
# Now check for equivilence vs reference design
self.assertEqual(len(bits_ref), len(bits_out))
self.assertEqual(bits_ref, bits_out)
def test_lut_int(self):
self.bitread_frm_equals('lut_int.fasm', 'lut_int/design.bits')
def test_ff_int(self):
self.bitread_frm_equals('ff_int.fasm', 'ff_int/design.bits')
@unittest.skip
def test_ff_int_op1(self):
'''Omitted key set to '''
self.bitread_frm_equals('ff_int_op1.fasm', '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'''
self.fasm2frames("CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX")
@unittest.skip
def test_opkey_01_1(self):
self.fasm2frames("CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX 1")
@unittest.skip
def test_opkey_enum(self):
'''Optional key with enumerated value should produce syntax error'''
try:
# CLBLM_L.SLICEM_X0.AMUXFF.O6 !30_06 !30_07 !30_08 30_11
self.fasm2frames("CLBLM_L_X10Y102.SLICEM_X0.AFFMUX.O6")
self.fail("Expected syntax error")
except TextXSyntaxError:
pass
def test_ff_int_0s(self):
'''Explicit 0 entries'''
self.bitread_frm_equals('ff_int_0s.fasm', 'ff_int/design.bits')
def test_badkey(self):
'''Bad key should throw syntax error'''
try:
self.fasm2frames("CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX 2")
self.fail("Expected syntax error")
except TextXSyntaxError:
pass
@unittest.skip
def test_dupkey(self):
'''Duplicate key should throw syntax error'''
try:
self.fasm2frames(
"""\
CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX 0
CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX 1
""")
self.fail("Expected syntax error")
except TextXSyntaxError:
pass
@unittest.skip
def test_sparse(self):
'''Verify sparse equivalent to normal encoding'''
frm_fn = 'lut_int.fasm'
fout_sparse_txt = self.fasm2frames(
self.get_test_data(frm_fn), sparse=True)
bits_sparse = frm2bits(fout_sparse_txt)
fout_full_txt = self.fasm2frames(
self.get_test_data(frm_fn), sparse=False)
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)
def test_stepdown_1(self):
2019-12-11 09:22:46 +01:00
self.bitread_frm_equals(
'iob/liob_stepdown.fasm', 'iob/liob_stepdown.bits')
def test_stepdown_2(self):
2019-12-11 09:22:46 +01:00
self.bitread_frm_equals(
'iob/riob_stepdown.fasm', 'iob/riob_stepdown.bits')
if __name__ == '__main__':
unittest.main()