デザインとテストベンチのコーディング・エラーをオンザフライで特定して修正

米国シノプシス 

R&Dマネージャー Gilad Tal

アプリケーション・エンジニアリング担当シニア・マネージャー Yaron Ilani

シノプシス 特別アーキテクト Alex Potapov


概要

チップ検証の世界では、製造前にできるだけ多くのバグを見つけて修正すること、そしてその作業を開発プロセスのなるべく早い段階で実行することが鉄則です。こうした検証における「シフトレフト」のニーズに応えるには、プロジェクトの最も早い段階からエンジニアが高度な解析およびデバッグ・テクノロジを利用できるようにする必要があります。そして、設計エンジニアがRTL(Register Transfer Level)デザインをコーディングしている時点、あるいは検証チームがHVL(ハードウェア検証言語)を使用してテストベンチおよびその周辺環境を作成している時点で、多くの種類のエラーを「オンザフライ」で検出できることが望まれます。更に、これらエラーの修正方法についての提案をエンジニアがコードを入力中にインタラクティブに受け取ることができるのが理想です。

 

最近では、ハードウェア設計および検証に最適化された強力なエンジンを搭載し、高度な機能をインタラクティブに実行するソリューションによってこうしたフローが現実のものとなっています。このホワイトペーパーでは、このアプローチの利点について述べた後、業界をリードするシノプシスのソリューション「Euclide」をご紹介します。

チップ開発に求められる条件

チップの設計と検証は、ここ数十年で大きく進歩しました。かつては、設計者が手作業で回路をレイアウトしたり、ゲートレベルの回路図を作成したりしていました。プリシリコン検証という概念はほとんど存在しておらず、人手で作成したテスト・ベクターを使用して検証を実行し、その結果を波形の目視でチェックするのが一般的でした。デバッグは、ファースト・シリコンが完成してからブリングアップ・ラボで行うことがほとんどでした。その後、チップのゲート数と複雑さが増すにつれ、こうしたフローはあらゆる面で破綻を来し、新しい言語とメソドロジが求められるようになりました。RTL記述によって数百万~数十億ゲートのデザインを扱えるようになったほか、HVLを使用することで、擬似ランダム・スティミュラスや結果の自己チェック機能を備えたテストベンチを使用した高度な検証が可能となっています。プロジェクトのスケジュール遅れをなくすため、そしてラボやフィールドでバグが見つかった場合にチップ・リスピンを繰り返して多額のコストが発生するのを回避するためには、こうした変化は必然とも言えるものでした。

 

最近のハードウェア設計および検証では、エンジニアがコードを作成、テスト、デバッグする機会が増えており、このプロセスはある意味、ソフトウェア開発に似てきています。したがって、ハードウェア・エンジニアもソフトウェア・プログラミング・チームの間で定評のあるツールや手法を導入するのが理にかなっています。たとえば、これまでコードの入力や編集に使用していた単なるテキスト・エディターを、より高度なソリューションに置き換えるのもその1つです。最近のテキスト・エディターには、簡易的な構文チェックやホワイトスペース揃え、言語構文要素とユーザー信号・構造体の色分け、複数ファイルに対する最小限のサポートなど、便利な機能が追加されていますが、基本的にテキスト・エディターは一度に1ファイルを扱うためのツールであり、プロジェクト全体に対する見通しはほとんど得られません。RTLおよびDVLコードを作成するチップ開発チームが必要としているのは、コード入力中に構文やセマンティクスの正しさをチェックしてくれると同時に、多数のソースコード・ファイルやライブラリで構成されるプロジェクトを効果的に管理してくれるソリューションです。また、デザインおよびテストベンチ全体を見通すことができ、そのコンテキスト情報に基づいてより高度なチェックを実行できる機能も求められます。ファイル間での信号トレースや、数百ファイルにまたがるコード要素のリネームなども簡単に行えるとなおよいでしょう。これらのタスクをテキスト・エディターで実行しようとすると、途方もない量の手作業が発生してしまいます。最新のソリューションをひとたび導入すれば、二度と以前の状態に戻りたいとは思わなくなるはずです。

 

