| # SPDX-License-Identifier: Apache-2.0 | |
| # Copyright 2017 The Meson development team | |
| from __future__ import annotations | |
| import itertools | |
| import typing as T | |
| from . import ExtensionModule, ModuleReturnValue, ModuleInfo | |
| from .. import build | |
| from .. import mesonlib | |
| from ..interpreter.type_checking import CT_INPUT_KW | |
| from ..interpreterbase.decorators import KwargInfo, typed_kwargs, typed_pos_args | |
| if T.TYPE_CHECKING: | |
| from typing_extensions import TypedDict | |
| from . import ModuleState | |
| from ..interpreter import Interpreter | |
| from ..programs import Program | |
| class ProjectKwargs(TypedDict): | |
| sources: T.List[str | build.TargetSources] | |
| constraint_file: str | build.TargetSources | |
| class IceStormModule(ExtensionModule): | |
| INFO = ModuleInfo('FPGA/Icestorm', '0.45.0', unstable=True) | |
| def __init__(self, interpreter: Interpreter) -> None: | |
| super().__init__(interpreter) | |
| self.tools: T.Dict[str, Program] = {} | |
| self.methods.update({ | |
| 'project': self.project, | |
| }) | |
| def detect_tools(self, state: ModuleState) -> None: | |
| self.tools['yosys'] = state.find_program('yosys') | |
| self.tools['arachne'] = state.find_program('arachne-pnr') | |
| self.tools['icepack'] = state.find_program('icepack') | |
| self.tools['iceprog'] = state.find_program('iceprog') | |
| self.tools['icetime'] = state.find_program('icetime') | |
| @typed_pos_args('icestorm.project', str, | |
| varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, | |
| build.GeneratedList)) | |
| @typed_kwargs( | |
| 'icestorm.project', | |
| CT_INPUT_KW.evolve(name='sources'), | |
| KwargInfo( | |
| 'constraint_file', | |
| (str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList), | |
| required=True, | |
| ) | |
| ) | |
| def project(self, state: ModuleState, | |
| args: T.Tuple[str, T.List[str | build.TargetSources]], | |
| kwargs: ProjectKwargs) -> ModuleReturnValue: | |
| if not self.tools: | |
| self.detect_tools(state) | |
| proj_name, arg_sources = args | |
| all_sources = self.interpreter.source_strings_to_files( | |
| list(itertools.chain(arg_sources, kwargs['sources']))) | |
| constraint_file = self.interpreter.source_strings_to_files([kwargs['constraint_file']])[0] | |
| blif_target = build.CustomTarget( | |
| f'{proj_name}_blif', | |
| state.subdir, | |
| state.environment, | |
| [self.tools['yosys'], '-q', '-p', 'synth_ice40 -blif @OUTPUT@', '@INPUT@'], | |
| all_sources, | |
| [f'{proj_name}.blif'], | |
| state.current_build_project, | |
| ) | |
| asc_target = build.CustomTarget( | |
| f'{proj_name}_asc', | |
| state.subdir, | |
| state.environment, | |
| [self.tools['arachne'], '-q', '-d', '1k', '-p', '@INPUT@', '-o', '@OUTPUT@'], | |
| [constraint_file, blif_target], | |
| [f'{proj_name}.asc'], | |
| state.current_build_project, | |
| ) | |
| bin_target = build.CustomTarget( | |
| f'{proj_name}_bin', | |
| state.subdir, | |
| state.environment, | |
| [self.tools['icepack'], '@INPUT@', '@OUTPUT@'], | |
| [asc_target], | |
| [f'{proj_name}.bin'], | |
| state.current_build_project, | |
| build_by_default=True, | |
| ) | |
| upload_target = build.RunTarget( | |
| f'{proj_name}-upload', | |
| [self.tools['iceprog'], bin_target], | |
| [], | |
| state.subdir, | |
| state.environment, | |
| state.current_build_project, | |
| ) | |
| time_target = build.RunTarget( | |
| f'{proj_name}-time', | |
| [self.tools['icetime'], bin_target], | |
| [], | |
| state.subdir, | |
| state.environment, | |
| state.current_build_project, | |
| ) | |
| return ModuleReturnValue( | |
| None, | |
| [blif_target, asc_target, bin_target, upload_target, time_target]) | |
| def initialize(interp: Interpreter) -> IceStormModule: | |
| return IceStormModule(interp) |