예제 #1
0
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
예제 #2
0
 def __str__(self):
     if self.identifier is None:
         s = '{}({}-1 downto 0)'.format(
             self.unconstrained_name, math_parser.str_expression(self.size))
     else:
         s = self.identifier
     return s
예제 #3
0
def make_array_declarations_and_definitions(array_type):
    '''
    Create declarations and definitions of functions to convert to and from
    array types.
    '''
    if hasattr(array_type, 'size'):
        width_expression = math_parser.str_expression(array_type.width)
        width_declaration = width_declarations_template.format(
            type=array_type,
            width_expression=width_expression,
        )
        if array_type.unconstrained_type.identifier is None:
            subtype_width = math_parser.str_expression(
                array_type.unconstrained_type.subtype.width)
            unconstrained = False
        else:
            # We don't need to define functions because it's not a new kind of
            # array it's just constraining an existing one.
            subtype_width = None
    else:
        width_declaration = ''
        unconstrained = True
        if array_type.subtype.identifier is None:
            subtype_width = math_parser.str_expression(
                array_type.subtype.width)
        else:
            subtype_width = array_type.subtype.identifier + '_slvcodecwidth'

    # Define functions unless we have defined size and subtype has identifier
    if subtype_width is None:
        # No functions to define.
        declarations = width_declaration
        definitions = ''
    else:
        functions_declarations = functions_declarations_template.format(
            type=array_type)
        declarations = '\n'.join([width_declaration, functions_declarations])
        template_fn = os.path.join(os.path.dirname(__file__), 'templates',
                                   'slvcodec_array_template.vhd')
        with open(template_fn, 'r') as template_file:
            definitions_template = jinja2.Template(template_file.read())
        definitions = definitions_template.render(
            type=array_type.identifier,
            subtype_width=subtype_width,
            unconstrained=unconstrained,
        )
    return declarations, definitions
예제 #4
0
def make_record_declarations_and_definitions(record_type):
    '''
    Create declarations and definitions of functions to convert to and from
    record types.
    '''
    declarations = declarations_template.format(
        type=record_type,
        width_expression=math_parser.str_expression(record_type.width),
    )
    template_fn = os.path.join(os.path.dirname(__file__), 'templates',
                               'slvcodec_record_template.vhd')
    with open(template_fn, 'r') as f:
        definitions_template = jinja2.Template(f.read())
        indices_names_and_widths = []
    for index, name_and_subtype in enumerate(record_type.names_and_subtypes):
        name, subtype = name_and_subtype
        indices_names_and_widths.append(
            (index, name, math_parser.str_expression(subtype.width)))
    definitions = definitions_template.render(
        type=record_type.identifier,
        indices_names_and_widths=indices_names_and_widths)
    return declarations, definitions
예제 #5
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
예제 #6
0
def make_enumeration_declarations_and_definitions(enumeration_type):
    '''
    Create declarations and definitions of functions to convert to and from
    enumeration types.
    '''
    declarations = declarations_template.format(
        type=enumeration_type,
        width_expression=math_parser.str_expression(enumeration_type.width),
    )
    template_fn = os.path.join(os.path.dirname(__file__), 'templates',
                               'slvcodec_enumeration_template.vhd')
    with open(template_fn, 'r') as f:
        definitions_template = jinja2.Template(f.read())
        definitions = definitions_template.render(
            type=enumeration_type.identifier,
            literals=enumeration_type.literals,
            n_literals=len(enumeration_type.literals),
        )
    return declarations, definitions
예제 #7
0
 def width_as_str(self):
     '''
     Returns a string representing the port width.  May include
     constants and generics.
     '''
     return math_parser.str_expression(self.typ.width)