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