synthesis_project.py 7.03 KB
Newer Older
1 2 3
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
4
# Copyright (c) 2013, 2014 CERN
5
# Author: Pawel Szostek (pawel.szostek@cern.ch)
6
# Multi-tool support by Javier D. Garcia-Lasheras (javier@garcialasheras.com)
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
#
# 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/>.

23 24 25 26 27
from __future__ import print_function
import logging
from action import Action
import sys
import os
Pawel Szostek's avatar
Pawel Szostek committed
28
import new_dep_solver as dep_solver
29
from srcfile import SourceFileFactory
30
from dependable_file import DependableFile
31
import global_mod
Pawel Szostek's avatar
Pawel Szostek committed
32
from util import path
33

34
import importlib
35

36

37

38
class GenerateSynthesisProject(Action):
39

40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
    def _check_manifest(self):
        if not self.modules_pool.get_top_module().syn_tool:
            logging.error("syn_tool variable must be set in the top manifest.")
            sys.exit("Exiting")
        if not self.modules_pool.get_top_module().syn_device:
            logging.error("syn_device variable must be set in the top manifest.")
            sys.exit("Exiting")
        if not self.modules_pool.get_top_module().syn_grade:
            logging.error("syn_grade variable must be set in the top manifest.")
            sys.exit("Exiting")
        if not self.modules_pool.get_top_module().syn_package:
            logging.error("syn_package variable must be set in the top manifest.")
            sys.exit("Exiting")
        if not self.modules_pool.get_top_module().syn_top:
            logging.error("syn_top variable must be set in the top manifest.")
            sys.exit("Exiting")
56

57

58 59 60 61 62
    def run(self):
        self._check_all_fetched_or_quit()
        self._check_manifest()
        tool_object = global_mod.tool_module.ToolControls()   
        self._generate_synthesis_project(tool_object)
63

64

65
    def _write_project_vhd(self, tool, version):
66 67 68 69 70 71 72
        from string import Template
        from datetime import date
        import getpass

        today = date.today()
        date_string = today.strftime("%Y%m%d")
        template = Template("""library ieee;
73
use work.wishbone_pkg.all;
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

package sdb_meta_pkg is

  ------------------------------------------------------------------------------
  -- Meta-information sdb records
  ------------------------------------------------------------------------------

  -- Top module repository url
  constant c_SDB_REPO_URL : t_sdb_repo_url := (
    -- url (string, 63 char)
    repo_url => "$repo_url");

  -- Synthesis informations
  constant c_SDB_SYNTHESIS : t_sdb_synthesis := (
    -- Top module name (string, 16 char)
    syn_module_name  => "$syn_module_name",
    -- Commit ID (hex string, 128-bit = 32 char)
    -- git log -1 --format="%H" | cut -c1-32
    syn_commit_id    => "$syn_commit_id",
    -- Synthesis tool name (string, 8 char)
    syn_tool_name    => "$syn_tool_name",
    -- Synthesis tool version (bcd encoded, 32-bit)
98
    syn_tool_version => "$syn_tool_version", -- $syn_tool_version_str
99
    -- Synthesis date (bcd encoded, 32-bit)
100
    syn_date         => "$syn_date", -- $syn_date_str
101 102 103 104 105 106 107 108 109
    -- Synthesised by (string, 15 char)
    syn_username     => "$syn_username");

end sdb_meta_pkg;

package body sdb_meta_pkg is
end sdb_meta_pkg;""")

        project_vhd = open("project.vhd", 'w')
110 111 112
        date_std_logic_vector = []
        import re 
        for digit in date_string:
113
            date_std_logic_vector.append("{0:04b}".format(int(digit)))
114

115
        syn_tool_version = version
116
        syn_tool_version = re.sub("\D", "", syn_tool_version)
117 118 119
	syn_tool_std_logic_vector = []
	for digit in syn_tool_version:
	    syn_tool_std_logic_vector.append("{0:04b}".format(int(digit)))
120

121
        filled_template = template.substitute(repo_url=global_mod.top_module.url,
122
                                              syn_module_name=global_mod.top_module.syn_top,
123
                                              syn_commit_id=global_mod.top_module.revision,
124
                                              syn_tool_name=tool.upper(),
125 126
                                              syn_tool_version="0000"*(8-len(syn_tool_std_logic_vector))+''.join(syn_tool_std_logic_vector),
					      syn_tool_version_str=syn_tool_version,
127
                                              syn_date=''.join(date_std_logic_vector),
128
					      syn_date_str=date_string,
129 130 131
                                              syn_username=getpass.getuser())
        project_vhd.write(filled_template)
        project_vhd.close()
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150



    def _generate_synthesis_project(self, tool_object):

        tool_info = tool_object.get_keys()
        if sys.platform == 'cygwin':
            bin_name = tool_info['windows_bin']
        else:
            bin_name = tool_info['linux_bin']
        path_key = tool_info['id'] + '_path'
        version_key = tool_info['id'] + '_version'
        name = tool_info['name']
        id_value = tool_info['id']
        ext_value = tool_info['project_ext']

        env = self.env
        if not self.options.force:
            if self.env[path_key] is None:
151
                logging.error("Can't generate the " + name + " project. " + name + " not found.")
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
                quit()
        if not env[version_key]:
            logging.error(name + " version cannot be deduced. Cannot generate " + name + " "
                          "project file properly. Please use syn_" + id_value + "_version in the manifest "
                          "or set")
            sys.exit("Exiting")
        logging.info("Generating project for " + name + " v. %s" % env[version_key])
        
        if os.path.exists(self.top_module.syn_project) or os.path.exists(self.top_module.syn_project + "." + ext_value):
            logging.info("Existing project detected: updating...")
            update=True
        else:
            logging.info("No previous project: creating a new one...")
            update=False

        top_mod = self.modules_pool.get_top_module()
        fileset = self.modules_pool.build_file_set()
        non_dependable = fileset.inversed_filter(DependableFile)
        fileset.add(non_dependable)

        sff = SourceFileFactory()
        if self.options.generate_project_vhd:
          self._write_project_vhd(id_value, env[version_key])
          fileset.add([sff.new(path=path.rel2abs("project.vhd"),
                                 module=self.modules_pool.get_module_by_path("."))])\


        tool_object.generate_synthesis_project(update=update,
                         tool_version=self.env[version_key],
                         top_mod=self.modules_pool.get_top_module(),
                         fileset = fileset)

        logging.info(name + " project file generated.")