(57)【特許請求の範囲】
【請求項１】
設計対象において実行される各関数が配置されるメモリ上のアドレス範囲、または関数間を移動する命令が配置される前記メモリ上のアドレスを検出する検出部と、
前記設計対象で実行される各命令のアドレスと、前記アドレス範囲または前記関数間を移動する命令の前記アドレスとを比較し、比較結果に応じて前記関数間の呼び出し関係を示す関数スタックを生成する関数スタック生成部と、を有し、
前記関数スタック生成部は、前記設計対象で実行される命令の前記アドレスと、前記関数間を移動する命令の前記アドレスとが一致した場合、前記関数の前記アドレス範囲を参照して実際に関数間を移動したか判定し、判定結果に応じて前記関数スタックを更新することを特徴とするシミュレーション装置。
【請求項２】
前記設計対象におけるシミュレーション時刻に応じた前記関数スタックの履歴を表示する表示部をさらに有することを特徴とする請求項１記載のシミュレーション装置。
【請求項３】
前記関数スタック生成部は命令セットシミュレータを用いて前記関数スタックを生成し、
前記命令セットシミュレータから出力される前記関数スタックに含まれる時間情報を、前記設計対象におけるシミュレーション時刻に合わせて補正する時間書き換え処理部をさらに有することを特徴とする請求項１または２記載のシミュレーション装置。
【請求項４】
設計対象において実行される各関数が配置されるメモリ上のアドレス範囲、または関数間を移動する命令が配置される前記メモリ上のアドレスを検出し、
前記設計対象で実行される各命令のアドレスと、前記アドレス範囲または前記関数間を移動する命令の前記アドレスとを比較し、比較結果に応じて前記関数間の呼び出し関係を示す関数スタックを生成し、
前記設計対象で実行される命令の前記アドレスと、前記関数間を移動する命令の前記アドレスとが一致した場合、前記関数の前記アドレス範囲を参照して実際に関数間を移動したか判定し、判定結果に応じて前記関数スタックを更新することを特徴とするシミュレーション方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、シミュレーション装置及びシミュレーション方法に関する。
【背景技術】
【０００２】
今日のデジタルシステム及びＬＳＩ（Large Scale Integrated circuit）の開発において、ソフトウェアとハードウェアが混在したシステムの開発が一般的になってきている。そのようなシステムの開発の際には、ソフトウェアとハードウェアの協調検証が行われ、性能などの最適化が図られている。
【０００３】
ソフトウェアとハードウェアの協調検証の手法として、ソフトウェアの命令を実行する命令セットシミュレータ（ＩＳＳ：Instruction Set Simulator）と、ハードウェア論理シミュレータやエミュレータを協調させる方法がある。また、ハードウェア論理シミュレーションなどで、プロセッサの実データを使ってソフトウェアを実行させる場合もある。
【先行技術文献】
【特許文献】
【０００４】
【特許文献１】特開２００７−３２８７２２号公報
【特許文献２】特開２００３−２０８３３９号公報
【特許文献３】特開平１０−２８９１２８号公報
【発明の概要】
【発明が解決しようとする課題】
【０００５】
しかしながら、従来のソフトウェアとハードウェアの協調検証では、ソフトウェアの状態を検証する際、実行中の各関数が本質的には何をしているのかを検証することは困難であった。たとえば、主要関数を見れば処理概要をつかめる可能性もあるが、標準関数（除算関数や剰余算関数など）のような小さな関数は様々な関数から呼ばれるため、実際にはどのような機能を実現するために実行されているのかわかりづらい。
【０００６】
これにより、ソフトウェアとハードウェアの協調検証が困難となっていた。
上記の点を鑑みて、本発明は、設計対象の検証を容易に行うことが可能なシミュレーション装置及びシミュレーション方法を提供することを目的とする。
【課題を解決するための手段】
【０００７】
上記目的を達成するために、以下のようなシミュレーション装置が提供される。
このシミュレーション装置は、設計対象において実行される各関数が配置されるメモリ上のアドレス範囲、または関数間を移動する命令が配置される前記メモリ上のアドレスを検出する検出部と、前記設計対象で実行される各命令のアドレスと、前記アドレス範囲または前記関数間を移動する命令の前記アドレスとを比較し、比較結果に応じて前記関数間の呼び出し関係を示す関数スタックを生成する関数スタック生成部と、を有する。
【発明の効果】
【０００８】
開示のシミュレーション装置及びシミュレーション方法によれば、設計対象の検証を容易に行うことができる。
【図面の簡単な説明】
【０００９】
【図１】第１の実施の形態に係るシミュレーション装置を示す図である。
【図２】第２の実施の形態に係るコンピュータのハードウェア構成を示す図である。
【図３】本実施の形態のシミュレーション方法の概略を説明する図である。
【図４】設計対象で実行させるソフトウェアの実行形式ファイルを生成する処理の流れを示す図である。
【図５】ディスアセンブルデータの一例を示す図である。
【図６】割り込みベクタデータの一例を示す図である。
【図７】抽出された関数レンジデータ及び関数間を移動する命令のアドレスの一例の内容を示す図である。
【図８】命令トレースデータの一例を示す図である。
【図９】関数スタック生成処理の流れを示す図である。
【図１０】関数スタック生成処理の他の例を示す図である。
【図１１】関数スタックリストに関数スタックを追加した一例を示す図である。
【図１２】ＣＡＬＬ命令の検出後の関数スタックリストの一例の状態を示す図である。
【図１３】ＣＡＬＬ命令実行後の関数スタックリストの一例の状態を示す図である。
【図１４】ＲＥＴ命令の検出後の関数スタックリストの一例の状態を示す図である。
【図１５】ＲＥＴ命令実行後の関数スタックリストの一例の状態を示す図である。
【図１６】割り込みベクタ処理後の関数スタックリストの一例の状態を示す図である。
【図１７】ＲＥＴＩ命令の検出時の関数スタックリストの一例の状態を示す図である。
【図１８】ＲＥＴＩ命令実行後の関数スタックリストの一例の状態を示す図である。
【図１９】設計対象において実行されるプログラムに含まれるコードと、それを実行して得られた命令トレースデータの一例を示す図である。
【図２０】関数トレース情報の一例を示す図である。
【図２１】関数トレース情報の他の表示例を示す図である。
【図２２】第３の実施の形態に係るシミュレーション装置の構成を示す図である。
【発明を実施するための形態】
【００１０】
以下、本発明のシミュレーション装置及びシミュレーション方法の実施の形態を、図面を参照しつつ説明する。
〔第１の実施の形態〕
図１は、第１の実施の形態に係るシミュレーション装置を示す図である。
【００１１】
シミュレーション装置１０は、たとえば、ＳｏＣ（System on a Chip）などのＬＳＩや、各種デジタルシステムの協調設計において、ソフトウェアとハードウェアの協調検証を行うものである。
【００１２】
シミュレーション装置１０は、検出部１１、関数スタック生成部１２、関数トレース情報表示部１３、記憶部Ｄ１，Ｄ２，Ｄ３，Ｄ４，Ｄ５を有する。
また、図１では、シミュレーション装置１０が検証を行う設計対象の一例の概略構成を示している。この設計対象２０は、プログラムカウンタ（ＰＣ）２１ａを含むようなプロセッサ２１と、メモリ２２を有する。
【００１３】
検出部１１は、設計対象２０において実行されるソフトウェアの各関数が配置されるメモリ２２上のアドレス範囲（以下関数レンジという）、または関数間を移動する命令が配置されるメモリ２２上のアドレスなどを検出する。たとえば、検出部１１は、ソースコードに対するコンパイル―リンク処理時に、リンカによって実行形式ファイルとともに生成されるデータ（以下リンカデータという）から、関数レンジデータまたは関数間を移動する命令のアドレスを検出する。リンカデータの詳細については後述する。
【００１４】
図１の例では、検出部１１は記憶部Ｄ１に記憶されたリンカデータから、関数レンジデータまたは関数間を移動する命令のアドレスを検出し、関数レンジデータを記憶部Ｄ３、関数間を移動する命令のアドレスを記憶部Ｄ４に記憶する。
【００１５】
関数スタック生成部１２は、設計対象２０で実行される各命令のアドレスと、関数レンジデータまたは関数間を移動する命令のアドレスとを比較し、比較結果に応じて関数間の呼び出し関係を示す関数スタックを生成する。図１の例では、関数スタックは記憶部Ｄ５に記憶される。
【００１６】
設計対象２０で実行される各命令のアドレスは、ハードウェア論理シミュレーションで、プログラムカウンタ２１ａのプログラムカウンタ値をトレースすることで取得可能である。また、各命令のアドレスは、プロセッサ２１における図示しないプロセッサコアとキャッシュメモリ間のアドレス線のトレースをとっても取得可能である。
【００１７】
関数トレース情報表示部１３は、設計対象２０におけるシミュレーション時刻に応じた、関数スタックの履歴を関数トレース情報として表示する。
設計対象２０において実行される命令のアドレスは命令トレースデータとして、記憶部Ｄ２に記憶されている。以下では、設計対象２０において実行される各命令のアドレスをプログラムカウンタ値として説明する。
【００１８】
関数スタック生成部１２は、プログラムカウンタ値と、関数レンジデータとを比較し、そのプログラムカウンタ値であるときのシミュレーション時刻では、どの関数を実行しているのかを特定する。そして、関数スタック生成部１２は、プログラムカウンタ値が現在実行中の関数レンジから外れて、新しい関数の関数レンジに入ったことを検出した場合、その関数間の関係から、関数を呼ぶ動作が起きたのか復帰動作が起きたのかなどを判定する。関数スタック生成部１２は、判定結果をもとに、関数間の呼び出し関係を示す関数スタックを更新する。
【００１９】
また、関数スタック生成部１２は、プログラムカウンタ値と、関数間を移動する命令のアドレスとの比較結果をもとに、関数スタックを生成することもできる。関数間を移動する命令は、関数の呼び出し命令、元の関数への復帰命令などである。
【００２０】
プログラムカウンタ値が、関数間を移動する命令のアドレスを指定した場合、関数スタック生成部１２は、その命令がどの関数への移動を指示しているか検出する。そして、関数スタック生成部１２は、検出結果をもとに、関数間の呼び出し関係を示す関数スタックを更新する。
【００２１】
このような関数スタックを参照することで、ユーザは、実行中の各関数がどの関数から呼ばれ、本質的にどのような処理が行われているかなどが容易に検討可能となる。これにより、ソフトウェアとハードウェアの協調検証が容易になる。
【００２２】
なお、関数スタック生成部１２は、実際に関数間の移動が生じたか確認するために、関数レンジデータを参照して、プログラムカウンタ値が関数間を移動する命令によって指定された関数のアドレス範囲内であるか確認するようにしてもよい。ここで、関数スタック生成部１２は、プログラムカウンタ値が確かに指定された関数のアドレス範囲内となる場合には、関数間の移動を確定し、関数スタックを更新する（詳細は後述する）。
【００２３】
関数トレース情報表示部１３は、上記のように更新される関数スタックの履歴を関数トレース情報として表示することで、ユーザは、視覚的に関数の呼び出し関係を参照でき、ソフトウェアとハードウェアの協調検証が容易になる。関数トレース情報の表示処理の具体例については後述する。
【００２４】
また、検出部１１は、リンカデータから割り込みに関する情報を検出して、関数スタック生成部１２は、割り込みに関する情報をさらに参照して関数スタックを生成するようにしてもよい。この処理の詳細については後述する。
【００２５】
また、図１ではデータや命令を記憶する記憶部Ｄ１〜Ｄ５を図示しているが、１つのメモリにこれらの情報が記憶されていてもよい。
以下の実施の形態では、シミュレーション装置１０を汎用的なコンピュータに適用する場合を例にとり、さらに具体的に説明する。
【００２６】
［第２の実施の形態］
以下、第２の実施の形態を図面を参照して詳細に説明する。
図２は、第２の実施の形態に係るコンピュータのハードウェア構成を示す図である。
【００２７】
コンピュータ３０は、ＣＰＵ（Central Processing Unit）３１、ＲＡＭ（Random Access Memory）３２、ＨＤＤ（Hard Disk Drive）３３、グラフィック処理装置３４、入力インタフェース３５及び通信インタフェース３６を有する。
【００２８】
ＣＰＵ３１は、コンピュータ３０全体を制御する。また、ＣＰＵ３１は、ＨＤＤ３３に格納されたプログラムを実行して、コンピュータ３０の各部と連携して、図１で示した検出部１１、関数スタック生成部１２、関数トレース情報表示部１３の機能を実現する。
【００２９】
ＲＡＭ３２は、ＣＰＵ３１に実行させるオペレーティングシステム（以下、ＯＳと略記する）のプログラムやアプリケーションのプログラムの少なくとも一部を一時的に記憶する。また、ＲＡＭ３２はＣＰＵ３１による処理に必要な各種データを記憶する。ＲＡＭ３２は、図１で示した記憶部Ｄ１〜Ｄ５の各種情報を記憶するようにしてもよい。
【００３０】
ＨＤＤ３３は、ＯＳのプログラム、アプリケーションのプログラムを記憶する。また、ＨＤＤ３３はＣＰＵ３１による処理に必要な各種データを記憶する。なお、ＨＤＤ３３に代えて（または、ＨＤＤ３３と併せて）、ＳＳＤ（Solid State Drive）など他の種類の記憶装置を用いてもよい。
【００３１】
グラフィック処理装置３４は、表示装置３４ａと接続される。グラフィック処理装置３４は、ＣＰＵ３１からの命令に従って、関数トレース情報などを表示装置３４ａの画面に表示させる。
【００３２】
入力インタフェース３５は、キーボード３５ａとマウス３５ｂと接続される。入力インタフェース３５は、キーボード３５ａやマウス３５ｂから送られてくる信号をＣＰＵ３１に送信する。
【００３３】
通信インタフェース３６は、ネットワーク３６ａと接続される。通信インタフェース３６は、ネットワーク３６ａを介して他の情報処理装置とデータ通信する。
以下、図２で示したようなＣＰＵ３１がＲＡＭ３２などと連携して、たとえば、ＨＤＤ３３に格納されたプログラムを実行することで、本実施の形態のシミュレーション方法を実現する場合を例にして説明する。
【００３４】
図３は、本実施の形態のシミュレーション方法の概略を説明する図である。
まず、ＣＰＵ３１は、関数スタックを生成するために用いるデータの検出処理を行う（ステップＳ１）。ここでは、ＣＰＵ３１はリンカデータから、関数レンジデータ、関数間を移動する命令のアドレス、割り込みに関するデータ（以下割り込みベクタデータという）を検出し、抽出する。
【００３５】
次に、ＣＰＵ３１は命令トレースデータの他、ステップＳ１の処理で検出されたデータを用いて、関数スタックを生成する（ステップＳ２）。
そして、ＣＰＵ３１はグラフィック処理装置３４を制御して、関数トレース情報を表示装置３４ａに表示する（ステップＳ３）。
【００３６】
以下、各ステップの処理の詳細を説明する。
（データ検出処理）
ここでは、ＣＰＵ３１は、設計対象において実行されるソフトウェアのコンパイル―リンク時に生成されるリンカデータから、関数スタックを生成するために用いるデータを検出する。
【００３７】
図４は、設計対象で実行させるソフトウェアの実行形式ファイルを生成する処理の流れを示す図である。
以下の処理において、ＣＰＵ３１はコンパイラ及びリンカとして機能する。
【００３８】
まず、コンパイラによってソースファイル４０のコンパイルが行われ、オブジェクトファイル４１が生成される（ステップＳ１１）。次に、リンカは生成されたオブジェクトファイル４１とライブラリ４２中のオブジェクトファイルを結合して、実行可能なファイル、つまり実行形式ファイル４３を作成する（ステップＳ１２）。このとき、リンカはリンカデータ４４として、たとえば、外部シンボル相互参照情報リスト、ローカルシンボル情報リスト、ディスアセンブルデータ、割り込みベクタデータなどを出力する。
【００３９】
外部シンボル相互参照情報リストは、リンク後の各モジュールの外部定義シンボルと外部参照シンボルのモジュール間相互参照の情報である。
ローカルシンボル情報リストは、リンク後のモジュールごとのローカルシンボルを含んだ変数や関数などの情報である。
【００４０】
ディスアセンブルデータは、モジュールリンク後の情報をもとに、アセンブラが出力した相対形式のアセンブルリストを絶対形式で表示したものである。アセンブラ言語レベルでのデバッグを行う場合に参照可能であり、機械語の１ステップ単位のアドレスを知ることができる。
【００４１】
図５は、ディスアセンブルデータの一例を示す図である。
図のように、ディスアセンブルデータは、アドレスと、ディスアセンブルデータにおける行番号と、関数を示すシンボルを含む。
【００４２】
たとえば、図５のように、割り込みを示す“＿ｖｅｃｔｏｒ７”のアドレスが“０００Ｅ４ＤＦＣ”であることが示され、割り込みからの復帰命令（以下ＲＥＴＩ命令と呼ぶ）がアドレス“０００Ｅ４ＢＤＣ”に配置されていることが示されている。
【００４３】
また、“＿ＩｎｔｅｒｒｕｐｔＦｕｎｃＡ”への呼び出しが存在し、飛び先は“０００Ｅ０ＥＡ２”であることが示されている。また、この呼び出し命令（以下ＣＡＬＬ命令と呼ぶ）は“０００Ｅ４ＢＤ０”に配置され、“０００Ｅ４ＢＥＣ”に復帰命令（以下ＲＥＴ命令と呼ぶ）が配置されていることが示されている。
【００４４】
このようなディスアセンブルデータは、アセンブラをソースコードと対応づけながら解析するために用いられるため、デバッグ情報込みで出力されることが多い。また、コード上は間接アドレッシングであっても、ＣＡＬＬ命令では、飛び先のシンボルが明記されていることが多い。図５においても、関数名“ＬＤＩ”で、飛び先が明記されている。
【００４５】
なお、ＧＣＣ（GNU Compiler Collection）を用いることでも、同様のディスアンブルデータを取得することができる。
ＧＣＣのコンパイラは、コンパイルオプションにデバッグ用のフラグ（“−ｇ”や“−ｇｓｔａｂｓ＋”）をつけてコンパイルし、リンカはリンク処理を行って実行形式ファイルを生成する。ＣＰＵ３１は、この実行形式ファイルを入力データとしたｏｂｊｄｕｍｐコマンドを、“−ｄｉｓａｓｓｅｍｂｌｅ”オプションを付加して実行することにより、上記と同様のディスアセンブルデータを得ることができる。
【００４６】
図６は、割り込みベクタデータの一例を示す図である。
割り込みベクタデータは、各割り込みベクタごとに、割り込みが発生した場合に処理するプログラムの先頭アドレス（割り込みベクタ値）と、各割り込みベクタに付されたシンボル名を有している。
【００４７】
以上のようなリンカデータを、ＣＰＵ３１はｎｍコマンドで取得されるシンボルテーブルをもとに生成するようにしてもよい。
関数レンジデータや、関数間を移動する命令のアドレスは、たとえば、図５に示したようなディスアセンブルデータから検出され、抽出することができる。
【００４８】
図７は、抽出された関数レンジデータ及び関数間を移動する命令のアドレスの一例の内容を示す図である。図７（Ａ）は関数レンジデータ、図７（Ｂ）〜図７（Ｄ）は関数間を移動する命令のアドレスの一例の内容を示している。
【００４９】
各関数の関数レンジは、関数の開始アドレスと終了アドレスにより表すことができる。
ＣＰＵ３１は、たとえば、ディスアセンブルデータにおいて、関数のシンボルがあるアドレスから開始アドレスを、次の関数のシンボルがあるアドレス―１から終了アドレスを検出する。そして、ＣＰＵ３１は、これらを図７（Ａ）に示すような関数レンジデータとして、たとえば、ＲＡＭ３２に記憶する。
【００５０】
なお、１関数が複数に分割されている場合には、関数レンジデータは、分割された領域ごとの開始アドレス及び終了アドレスのリストになる。
また、リンカデータのうち、前述の外部シンボル相互参照情報リストやローカル情報シンボルリストは、少なくとも関数の先頭アドレス情報を含んでいるので、関数レンジデータを生成する際に用いてもよい。
【００５１】
関数間を移動する命令のうち、ＣＡＬＬ命令に関しては、図７（Ｂ）に示すように、ＣＡＬＬ命令が出現したアドレスと、飛び先アドレスがディスアセンブルデータから抽出され、ＲＡＭ３２などに記憶される。さらに、関数間を移動する命令のうちＲＥＴ命令に関しては、図７（Ｃ）に示すように、ＲＥＴ命令が出現したアドレスがディスアセンブルデータから抽出され、ＲＡＭ３２などに記憶される。関数間を移動する命令のうち割り込みからのＲＥＴＩ命令 に関しては、図７（Ｄ）に示すように、割り込みからのＲＥＴＩ命令が出現したアドレスがディスアセンブルデータから抽出され、ＲＡＭ３２などに記憶される。
【００５２】
なお、図６で示したような割り込みベクタデータも、ディスアセンブルデータから検出して、抽出することができる。
次に、図３で示した関数スタック生成処理の詳細を説明する。
【００５３】
（関数スタック生成処理）
以下の説明では、まず、関数レンジデータ、割り込みデータ、命令トレースデータを用いて関数スタックを生成する処理を説明する。
【００５４】
図８は、命令トレースデータの一例を示す図である。
命令トレースデータは、設計対象におけるハードウェア論理シミュレーションなどにより取得されるシミュレーション時刻ごとのプログラムカウンタ値を有している。プログラムカウンタ値は、たとえば、図１に示したような設計対象２０のプロセッサ２１が実行する命令を保持するメモリ２２のアドレスを示す。
【００５５】
図９は、関数スタック生成処理の流れを示す図である。
まず、ＣＰＵ３１は命令トレースデータを１つフェッチする（ステップＳ２０）。たとえば、ＣＰＵ３１は、図８に示したような命令トレースデータの最初の行、シミュレーション時刻“３ｃ５２６ｂｂ”及びその時刻におけるプログラムカウンタ値“ｅ００００”を取得する。このとき、ＣＰＵ３１は、関数レンジデータを参照して、取得したプログラムカウンタ値、つまりアドレスがどの関数の関数レンジに含まれるか調べる。
【００５６】
次に、ＣＰＵ３１は、関数レンジデータと、フェッチしたプログラムカウンタ値とを比較し、現在の関数レンジ内であるか否か判定する（ステップＳ２１）。ここで、プログラムカウンタ値が現在の関数レンジ内である場合には、ステップＳ２０の処理に戻る。
【００５７】
プログラムカウンタ値が現在の関数レンジ内ではない場合、ＣＰＵ３１は関数間を移動する命令の判定を行う（ステップＳ２２）。ここで、ＣＰＵ３１は、関数間の呼び出し関係を示す関数スタックを表現する関数スタックリスト４５を、たとえば、ＲＡＭ３２上に作成する。
【００５８】
そして、ＣＰＵ３１はステップＳ２２の処理の判別結果に応じて関数スタックリスト４５を更新する（ステップＳ２３）。そして、ＣＰＵ３１は、関数スタックリスト４５をもとに、関数スタックの更新をＲＡＭ３２などに出力する（ステップＳ２４）。このとき、ＣＰＵ３１は、関数スタックリスト４５の状態を、表示装置３４ａに表示させるようにしてもよい。関数スタックの履歴は、後述する関数トレース情報の表示処理のために、たとえば、ＲＡＭ３２またはＨＤＤ３３などに記憶しておく。
【００５９】
さらに、ＣＰＵ３１は、全命令トレースデータのフェッチが終了したか否かを判定する（ステップＳ２５）。全命令トレースデータのフェッチが終了していなければ、ステップＳ２０に戻り、ＣＰＵ３１は命令トレースデータの次の行をフェッチし、以降のステップＳ２１〜Ｓ２５の処理を繰り返す。全命令トレースデータのフェッチが終了していれば、ＣＰＵ３１は、関数スタックの生成処理を終了する。
【００６０】
なお、ＣＰＵ３１は、全命令トレースデータのフェッチが終了したか否かを判定する代わりに、たとえば、ユーザにより指定された区間の命令トレースデータのフェッチを終了したか否かを判定するようにしてもよい。
【００６１】
以下ステップＳ２２，Ｓ２３の処理を具体的に説明する。
ステップＳ２２の処理において、ＣＰＵ３１は、取得したプログラムカウンタ値が関数スタックのトップ―１の関数の関数レンジ内の場合にはＲＥＴ命令が発行されたと推定する。そして、ＣＰＵ３１は、ステップＳ２３の処理で、関数スタックリスト４５を更新して、関数スタックをポップする。それ以外の場合には、ＣＰＵ３１はＣＡＬＬ命令が発行されたと推定し、検出した関数を関数スタックにプッシュする。
【００６２】
たとえば、関数Ａ、関数Ｂの順で呼び出しが発生すると、関数Ａ，Ｂは、関数スタックリスト４５において、関数スタックに関数Ａ、関数Ｂの順で積まれる。この状態の関数スタックを、［Ａ，Ｂ］と表記する。その後、プログラムカウンタ値が関数スタックのトップ―１である関数Ａの関数レンジに移動した場合、ＣＰＵ３１は、関数スタックをポップする。これによって、関数スタックは［Ａ］となる。
【００６３】
ただし、ＣＰＵ３１は、取得したプログラムカウンタ値が、関数スタックのトップ―１の関数の関数レンジの先頭アドレスである場合、その関数へのＣＡＬＬ命令が発生したと判定し、その関数を関数スタックにプッシュする。
【００６４】
これにより、同じ関数が、関数Ａ（１回目）→関数Ｂ→関数Ａ（２回目）のように、入れ子の関係で呼び出された場合に、ＲＥＴ命令であると誤判定されることを防止することができる。
【００６５】
このようにして、ＣＰＵ３１は、関数レンジデータと命令トレースデータとを比較して、関数間を移動する命令を判別できる。これにより、命令トレースデータと関数レンジデータから、関数間の呼び出し関係を示す関数スタックを生成することができる。
【００６６】
ところで、ある関数へのＲＥＴ命令と同時に割り込みが入り、ＲＥＴ命令が受理され、割り込み先の関数が実行される場合、関数スタックの遷移に矛盾が生じる場合がある。
たとえば、関数Ｂの実行中において、関数ＡへのＲＥＴ命令と同時に関数Ｃへの割り込みが生じた場合、各関数の呼び出し関係は、関数Ａ→関数Ｂ→関数Ｃ（割り込みにより呼ばれる関数）→関数Ａ（復帰）という順になる。このとき、関数スタックは［Ａ］→［Ａ，Ｂ］→［Ａ，Ｂ，Ｃ（ｉｎｔ）］→［Ａ，Ｂ］と遷移する。最後の関数スタックの状態においてトップは［Ｂ］であるので、この関数スタックの遷移では、関数Ａへの復帰が再現されていない。なお、Ｃ（ｉｎｔ）の“ｉｎｔ”は関数Ｃが割り込みによって呼ばれた関数であることを示している。
【００６７】
これに対応するため、ＣＰＵ３１は、たとえば、ステップＳ２０の処理において、図６で示したような割り込みベクタデータを参照することで、割り込み発生に基づく関数間を移動する命令を検出する。そして、ＣＰＵ３１は、割り込みで実行されている関数から復帰するときには、たとえば、１つポップまたは２つポップのうち、矛盾していないほうを選択する。以下、具体的に説明する。
【００６８】
ＣＰＵ３１は、割り込みベクタデータを参照して、フェッチされたプログラムカウンタ値が、割り込みベクタデータに含まれるアドレスと一致した場合には、割り込みが発生したことを検出するようにする。
【００６９】
たとえば、関数Ａ→関数Ｂ→関数Ｃ→（割り込みにより呼ばれる関数）の順で関数の呼び出しがあったとする。この場合、関数Ｃが呼ばれるタイミングで、割り込みベクタ内のアドレスが検出される。このとき、関数スタックの状態は［Ａ］→［Ａ，Ｂ］→［Ａ，Ｂ，Ｃ（ｉｎｔ）］となる。
【００７０】
上記の例で、関数Ｃへの割り込みの後に、プログラムカウンタ値が関数Ａの関数レンジ内（先頭アドレス以外）に戻り、関数Ａへの復帰が行われたとする。このとき、ＣＰＵ３１は関数スタックリスト４５を参照し、［Ａ，Ｂ，Ｃ（ｉｎｔ）］の後に［Ａ，Ｂ］になるように１つポップすると関数スタックのトップが［Ｂ］となり矛盾するので、［Ａ，Ｂ，Ｃ（ｉｎｔ）］の後は［Ａ］となるように２つポップを行う。
【００７１】
これにより、たとえば、関数ＡへのＲＥＴ命令と同時に割り込みが入り、復帰が受理され、割り込み先に飛んだ場合でも、関数スタックは［Ａ］→［Ａ，Ｂ］→［Ａ，Ｂ，Ｃ（ｉｎｔ）］→［Ａ］となる。したがって、関数スタックの遷移に矛盾が生じることを防止することができる。
【００７２】
また、割り込みはどこで発生するかわからないため、プログラムカウンタ値が、関数レンジの先頭アドレスを示す場合に呼び出しとする判別の仕方では、関数スタックに矛盾が生じる場合がある。たとえば、関数Ａ→関数Ｂの順で呼び出しが発生し、その関数Ｂの呼び出しと同時に割り込みが発生し、関数Ｃが呼ばれた場合、関数Ｂへ復帰する際には、プログラムカウンタ値は、関数Ｂの関数レンジの先頭アドレスを示す。この場合、上述の判別方式では、復帰とは判別されず、関数Ｂの呼び出しと判別され、関数スタックは［Ａ］→［Ａ，Ｂ］→［Ａ，Ｂ，Ｃ（ｉｎｔ）］→［Ａ，Ｂ，Ｃ（ｉｎｔ），Ｂ］となる。
【００７３】
そのため、ＣＰＵ３１は以下のような検証を行う。
プログラムカウンタ値が、割り込みで呼ばれた関数の関数レンジから、次の関数の関数レンジの先頭アドレスに移動した場合、まず、ＣＰＵ３１は、仮の関数スタックを、たとえば、２つ作成する。たとえば、１つは、関数スタックを１つポップまたは２つポップした場合のうち矛盾のないものであり、もう１つは次の関数をプッシュした関数スタックである。
【００７４】
上記の例の場合、［Ａ，Ｂ，Ｃ（ｉｎｔ）］後に、１つポップした関数スタック［Ａ，Ｂ］と、関数Ｂをプッシュした関数スタック［Ａ，Ｂ，Ｃ（ｉｎｔ），Ｂ］が、仮の関数スタックとなる。
【００７５】
その後、ＣＰＵ３１は仮の関数スタックを用いて、ステップＳ２０〜Ｓ２５の処理を繰り返す。たとえば、関数Ｂの復帰後、関数Ｄ→関数Ｅ→関数Ｄ（復帰）→関数Ｂ（復帰）→関数Ａ（復帰）のように、関数の呼び出しが行われた場合、仮の関数スタックの１つである［Ａ，Ｂ］を起点とした関数スタックの遷移は以下のようになる。
［Ａ，Ｂ］→［Ａ，Ｂ，Ｄ］→［Ａ，Ｂ，Ｄ，Ｅ］→［Ａ，Ｂ，Ｄ］→［Ａ，Ｂ］→［Ａ］
この場合、矛盾は生じていない。一方、［Ａ，Ｂ，Ｃ（ｉｎｔ），Ｂ］を起点とした関数スタックの遷移は以下のようになる。
［Ａ，Ｂ，Ｃ（ｉｎｔ），Ｂ］→［Ａ，Ｂ，Ｃ（ｉｎｔ），Ｂ，Ｄ］→［Ａ，Ｂ，Ｃ（ｉｎｔ），Ｂ，Ｄ，Ｅ］→［Ａ，Ｂ，Ｃ（ｉｎｔ），Ｂ，Ｄ］→［Ａ，Ｂ，Ｃ（ｉｎｔ），Ｂ］
この場合、関数Ｂへの復帰までは矛盾がないが、次の関数Ａへの復帰の際、戻れる関数は関数Ｃとなり、矛盾が生じる。
【００７６】
したがって、関数スタック［Ａ，Ｂ，Ｃ（ｉｎｔ）］の後は、［Ａ，Ｂ］が正しい関数スタックであることがわかる。ＣＰＵ３１は、このような矛盾を検出した場合、たとえば、矛盾していた［Ａ，Ｂ，Ｃ（ｉｎｔ），Ｂ］を起点とした関数トレース情報を破棄する。
【００７７】
このように、本実施の形態の関数スタック生成処理では、矛盾しない関数スタックの遷移を見つける検証機能を実現しているので、ＣＡＬＬ命令やＲＥＴ命令など関数間を移動する命令を用いなくとも、精度よく関数トレース情報を生成することができる。
【００７８】
次に、関数スタック生成処理の他の例を説明する。ここでは、関数レンジデータ、割り込みデータ、命令トレースデータの他、図７（Ｂ）〜（Ｄ）に示したような、ディスアセンブルデータから抽出された関数間を移動する命令を用いて関数スタックを生成する処理を説明する。
【００７９】
図１０は、関数スタック生成処理の他の例を示す図である。
まず、ＣＰＵ３１は、図９の処理と同様に、命令トレースデータを１つフェッチする（ステップＳ３０）。
【００８０】
次に、ＣＰＵ３１は、図９の処理で用いたような関数スタックリストに関数スタックがあるか否かを判定する（ステップＳ３１）。ここで、関数リストに関数スタックがある場合には、ステップＳ３２の処理が実行され、関数スタックがない場合には、ステップＳ３２の処理がスキップされ、ステップＳ３３の処理が実行される。
【００８１】
ステップＳ３２の処理ではコミット処理が実行される。ここでは、ＣＰＵ３１は、各種フラグの状態に応じて、関数の呼び出しの種別の判定を行い、判定結果に応じて関数スタックのポップやプッシュを行う。また、ＣＰＵ３１は、関数スタックの更新に応じて関数トレース情報も更新する。
【００８２】
関数スタックがないと判定された場合、またはコミット処理の後、ＣＰＵ３３は、フェッチした命令トレースデータのプログラムカウンタ値が、割り込みベクタに含まれるアドレスか否か判定する（ステップＳ３３）。ここで、プログラムカウンタ値が割り込みベクタに含まれるアドレスと判定された場合、ステップＳ３４の処理が実行され、割り込みベクタに含まれるアドレスではない場合には、ステップＳ３４の処理がスキップされ、ステップＳ３５の処理が実行される。
【００８３】
ステップＳ３４の処理では割り込みベクタ処理が行われる。ここでは、ＣＰＵ３１は、取得したシミュレーション時刻で実行されている関数の関数レンジを見つけ、この関数が１つ入った関数スタックを作成し、関数スタックリストに追加し、ステップＳ３５の処理に進む。
【００８４】
ステップＳ３５の処理では、ＣＰＵ３１は、図７（Ｂ）〜（Ｄ）で示したようなデータを参照し、プログラムカウンタ値が関数間を移動する命令のアドレスを示すものであるか否かを判定する（ステップＳ３５）。なお、この例では、割り込みの有無については、ステップＳ３３の処理で判定済みなので、ＣＰＵ３１は、割り込み以外の関数間を移動する命令の有無についての判定を行う。ここで、プログラムカウンタ値が関数間を移動する命令のアドレスを示すものである場合には、ステップＳ３６の処理が実行され、そうではない場合にはステップＳ３６の処理がスキップされ、ステップＳ３７の処理が実行される。
【００８５】
ステップＳ３６の処理では、ＣＰＵ３１は、検出された関数間を移動する命令の種別に応じて、フラグを“ｔｒｕｅ”に変更し、ステップＳ３７の処理に進む。
ステップＳ３７の処理では、ＣＰＵ３１は、全命令トレースデータのフェッチが終了したか否かを判定する。全命令トレースデータのフェッチが終了していなければ、ステップＳ３０に戻り、ＣＰＵ３１は命令トレースデータの次の行をフェッチし、以降のステップＳ３１〜Ｓ３７の処理を繰り返す。全命令トレースデータのフェッチが終了していれば、ＣＰＵ３１は、関数トレース情報の生成処理を終了する。
【００８６】
なお、ＣＰＵ３１は、全命令トレースデータのフェッチが終了したか否かを判定する代わりに、たとえば、ユーザにより指定された区間の命令トレースデータのフェッチを終了したか否かを判定するようにしてもよい。
【００８７】
以下具体例を用いて、上記の関数スタックの生成処理を説明する。
ステップＳ３０の処理でフェッチされた命令トレースデータの最初の一行目において、プログラムカウンタ値で示されるアドレスが、図８に示すように“ｅ００００”番地であったとする。ステップＳ３１では、まだ関数スタックが存在しないので、関数スタックはないと判定され、ステップＳ３２のコミット処理がスキップされ、ステップＳ３３の処理が行われる。
【００８８】
ステップＳ３３の処理において、アドレス“ｅ００００”は、図６に示す“＿ｓｔａｒｔ”の割り込みベクタ値と一致するので、ステップＳ３４の割り込みベクタ処理が実行される。なお、“＿ｓｔａｒｔ”は、スタートアップルーチンを行うための割り込みを示している。
【００８９】
図１１は、関数スタックリストに関数スタックを追加した一例を示す図である。
図１１では、割り込みベクタ処理において、関数スタックリスト５０に追加された関数スタック５１と、割り込みベクタを示す“＿ｓｔａｒｔ”の関数レンジ５１ａが示されている。以下では、関数スタック５１に積まれる関数を、図１１のようにその関数の関数レンジ５１ａで表すが、たとえば、関数のＩＤ番号であってもよい。
【００９０】
関数スタックリスト５０には、ＲＥＴＩ命令の有無を示すフラグ“ｉｓ＿ｒｅｔｉ”が記憶されている。また、関数スタック５１には、ＣＡＬＬ命令の発生の有無を記憶するフラグ“ｉｓ＿ｃａｌｌ”、ＲＥＴ命令の発生の有無を記憶するフラグ“ｉｓ＿ｒｅｔ”、現在の関数レンジ、行き先の関数レンジが記憶されている。
【００９１】
なお、“ｂｏｏｌ”は、“ｉｓ＿ｒｅｔｉ”などが、ｔｒｕｅまたはｆａｌｓｅを格納する整数型の変数であることを宣言している。図１１で示す例では何れのフラグも“ｆａｌｓｅ”となっている。
【００９２】
次に、ステップＳ３５の判定処理が行われるが、前述のように割り込みベクタが検出された場合には、関数間を移動する命令が発生したとは判定されず、ステップＳ３６の処理がスキップされ、ステップＳ３７の判定処理が行われる。ステップＳ３７の判定処理時には、まだ全命令トレースデータのフェッチが終了していないので、ステップＳ３０の処理が再び行われる。
【００９３】
ステップＳ３０の処理で命令トレースデータの次の行がフェッチされた後、ステップＳ３１の処理では、図１１で示したような関数スタック５１が作成されている場合には、関数スタックがあると判定される。これにより、コミット処理が行われるが、図１１に示されているように、各フラグは全て“ｆａｌｓｅ”になっている。そのため、ＣＰＵ３１は、たとえば、フェッチしたプログラムカウンタ値が関数間を移動する命令の位置を示すものであっても、関数スタックの更新を行わない。
【００９４】
たとえば、ステップＳ３０の処理で、フェッチしたプログラムカウンタ値が関数間を移動する命令の位置を示すものであった場合、ステップＳ３３の判定処理では“ＮＯ”と判定され、ステップＳ３５の判定処理では、“ＹＥＳ”と判定される。そして、ステップＳ３６の処理で、関数間を移動する命令の種別に応じたフラグが“ｔｒｕｅ”に変更される。
【００９５】
図１２は、ＣＡＬＬ命令の検出後の関数スタックリストの一例の状態を示す図である。
ステップＳ３５の判定処理にてＣＡＬＬ命令が検出されると、ＣＰＵ３１は、ＣＡＬＬ命令の飛び先アドレス（図７（Ｂ）参照）で示される関数を、関数レンジデータ（図７（Ａ）参照）から検出し、行き先関数レンジとして関数スタック５１に登録する。図１２では、ＣＡＬＬ命令の発生を示すフラグ“ｉｓ＿ｃａｌｌ”が“ｔｒｕｅ”と変更され、行き先関数レンジとして関数“ＦｕｎｃＡ”が登録された場合について示されている。
【００９６】
その後、ステップＳ３７の判定処理を介してステップＳ３０の処理に戻り、ステップＳ３１の判定処理を介してコミット処理が実行される。
ここでのコミット処理では、関数スタック５１のフラグ“ｉｓ＿ｃａｌｌ”が“ｔｒｕｅ”であるので、ＣＰＵ３１は、関数レンジデータを参照して、フェッチしたプログラムカウンタ値が、“ＦｕｎｃＡ”の関数レンジに含まれているか否か判定する。
【００９７】
図１３は、ＣＡＬＬ命令実行後の関数スタックリストの一例の状態を示す図である。
フェッチしたプログラムカウンタ値が、“ＦｕｎｃＡ”の関数レンジに含まれている場合、ＣＰＵ３１は、ＣＡＬＬ命令が実際に実行され、関数間の移動が発生したと判定する。そして、ＣＰＵ３１は、現在の関数レンジとして“ＦｕｎｃＡ”を登録し、“ＦｕｎｃＡ”の関数レンジ５１ｂを関数スタック５１に積む。また、ＣＰＵ３１は、フラグ“ｉｓ＿ｃａｌｌ”を“ｆａｌｓｅ”に戻す。
【００９８】
次に、ＲＥＴ命令検出時の、関数スタックの操作について説明する。
図１４は、ＲＥＴ命令の検出後の関数スタックリストの一例の状態を示す図である。
ステップＳ３５の判定処理にてＲＥＴ命令が検出されると、ステップＳ３６の処理では、ＲＥＴ命令の発生を示すフラグ“ｉｓ＿ｒｅｔ”が“ｔｒｕｅ”と変更される。
【００９９】
その後、ステップＳ３７の判定処理を介してステップＳ３０の処理に戻り、ステップＳ３１の判定処理を介してコミット処理が実行される。
ＣＰＵ３１は、関数スタック５１のフラグ“ｉｓ＿ｒｅｔ”が“ｔｒｕｅ”であるので、関数レンジデータを参照して、フェッチしたプログラムカウンタ値が、関数スタック５１に積まれているトップ―１の関数レンジに含まれているか否かを判定する。図１４の例では、トップ―１の関数レンジは、“ＦｕｎｃＡ”の関数レンジ５１ｂであるので、ＣＰＵ３１は、この関数レンジ５１ｂ内に、フェッチしたプログラムカウンタ値が含まれるか否か判定する。
【０１００】
図１５は、ＲＥＴ命令実行後の関数スタックリストの一例の状態を示す図である。
フェッチしたプログラムカウンタ値が、“ＦｕｎｃＡ”の関数レンジに含まれている場合、ＣＰＵ３１は、ＲＥＴ命令が実際に実行され、関数間の移動が発生したと判定する。そして、ＣＰＵ３１は、関数スタック５１をポップし、現在の関数レンジとして“ＦｕｎｃＡ”を登録する。また、ＣＰＵ３１は、フラグ“ｉｓ＿ｒｅｔ”を“ｆａｌｓｅ”に戻す。
【０１０１】
次に、割り込み検出時の、関数スタックの操作について説明する。
ＣＰＵ３１は、ステップＳ３３の処理で割り込みを検出すると、ステップＳ３４の割り込みベクタ処理で、先の“＿ｓｔａｒｔ”の検出時と同様に、新たな関数スタックを形成する。たとえば、図１４で示したような関数スタックリスト５０の状態（ただし、フラグ“ｉｓ＿ｒｅｔ”は“ｆａｌｓｅ”）のとき割り込みが検出されると、関数スタックリスト５０は以下のようになる。
【０１０２】
図１６は、割り込みベクタ処理後の関数スタックリストの一例の状態を示す図である。
関数スタックリスト５０に、新たな関数スタック５２が作成されている例を示している。ここでは、“＿ｖｅｃｔｏｒ＿７”という割り込みベクタが検出された場合の関数スタック５２の例を示している。現在の関数レンジとして、“＿ｖｅｃｔｏｒ＿７”が登録され、“＿ｖｅｃｔｏｒ＿７”の関数レンジ５２ａが関数スタック５２に積まれている。
【０１０３】
次に、割り込みからの復帰時の関数スタックの操作について説明する。
図１７は、ＲＥＴＩ命令の検出時の関数スタックリストの一例の状態を示す図である。
たとえば、ＣＰＵ３１は、図１６のような関数スタックリスト５０の状態で、ステップＳ３５の処理でＲＥＴＩ命令を検出すると、ステップＳ３６の処理で、図１７に示すように、関数スタックリスト５０のフラグ“ｉｓ＿ｒｅｔｉ”を“ｔｒｕｅ”に変更する。
【０１０４】
その後、ステップＳ３７の判定処理を介してステップＳ３０の処理に戻り、ステップＳ３１の判定処理を介してコミット処理が実行される。
ここでのコミット処理では、関数スタックリスト５０のフラグ“ｉｓ＿ｒｅｔｉ”が“ｔｒｕｅ”であるので、ＣＰＵ３１は、トップ―１の関数スタックのトップの関数レンジに、フェッチしたプログラムカウンタ値が含まれているか否か判定する。図１６に示した関数スタックリスト５０の場合、トップ―１の関数スタックは関数スタック５１であり、関数スタック５１のトップの関数レンジは、“ＦｕｎｃＢ”の関数レンジ５１ｃである。
【０１０５】
図１８は、ＲＥＴＩ命令実行後の関数スタックリストの一例の状態を示す図である。
トップ―１の関数スタックのトップの関数レンジに、フェッチしたプログラムカウンタ値が含まれていると判定された場合には、ＣＰＵ３１は、実際にＲＥＴＩ命令が実行され、“ＦｕｎｃＢ”に復帰したと判定する。これにより、ＣＰＵ３１は、たとえば、図１７に示したような関数スタックリスト５０から、関数スタック５２を取り除き、図１８で示すような状態に変更する。
【０１０６】
なお、フラグ“ｉｓ＿ｒｅｔｉ”が“ｔｒｕｅ”であり、フェッチしたプログラムカウンタ値が、関数スタックのトップの関数レンジに含まれていない場合に、トップ―１の関数レンジへ戻る動作を検出できないまま、割り込み先に移動した可能性がある。ＣＰＵ３１は、これを考慮して、フェッチしたプログラムカウンタ値が、関数スタックのトップの関数レンジに含まれていない場合に、関数スタックのトップ―１の関数レンジに含まれているか否かを判定する。もし、フェッチしたプログラムカウンタ値がトップ―１の関数レンジに含まれている場合には、その関数に復帰させる。たとえば、ＣＰＵ３１は、図１８で示した関数スタック５１をポップして、関数レンジ５１ｂの“ＦｕｎｃＡ”に復帰させる。
【０１０７】
以上のような処理により、矛盾しない関数スタックの履歴を見つける検証機能を有さなくとも、より正確な関数スタックの積み下ろしが再現される。ＣＰＵ３１は、以上のような関数スタックリスト５０における関数スタックの履歴を、関数トレース情報として出力し、たとえば、ＲＡＭ３２に記憶する。
【０１０８】
また、上記の関数スタック生成処理では、ＣＰＵ３１は、プログラムカウンタ値が、関数間を移動する命令のアドレスに一致した場合、命令トレースデータのフェッチを進め、関数レンジデータをもとに、実際にその命令が実行されたか否かを判定する。そして、ＣＰＵ３１は、実際にその命令が実行されたと判定した場合に、関数スタックの更新を行っている。
【０１０９】
つまり、上記の関数スタック生成処理では、関数間を移動する命令の有効性を検証して、無効な命令を無視することができる。
これによって、より正確な関数スタック及び関数トレース情報が生成可能となる。
【０１１０】
以下、関数間を移動する命令の有効性を検証することによる効果を具体的に説明する。
図１９は、設計対象において実行されるプログラムに含まれるコードと、それを実行して得られた命令トレースデータの一例を示す図である。
【０１１１】
図１９（Ａ）に示すように、このコードには、“０ｘＦ００００”のようなアドレスと、“ＲＥＴ”などの命令が記述されている。なお、このコードを含む関数のレンジは、開始アドレス“０ｘＦ００００”、終了アドレス“０ｘＦ００１０”であるとする。
【０１１２】
このとき、図１９（Ａ）に示したようなコードを実行することによって、たとえば、図１９（Ｂ）に示すような命令トレースデータが得られる。図１９（Ｂ）ではシミュレーション時刻については図示を省略しており、プログラムカウンタ値（アドレス）の遷移を示している。
【０１１３】
図１９（Ｂ）で示される命令トレースデータにおいて、（１）では、ＲＥＴ命令が配置されているアドレス“０ｘＦ０００６”が読まれたことが示されているが、その次のアドレスは、“０ｘＦ００００”となっている。これは、直前のアドレス“０ｘＦ０００４”における条件分岐（“もし０フラグが立っていたら０ｘＦ００００にジャンプ”）が実行されたことを示している。したがって、ここではＲＥＴ命令は実行されていない。したがってこのようなＲＥＴ命令は無視すべきである。
【０１１４】
本実施の形態の手法では、ＣＰＵ３１は、関数間を移動する命令の検出後、命令トレースデータのフェッチを進め、関数レンジデータをもとに、実際にその命令が実行されたか否かを判定しているので、このようなＲＥＴ命令を無視することができる。図１９（Ｂ）の例では、ＣＰＵ３１は、アドレス“０ｘ０００６”でＲＥＴ命令を検出後、アドレス “０ｘ０００４”までフェッチを進めた後、前述した関数のレンジから出ていないことを判定しため、ＲＥＴ命令を無視している。
【０１１５】
一方、図１９（Ｂ）で示される命令トレースデータにおいて、（２）でも、ＲＥＴ命令が配置されているアドレス“０ｘＦ０００６”が読まれたことが示されており、次のアドレスは、“０ｘＥ００５０”となっている。つまり、前述した関数レンジ外のアドレスとなっている。このアドレスが関数スタックのトップ―１の関数の関数レンジ内であれば、（２）のＲＥＴ命令は行使されて、その命令にあった動作が行われていることがわかる。本実施の形態の手法では、ＣＰＵ３１は、関数間を移動する命令の検出後、命令トレースデータのフェッチを進め、関数レンジデータをもとに、実際にその命令が実行されたか否かを判定しているので、このようなＲＥＴ命令を有効と判定することができる。
【０１１６】
これによって、命令の実行有無を設計対象のプロセッサの内部に立ち入らずに判定でき、命令トレースデータに含まれる無効な命令アドレスを検出することができる。また、命令トレースデータの取得時の処理が簡単になり、取得時のエラーに対する耐性を上げることができるという効果も期待できる。
【０１１７】
また、呼び出し先の関数レンジが見つけられない場合には、ＣＰＵ３１が関数間を移動する命令を無視することによって、標準関数など、ディスアセンブルできないコードにも対応できる。
【０１１８】
なお、上記の説明では、関数間を移動する命令の位置が、アドレス（即値）で指定される場合について説明したが、ポインタで指定される場合についても同様に適用可能である。その場合、たとえば、ポインタを格納したレジスタ番号が指定された場合に、関数間を移動する命令が指定されたと判定されるようにすればよい。
【０１１９】
図９、図１０で示したような関数スタック生成処理によって、たとえば、以下のような関数トレース情報が生成される。
図２０は、関数トレース情報の一例を示す図である。
【０１２０】
図のように関数トレース情報には、たとえば、シミュレーション時刻と、アドレス値（図１０の処理では、コミット処理が行われた時点でのプログラムカウンタ値）、そのアドレス値が示す命令が含まれる。また、関数トレース情報には、現在実行中の関数位置、関数スタックリスト、現在実行中の関数のＩＤ番号とその関数名に関する情報が含まれる。
【０１２１】
現在実行中の関数位置において、１つ目の引数（左側の数字）は、現在実行中の関数が含まれる関数スタックリストの関数スタックのインデックス番号を示している。また、２つ目の引数（右側の数字）は、関数スタック中での当該関数のインデックス番号である。関数スタックリストでは、関数のＩＤ番号を用いて関数スタックの状態が示されている。
【０１２２】
次に、図３で示した関数トレース情報表示処理の詳細を説明する。
（関数トレース情報表示処理）
ＣＰＵ３１は、グラフィック処理装置３４を制御して、ＲＡＭ３２またはＨＤＤ３３などに記憶された関数スタックの履歴を、たとえば、図２０で示したような関数トレース情報として表示装置３４ａに表示する。
【０１２３】
ユーザは、このような関数トレース情報を見ると、現在実行中の関数だけではなく、この関数を呼んでいる関数も認識できるため、関数間の呼び出し関係を含む関数の実行状況が容易に理解できる。
【０１２４】
これにより、たとえば、剰余算関数のような小さな関数が、ユークリッド互除法関数により呼び出されているのか、線形合同法関数により呼び出されているのかなどが容易に判断でき、関数がどのような機能を実現するために実行されているのか認識できる。
【０１２５】
そのため、実際にプログラムを開発した実設計者でなくても、設計対象の動作の把握が容易になり、ソフトウェアとハードウェアの協調検証が容易になる。
また、実設計者であっても、剰余算のコール回数が多いことがわかっているが、どの処理がきっかけで起きているのか調べたいというような場合、上記の関数トレース情報を参照することで直感的、かつ定量的に把握することができるようになる。
【０１２６】
また、シミュレーション時刻が含まれる命令トレースデータを、設計対象に対するハードウェア論理シミュレーションを用いて取得したことで、ハードウェアの時間精度で、ソフトウェアとハードウェアの協調検証ができる。
【０１２７】
なお、ＣＰＵ３１は、グラフィック処理装置３４により関数トレース情報を以下のような波形データに変換させ、表示装置３４ａに表示させるようにしてもよい。
図２１は、関数トレース情報の他の表示例を示す図である。
【０１２８】
横軸は、シミュレーション時間を示している。図２１では、関数のＩＤと関数名で示された各関数の実行状況が波形データにて示されている。もちろん、関数のＩＤのみ示すようにしてもよいし、関数名のみ示すようにしてもよい。また、たとえば、“＿０００＿ｓｔａｒｔ”のように、ＩＤと関数名の両方の情報を１つの名前で表現するようにしてもよい。
【０１２９】
ＣＰＵ３１は、図２０で示した関数スタックリスト中の関数スタックに含まれている関数に、その関数スタックのインデックス番号＋１の番号を割り当て、グラフィック処理装置３４により、その番号に応じた表示の仕方で表示処理させている。
【０１３０】
たとえば、ＣＰＵ３１は、図２１に示すように、インデックス番号０の関数スタックに含まれる関数“＿ｓｔａｒｔ”、“＿ｍａｉｎ”、“＿ＥｎｃＭａｉｎ”などには、番号１を割り当て、斜線柄で表示させる。また、ＣＰＵ３１は、インデックス番号１の関数スタックに含まれる関数“＿ｖｅｃｔｏｒ  ６”、“＿Ｉｎｔｅｒｒｕｐｔ”などには、番号２を割り当て、縦縞柄で表示させる。また、ＣＰＵ３１は、割り込まれて実行待ちの関数については、たとえば、チェック柄で表示させる。
【０１３１】
以上のような表示処理により、ユーザは、関数の実行状況や、関数間の包含関係などを視覚的及び直観的に容易に把握することができる。たとえば、図２１に示すように、ＩＤ番号“＿１１２”の関数が、関数“＿ｓｔａｒｔ”、“＿ｍａｉｎ”、“＿ＥｎｃＭａｉｎ”に包含されている様子がすぐにわかる。
【０１３２】
また、ユーザは、割り込みによる遅延の様子なども、図２１に示したような関数トレース情報を参照することで、視覚的及び直観的に把握することができる。
また、第１の実施の形態は、第２の実施の形態において、ｃａｌｌの出現とこのコミットを関数レンジの変化とその時のアドレスが関数の先頭番地であることで代用し、ｒｅｔ、ｒｅｔｉの出現とこのコミットを関数レンジの変化とその時のアドレスが関数の先頭番地以外であることで代用した方式ということもできる。
【０１３３】
〔第３の実施の形態〕
第３の実施の形態のシミュレーション装置では、第２の実施の形態で説明した関数スタックの生成処理を、ＩＳＳを用いて行うものである。
【０１３４】
図２２は、第３の実施の形態に係るシミュレーション装置の構成を示す図である。
このシミュレーション装置６０は、ＩＳＳ６１、疑似命令メモリ６２、疑似データメモリ６３、時間書き換え処理部６４、記憶部Ｄ１０，Ｄ１１，Ｄ１２を有している。
【０１３５】
ＩＳＳ６１は、設計対象２０のプロセッサ２１の動きを模擬するものである。さらに、本実施の形態のＩＳＳ６１は、第２の実施の形態で説明したような関数スタックの生成処理を行う。
【０１３６】
疑似命令メモリ６２は、プロセッサ２１が実行する命令を格納する命令メモリを模擬するものである。たとえば、リンカデータから検出された関数間を移動する命令などが格納される。また、疑似命令メモリ６２は、図６で示したような、割り込みベクタデータを保持するようにしてもよい。
【０１３７】
さらに、疑似命令メモリ６２は、ＩＳＳ６１と設計対象２０のプロセッサ２１との精度が異なる場合には、その精度差（抽象度差）を吸収する機能を有する。具体的には、疑似命令メモリ６２は、命令トレースデータによりＩＳＳ６１が実施可能な命令以外が指定された場合、その命令をスキップして、ＩＳＳ６１で実施可能な命令をＩＳＳ６１に渡す。これにより、ＩＳＳ６１と設計対象２０のプロセッサ２１との精度差を吸収することができる。
【０１３８】
疑似データメモリ６３は、プロセッサ２１に入力されるデータを格納するデータメモリを模擬するものである。
時間書き換え処理部６４は、ＩＳＳ６１から出力される関数トレース情報のシミュレーション時間を、命令トレースデータに含まれるシミュレーション時間に書き換える処理を行う。
【０１３９】
記憶部Ｄ１０は、設計対象２０に対するハードウェア論理シミュレーションのシミュレーション時刻ごとのプログラムカウンタ値を、命令トレースデータとして記憶する。なお、ＩＳＳ６１は、設計対象２０のプロセッサ２１がキャッシュメモリ（図示せず）を含むようなものであっても、これを模擬できる。そのため、ハードウェア論理シミュレーションで命令トレースデータを取得する際に、プロセッサ２１におけるプロセッサコアとキャッシュメモリ間のアドレス線のトレースを行わなくても、プロセッサ２１の外部端子のトレースを行えばよい。このとき、命令トレースデータとデータが混載している場合には、メモリマップ情報などを用いて分離することができる。
【０１４０】
記憶部Ｄ１１は、ＩＳＳ６１で用いるデータを記憶する。
記憶部Ｄ１２は、生成した関数スタックの履歴（関数トレース情報）を記憶する。
なお、シミュレーション装置６０の具体的なハードウェア構成は、図２で示したコンピュータ３０と同様である。ＩＳＳ６１、疑似命令メモリ６２、疑似データメモリ６３、時間書き換え処理部６４は、ソフトウェアで実現可能である。また、記憶部Ｄ１０〜Ｄ１２は、図２で示したようなＲＡＭ３２またはＨＤＤ３３を用いて実現可能である。
【０１４１】
このようなシミュレーション装置６０では、ＩＳＳ６１は、記憶部Ｄ１０に記憶された命令トレースデータで指定された命令を疑似命令メモリ６２から取得して実行する。このとき疑似命令メモリ６２は、ＩＳＳ６１が実行しない命令についてはＩＳＳ６１に渡さない。命令の実行の際にデータが必要な場合には、疑似データメモリ６３は記憶部Ｄ１１からデータを読んで、ＩＳＳ６１に渡す。
【０１４２】
ＩＳＳ６１は、疑似命令メモリ６２から関数間の移動する命令や割り込みを検出した場合、第２の実施の形態で説明したような関数スタック生成処理により、前述したような関数スタックリストを作成して、関数スタックを生成する。
【０１４３】
なお、このとき出力される関数スタックのシミュレーション時間は、ＩＳＳ６１によるソフトウェアの時間であるので、時間書き換え処理部６４は、この時間をハードウェア論理シミュレーションの時間に書き換えてから、記憶部Ｄ１２に出力する。
【０１４４】
具体的には、時間書き換え処理部６４は、疑似命令メモリ６２を介して、ハードウェア論理シミュレーションのシミュレーション時刻が含まれる命令トレースデータを取得する。そして、時間書き換え処理部６４は、出力された関数スタックに含まれる各命令が実行される時刻を、その命令が実行される命令トレースデータ上の時刻で書き換える。
【０１４５】
これにより、ハードウェア論理シミュレータの時間精度の関数スタック及び関数トレース情報を生成することができ、ハードウェアとソフトウェアの協調検証に用いることができるようになる。たとえば、ＩＳＳ６１から取れるデータ（たとえば、命令種別）と、実際にプロセッサ２１が設計データに組み込まれた時の時間情報の関係を、ハードウェア論理シミュレーションの時間精度で比較評価ができる。また、たとえば、命令種別ごとの処理時間の統計データをとることや、命令種別とデータアドレスのアクセス先を使い、アドレス空間ごとのロード・ストアの時間の統計データ、時分割による統計データ、時系列による逐次表示が可能である。数種のプロセッサ２１で同等のデータを収得して、グラフ化（波形データ化）すれば、競合を可視化でき、ユーザにより高度な分析を可能にするデータを提供し得る。
【０１４６】
また、上記の説明では、時間書き換え処理部６４は、命令トレースデータを利用するとしたが、データトレースデータの時間情報で、関数トレース情報の時間情報を修正するようにしてもよい。
【０１４７】
以上、第１乃至第３の実施の形態のシミュレーション装置を説明してきたが、上記シミュレーション装置の処理内容を記述したプログラムは、コンピュータで読み取り可能な記録媒体に記録しておくことができる。コンピュータで読み取り可能な記録媒体には、磁気記録装置、光ディスク、光磁気記録媒体、半導体メモリなどがある。磁気記録装置には、ＨＤＤ、フレキシブルディスク（ＦＤ）、磁気テープ（ＭＴ）などがある。光ディスクには、ＤＶＤ（Digital Versatile Disc）、ＤＶＤ−ＲＡＭ、ＣＤ−ＲＯＭ（Compact Disc - Read Only Memory）、ＣＤ−Ｒ（Recordable）／ＲＷ（ReWritable）などがある。光磁気記録媒体には、ＭＯ（Magneto - Optical disk）などがある。
【０１４８】
上記プログラムを流通させる場合には、たとえば、そのプログラムが記録されたＤＶＤ、ＣＤ−ＲＯＭなどの可搬型記録媒体が販売される。また、プログラムをサーバコンピュータに格納しておき、ネットワークを介して、サーバコンピュータから他のコンピュータにそのプログラムを転送することもできる。
【０１４９】
上記プログラムを実行するコンピュータは、たとえば、可搬型記録媒体に記録されたプログラム若しくはサーバコンピュータから転送されたプログラムを、自己の記憶装置に格納する。そして、コンピュータは、自己の記憶装置からプログラムを読み取り、プログラムに従った処理を実行する。なお、コンピュータは、可搬型記録媒体から直接プログラムを読み取り、そのプログラムに従った処理を実行することもできる。また、コンピュータは、サーバコンピュータからプログラムが転送される毎に、逐次、受け取ったプログラムに従った処理を実行することもできる。
【０１５０】
以上、実施の形態に基づき、本発明のシミュレーション装置及びシミュレーション方法の一観点について説明してきたが、これらは一例にすぎず、上記の記載に限定されるものではない。
【０１５１】
たとえば、図９、図１０で示したような関数スタックの生成処理を、ＦＰＧＡ（Programmable Logic Device）などのＬＳＩで実現するようにしてもよい。
また、第３の実施の形態において、ＩＳＳ６１が関数スタックを生成するのではなく、ＩＳＳ６１で検出した関数間を移動する命令のアドレスを、第１または第２の実施の形態における関数スタックの生成処理のための入力情報としてもよい。
【符号の説明】
【０１５２】
１０  シミュレーション装置
１１  検出部
１２  関数スタック生成部
１３  関数トレース情報表示部
２０  設計対象
２１  プロセッサ
２１ａ  プログラムカウンタ（ＰＣ）
２２  メモリ
Ｄ１〜Ｄ５  記憶部
【図１】
0005504960.tif 000002
【図２】
0005504960.tif 000003
【図３】
0005504960.tif 000004
【図４】
0005504960.tif 000005
【図５】
0005504960.tif 000006
【図６】
0005504960.tif 000007
【図７】
0005504960.tif 000008
【図８】
0005504960.tif 000009
【図９】
0005504960.tif 000010
【図１０】
0005504960.tif 000011
【図１１】
0005504960.tif 000012
【図１２】
0005504960.tif 000013
【図１３】
0005504960.tif 000014
【図１４】
0005504960.tif 000015
【図１５】
0005504960.tif 000016
【図１６】
0005504960.tif 000017
【図１７】
0005504960.tif 000018
【図１８】
0005504960.tif 000019
【図１９】
0005504960.tif 000020
【図２０】
0005504960.tif 000021
【図２１】
0005504960.tif 000022
【図２２】
0005504960.tif 000023