コード例 #1
0
ファイル: typ_parser.py プロジェクト: julian-becker/slvcodec
def get_bounds(type_range):
    '''
    Takes a type parsed by inner_vhdl_module and returns math_parser
    expressions for the upper and lower bounds.
    '''
    if type_range is None:
        upper = None
        lower = None
    else:
        if type_range.direction == 'to':
            upper = type_range.right
            lower = type_range.left
        elif type_range.direction == 'downto':
            upper = type_range.left
            lower = type_range.right
        else:
            assert(type_range.left is None)
            assert(type_range.right is None)
            upper = None
            lower = None
    if (upper is None) and (lower is None):
        upper_expression = None
        lower_expression = None
    else:
        upper_expression = math_parser.parse_and_simplify(upper)
        lower_expression = math_parser.parse_and_simplify(lower)
    return lower_expression, upper_expression
コード例 #2
0
ファイル: typ_parser.py プロジェクト: julian-becker/slvcodec
def get_constraint_bounds(constraint):
    '''
    Takes a VHDL constraint and return math_parser expressions
    for the lower and upper bounds.

    >>> get_constraint_bounds('   (3+6 to 7)  ')
    (9, 7)
    >>> get_constraint_bounds('(26 downto 10*2 )')
    (20, 26)
    '''
    _constrained_range_re = re.compile(r"""
        \s*\(
        \s*(?P<range_left>.+?)
        \s+(?P<direction>to|downto)\s+
        (?P<range_right>.+?)\s*
        \)\s*""", re.MULTILINE | re.IGNORECASE | re.VERBOSE | re.DOTALL)
    match = _constrained_range_re.match(constraint)
    if match:
        gd = match.groupdict()
        if gd['direction'] == 'to':
            high = gd['range_right']
            low = gd['range_left']
        elif gd['direction'] == 'downto':
            high = gd['range_left']
            low = gd['range_right']
        high_expr = math_parser.parse_and_simplify(high)
        low_expr = math_parser.parse_and_simplify(low)
        size_as_string = '{} + 1 - {}'.format(high, low)
        size = math_parser.parse_and_simplify(size_as_string)
    else:
        raise Exception('Failed to parse constraint.')
    return low_expr, high_expr
コード例 #3
0
ファイル: typ_parser.py プロジェクト: julian-becker/slvcodec
def get_range_bounds(type_range):
    '''
    Takes a VHDL range and return math_parser expressions
    for the lower and upper bounds.

    >>> get_range_bounds('range 17 to 201')
    (17, 201)
    >>> get_range_bounds('range 7*2 downto 7*1')
    (7, 14)
    '''
    _type_range_re = re.compile(r"""
        \s*range
        \s*(?P<range_left>.+?)
        \s+(?P<direction>to|downto)\s+
        (?P<range_right>.+?)\s*$
        """, re.MULTILINE | re.IGNORECASE | re.VERBOSE | re.DOTALL)
    match = _type_range_re.match(type_range)
    if match:
        gd = match.groupdict()
        if gd['direction'] == 'to':
            high = gd['range_right']
            low = gd['range_left']
        elif gd['direction'] == 'downto':
            high = gd['range_left']
            low = gd['range_right']
        high_expr = math_parser.parse_and_simplify(high)
        low_expr = math_parser.parse_and_simplify(low)
    else:
        raise Exception('Failed to parse constraint.')
    return low_expr, high_expr
コード例 #4
0
ファイル: vhdl_parser.py プロジェクト: julian-becker/slvcodec
def process_parsed_package(parsed_package, parsed_uses):
    '''
    Process a parsed package (from inner_vhdl_parser) into an UnresolvedPackage object.
    '''
    p_constants = parsed_package.constants
    p_types = get_types(parsed_package)
    constants = {}
    for constant in p_constants:
        if constant.text == '':
            # This typically happens when a parameters file has been generated
            # incorrectly.
            raise Exception('Constant {} has no value to parse'.format(
                constant.identifier))
        constants[constant.identifier] = math_parser.parse_and_simplify(
            constant.text)
    processed_types = [(t.identifier, typ_parser.process_parsed_type(t))
                       for t in p_types]
    # Filter out the types that could not be processed.
    types = dict([(k, v) for k, v in processed_types if v is not None])
    failed_type_keys = [k for k, v in processed_types if v is None]
    if failed_type_keys:
        logger.warning('Failed to parse types %s', str(failed_type_keys))
    processed_package = package.UnresolvedPackage(
        identifier=parsed_package.identifier,
        types=types,
        constants=constants,
        uses=parsed_uses,
    )
    return processed_package
コード例 #5
0
def test_substitute():
    string = 'fish + 3 * bear * shark / house'
    simplified = sm.parse_and_simplify(string)
    substituted = sm.make_substitute_function({
        'fish': 2,
        'bear': 4,
        'shark': 3,
        'house': 2,
    })(simplified)
    final = sm.simplify(substituted)
    assert final == 2 + 3 * 4 * 3 / 2
コード例 #6
0
ファイル: typ_parser.py プロジェクト: julian-becker/slvcodec
def get_constraint_size(constraint):
    '''
    Takes a vhdl constraint and return a math_parser expression for the size.

    >>> get_constraint_size(' (FISH*2-1 downto FISH )')
    'FISH'
    >>> get_constraint_size('(FISH*5-1 downto 0)').str_expression()
    '5*FISH'
    '''
    low, high = get_constraint_bounds(constraint)
    size = math_parser.parse_and_simplify('{} + 1 - {}'.format(
        math_parser.str_expression(high), math_parser.str_expression(low)))
    return size
コード例 #7
0
def test_simplifications():
    ins_and_outs = (
        ('fish + 8*bear + 2 * (fish - bear)', ('(3*fish+6*bear)',
                                               '(6*bear+3*fish)')),
        ('4 + (4 - 4) * 2 - 3', ('1', )),
        ('7 * 7', ('49', )),
        ('2 * (3 + 5)', ('16', )),
        ('logceil(5+3)-2', ('1', )),
        ('1 + 1', ('2', )),
        ('(logceil(5*4)-1)+1-0', ('5', )),
        ('3 * 2 / fish / (3 / 4)', ('8/fish', '8*1/fish')),
        ('fish + 1 - 1', ('fish', )),
        ('(fish + 1) - 1', ('fish', )),
        ('fish + 2 * fish', ('3*fish', )),
    )
    for in_string, expected_strings in ins_and_outs:
        simplified = sm.parse_and_simplify(in_string)
        out_string = sm.str_expression(simplified)
        assert out_string in expected_strings
コード例 #8
0
def test_fails_on_power():
    string = '2 ** 6'
    with pytest.raises(sm.MathParsingError) as e:
        simplified = sm.parse_and_simplify(string)
    message = e.value.args[0]
    assert all([s in message for s in ('**', 'power')])
コード例 #9
0
def test_empty_constant_list():
    string = '3 * 12'
    simplified = sm.parse_and_simplify(string)
    constants = sm.get_constant_list(simplified)
    assert constants == set()
コード例 #10
0
def test_constant_list():
    string = '3 * (fish + 6) - 2 * bear - fish'
    simplified = sm.parse_and_simplify(string)
    constants = sm.get_constant_list(simplified)
    assert constants == set(['fish', 'bear'])