Esempio n. 1
0
        // 外部プログラムを実行(出力を必要とする場合)
        public static GHDLResult ExecToolAndGetResult(string FileName, string args, GHDLResult result = null)
        {
            string outMessage = "";
            string errMessage = "";

            if (result == null)
            {
                result = new GHDLResult();
            }
            Process p = ExecTool(FileName, args, true);

            if (p == null)
            {
                return(null);
            }
            p.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
            {
                if (e.Data != null)
                {
                    outMessage += e.Data + "\n";
                }
            });
            p.ErrorDataReceived += new DataReceivedEventHandler((sender, e) =>
            {
                if (e.Data != null)
                {
                    errMessage += e.Data + "\n";
                }
            });
            p.BeginOutputReadLine();
            p.BeginErrorReadLine();
            if (!p.WaitForExit(settings.procLimit))
            {
                p.Kill();
                Warn("GHDLが指定した時間内に終了しなかったため,強制停止しました.\n再度試すか,無限ループとなる記述がないか確認してください.");
                p.Close();
                return(null);
            }
            result.code = p.ExitCode;
            if (!string.IsNullOrEmpty(result.message) && (outMessage != "" || errMessage != ""))
            {
                result.message += "\n";
            }
            result.message += outMessage + errMessage;
            p.Close();

            return(result);
        }
Esempio n. 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);
                }
            }
        }