こうしたアプローチがチップ開発に大きな価値をもたらすことは知られていましたが、実際にそのような価値を提供できるソリューションを開発するのは容易ではありませんでした。現在、設計および検証エンジニアはほとんどのコーディングをSystemVerilogで行っています。SystemVerilogはRTL構文、アサーション、制約付きランダム・テストベンチのサポート、オブジェクト指向プログラミング(OOP)機能などで構成される非常に複雑な言語で、同じタスクをさまざまな方法で達成できるようになっています。SystemVerilogの完全なパーサーを開発するだけでも大変なことですが、それだけでは設計および検証エンジニアのニーズを満たすことができません。より深いレベルでのチェックを実行し、プロジェクトのコンテキストを完全に理解するには、SystemVerilogコード全体をエラボレーションする必要があります。エラボレーションとは、シミュレーション、エミュレーション、合成などのEDAツールに実装されている処理ステージの1つで、すべてのユーザー・パラメータを完全に解決し、generateブロックをアンロールし、すべてのSystemVerilog要素に対する目的のインスタンスを見つけて接続を完成させる処理を言います。また、ビットレベルでの信号解析、デッドコードの検出、およびクロック/リセット信号の認識によりユーザーの意図をより的確に支援するには、オンザフライでの擬似シンセシスも必要です。更に、解析とチェックの実行、結果の指摘、修正案の提示は高度なエンジンによってサポートする必要がありますが、リアルタイムのフィードバックを実現するには、これらエンジンに高い性能が要求されます。

Euclideの概要

シノプシスのEuclideは業界をリードするチップ設計および検証ソリューションで、上で述べたすべての価値を備えています。フロントエンドには、多くのユーザーになじみのあるEclipseプラットフォームを採用しています。また、EuclideはSystemVerilog言語を完全にサポートしています。多くの設計/検証ツールはSystemVerilog言語のサブセットしかサポートしておらず、サポートされる範囲もツールごとに異なることを考えると、これは非常に重要な点です。更に、ほとんどすべてのSystemVerilogテストベンチでビルディング・ブロックとして使われているUVM(Universal Verification Methodology)に関する知識も内蔵しています。Euclideはオンザフライでコンパイル、エラボレーション、擬似シンセシス、ルール・チェックをインクリメンタルに実行する機能をエディターに統合しており、大規模なデザインであってもわずか数秒でフィードバックを提示します。設計および検証エンジニアがコードを入力すると即座に分析とチェックが実行され、エラーやワーニングが提示されます。多くの場合、Euclideでは問題の簡単な修正方法(Quick Fix)が提案され、エンジニアはその提案をそのまま、または一部手を加えて適用できます。

 

図1に、シノプシスEuclideのアーキテクチャ概要を示します。パーサーはインクリメンタルに動作し、コード入力中にオンザフライでチェックを実行します。他のツールでは、コードへの変更をいったん保存してから明示的にコンパイルを開始する必要があるのに比べ、Euclideでははるかにインタラクティブな操作が可能となっています。コンパイル/エラボレーション・エンジンは高い弾力性と回復性を備えており、コーディング・エラーがあっても動作が止まることなく、コードの処理を継続します。この堅牢性は、効率的なコード解析およびデバッグに欠かすことができません。一般的なコンパイル/エラボレーション・エンジンの場合、コードに重大なエラーが検出されると動作を停止してしまい、問題を少しずつ修正してはコンパイル/エラボレーションをインクリメンタルに実行するという工程を延々と繰り返す必要があります。

 

一般に、合成はデザインに対して適用するものと考えられていますが、実際にはこれらアルゴリズムの多くはテストベンチ・コードにも適用できます。このため、Euclideは完全なSystemVerilogデザインおよびテストベンチに対して擬似シンセシスを実行します。この画期的な統合アプローチにより、EuclideはSystemVerilogテストベンチをRTL解析と同等の深さまで解析することを可能としており、他に類を見ないテストベンチ・リントチェック・ツールに仕上がっています。Euclideのパーサー、エラボレーター、および擬似シンセシス・エンジンの機能は、テキスト・エディターは言うに及ばず、一般的なSystemVerilogベースの製品と比べても群を抜いています。この結果、コード品質が向上し、よりよいデザインとより効率的なテストベンチの作成が可能となります。

図1: EuclideのアーキテクチャとGUI

