| # 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 ExternalProgram |
| |
| class ProjectKwargs(TypedDict): |
| |
| sources: T.List[T.Union[mesonlib.FileOrString, build.GeneratedTypes]] |
| constraint_file: T.Union[mesonlib.FileOrString, build.GeneratedTypes] |
| |
| 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, T.Union[ExternalProgram, build.Executable]] = {} |
| 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[T.Union[mesonlib.FileOrString, build.GeneratedTypes]]], |
| 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']))) |
| |
| blif_target = build.CustomTarget( |
| f'{proj_name}_blif', |
| state.subdir, |
| state.subproject, |
| state.environment, |
| [self.tools['yosys'], '-q', '-p', 'synth_ice40 -blif @OUTPUT@', '@INPUT@'], |
| all_sources, |
| [f'{proj_name}.blif'], |
| ) |
| |
| asc_target = build.CustomTarget( |
| f'{proj_name}_asc', |
| state.subdir, |
| state.subproject, |
| state.environment, |
| [self.tools['arachne'], '-q', '-d', '1k', '-p', '@INPUT@', '-o', '@OUTPUT@'], |
| [kwargs['constraint_file'], blif_target], |
| [f'{proj_name}.asc'], |
| ) |
| |
| bin_target = build.CustomTarget( |
| f'{proj_name}_bin', |
| state.subdir, |
| state.subproject, |
| state.environment, |
| [self.tools['icepack'], '@INPUT@', '@OUTPUT@'], |
| [asc_target], |
| [f'{proj_name}.bin'], |
| build_by_default=True, |
| ) |
| |
| upload_target = build.RunTarget( |
| f'{proj_name}-upload', |
| [self.tools['iceprog'], bin_target], |
| [], |
| state.subdir, |
| state.subproject, |
| state.environment, |
| ) |
| |
| time_target = build.RunTarget( |
| f'{proj_name}-time', |
| [self.tools['icetime'], bin_target], |
| [], |
| state.subdir, |
| state.subproject, |
| state.environment, |
| ) |
| |
| return ModuleReturnValue( |
| None, |
| [blif_target, asc_target, bin_target, upload_target, time_target]) |
| |
| |
| def initialize(interp: Interpreter) -> IceStormModule: |
| return IceStormModule(interp) |