Exemple #1
0
        // ソースを解析して Entity の階層関係を作成
        public List <EntityHierarchyItem> Update()
        {
            Dictionary <string, string>         inFile             = new Dictionary <string, string>();
            Dictionary <string, List <string> > duplicatedEntities = new Dictionary <string, List <string> >();
            List <string> entities = new List <string>();

            items = new List <EntityHierarchyItem>();
            List <VHDLSource.Component> components = new List <VHDLSource.Component>();

            // Entity, Component 宣言を数え上げる
            foreach (string FileName in project.sourceFiles)
            {
                VHDLSource src = new VHDLSource(FileName);
                if (!src.isValid)
                {
                    continue;
                }
                foreach (string entity in src.entities)
                {
                    if (entities.Contains(entity))
                    {
                        if (!duplicatedEntities.ContainsKey(entity))
                        {
                            duplicatedEntities[entity] = new List <string>();
                            duplicatedEntities[entity].Add(inFile[entity]);
                        }
                        duplicatedEntities[entity].Add(FileName);
                    }
                    else
                    {
                        entities.Add(entity);
                        inFile[entity] = FileName;
                    }
                }
                foreach (VHDLSource.Component component in src.components)
                {
                    components.Add(component);
                }
            }
            if (entities.Count == 0)
            {
                return(InvalidHierarchy("<!> Entity が見つかりません."));
            }
            if (duplicatedEntities.Count != 0)
            {
                return(ReportDuplicatedEntities(duplicatedEntities));
            }

            // 他から参照されていない Entity を列挙
            List <string> roots = new List <string>(entities);

            foreach (VHDLSource.Component component in components)
            {
                if (roots.Contains(component.Name))
                {
                    roots.Remove(component.Name);
                }
            }
            if (roots.Count == 0)
            {
                return(InvalidHierarchy("<!> Entity の循環参照を検出しました."));
            }

            // 参照をたどり,木を生成
            List <List <EntityHierarchyItem> > trees = new List <List <EntityHierarchyItem> >();

            foreach (string root in roots)
            {
                List <EntityHierarchyItem> tree = SearchEntityTree(root, new List <string>(), entities, components);
                if (tree == null)
                {
                    return(InvalidHierarchy("<!> Entity の循環参照を検出しました."));
                }
                trees.Add(tree);
            }
            trees.Sort((a, b) => b.Count - a.Count);

            // トップモジュール・波形ファイルの設定
            if (!entities.Contains(project.topModule) || project.guessTopModule)
            {
                project.topModule      = trees[0][0].Name;
                project.guessTopModule = true;
            }
            if (entities.Contains(project.topModule))
            {
                string file = inFile[project.topModule];
                int    pos  = file.LastIndexOf(".");
                pos = (pos == -1) ? file.Length : pos;
                project.wavePath = Path.GetDirectoryName(file) + "\\" + Path.GetFileNameWithoutExtension(file) + ".vcd";
            }

            // 各 Entity に対応するソースのパス名を設定
            foreach (List <EntityHierarchyItem> tree in trees)
            {
                foreach (EntityHierarchyItem item in tree)
                {
                    if (inFile.ContainsKey(item.Name))
                    {
                        item.LongPath  = inFile[item.Name];
                        item.ShortPath = Path.GetFileName(item.LongPath);
                    }
                    item.IsTop = item.Name.Equals(project.topModule);
                }
                items.AddRange(tree);
            }
            return(items);
        }
Exemple #2
0
        // GHDLを何度か実行して,VHDLのコンパイルとシミュレーションを行う
        public static void CompileAndSimulate()
        {
            int               numSources = 0, numErrors = 0;
            string            args;
            const string      compileOption    = "-fexplicit -fsynopsys";
            string            simulationOption = "--vcd=wave.vcd --ieee-asserts=disable --stop-time=" + settings.simLimit;
            List <VHDLSource> sources          = new List <VHDLSource>();

            // 入力が空でないかをチェック
            if (!settings.Check())
            {
                return;
            }
            settings.Save();
            if (!currentProject.Check())
            {
                return;
            }

            // 入力のリストアップ・整形・解析
            args = "-a " + compileOption;
            CleanWorkDir();
            GHDLResult analResult = null;

            foreach (string FileName in currentProject.sourceFiles)
            {
                numSources += 1;
                VHDLSource newSource = new VHDLSource(FileName, numSources);
                if (newSource.isValid)
                {
                    newSource.CheckDataFileReference(currentProject.hierarchy);
                    newSource.CopyToWorkDirectory(workDir);
                }
                if (!newSource.isValid)
                {
                    Warn(newSource.content);
                    return;
                }
                sources.Add(newSource);
                args       = "-a " + compileOption + " " + newSource.FileName.Internal;
                analResult = ExecToolAndGetResult(GetGHDLPath(), args, analResult);
                if (analResult == null)
                {
                    return;
                }
                if (analResult.code != 0)
                {
                    numErrors += 1;
                }
            }

            // 解析にエラーがなければ,再解析(Elaborate)を行う
            if (numErrors == 0)
            {
                args       = "-e " + compileOption + " " + currentProject.topModule;
                analResult = ExecToolAndGetResult(GetGHDLPath(), args, analResult);
                if (analResult == null)
                {
                    return;
                }
                if (analResult.code != 0)
                {
                    numErrors = -1;
                }
            }

            // ソースの解析結果の整形
            analResult.RestoreFileName(currentProject.sourceFiles);
            if (numErrors != 0)
            {
                string errorIn;
                if (numErrors == -1)
                {
                    errorIn = "ファイル全体";
                }
                else
                {
                    errorIn = numErrors + "個のファイル";
                }
                Warn(errorIn + "の解析中にエラーが発生しました.詳しくはログを参照してください.");
                analResult.code = 1;
                analResult.ShowMessage();
                return;
            }
            else if (analResult.message != "")
            {
                analResult.ShowMessage();
                if (!WarnAndConfirm("解析中に警告が発生しました.詳しくはログを参照してください.\n" +
                                    "続けてシミュレーションを行いますか?"))
                {
                    return;
                }
            }

            // シミュレーションとその結果の整形
            args = "-r " + compileOption + " " + currentProject.topModule + " " + simulationOption;
            GHDLResult simResult = ExecToolAndGetResult(GetGHDLPath(), args);

            if (simResult == null)
            {
                return;
            }
            simResult.RestoreFileName(currentProject.sourceFiles);
            if (simResult.violateAssertion)
            {
                String timeString = String.Format("{0:#,0.###}", simResult.simTime / 1000000.0);
                Info("シミュレーションは " + timeString + " ns 後に停止しました.");
            }
            else if (simResult.code != 0)
            {
                Warn("シミュレーション中にエラーが発生しました.詳しくはログを参照してください.");
                simResult.ShowMessage();
                return;
            }
            else
            {
                Warn("シミュレーションは " + settings.simLimit + " 以内に終了しませんでした.");
            }

            // 出力ファイル(波形・テストベンチ出力)のコピー
            try
            {
                File.Copy(workDir + "wave.vcd", currentProject.wavePath, true);
                StreamWriter sw = new StreamWriter(currentProject.wavePath, true, Encoding.GetEncoding("ISO-8859-1"));
                sw.WriteLine("#" + simResult.simTime);
                sw.Close();
            }
            catch (IOException)
            {
                Warn("波形ファイルのコピー中にエラーが発生しました.");
            }
            foreach (VHDLSource source in sources)
            {
                source.CopyFromWorkDirectory(workDir);
                if (!source.isValid)
                {
                    Warn(source.content);
                }
            }
        }