SystemVerilogチェックは、ユーザーがコードを入力中にオンザフライでインクリメンタルに実行されます。図1に示した「堅牢性」とは、ほとんどのパーサーでは動作が停止してしまうようなエラーがコードに含まれていても、チェックを継続できることを意味しています。エラーとワーニングは、コードの該当セクションに直接マーキングされます。複数のビューを同時に開くことができ、それぞれにハイパーリンクが設定されてクロスプローブが容易に行えるのも、使いやすさの向上に寄与しています。[Problems]ペインでエラーやワーニングをクリックすると、該当するファイルのコード行、およびデザイン・インスタンス階層ツリーの該当する階層へ直接ジャンプできます。

 

チェックに使用するルールはユーザーごとやプロジェクトごと、あるいは全社共通に設定が可能です。たとえば、UVMエージェントを継承するクラスはすべてファイル名の末尾を「agent」とする必要があるといったルールや、コードおよびプロジェクト・ファイルの構成をチェックするルールなど、ユーザーがカスタム・ルールを追加することができます。Euclideには、特定のファイルやコード・セクションに問題が存在することが事前に分かっており、それらに対する指摘を抑制したい場合や、フルチップの最上位にRTLを統合する際に下層ブロックの解析を一時的にスキップしたい場合など、さまざまなブラックボックス機能を簡単に利用できます。また、必要に応じてエラーやワーニングを明示的に除外するWaiver機能もあります。

Euclideのテストベンチ・チェック

前述のとおり、シノプシスEuclideはSystemVerilogテストベンチの構文とUVMライブラリの要素を扱うことができます。Euclideには手続き型の検証コードを解析する機能があり、通常なら後段のシミュレーションでなければ見つからないような問題も数多く検出できます。たとえば、デッドコード(どのような条件においても到達不能なコード・セクション)を検出して指摘する機能もあります。テストベンチのデッドコードは問題にならないと思われるかもしれませんが、コーディング・エラーが原因で検証環境の一部へのアクセスがブロックされているケースが多々あります。シミュレーションの段階になってテストベンチがうまく動作しないことに気付き、そこから問題の特定とデバッグを開始するのは効率が良くありません。Euclideは無限ループおよび再帰、nullクラス・インスタンスへのアクセス、動的キャスト違反、データ型の不一致、配列の範囲外アクセス、“unique” case違反、制約およびSVA(SystemVerilog Assertion)のエラーなどを検出します。図2は、nullオブジェクトへのアクセスを特定するチェック機能の例を示したもので、これによりシミュレーション時間の短縮が可能となります。

図2: nullオブジェクトへのアクセスを指摘

このようなテストベンチの問題をコーディング時に検出できるようになると、検証工程の大幅なシフトレフトが可能となります。シミュレーションはテストベンチとデザインがほぼ完成するまで始めることができませんが、Euclideはプロジェクトの早い段階で、入力したばかりの不完全なコードに対してもこれらの問題を見つけることができます。これらの機能が特に重要なのは、テストベンチにバグがあるとデザインの問題が隠蔽され、最悪の場合、シミュレーションでテストベンチのバグが検出されず、RTLにバグを残したまま製造工程に進んでリスピンが発生することがあるためです。

 

多くの場合、Euclideは問題を指摘するだけでなく、簡単な修正アドバイス(Quick Fix)も提示します。図3では、ユーザーが宣言だけして実際には構築されていないcovergroupが検出されています。このQuick Fixを適用すると、covergroupが構築され、必要な情報が可能な限り自動で入力されます。ユーザーが入力する必要のある部分は、コードに「TODO」コメントとして追加されます。

図3: 欠落しているcovergroupを指摘

多くの企業やプロジェクトには、十分に定義されたテストベンチのメソドロジが存在します。Euclideには標準で多くのルールが内蔵されているほか、ユーザー固有のルールも追加でき、これらを組み合わせてメソドロジを構成できます。前述のとおり、これらのルールはチーム・メンバー間で共有が可能で、プロジェクトや組織全体に適用できます。図4は、プロジェクト内の全員に適用されるカスタム・ルールに違反した場合のチェック例を示したものです。

図4: メソドロジ・ルールのチェック

