xilinx.py 5.69 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 - 2015 CERN
# Author: Pawel Szostek (pawel.szostek@cern.ch)
# Multi-tool support by Javier D. Garcia-Lasheras (javier@garcialasheras.com)
#
# This file is part of Hdlmake.
#
# Hdlmake is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Hdlmake is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Hdlmake.  If not, see <http://www.gnu.org/licenses/>.
#

"""Module providing generic support for Xilinx synthesis tools"""


27
from __future__ import absolute_import
28
from .make_syn import ToolSyn
29
from hdlmake.srcfile import VHDLFile, VerilogFile, SVFile, TCLFile
30
import logging
31 32


33
class ToolXilinx(ToolSyn):
34 35 36

    """Class providing the interface for Xilinx Vivado synthesis"""

37 38 39
    _XILINX_SOURCE = (
        "add_files -norecurse $(sourcefile); "
        "set_property IS_GLOBAL_INCLUDE 1 [get_files $(sourcefile)]")
40 41 42 43 44 45

    HDL_FILES = {
        VHDLFile: _XILINX_SOURCE,
        VerilogFile: _XILINX_SOURCE,
        SVFile: _XILINX_SOURCE}

46
    SUPPORTED_FILES = {TCLFile: 'source $(sourcefile)'}
47

48 49
    CLEAN_TARGETS = {'mrproper': ["*.bit", "*.bin"]}

50
    _XILINX_RUN = '''\
51 52
$(TCL_OPEN)
{1}
53 54 55 56
reset_run {0}
launch_runs {0}
wait_on_run {0}
set result [get_property STATUS [get_runs {0}]]
57 58
set keyword [lindex [split '$$'result " "] end]
if {{ '$$'keyword != \\"Complete!\\" }} {{
59
    exit 1
60 61
}}
$(TCL_CLOSE)'''
62

63 64 65
    TCL_CONTROLS = {'create': 'create_project $(PROJECT) ./',
                    'open': 'open_project $(PROJECT_FILE)',
                    'close': 'exit',
66 67
                    'project': '$(TCL_CREATE)\n'
                               '{0}\n'
68
                               'source files.tcl\n'
69 70 71 72 73
                               'update_compile_order -fileset sources_1\n'
                               'update_compile_order -fileset sim_1\n'
                               '$(TCL_CLOSE)',
                    'synthesize': _XILINX_RUN,
                    'par': _XILINX_RUN,
74 75 76 77
                    'install_source': '$(PROJECT).runs/impl_1/$(SYN_TOP).bit'}

    def __init__(self):
        super(ToolXilinx, self).__init__()
78 79
        self._hdl_files.update(ToolXilinx.HDL_FILES)
        self._supported_files.update(ToolXilinx.SUPPORTED_FILES)
80 81
        self._clean_targets.update(ToolXilinx.CLEAN_TARGETS)
        self._tcl_controls.update(ToolXilinx.TCL_CONTROLS)
82

83 84
    def _get_properties(self):
        """Create the property list"""
85
        syn_properties = self.manifest_dict.get("syn_properties")
86
        language = self.manifest_dict.get("language")
87 88
        if language == None:
            language = "vhdl"
89
        properties = [
90 91 92
            ['part', '$(SYN_DEVICE)' +
                     '$(SYN_PACKAGE)' +
                     '$(SYN_GRADE)', 'current_project'],
93
            ['target_language', language, 'current_project'],
94
            ['top', '$(TOP_MODULE)', 'get_property srcset [current_run]']]
95 96 97
        fetchto = self.manifest_dict.get("fetchto")
        if not fetchto is None:
            properties.append(['ip_repo_paths', fetchto, 'current_fileset'])
98 99
        if not syn_properties is None:
            properties.extend(syn_properties)
100 101
        return properties

102
    def _makefile_syn_tcl(self):
103 104 105
        """Create a Xilinx synthesis project by TCL"""
        prop_val = 'set_property "{0}" "{1}" [{2}]'
        prop_opt = 'set_property -name {{{0}}} -value {{{1}}} -objects [{2}]'
106 107 108
        project_new = ['# project properties']
        synthesize_new = ['# synthesize properties']
        par_new = ['# par properties']
109
        properties = self._get_properties()
110
        for prop in properties:
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
            if len(prop) > 1:
                tmp = prop_val
                name_list = prop[0].split()
                if len(name_list) == 2:
                    if name_list[1] == "options":
                        tmp = prop_opt
                    else:
                        logging.error('Unknown project property: %s', prop[0])
                if len(prop) == 2:
                    name_hierarchy = name_list[0].split(".")
                    if name_hierarchy[0] == "steps":
                        if name_hierarchy[1] == "synth_design":
                            synthesize_new.append(tmp.format(
                                prop[0], prop[1], 'get_runs synth_1'))
                        else:
                            par_new.append(tmp.format(
                                prop[0], prop[1], 'get_runs impl_1'))
                    else:
129
                        project_new.append(tmp.format(
130 131
                            prop[0], prop[1], 'current_project'))
                elif len(prop) == 3:
132
                    project_new.append(tmp.format(prop[0], prop[1], prop[2]))
133 134
                else:
                    logging.error('Unknown project property: %s', prop[0])
135 136 137 138 139 140 141 142 143 144 145 146
        tmp_dict = {}
        tmp_dict["project"] = self._tcl_controls["project"]
        tmp_dict["synthesize"] = self._tcl_controls["synthesize"]
        tmp_dict["par"] = self._tcl_controls["par"]
        self._tcl_controls["project"] = tmp_dict["project"].format(
            "\n".join(project_new))
        self._tcl_controls["synthesize"] = tmp_dict["synthesize"].format(
            "synth_1",
            "\n".join(synthesize_new))
        self._tcl_controls["par"] = tmp_dict["par"].format(
            "impl_1",
            "\n".join(par_new))
147
        super(ToolXilinx, self)._makefile_syn_tcl()