シノプシスEuclideはSystemVerilogの構文とその一般的な使用方法を詳細に理解しているため、非常に小さな問題も検出して指摘してくれます。図5に、興味深い例を示します。ここでは、ユーザーが重み付きの分散を使用して制約を定義しています。[1:5]:=50の構文は、1~5の各値に対する重みが50%であることを意味します。しかし恐らく、ユーザーの意図は[1:5]:/50(50を5つの値で割り、各値の重みを10%とする)であると推定されます。このプロジェクトで、「分散の重みの合計を100とする」というルールが適用されている場合、Euclideは合計が300であることを指摘します。この種のエラーは検証プロセスの終盤まで気付かず、カバレッジ目標がなかなか達成されないことでようやく見つかるということがあります。この問題をデバッグするのは容易ではなく、信号に対する制約に誤った分散値を指定していると、シミュレーション時間ばかりが無駄に浪費される結果となります。

図5: コーディング・エラーの可能性を指摘

EuclideのUVMチェック

前述のとおり、EuclideはUVMライブラリの要素と、下層のSystemVerilogテストベンチ構文の両方を扱うことができます。Euclideが検出するUVMエラーには、非常に複雑なものも含まれます。Euclideには、UVM規格への適合に問題のある誤ったコードをチェックするルールが豊富に内蔵されています。中には、初期バージョンのメソドロジからUVM 1.2またはIEEE 1800.2規格への移行を支援するようなルールもあります。図6に示すように、Euclideには標準で多くのUVMルールが内蔵されているほか、ユーザー独自のルールを定義して適用することもできます。

図6: EuclideのUVMルール

シノプシスEuclideはUVMに関する深い知識を備えているため、テストベンチ・コードの入力中に高度なチェック、問題に対するQuick Fixの提案、およびさまざまな入力支援を実行できます。テンプレートは多くの一般的な構文に対するものが用意されているほか、ユーザーによるカスタム・テンプレートを追加して拡張することもできます。図7を例に、この機能がどのように役立つかを説明します。ここでは、ユーザーがテストベンチ・コードに新しいクラスを追加する場合を考えます。これをすべてユーザーが入力するのは非常に骨の折れる作業です。そこで、ユーザーはEuclideに用意されている標準およびカスタムのクラス・テンプレートから1つを選びます。ユーザーが新しいクラスの名前を入力すると、このテンプレートから生成されたすべてのコードが自動的に更新されます。このように、信号や構造体の名前を変更すると関連するファイル全体に変更が反映されるリファクタリング機能もEuclideの大きな特長の1つです。

図7: クラスを追加するためのテンプレート

これ以外にも、Euclideにはテストベンチ・コードの作成および修正に大いに役立つ機能があります。図8に、その例を3つ示します。まず、ユーザーがクラス名の入力を開始すると、入力した文字列に一致する定義済みのクラスがリストに表示されます(オートコンプリート機能)。長いクラス名を入力しなくても、リストから選ぶだけでよいため、時間を節約できます。次に、ユーザーがコンテント・アシスト機能を呼び出すと、選択したクラスで利用可能なメンバーが表示されます。これらメンバーのうち1つを選んで、テンプレートして使用できます。Euclideによって生成されるコードには、図3に示したのと同じような、ユーザーに対する「TODO」コメントが追加されます。「TODO」コメントに関連するタスクは、プロジェクトの[Tasks]ペインにも追加されます。

図8: Euclideのコーディング支援機能

Euclideのデザイン・チェック

SystemVerilog RTLデザインはOOPを使用しませんが、シノプシスEuclideは設計エンジニアにも多くの利点をもたらします。コンパイル/エラボレーション・チェック、合成チェック、カスタマイズ可能ルール、デッドコード/範囲外アクセス検出、case違反、Quick Fix、オートコンプリート、コンテント・アシストなど、これまでに紹介した検証用機能の多くが、RTLデザイン・コードでも利用できます。これ以外にも、リスクを高めたりデザインの動作を損なったりするようなコーディング・プラクティスを指摘するチェック機能もあります。図9は、フリップフロップのリセット極性の指定に誤りがあるRTL構文が検出された例を示しています。これが設計者の意図したとおりであるなら、指摘に対してWaiverを適用することもできますが、コーディング・エラーの可能性が高いと考えられます。こうしたエラーも、Euclideなら非常に早い段階で見つけることができます。

図9: Euclideのデザイン・チェック

図10は、Euclideから設計エンジニアに提示される高度なアシスタンス機能の例を示したものです。ここでは、ユーザーがあるモジュールをインスタンス化していますが、1つのポートを含めるのを忘れています。Euclideはインスタンスと宣言を比較し、欠落しているポートを検出して指摘します。更にQuick Fixを提案し、ユーザーがこれを受け入れると、コードにポートが追加されます。Euclideの分析およびチェック機能がなければ、このようなエラーはシミュレーション用にデザインをコンパイルしようとしてエラーになるまで検出されないことも考えられます。これ以外にも、コンパイルの時点ではエラーにならず、シミュレーションやエミュレーション、あるいはブリングアップ・ラボやフィールドでエラーが発生するまで検出されないようなエラーもあります。コーディングの段階でなるべく多くのバグを検出できるなら、それに越したことはありません。

図10: デザインのインスタンス化に関するチェック

シノプシスEuclideには、デザインとテストベンチの両方のコードについて、シノプシスのシミュレータVCS®やエミュレータZeBu®など、開発フローの他のツールとの互換性をチェックする機能もあります。また、これらツールに対するコンプライアンス・チェックだけでなく、潜在的なパフォーマンス・ボトルネックを取り除くチェック機能もあります。これ以外のデザイン・チェックとして、組み合わせループ、意図しないラッチ、ゲートなしフリップフロップ、クロックとリセットの問題、ドライバー/ロード違反、幅の不一致やその他データ型の不一致などが含まれます。その他、Euclideにはデザインおよびテストベンチのコーディングに役立つ次のような機能があります。

 

  • 信号、ドライバー、ロードのトレース
  • デザインおよびUVMの階層ツリー表示
  • 宣言、実装、インスタンス間での容易なナビゲーション
  • 解決したデータ型およびパラメータ値の表示
  • 自動インデントおよびコード・フォーマット
  • バージョン管理ツールとの統合によるプロジェクト管理の容易化

まとめ

設計および検証用のコードをテキスト・エディターで作成したりメンテナンスしたりするのは、手書きによる回路図や人手によるレイアウトと同様に時代遅れのアプローチと言えます。現在のチップ開発プロジェクトには、SystemVerilog RTLおよびテストベンチに最適化したソリューションが必要です。革新的なエンジンを搭載したシノプシスEuclideは、SystemVerilogコードをインタラクティブかつインクリメンタルに解析し、デザインおよびテストベンチのバグを早い段階で見つけることができる唯一無二のソリューションです。Euclideを使用すると、ZeBuとの互換性が確保された正しいコードが即座に得られるほか、多大なコストの発生要因であるテストベンチ・エラーを減らしてVCSのパフォーマンスを向上させることができます。また、シノプシスVerdi®との統合により、シームレスなデバッグとコード開発も可能です。

 

シノプシスEuclideには、チップ開発チームにとって多くの利点があります。設計および検証エンジニアは、コードの作成と編集にかかる時間を大幅に短縮しながら、コード品質を高めることができます。充実したコード表示およびナビゲーション機能により、継承したデザインおよびテストベンチへの理解が容易になります。SystemVerilogの初心者は短期間で言語を習得できるようになる一方、経験豊富なエンジニアもQuick Fixやコード・テンプレートを活用することにより、一般的な操作の多くを少ない労力で達成できるようになります。ファイル管理、バージョン管理、バグトラッキング、タスク管理の機能や、他のEDAツールとの統合により、きわめて大規模なチップ開発プロジェクトも円滑に進めることができます。

 

Euclideのメリットは、単にコード開発の期間短縮にとどまりません。一般的なコーディング・エラーの多くをソースコード入力中にオンザフライでチェックできるため、チップ検証を大幅にシフトレフトできます。インクリメンタルに動作する画期的なコンパイル、エラボレーション、擬似シンセシス・エンジンを利用して高度なチェックを実行することにより、複雑な問題も見つけることができます。これらのチェックによって、デザインとテストベンチのコードに潜むバグをシミュレーションや合成のはるかに前の段階で特定できるほか、エラーやその疑いのある構文が指摘されるためデザインの品質も向上します。また、プロジェクト全体で共通のコーディング・スタイルやメソドロジを適用することにより、デザインおよびテストベンチの統合も容易になります。問題のあるコードは入力時に検出および修正されるため、シミュレーション、エミュレーション、合成もより円滑に進めることができます。シノプシスEuclideによりエンジニアの生産性向上とプロジェクトの期間短縮が実現し、バグの取りこぼしによるチップのリスピンを減らすことができます。