EDA ツールを用いた論理回路設計
実験概要
EDA Electronic Design Automation
タル LSI の設を行算機上で LSILarge Scale Integration
設計に加え,き換え可能な論理素子である FPGAField Programmable Gate Array
用いた回路の動作実験と,実験課題を通して,論理回路設計,シミュレーション,論理合成
などの論理回路設計における各段階の基本的な技術を習得する.
実験スケジュール
本実験は全 2 週で,以下のようなスケジュールで行う
1 週(予習:本指導書の 1 章,2 章,3 章,4 章)ハードウェア記述言語の一つである
Verilog HDL よる簡単な組合せ回路の設計と,設計した回路の動作実験を行う.回
路の動作実験ではFPGA を搭載した実験基板を用いて設計した回路を実際に動作さ
せる.
実験 1(簡単な組合せ回路の設計と動作実験)
実験 2(加算を行う組合せ回路の設計)
2 週(予習:本指導書の 4 章,5 章,6 章)Verilog HDL による組合せ回路順序回路
の記述,EDA ツールを用いた回路設計についての実験を行た,実験課題として,
2 10 BCD: Binary Coded Decimalカウンタの設計,系列検出器(有限オー
トマトン)の設計を行う
実験 3(加算を行う順序回路の設計)
実験課題 1BCD カウンタの設計)
実験課題 2(系列検出回路の設計)
指導書の構成
1 では,ィジタル LSI の設計フローについて述べ,2 章では, Verilog HDL よる回
路記述について説明する3 章では,本実験で用いる EDA ツールの使い方について,EDA
ツールを用いた回路設計「基礎編」として説明する.4 章では,組合せ回路,順序回路の設
計について,EDA ツールを用いた回路設計「中級編」として説明する.5 では,第 2
目に行う実験課題を示し6 では,レポートの内容と調査課題について説明する.7 章は
実験基板のピン配置ファイル,クロックの使い方,回路の記述例の付録である.
実験の進め方
実験は,23 1 組(各班 2 組で構成)で実施する.組ごとに,実験機器を共有しなが
ら,全ての実験を進める.
実験課題目次
1 はじめに 1
1.1 ハードウェア記述言語を用いたディジタル LSI 設計 . . . . . . . . . . . . . . 1
1.2 ハードウェア記述言語 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.3 ディジタル LSI の設計フロー . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3.1 回路の動作記述 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3.2 機能レベルシミュレーション . . . . . . . . . . . . . . . . . . . . . . 3
1.3.3 論理合成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3.4 ゲートレベルシミュレーション . . . . . . . . . . . . . . . . . . . . . 3
1.3.5 レイアウト設計 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3.6 レイアウト後のシミュレーション . . . . . . . . . . . . . . . . . . . . 4
1.3.7 FPGA を用いたプロトタイピング . . . . . . . . . . . . . . . . . . . . 4
2 Verilog HDL による回路動作記述の基礎 5
2.1 Verilog HDL 記述の基本構造 . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2 基本的な構文と意味 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3 always ブロック . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.4 時間のモデル . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.5 順序回路の記述 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.6 状態機械 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.7 モジュールと階層設計 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.8 回路の動作環境の記述 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3 EDA ツールを用いた回路設計「基礎編」 12
3.1 計算機と EDA ツールの環境設定 . . . . . . . . . . . . . . . . . . . . . . . . 13
3.1.1 計算機と EDA ツール . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.1.2 EDA ツールの環境設定 . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.2 Verilog HDL による回路記述 . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.3 ModelSim による機能レベルシミュレーション . . . . . . . . . . . . . . . . . 15
3.4 Quartus II によるコンパイル . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.4.1 準備 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.4.2 GUI によるコンパイル . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.4.3 CUI によるコンパイル . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.5 FPGA を用いた回路実現 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.5.1 DE2-115 ボード . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.5.2 ダウンロード . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4 EDA ツールを用いた回路設計「中級編」 24
4.1 組合せ回路の設計 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.2 順序回路の設計 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
5 実験課題 28
6 実験と実験課題のレポートについて 30
7 その他 30
7.1 FPGA のピン配置の変更 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
7.2 Altera DE2-115 ボードのクロックの使い方 . . . . . . . . . . . . . . . . . . . 30
7.3 種々の回路の Verilog HDL 記述 . . . . . . . . . . . . . . . . . . . . . . . . . 31
作成者: 中村 一博,高木 一義
改訂者: 大野 誠寛,松原
協力者: 安藤 友樹
最終更新日: 2015 8 31
4.01
1 はじめに
1.1 ハードウェア記述言語を用いたディジタル LSI 設計
現代の生活では,多種多様の電気電子機器が身の回りに存在しておりそれらの機器に
LSI 回路が多数搭載されている.パソコンやゲーム機に搭載されている CPUメモリ等
のみならず各種家庭電化製品音声画像機器においてもデタル化が進み,制御デー
タ処理等の用途で LSI は不可欠なものとなってきている.また,LSI 高集積化低消費
力化により,携帯情報端末なども実現可能になった.
このような状況は,年の LSI 製造技術の進歩によりLSI 搭載できる回路の規模が
増大し,高度で多様な機能を実現できるようになったため可能になった.LSI 製造技術
は,物性・デバイスの技術,微細加工技術である.しかし,回路が大規模で複雑になれば回
路設計も複雑で困難なものとなる.製造技術とともに,どのような考え方で回路を構成する
か,すなわち,LSI 設計技術の進歩もまた,必要不可欠なものである.
初期 LSI 回路設計ではレイアウトのマスクパタンを人手で描いて設計が行われた
の後,レイアウトの自動化が可能になりトランジスタレベルあるいは論理レベルの回路図
を描いて回路を設計する手法がとられた.CADComputer Aided Designシステムの発達
によ,ソフトウェアによる回路図入力の支援や回路シミュレーションが可能となったが
回路が大規模になるにて,このようなレベルで人間が考えて設計することは困難となる
現在実現可能な,数百万,数千万ゲート規模の回路を,人手で設計することはほぼ不可能で
あろう
ソフトウェアの設計において,アセンブラでコードを書いていた時代から,高級言語によ
る設計へと移り変わっていったのと同様に,ハードウェアの設計においても,より抽象度の
高い設計入力へと移り変わっていったのは自然な流れである.すなわち,ハードウェア記述
言語HDL: Hardware Description Language)を用いた設計フローへの変遷である.
ハードウア記述言語は路の機能を,ソフトウのプログラムと同様,動作記述のレ
ベルでプログラムテキストとして記述できる.ハードウェア記述言語は,ハードウェアの
様記述ための言語としての機能を持っていた.即ち,ハードウェア記述言語で記述された
仕様と,別に設計された回路との動作の比較を行い,期待された動作を確認する役割を持っ
ていた.しかし,論理合成システムと呼ばれる,ハードウェア記述を自動的に回路記述に変
換するシステムが実用化されたことによりハードウェア記述言語はハードウェア設計
記述としての役割を持つこととなった.論理合成システムは,ソフトウェアの高級言語にお
けるコンパイラと同様の役割を持つシステムであ,その発展は,大規模回路の設計期間短
縮,設計生産性の向上に大きく寄与した.
特にディジタル回路の設計においては,ハードウェア記述言語による回路設計が現在の主
流である.アナログ,高周波回路の設計においては,回路図あるいはレイアウト図を用いた
設計が現在でも重要であるが,記述言語による設計フローも発展しつつある.今後は,オブ
ジェクト指向型の設計技術,システムレベルの設計技術の発展が重要になると考えられる.
1.2 ハードウェア記述言語
現在ではHDL により論理回路をジスタ転送レベル(RTL: Register Transfer Level
で記述し,設計を行うことが多くなっている.HDL はハードウェアの仕様を記述する言
であると同時に,設計を記述する言語でもある広く普及している HDL しては,VHDL,
Verilog HDL が挙げられる.
1
VHDL は,米国国防総省の VHSICVery High Speed Integrated Circuit)プロジェクト
で,ハードウェアの記述言語(VHDL: VHSIC Hardware Description Language)として採
用されたものであHDL の一つの標準規格である.VHDL Ada に似た構文を採用して
いる.Verilog HDL Cadence 社の論理シミュレータ Verilog XL 用の言語として普及して
きた.Verilog HDL C 語の文法要素を多く採用している.VHDL は,IEEE Std-1076
VHDL87)及び Std-1164VHDL93)として早い時期から規格化されている.それに対し
て, Verilog HDL はシミュレーション用の言語として事実上の業界標準であったが,IEEE
Std-1364 として改めて規格となった.
国内の設計システムとしては,NTT による,記述言語 SFL 用いた LSI 計システム
PARTHENON が挙げられる.PARTHENON SFL は実際の LSI 設計の実績もあり,研
究用,大学等での教育用としても広く使用されてきた.本電子工業振興協会の LSI 設計用
記述言語標準化委員会で策定された HDL である UDL/I は,処理系がフリーソフトウェア
として配布されており,シミュレーション及び合成ツールが入手可能である.
今後は,より上位のアルゴリズムレベルの記述が一般的になっていくと考えられる.現在
では,
C, C++, Java
等をベースにしたハードウェア設計記述や環境が研究され,すでに実
用化されているものもある.
1.3 ディジタル LSI の設計フロー
1 LSI 設計フローと,用いられるツールを示す.設計の工程はいくつかの段階に
分けられそれぞれの設計段階でのハードウェアの表現が存在する設計フローは,上位の
設計段階での回路の表現を,下位での表現に等価変換していく工程である.
1: LSI の設計フロー
2
1.3.1 回路の動作記述
ハードウェア記述言語を用いて,回路の動作を記述する.データの値を保持する変数(レ
ジスタ)と,それらの間の演算やデータ転送の流れと制御を,言語記述によって指定する.
これらはそれぞれ記憶素子,組合せ回路として実現されることになる.このようなレベルで
の設計はレジスタ転送レベル(RTL: Register Transfer Level設計,あるいは機能設計と
呼ばれる.
アと違いき方によは論理合成が不可能な記述となるため,
ト回路の構造を意識して記述することが重要となる.
1.3.2 機能レベルシミュレーション
設計した回路が要求されている機能を満たしているかどうかを確認する.機能レベルでの
シミュレーションを行うことにより処理手順や論理の誤りを早期に発見することが可能と
なる.また,一般に,より上位の設計段階でのシミュレーションはより高速に行うことがで
きるため,この点でも機能レベルでシミュレーションを行うメリットがある.
また,回路を実際に動作させる入出力などの環境(テストベンチ)もハードウェア記述言
語で記述することが可能であり軟で汎用的なシミュレーション環境の構築が可能である
1.3.3 論理合成
ハードウア記述言語で記述した機能を,記憶素子や論理ゲート等の回路素子に置き換え,
機能レベルの記述からゲートレベルの記述に変換する.出力であるゲートレベルの記述は,
ネットリストと呼ばれる,論理回路図と等価なテキスト表現であ,実際のゲート等の部品
間の接続を記述したものである.
論理合成システムでは,ANDORNOTフリップフロップなどの基本素子セル
あらかじめ設計されているものとして,これらを部品として使った回路を合成する.基本素
子の面積,動作速度,消費電力などの設計情報を蓄えておくデータベースはセルライブラリ
と呼ばれる.LSI 製造のテクノロジ毎に異なるセルライブラリを用いることにより各テク
ノロジに対応した回路を合成できる.
論理合成においては,回路全体の面積,動作速度,消費電力などのパラメータが要求を満
たすよう設計する必要がある.論理合成ツールによっては,設計者が,どのパラメータを優
先して最適化するか,最適化の条件をきめ細かに指定できるものがある最適化条件を変え
て合成することにより,要求を満たす回路が実現可能かどうかを模索する工程が繰り返され
る.例えば,回路面積の上限を制約条件として,動作速度を最適化するなどの指定をするの
一般的であるフトのコンパイルにおいても,性能を左右するコンパイルオプ
ンをいくつか試すことは行われるが,ハードウェアの場合は,出力された回路の性能への要
求がより明確であることが多いためこの過程はより重要となる.なお,本実験で使用する
Quartus II による論理合成では,設計者が最適化条件を細かく指定することはできず自動
的に最適な回路を生成する.
1.3.4 ゲートレベルシミュレーション
セルライブラリに記述されている,各セルの機能,面積,動作速度,消費電力などの情報
を用いて,合成されたゲートレベルの回路が正しく機能を実現しているかを確認する.配線
3
に起因する回路遅延時間は,回路面積の見積りなどからおおよその配線長を見積ることによ
り推測される.
機能レベルでの記述が合成後の回路を意識して書かれていない場合,論理合成によって動
作が変わってしまうことがあり得るので,ここでのチェックが必要となる.また,機能レベ
ルでのシミュレーションに比べ,各セルの実現方法と接続関係がより明確であるため,回路
の動作速度などの性能をより正確に見積もることができる.
1.3.5 レイアウト設計
LSI 上に実際に作成されるレイアウトのマスクパタンを生成する.レイアウトを設計入力
とし,図形エディタ上で各素子を描画していくフルカスタム設計も行われているが,セルラ
イブラリに記述されている基本素子のレイアウトと,ネットリストに記述されている素子の
接続関係の情報から,回路全体のレイアウトを半自動的に生成するシステムが広く用いられ
るようになってきている.セルベースのレイアウト設計では各素子の位置を決定する配置
の段階と,素子間の結線の経路を決定する配線の段階の
2
段階で構成される近年では,
子の動作速度に比べ,配線での信号遅延の割合が大きくなってきているため,レイアウトの
品質は回路の品質を大きく左右する.
1.3.6 レイアウト後のシミュレーション
セルライブラリの情報に加え,レイアウトの情報から配線長などを抽出し,設計された回
路の機能とタイミングを検証する.レイアウト設計により素子の面積や配線長などが全て
決まるので,素子遅延や配線遅延をここで初めて正確に算出することが可能になる.基本的
にはゲートレベルシミュレーションと同様であるが,タイミングを含めてより正確なシミュ
レーションが可能である.また,より正確な評価のために,マスクパタンからトランジスタ
回路を抽出し,トランジスタの動作モデルを用いてシミュレーションを行うことも多い.
1.3.7 FPGA を用いたプロトタイピング
レイアウト設計まで LSI の設計フローは完了するが,回路の動作検証,評価がシミュ
レーションだけでは不十分であったりLSI の製造を待たずに周辺の回路と組み合わせた検
証,評価をしたい,などの場合には,プロトタイプを作成して動作検証を行うことがある.
このために,書き換え可能な論理素子である FPGAField Programmable Gate Array)が
用いられる.
FPGA 設計者がその場でプログラムすることが可能な論理素子でありくのもの
機能の書き換えを何度も行うことができるFPGA 能を書き換え可能な論理ブロ
と,組み換え可能な論理ブロック間の配線から成るFPGA けの回路設計ではLSI
計と同様,ハードウェア記述言語やネットリストを入力とし,各社 FPGA れぞれに専
用のマッピングツールを用いて回路が FPGA の構成データに変換される.
FPGA いたプロトタイピングでは,設計した LSI のタイミングなどの正確な評価は
できないが,ソフトウェアによるシミュレーションに比べ,実機に近い環境でのより高速な
動作評価が可能である.
4
2 Verilog HDL による回路動作記述の基礎
2.1 Verilog HDL 記述の基本構造
Verilog HDL の基本構造や構文要素は,C 言語に類似しているVerilog HDL 記述のフ
イル名 *.v することが多い.ツールによってはこれは必須で,更にモジュール名とファ
イル名を一致させる必要があるものもある.
2 に,2 入力 1 出力のセレクタ回路 Verilog HDL 述を示す.この回路は,セレク
ト入力 S1 0 1 によって,データ入力 D0 るいは D1 の値を Y 出力する.この
述を例に,Verilog HDL の基本構造を見ていく
/* */ で囲んだ部分,及び,// から行末まではコメントである.
Verilog HDL ではモジュールが一つの設計の単位になる.一つのモジュールの宣言は,
module, endmodule で囲まれる.
まずモジュール名 mux21 を定義し,ポート(入出力インタフェース) ( ) 内に記述
する.続いて,各ポートの型 (入力,出力,ビット数) を宣言する.C 語(ANSI
前の K&R 風)の関数名,引数と同様である.
この例にはないが,内部で用いる変数や内部で呼び出すモジュールもここで宣言する.
残りはモュールの動作の本体の記述である.この例では,S1, D0, D1 いずれかが
変化した時に,Y への代入の右辺を計算し,Y へ代入している.代入文中の ~, &, |
は論理演算子である.この例のような論理演算による単純な代入は組合せ論理回路の
記述となる.
/* *
* mux21.v *
* 2-1 マルチプレクサ *
* (2-1 セレクタ回路) *
* */
module mux21 (S1, D0, D1, Y); // 入出力ポート
input S1, D0, D1; // 入力 S1, D0, D1
output Y; // 出力 Y
// Multiplexer body
// Y = ((not S1) and D0) or (S1 and D1)
assign Y = (~S1 & D0) // 出力ポートに対する
| ( S1 & D1); // 代入は assign 文で行う
endmodule
2: 2-1 セレクタ回路
2.2 基本的な構文と意味
Verilog HDL のデータの種類には,入出力ポートの他にレジスタとネットがある.レジス
タは, reg, ットは主に wire として宣言する.reg 記憶素子,wire は配線素子を表わ
すが,reg として宣言してもフリップフロップが生成されるとは限らない.
5
Verilog HDL ではinput, output, inout, reg, wire デーと呼る.
タ型は,データの扱われ方を示すものであるがデータがとり得る値の型を厳密に区別した
ものではない.基本となる 1 ビットのデータは 0, 1, x, z 4 値を持つ.x 不定,z
ハイインピーダンスを表わす多ビットのデータは,型名の直後に [3:0] のようにレンジ
を指定する.演算子は C 言語とほぼ同じのものが使える.多ビットのデータはビットベク
トルであるとともに,符号なし整数として扱われる.例に示した論理演算の他に 3 に示
すような演算がある.C 言語にない演算子としては,連接 {a, b} とリダクション(&
a , | a など)が挙げられる.
演算子等 意味 使用例
&, | bitwise AND, OR a & b
~ bitwise NOT ~a
^ bitwise XOR a ^ b
{ } ビット連接 {a, b}
&, |, ^ 全桁の AND, OR, XOR &a
a[n] & a[n-1] & ... & a[0]
~&, ~| 全桁の NAND, NOR ~& a
~(a[n] & a[n-1] & ... & a[0])
+,-,*,/,% 算術演算 a + b
==, !=, === 論理等価,非等価演算 a == b
>, >=, <, <=, = 算術比較演算 a > b
? : 条件演算 (a>=b) ? a : b
<<, >> シフト演算 a << 2
[n:m] 部分ビット参照/代入 a[3:2] {a[3], a[2]}
数字 10 進定数 0, 1, 29
n’bxx n ビット 2 進定数 2’b01
n’hxx n ビット 16 進定数 12’ha5a
3: Verilog HDL の演算子等
配列の宣言は,データ名の後に [0:255] などのように記述する.前述の,wire, reg
どの型名の後に記述するレンジとは扱いが異なり配列要素のビットを並べて整数として扱
うことはできないwire 対する代入は assign で行うれは組合せ回路の記述となる
条件付き代入は,?: 演算子や,always 構造内での if, case, casex などの構文で記述で
きる.
2.3 always ブロック
Verilog HDL では,逐次的に解釈されるひとまとまりの機能を always ブロック構造の中
に記述する.always ブロックの中では if などの制御構造が記述できる.図 2 Y への代
入文を always ブロックで記述すると以下のようになる.
always @(S1 or D0 or D1) begin
Y = (~S1 & D0) | ( S1 & D1);
end
always の次に記述されている @( ) は,イベント制御と呼ばれる.( ) のイベント式
には,変数名,posedge 数名,あるいは negedge 変数名 いった表現を or でつないで
列挙する.このリスト中の変数が変化した時にこの always ブロック内の文が起動される.
reg 対する代入は always ブロクの中で行う代入にはブロキング代=とノン
ブロッキング代入<=がある.ブロッキング代入では,値は左辺に即反映される.ノンブ
ッキング代入では,begin - end の右辺の評価が全て行われた後,全ての代入が同時
6
実行される.記述の順序に依存しない意味を持つようにするため,reg に対する代入は全て
ノンブロッキング代入で書くのが望ましい.
代入が全て同時に反映されるということは,例えば,1 つの always 中に
Y <= X;
Z <= Y;
という記述がある場合,Z に代入される Y の値は,上の行で X の値を代入される前の Y
値である.
基本的には,一つの reg 駆動す always ブロ(ドライバは唯一であるまり
一つの reg に対して,複数の always ブロックで代入を行なうことはできない.
組合せ回路の出力は現在の入力の値のみに依存して決まる.組合せ回路を always ブロッ
クで記述する場合は,always で参照しているすべての変数をイベントリストに入れ,ま
た,すべての条件を網羅して代入文を記述する必要がある.入力が変化しても代入が行われ
ない場合があると,出力の値は変化しないことになるため過去の値を保持する必要があ
順序回路となってしまうこの点は誤りやす設計者の予期しない記憶素子が合成されて
しまうことがあるので,十分に注意する必要がある.組合せ回路を記述していることを確実
にするためには,データを wire で宣言し always を使わず assign 文で代入を行うとよい
が,同じ条件の下で変化するデータがいくつかある場合には,always まとめて代入する
ほうが全体の記述が簡潔になることが多い.
2.4 時間のモデル
ハードウェアの動作記述では並列に動作する回路を記述できるため,ソフトウェアのプロ
グラミング言語と比較すると,時間の概念が特徴的である.
1 モジュール内に記述された複数の assign 文や always ブロックは,全て同時に動
する.また,前述のように,1 つの always ブロック内のノンブロッキング代入文は全て
同時に値が反映される.assign Z = X & Y; いう記述に対し,処理系は右辺の変数に値
の変化(イベント)があるかどうか調べ,もしあれば, (微小時間)後の左辺の値を
更新する.時 t のシグナル X 値を X(t) と書くと,この式は Z (t + ∆) = X(t) & Y (t)
という意味になる.
2.5 順序回路の記述
前述のように,always の分岐の条件により代入が行われないことがあり得るデータは,
以前の値を保持する必要があるため,記憶素子(フリップフロップレジスタ)として扱わ
れる.
特定のクロックシグナルの立ち上がりあるいは立ち下がりのイベントによって全ての記
憶素子が動作するように記述すれば,単相クロック完全同期式の順序回路の記述となる
まり全な同期式順序回路であれば,全てのフリップフロップは reg で宣言し,値の更新
always @(posedge clock) という形のイベントで制御された構造中に記述すればよい.
次に,非同期リセット付きフリップフロップの例を説明する.記憶素子としてはリセット
/ リセット付きのエッジトリガ式フリップフロップのモデルが用意されていることが多く
通常はクロックの他にリセットシグナルを記述する.複数のクロックがある記述個々の記
憶素子が他の論理のイベントで駆動される非同期回路の記述なども Verilog HDL として
7
正しいがタイミングの検証を綿密に行う必要があること,また,デバイスによっては実現
できない場合があること(FPGA など)に注意する必要がある.
4 2 ビットの同期カウンタ(00 01 10 11 00 · · ·)の例を示す2 ビット
の記憶素子に対応するレジスタ r0, r1 する.クロック clk, リセッ reset, ウント
アップするかどうかを指定する信号 i0 を入力として持つ.出力は y0, y1 で,内部状態を
そのまま出力している.y0, y1 は出力ポートなので,代入文の右辺には使えない.
/* *
* counter2.v *
* 2-bit カウンタ *
* */
/* reset == 0 のとき, カウンタの値をリセット *
* i0 == 1 のとき, クロック信号 clk に同期してカウントアップ */
module counter2 (reset, clk, i0, y0, y1); // 入出力ポート
input reset, clk, i0; // 入力
output y0, y1; // 出力
// 現在の値を記憶しておく flip-flop の宣言
reg r0, r1; // flip-flop (1-bit レジスタ)
// Counter body
/* クロック,リセット信号に関係のない *
* 信号線,出力ポートへの代入 */
assign y0 = r0; // 出力ポートに対する
assign y1 = r1; // 代入は assign 文で行う
/* クロックの立上り or リセット信号の立下がりイベント *
* が発生したときに行う処理 *
* flip-flop への代入 */
always @(posedge clk or negedge reset) begin
if (reset == 1’b0) begin
// reset == 0 (binary, 桁数 1) のとき, カウンタのリセット
r0 <= 1’b0; r1 <= 1’b0; // r0r1 = 00
end else begin
if (i0 == 1’b1) begin
/* i0 == 1 (binary, 桁数 1) のとき, カウントアップ *
* r1r0 = 00 01 10 11 00 ... */
r0 <= ~r0; // r0 = not t0
// r1 = ((not r0) and r1) or (r0 and (not r1))
r1 <= ((~r0) & r1) | (r0 & (~r1));
end
end
end
endmodule
4: 2 ビット同期カウンタ
この例は典型的な非同期リセット付き,立ち上がりッジ同期の順序回路の記述である
Verilog HDL 文法上は同じ意味を持つ書き方が他にも考えられるがあまり凝った書き方
をすると処理できない場合があるので,基本的にはこの枠組での記述,あるいは必要に応じ
てクロック,リセットの論理を逆にした記述が推奨される.
8
2.6 状態機械
4 2 ビットカウンタでは,次状態関数を直接記述したが,有限オートマトンの状態
遷移を状態名で記述し,次状態関数の生成を自動的に行なわせることもできる.
5 4 状態カウンタの例を示すここでは st0, st1, st2, st3 2 ビット定数とし
て定義し,変数 st に対する代入で状態遷移を表している.
状態毎の動作を書くには case 文が便利である.状態を表わす変数を条件として用い,
移はこの変数の代入として明示的に記述る.出力は ?: 用い条件付き代入文で
述しており,この部分は st の変化で起動される組合せ回路となる.前述のように,複数の
always ック assign 文を記述した場合,構造は列に動作する.データへの参照は
どの文からでもできるが,1 つのデータへの代入は単一 always ブロックあるいは assign
文に限られる.
2.7 モジュールと階層設計
ある程度大規模な回路の設計では,まとまった機能単位 1 のモジュールを設計し上
のモジュールでそれを部品として用いるといった,階層設計を行うのが普通である.Verilog
HDL では,module の呼び出しを用いて階層的な設計を記述する.
2 を二 4 タの 6 4 counter2
counter2a, counter2b 2 counter2a "11" counter2b
をカウントアップする.
上位のモジュールでは,で用いるモジュールを記述したファイルを ‘include で参照し
名前を付けて呼び出.この際にこの部品の実体 counter2a, counter2b の結線関係を指
定する.それぞれの値がポートの宣言順に割当てられる.
2.8 回路の動作環境の記述
回路の動作を確認するには,回路に入力を与えて出力を観測する必要がある.入力を与え
るために,HDL シミュレータ固有のコマンドを用いる方法もあるが,回路をテストする
めの枠組ちテストベンチを HDL で記述して用意する方法が汎用性が高く一般的である.
テストベンチは,設計された対象回路が本来組み込まれる環境をシミュレートするように記
述する.つまり適当な入力波形を発生し,モジュールとして呼び出した対象回路に入力す
る動作を記述すればよい.
7 に,前述の 2 ットカウンタ counter2 ためのテストベンチを示すcounter2
呼び出し,クロック等の入力を発生している.reset, clk, i0 には,"#" で指定された時
間の後に値が代入されるalways 中の文は指定された時間毎に繰返し実行されinitial
中の文は 1 回だけ実行される.特にclk 10ns 毎に反転するため,20ns 周期のクロック
波形が生成されることになる.
このテストベンチで用いた # よる遅延時間量の記述は論理合成できないことに注意
る.これらの記述はシミュレーション上は意味があるが,遅延時間を指定できるデバイスは
存在せずまた,論理合成の段階での回路の遅延は合成系に与える制約条件に従って最適化
されるパラメータの一つなので,回路の記述としては意味がない. 
9
/* *
* counter2st.v *
* 状態変数を用いた *
* 2-bit カウンタ *
* */
/* reset == 0 のとき, カウンタの値をリセット *
* i0 == 1 のとき, クロック信号 clk に同期してカウントアップ */
// define を用いた状態割り当て
‘define st0 2’b00
‘define st1 2’b01
‘define st2 2’b10
‘define st3 2’b11
module counter2st (reset, clk, i0, y0, y1); // 入出力ポート
input reset, clk, i0; // 入力
output y0, y1; // 出力
// 現在の状態を記憶しておく 2-bit レジスタの宣言
reg [1:0] st; // 2-bit レジスタ
// Counter body
/* クロックの立上り or リセット信号の立下がりイベント *
* が発生したときに行う処理 *
* flip-flop への代入 */
always @(posedge clk or negedge reset) begin
if (reset == 1’b0) begin
// reset == 0 (binary, 桁数 1) のとき,
// 状態変数に初期状態をセット
st <= ‘st0;
end else begin
if (i0 == 1’b1) begin
/* i0 == 1 (binary, 桁数 1) のとき, 状態遷移 *
* st = st0 st1 st2 st3 st0 ... */
case (st)
‘st0: begin
st <= ‘st1;
end
‘st1: begin
st <= ‘st2;
end
‘st2: begin
st <= ‘st3;
end
‘st3: begin
st <= ‘st0;
end
endcase
end
end
end // always @(posedge clk or negedge reset) begin
/* クロック,リセット信号に関係のない *
* 信号線,出力ポートへの代入 */
// 出力ポートに対する代入は assign 文で行う
assign {y1, y0} = (st == ‘st0) ? 2’b00 : (
(st == ‘st1) ? 2’b01 : (
(st == ‘st2) ? 2’b10 : 2’b11));
endmodule
5: 状態変数を用いた順序回路の記述
10
/* *
* counter4.v *
* counter2.v を用いた階層設計 *
* による 4-bit カウンタ *
* */
‘include "counter2.v" // counter2.v の取り込み
module counter4 (reset, clk, i0, y); // 入出力ポート
input reset, clk, i0; // 入力
output [3:0] y; // 4-bit 出力
wire counter2b_in; // 1-bit 信号線
// module counter2 (reset, clk, i0, y0, y1) の実体化
counter2 counter2a(reset, clk, i0, y[0], y[1]);
counter2 counter2b(reset, clk, counter2b_in, y[2], y[3]);
// Counter body
// wire に対する代入も assign 文で行う
assign counter2b_in = y[0] & y[1];
endmodule
6: 階層設計による 4 ビットカウンタ
/* *
* test_counter2.v *
* 2-bit カウンタのテストベンチ *
* */
‘timescale 1ns / 1ns // シミュレーションの単位時間 / 精度
// 1 ns = 1/1000000000 sec
‘include "counter2.v" // counter2.v の取り込み
module test ; // テストベンチモジュール, 入出力ポート無し
// counter2 の入力用 flip-flop(1-bit レジスタ) の宣言
reg reset, clk, i0; // flip-flop
// counter2 の出力用 wire(信号線) の宣言
wire y0, y1; // 1-bit 信号線
// module counter2 (reset, clk, i0, y0, y1) の実体化
counter2 counter2a(reset, clk, i0, y0, y1);
// 周期 20 単位時間のクロック信号の生成
always begin
// 10 単位時間毎に値が変化
#10 clk = ~clk;
end
initial begin
// reset, clk, i0 の初期値
reset = 1; clk = 0; i0 = 0;
#20 reset = 0; i0 = 0; // 20 単位時間 (20 ns)
#20 reset = 1; i0 = 1; // 更に 20 単位時間 (20 ns)
#80 $finish; // 更に 80 単位時間 (80 ns) , 終了
end
endmodule
7: 2 ビットカウンタのテスト回路
11
3 EDA ツールを用いた回路設計「基礎編」
1 週目の実験では,単な組合せ回路の設計と回路の動作実験を行回路の動作実験
では,FPGA を搭載した実験基板を使い,FPGA 上に設計した回路を実現する.ここでは,
EDA ツールを用いた LSI 設計の設計フローの理解を目指す
実験 1 次の 2 入力 1 出力セレクタ回路を設計し,動作実験を実施せよ.
設計する 2 入力 1 出力セレクタ回路の仕様
入力: デー D0, D1 それぞれ 1 セレクト信 S11 ト)
出力: データ Y1 ビット)
機能:セレクト信号 S1 値が 0 1 かにより,デー D0, D1 の値を
Y に出力
8 はこのセレクタ回路の回路図と真理値表である.
回路設計および動作実験の手順
1. 環境設定
計算機と EDA ツールの環境設定をする.
2. Verilog HDL による回路記述とテストベンチの作成
レク回路 Verilog HDL mux21.v と,テトベチ(機能
ベルシミュレーション用の回路の動作環境の記述)test mux21.v 作成
する.
3. 機能レベルシミュレーション
セレクタ回路の機能レベルシミュレーションを行う
4. 論理合成,レイアウトFPGA マッピング(コンパイル)
セレクタ回路のコンパイルを行う
5. FPGA を用いた回路実現
セレクタ回路を DE2-115 ボード FPGA ダウンロードし,実際の動
作を観察する.なお,DE2-115 ードの SW0 S1 に, KEY0, KEY1
がそれぞれ D0, D1 に対応する.最も左の LED Y に対応する.
Y
D0
S1
D1
D1S1 D0 Y
0
0
0
0
1
1
1
1
0
0
1
1
0
0
1
1
0
1
0
1
0
1
0
1
0
0
1
1
0
1
0
1
8: 2 入力 1 出力セレクタ回路の回路図と真理値表
12
3.1 計算機と EDA ツールの環境設定
3.1.1 計算機と EDA ツール
ICE ではCent OS version 6.4 64 版)がインストールされた計算機を使用できる.
本実験を実施するにあたって,この計算機には,以下のツールがインストールされている.
シミュレータ ModelSim-ASEAltera Starter EditionAltera 社)
FPGA 用統合開発ソフトウェア  Quartus II Web Edition version 13Altera 社)
シミュレ ModelSim-ASE は,Altera のすてのバイス(MAX CPLDArria
CycloneStratix シリーズ FPGA を含む)向けのシミュレーションツールである.図 1
FPGA 計フローにおける,機能レベルシミレーシンとゲートレベルシュレーョン
の両方で使用できる商用の ModelSim-AEAltera Edition比較して,10,000 インの
制限,無償 (ライセンス不要)であること以外は違いはない.
FPGA 開発フト Quartus II Web Edition version 13 Altera 社の FPGA
SoCおよび CPLD 用いた設計開発に必要となる論理合成,レイアウ(配置配線
イミング解析,FPGA マッピング等のさまざまな機能を備えた統合開発ソフトウェアであ
る. 1 FPGA 設計フローにおける論理合成か FPGA ッピングまでサポートしてい
る.Quartus II Web Edition は,Altera 社のウェブサイトからダウンロードして無償で利
用できる.
他にも,教育機関向けに特に安価でソフトウェアを提供しているベンダもある.また,
時点では市販のツールには及ばないものの,フリーソフトウェアとして開発が続けられてい
るツール群もあり,今後が期待される.これらのツールは,実際に企業で使われているもの
と同一のものであり企業で LSI 設計環境と同じものが教育機関で低コストで利用可能と
いうことになる.後のハードウェア設計,LSI 設計の教育環境の一層の普及が期待される
本実験で使用する EDA ツールに関して何か変更が生じた時は下記の URL にその情報を
掲載するので,実験中に案内があった際には参照すること.
http://www.ice.nuie.nagoya-u.ac.jp/jikken/hard/j2hard-eda/index.html
3.1.2 EDA ツールの環境設定
使 Altera EDA ICE Linux 利用
て述EDA ール /pub1/jikken/eda3 インールいるこれ
使/pub1/jikken/eda3/cadsetup.csh.altera
を読み込む必要がある.もしくは,設定ファイルの内容を参考に,コマンドのパス,環境変
数を各自で設定しても構わない.
1. 端末ln -s /pub1/jikken/eda3/cadsetup.csh.altera ~/と入力して,同フ
イルのシンボリックリンクをホームディレクトリに作成する.
2. source ~/cadsetup.csh.alteraと入力して,設定を読み込む source ンド
で読み込んだ設定ファイルの内容は,端末を終了すると無効になってしまうので,端
末を立ち上げる度に source コマンドを実行して設定を読み込む必要がある.繰り
し実行するのは面倒な場合には,ホームディレクトリに .cshrc ファイルを作成して,
先に説明した,設定を読み込むコマンドを記述することで,端末を起動した際に,自
動的にコマンドが実行されるようにしても良い.
13
3.2 Verilog HDL による回路記述
以下の手順にしたがって,Verilog HDL による回路記述とテストベンチを作成する.
1. 作業用ディレクトリの作成 回路のシミュレーションや論理合成等の処理では,数多くの
中間ファイルが生成されるので,設計する回路ごとに作業用ディレクトリを作成する.
端末でmkdir ジュール名(ここでは,作成する回路のモジュール名 mux21 合わ
せて, mux21 とする)」を実行し,以降の作業は,このディレクトリ内で実行する.
2. セレクタ回路の記述 8 のセレクタ回路に対応する Verilog HDL 述は,2.1 節の図 2
の通りである.2.1 節の Verilog HDL 記述の基本構造に関する説明を理解したのち,
キストエディEmacs vi 好きなアプリケーションを使用して構わない)
レクタ回路 Verilog HDL 記述を作成する.ファイル名はモジュール名 mux21 に合わ
せて mux21.v とする.
3. セレクタ回路用テストベンチの作成 セレクタ回路の動作を確認するためのテストベンチ
(回路の作環境の記述 を図 9 に示2.8 節におけ,回路の動作環境記に関
,セ.ファイ
test mux21.v とする.
/* *
* test_mux21.v *
* 2-1 セレクタ回路のテストベンチ *
* */
‘timescale 1ns / 1ns // シミュレーションの単位時間 / 精度
// 1 ns = 1/1000000000 sec
‘include "mux21.v" // mux21.v の取り込み
module test ; // テストベンチモジュール, 入出力ポート無し
// mux21 の入力用 flip-flop(1-bit レジスタ) の宣言
reg S1, D0, D1; // flip-flop
// mux の出力用 wire(信号線) の宣言
wire Y; // 1-bit 信号線
// module mux21 (S1, D0, D1, Y) の実体化
mux21 mux21a(S1, D0, D1, Y);
initial begin
// S1, D0, D1 の初期値
S1 = 0; D0 = 0; D1 = 0;
// 20 単位時間 (20 ns)
#20 S1 = 0; D0 = 1; D1 = 0;
// 更に 20 単位時間 (20 ns)
#20 S1 = 1; D0 = 1; D1 = 0;
// 更に 20 単位時間 (20 ns)
#20 S1 = 0; D0 = 0; D1 = 0;
// 更に 80 単位時間 (80 ns) , 終了
#80 $finish;
end
endmodule
9: 2-1 セレクタ回路のテストベンチ
14
3.3 ModelSim による機能レベルシミュレーション
Verilog HDL 記述した回路が,機能的に正しく動作するかどうかを調べるために,論理
シミュレータと呼ばれるソフトウェアが用いられる.論理シミュレータは,ハードウェア記
述言語による回路記述を中間ファイルに変換するコンパイあるいはアナライズと呼ばれる
工程を最初に行う.続いて,この中間ファイルを用いて回路の入出力シグナルをトレースす
機能レベルシミュレーションが行われる.
3.1 節の通りに環境設定をした後,Altera 社のシミュレータ ModelSim を用いて,以下の
手順でセレクタ回路の機能レベルシミュレーションを行う
1. シミュレータの起動 vsim test mux21.v
とする) &を実行すると, ModelSim が起動する.以降,GUI 下側に表示される
Transcript 入力ウインドウModelSim>」でコマンド入力待ちになっているところ)
にコマンドを入力して作業を進める.図 10 に起動後の初期画面を示す
10: Mo delSim 起動後の初期画面
2. 準備 ModelSim> vlib work実行しライブラリを作成するこの処理は,めて
シミュレーションをするときだけ,実行すれば良い.
3. コンパイル ModelSim> vlog テスンチ述フイル行しVerilog HDL
述のァイルをコンパイルする.常にコンパイルできた場合には,上位のモジ
ル名(Top level modules)が表示される.コンパイルでエラーが発生した場合は,エ
ラーの内容と行番号が表示される.
4. 最上位モジュールの読込み ModelSim> vsim 最上位モジール名」を実行しコンパ
イルした Verilog HDL 記述内の最上位のモジュールを読み込む.
5. 信号の波形表示の準備
(a) VSIM> view wave行し号の波形 Wave ウインド
(b) 波形を表示する信号を指定するべての信号を表示する場合には,VSIM> add
wave *」を実行する.特定の信号だけを表示する場合には,VSIM> add wave
信号名」を実行する.信号名は,正規表現を使って指定することもできる.
15
6. シミュレーションの実行 VSIM> run シミュレーション時間」を実行し,シミュレー
ションを実行する.シミュレーション時間として指定する値は例えば mux21 テス
トベンチでは最後のイベント発生時刻が 80 ns であるので,1 ns 80 ns までの値を
指定する.図 11 に,2. から 6. までのコマンドを実行したときの画面を示す
11: Transcript にコマンドを入力したときの画面
シミュレーションを実行すると,テストベンチを実行した結果の信号の波形 Wave
ウインドウに表示される. 12 すべての波形を表示したシミュレーション結果の
画面を示す
12: Mo delSim でシミュレーションした画面
7. シミュレーションの再実行 シミュレーション時間を延ばすなど,Verilog HDL 記述を変
更せに再度シミュレーション実行したときには6. を再実行る.Verilog
HDL 述を変更したときは,VSIM> quitを実行し,シミュレーションを一度終了
して,再度 1. から実行する.
8. シミュレータの終了 シミュレータを終了するときは,ModelSim のウインドウを閉じる
か,Transcript ウインドウで,VSIM> quit」を実行する.
16
3.4 Quartus II によるコンパイル
3.4.1 準備
機能レベルシミュレーションによって,ハードウェア記述言語で記述した回路が期待通り
に動作することが確認できたら,次は,論理合成系と呼ばれるソフトウェアを用いて理合
をする.論理合成は,ハードウェア記述言語により記述された回路を最適化し,ゲートレ
ベルの記述であるネットリストへ変換する.
Quartus II は, 3.1 で述べたように,FPGA 設計フローにおける論理合成から FPGA
マッピングまでの機能をサポートしているQuartus II ではこれらの機能を実行する一連の
処理をンパイルと読んでいる.さらに,Quartus II 各機能は,GUI 実行できるだけ
でなくCUI(端末上からコマンドを実行すること)でも実行することができる.
本節では,Quartus II GUI CUI 用いて,コンパイルを行う手順を示す基本的
はどちらのインタフェースを用いても同じ結果が得られるが,例えば各機能の実行結果を
視覚的に確認する場合には GUI を,機能をまとめて実行する場合には CUI 用いること
を想定している.
Quartus II によるコンパイルにおいては回路のソースファイルに加えて,以下のファイ
ルが必要となる.それぞれダウンロードして,作業ディレクトリに置く
プロジェクトファイル(*.qpf
Quartus II のプロジェクトファイルであり使用する Quartus II のバージョンとプ
ジェクト名を定義する.ここでは,以下のファイルを使用する.
http://www.ice.nuie.nagoya-u.ac.jp/jikken/hard/j2hard-eda/first/mux21.qpf
FPGA 設定ファイル(*.qsf
Verilog HDL ソースコードに定義されている入出力と,FPGA 物理的な入出力ピン
の対応付けピン配置設定定義するフイルである例えばmux21 の場合は,
計したセレクタ回路の各ポート S1, D0, D1, Y を,FPGA 数百本ある IO の中
で,どのピンに割り当てるかを指定する必要がある.ここでは,以下のファイルを使
用する.
http://www.ice.nuie.nagoya-u.ac.jp/jikken/hard/j2hard-eda/first/mux21.qsf
3.4.2 GUI によるコンパイル
まずGUI でコンパイルする方法について説明する.論理合成イアウ(配置配線)
FPGA ピングの各機能を個別に実行したい場合や,各機能の実行結果を視覚的に確認
たい場合に使用する.
1. Quartus II の起動 端末で「quartus &」と入力して, Quartus II GUI を起動する.
13 Quartus II GUI 起動したときの画面を示すなお,Quartus II GUI
を初めて立ち上げると,ツールの紹介ウインドウが 2 つ表示される.1 つ目のウイン
ドウは,2 番目の選択肢を選択する.2 つ目のウインドウではDon’t show」にチ
クして,×をクリックする.これらの操作により,次回以降,紹介ウインドウは表示
されなくなる.
17
13: Quartus II を起動した画面
14: 読み込まれた Entity の確認
2. プロジェクトの読み込み File Open Project...」でmux21.qpf
を読み込む 14 に示すように,Project Navigator ウインドウの Entity 部に,対象
となる FPGACyclone IV E: EP4CE115F29C7と,モジュールの名称(mux21
表示されていることを確認する.
3. コンパイル Processing Start Compilationンパイルを実行する.エラーが発
生しなければ 15 示すように,コンパイルが成功する.もしエラーが発生した
合には,Message ウインドウにエラー内容が表示されるので,該当箇所を修正する.
4. コンパイル結果の確認 コンパイルに成功すると,最適化後の回路と,回路に関する情報
を確認することができる.
最適化後の回路構成
最適化後の回路はTools Netlist Viewers Technology Map Viewer (Post-
Mapping) で確認できる 16 に示すように出力ポーブロクとそれ
らのブロック間の接続が表示される.ブロックをダブルクリックすると, 17
に示すように,内部の回路構成が表示される.
回路に関する情報:ロジックエレメント数
回路の実現に使用したロジックエレメント数は,図 18 に示すように,コンパイ
ルが完了した際に,画面に表示される「Flow Summary」で確認できる.
回路に関する情報:回路の遅延時間
回路を実行した際の遅延時間は,TimeQuest Timing Analyzer というツールで確
18
15: mux21 のコンパイル成功時の画面
16: mux21 のマッピング結果
認できる.
1. Quartus II のメニューで,Tools TimeQuest Timing Analyzer」をクリッ
クして,TimeQuest Timing Analyzer を起動する.
2. TimeQuest Timing Analyzer Tasks
から,Rep orts(フォルダのアイコン) Custom Reportsフォルダのアイ
コン) Report Path...」をダブルクリックする.
3. Report Path インドウの From To 設定画面では何も指定せずにRe-
port Path ボタンを押す
4. 19 に示すように,延時間の解析結果(モジュール毎の遅延時間合計の
遅延時間)が表示される.時間の単位は,ns である.
17: mux21 のマッピング結果(モジュールの詳細を表示)
19
18: mux21 の合成結果の概要
19: mux21 の回路遅延時間の表示
20
3.4.3 CUI によるコンパイル
次にCUI ンパイルする方法について述べる.端末で,論理合成イアウトFPGA
マッピングの各機能を実行する一連の処理をまとめて実行する場合に使用する.
1. 端末でquartus sh --flow compile mux21と入力し,コンパイルを実行する.
ラーが表示された場合,の内容を読み必要に応じてソースを修正するエラーがな
場合には, 20 に示すように,Quartus II Full Compilation was successful.
と表示される.
20: CUI によるコンパイル実行が成功した場合の画面
21 に示すよう,カレントディレクトリ以に,ストリム・アウト・ファイル
mux.sof)が生成されていることを確認する.
21: sof ファイルが生成されていることの確認
3.5 FPGA を用いた回路実現
論理シミュレーションや論理合成が通ってもそれが本当に実際のハードウェア上で動く
かどうか 100%証の限りではない.そのため設計した回路が正しく動作するかどうかを,
FPGA(書き換え可能なゲートアレイ)を搭載した評価ボードを用いて確認する.
3.5.1 DE2-115 ボード
まず本実験で使用する DE2-115 ードについて説明する 22 Altera 社の FPGA
Altera Cyclone IV E)を搭載した DE2-115 ボードの写真を示す
FPGA の入力デバイスとして 18 個のスライドスイッチと 4 のプッシュスイッチを使
用できる.ライドスイチは上側にした状態で 1 下側にした状態 0 を入力できる.
プッシュスイッチは,押した状態で 0,押していない状態で 1 入力できる.一方,出力デ
バイスとしては 26 LED (赤色が 18 色が 8 個) 8 桁の 7 セグメント LED
利用できる.LED は,点灯した状態が 1,消灯した状態が 0 が出力されていることを示す
Cyclone IV は,下記のような PS/2 コネクタ(マウス/キーボードを接続)と XSGA
ネクタ(ディスプレイを接続)とも接続されている.
21
22: Altera DE2-115 ボード
PS/2 コネクタ PS/2 ネクタは 6-pin mini-DIN コネクタで,5, 2 pin VCC, GND であ
る.1, 3 pin MOUSE CLK, MOUSE DATA 信号で FLEX10K 接続されている.
MOUSE CLK マウス,キーボードに与えるクロック信号,MOUSE DATA はマ
ス,キーボードから DE2-115 ボードに送られるデータである.
XSGA コネクタ XVGA コネクタは 15-pin D-sub コネクタである.1, 2, 3 pin それぞれ
RED, GREEN, BLUE 信号,13, 14 pin HORIZ SYNC, VERT SYNC4, 5, 9, 15
pin No Connect6, 7, 8, 10, 11 pin GND である.
この他にも, Cyclone IV は,USB コントローラを介し USB Device ポートUSB Host
ポーAudio CODEC を介 Mic In, Line In, Line Out ートTV デコーダを介 Video
In ートイーサットコントローラを介しイーサネットポートとも接続されている.それ
以外に,RS-232 ポートSD カードポートIrDA トランシーバ,LCD64MB SDRAM
2 個,2MB SRAM8MB のフラッシュメモリとも接続されている.
3.5.2 ダウンロード
以下の手順に従って,ストリーム・アウト・ファイルをダウンロードしてみよう
1. ボードの接続 22 に示したように,DE2-115 ボードと Linux マシンを USB ケーブル
で接続する.DE2-115 ボードに電源を供給する専用の AC アダプタを接続し,電源を
入れる(赤色のプッシュボタンを押す)
2. ボード接続の確認 端末でdmesg」と入力し, 23 示すようにLinux ボード接続
を認識できていることを確認する.する.もし,ボード接続がうまく認識されない場
合は,1. の手順を確認した後,指導教員もしくは TA に相談すること.
22
23: dmesg コマンドの実行結果(DE2-115 ボードの接続が認識された)
3. ダウンロード用設定ファイルの取得 FPGA のダウンロードするために,以下のファ
ルが必要となる.ダウンロードして,作業ディレクトリに置く
ダウンロード用設定ファイル(*.cdf
FPGA sof ァイルをダウンロードするための設定が記述されている.ここで
は,以下のファイルをダウンロードし,mux21.sof と同じディレクトリに置く
http://www.ice.nuie.nagoya-u.ac.jp/jikken/hard/j2hard-eda/first/mux21.cdf
4. ストリーム・アウト・ファイルのダウンロード 端末上quartus pgm mux21.cdf
実行しFPGA にダウンロードする.ダウンロードが成功すると,図 24 に示すよ
に,Quartus II 32 bit Programmer was successful.表示される.ラーが
生した場合には,ダウンロード対象の sof ファイルや cdf ファイルが正しく生成され
ているか,評価ボードが正しく接続されているか等を確認する.
24: mux21.sof のダウンロードが成功したときの画面
5. 動作確認 ダウンロードしたストリーム・アウト・ファイルが仕様通りに動作することを
確認する.お,セレクタ回路入出力信号 DE2-115 ードのデバイスの対応関係は,
本章の最初の説明に記述してある.
23
4 EDA ツールを用いた回路設計「中級編」
本実験では,加算を行う回路の設計を例題に,組合せ回路と順序回路の記述EDA ツー
ルを用いた回路の設計方法についての実験を行う
4.1 組合せ回路の設計
組合せ回路の設計についての実験を行う
実験 2 次の 16 ビット加算回路の設計を下記の手順で実施せよ.
設計する 16 ビット加算回路の仕様
入力: 被演算数 x, y(各 16 ビット),桁上げ入力 cin1 ビット)
出力: sum16 ビット),桁上げ出力 cout1 ビット)
機能:x + y を計算し,和と桁上げを出力する組み合わせ回路
回路設計の手順
1. Verilog HDL による回路記述とテストベンチの作成
2.2 節から 2.4 節を読み,Verilog HDL の基本的な構文と意味,always
モデについて解しのち16 ト加路の Verilog
HDL 記述 adder16.v と,テストベンチ test adder16.v を作成する.
2. 機能レベルシミュレーション
3.3 節を参考に,加算回路の機能レベルシミュレーションを行う入力値
をいくつか与えて加算回路が正しく動作することを確認する.
3. 論理合成
3.4 節を参考に,論理合成を実行し,回路構成やロジックエレメント数
遅延時間等を確認する.
25 と図 26 に加算回路とテストベンチの記述例をそれぞれ示す
24
/* *
* adder16.v *
* 16 ビット加算回路 *
* */
module adder16 (x, y, cin, sum, cout);
input [15:0] x, y;
input cin;
output [15:0] sum;
output cout;
assign {cout, sum} = x + y + cin;
endmodule
25: 16 ビット加算回路
/* *
* test_adder16.v *
* 16 ビット加算回路のテストベンチ *
* */
‘timescale 1ns / 1ns // シミュレーションの単位時間 / 精度
// 1 ns = 1/1000000000 sec
‘include "adder16.v" // adder16.v の取り込み
module test;
reg [15:0] x, y;
reg cin;
wire [15:0] sum;
wire cout;
adder16 adder16a(x, y, cin, sum, cout);
always begin
#10 x = x + 100;
end
always begin
#5 y = y + 300;
end
initial begin
x = 0 ; y = 0 ; cin = 0;
end
endmodule
26: 16 ビット加算回路のテストベンチ
25
4.2 順序回路の設計
次は序回路の設計についての実験を行う順序回路は組合せ回路と記憶素子からなり
順序回路 = 組合せ回路 + 憶素子(フリプフロッレジスタある.フリプフロ
プは,クロック入力のエッジ(立ち上がり,立ち下がり)のイベントに同期して動作する
回路全体が一つのクロックシグナルのイベントによって動作する順序回路を単相クロック同
期式順序回路という.ここでは,この単相クロック同期式順序回路を設計する.
実験 3 次の 16 ビット加算回路の設計を下記の手順で実施せよ.
設計する 16 ビット加算回路の仕様
入力: クロック clk1 ビット,リセット reset1 ビット,被演算
x, y(各 16 ビット),桁上げ入力 cin1 ビット)
出力: sum16 ビット),桁上げ出力 cout1 ビット)
能:x + y を計算し,和と桁上げを出力する.ただし,入力値を加
した結果は次のクロクの立ち上がりで出力に反映されるまた,リセ
トが 0 になると出力の各ビットは 0 になる(非同期リセット)
回路設計の手順
1. Verilog HDL による回路記述とテストベンチの作成
2.5 から 2.7 を読み,Verilog HDL よる順序回路の記述,状態機械,
ルと層設につて理したち,序回 16 ト加
路の Verilog HDL 記述 adder16s.v と,テストベンチ test adder16s.v
を作成する.
2. 機能レベルシミュレーション
実験 2 と同様に,加算回路の機能レベルシミュレーションを行う
3. 論理合成
実験 2 同様に,論理合成を実行し,回路構成やロジックエレメント数
遅延時間等を確認する.
27 と図 28 に順序回路版 16 ビット加算回路とテストベンチの記述例をそれぞれ示す
26
/* *
* adder16s.v *
* 順序回路版 16 ビット加算回路 *
* */
module adder16s (clk, reset, x, y, cin, sum, cout);
input [15:0] x, y;
input clk, reset, cin;
output [15:0] sum;
output cout;
reg [15:0] r0, r1;
assign {cout, sum} = r0 + r1 + cin;
always @(posedge clk or negedge reset) begin
if (reset == 1’b0) begin
r0 <= 0 ; r1 <= 0;
end else begin
r0 <= x; r1 <= y;
end
end
endmodule
27: 順序回路版 16 ビット加算回路
/* *
* test_adder16s.v *
* 順序回路版 16 ビット加算回路のテストベンチ *
* */
‘timescale 1ns / 1ns // シミュレーションの単位時間 / 精度
// 1 ns = 1/1000000000 sec
‘include "adder16s.v" // adder16.v の取り込み
module test ;
reg reset,clk, cin;
reg [15:0] x, y;
wire [15:0] sum;
wire cout;
adder16s adder16sa(clk, reset, x, y, cin,sum, cout);
always begin
#5 clk = ~clk;
end
always begin
#8 x = x + 100;
y = y + 200;
end
initial begin
reset = 1; clk = 0; x = 0; y = 0; cin = 0 ;
#20 reset = 0;
#20 reset = 1;
end
endmodule
28: 順序回路版 16 ビット加算回路のテストベンチ
27
5 実験課題
実験課題 1 次の 2 の順序回路を Verilog HDL で記述し,機能レベルシミュレーショ
ンにより動作を確認せよ.また,論理合成を実行して,合成結果を確認せよ.
1. 1 桁の BCD コード4 ビット)を出力する BCD カウンタ0 1 ...
8 9, 9 の次は 0 1 2 ...)の設計を行いなさい.
設計する 1 桁の BCD カウンタの仕様
入力: クロック clk1 ット)リセッ reset1 ビット)カウン
トアップ信号 x1 ビット)
出力: カウンタ値出力 bcd1 out 4 ビット)
機能:リセット 0 になると出力の各ビットは 0 になる(非同期リ
セット.出力値は,clk 0 から 1 変化かつカウントアップ信号
1 なるたびにカウントアップし0000 0001 0010 ...
1001 0000 0001 ... のようになる.
2. 2 桁の BCD ード8 ビット)を出力する BCD カウンタ0 0 0 1 ...
0 8 0 9, 0 9 次は 1 0 1 1 1 2 ...)の設計を,階層設計により
行いなさい.
設計する 2 桁の BCD カウンタの仕様
入力: クロック clk1 ット)リセッ reset1 ビット)カウン
トアップ信号 x1 ビット)
出力: カウンタ値出力 bcd2 out8 ビット)
機能:リセット 0 になると出力の各ビットは 0 になる(非同期リ
力値は,clk 0 1 化かつカウント信号
1 になるたびにカウントアップし,0000 0000 0000 0001 0000
0010 ... 1001 1001 0000 0000 0000 0001 ... のように
なる.
28
実験課題 2 次の順序回路を Verilog HDL で記述し,機能レベルシミュレーションによ
り動作を確認せよ.また,論理合成を実行して,合成結果を確認せよ.
1. 0011 および 0010 いう入力系列が入力される毎に 1 出力する系列検出回
路(有限オートマトン)の設計を,状態機械による順序回路記述により行い
なさい.
設計する系列検出器の仕様
入力: クロック clk1 ット)リセッ reset1 ビット)データ
入力 x1 ビット)
出力: 検出結果出力 y 1 ビット)
機能リセットが 0 なると出力は 0 なる(非同期リセット)
力値は,0011 または 0010 という系列を検出したときのみ 1 になる.
動作例: 入力として 100111・がシリアルに入ってきたとき
 入力 1 に対して 0 を出力
 入力 0 に対して 0 を出力
 入力 0 に対して 0 を出力
 入力 1 に対して 0 を出力
 入力 1 に対して 1 を出力( 0011 を検出)
 入力 1 に対して 0 を出力
 ・
 ・
 ・
29
6 実験と実験課題のレポートについて
1. 実験 1実験 2実験 3,実験課題 1実験課題 2 ついて,実験の概要,使用機器な
らびにソフトウェア,以下の各段階の説明,実験の考察を,文章ならびに図,表を交
えてまとめよ.
回路の Verilog HDL 記述(回路の動作説明を含めて説明)
機能レベルシミュレーション(テストベンチとシミュレーション結果の説明)
論理合成(論理合成ツールによる最適化後の回路の構成,遅延時間,ロジックエ
レメント数等の説明)
FPGA ボードでの動作実験(実験 1 のみ)
2. 実験 2 と実験 3 では,16 ビット加算回路を組合せ回路で実現する方法と順序回路で
実現する方法を試した.論理合成の結果を比較し,考察せよ.
3. 今回の実験では論理合成ツールQuartus IIって,Verilog HDL で記述した論
理回路を最適化している.論理合成における,論理回路の最適化について調査し,特
に,具体的にどのような最適化手法があるのか,さらに,最適化された論理回路の遅
延時間と面積の関係について説明せよ.
7 その他
7.1 FPGA のピン配置の変更
実験で使用す FPGA ピン配置フイルは,ぼ全てあらかじめ用意されているが,
下のようにしてピン配置を変更することもできる.
入出力の設定例として,実験で使用した「mux21.qsf」を例に説明する.このファイルを
編集して直接入出力の指定を書き込むことができる.ファイルに以下のように書き込む.
set_location_assignment PIN_AB28 -to S1
set_location_assignment PIN_M23 -to D0
set_location_assignment PIN_M21 -to D1
set_location_assignment PIN_H15 -to Y
これでプッシュスイッチ key0, key1 それぞれ入力 D0, D1 ,トグルスイッ 0 が入力 S1
になる.Y 最も左の LED 出力される.ピン番号とボード上の各入出力デバイスとの対
応は DE2-115 ボードのマニュアルに詳しく書かれている.
7.2 Altera DE2-115 ボードのクロックの使い方
DE2-115 ードには発振器がついておりクロックを入力として使うことができる.
としてクックを使いたいときは.qsf set location assignment PIN Y2 -to clk
設定する.ただし,周波数が 50MHz のため,早すぎて視覚できないので,適当に分周して
使わなければならない.以下に,分周回路の Verilog HDL 記述の例を示す
30
module divider (clk, sysreset, clkin);
input clk, sysreset;
output clkin;
reg [23:0] cnt;
always @(posedge clk or negedge sysreset) begin
if(sysreset == 1’b0) cnt <= 0;
else cnt <= cnt + 1;
end
assign clkin = ~cnt[22];
endmodule
最後の assign のレジスタcntの何ビット目を使うかを変更することで周波数を 2
n
ずつ
変えることができる.
7.3 種々の回路の Verilog HDL 記述
Verilog HDL を使って実験課題の回路を記述するにあた,課題と直接は関係しないが
記述スタイルの参考になると思われる回路の記述例をいくつか示す
32 ビット入力 8 ビット出力の 2 ビット左シフトモジュール
/********************/
/* shifter32_8_l2.v */
/********************/
// +----+
// sh_a[31:0]->| |->sh_y[7:0]
// +----+
module shifter32_8_l2 (sh_a, sh_y); // 入出力ポート
input [31:0] sh_a; // 入力 32-bit
output [7:0] sh_y; // 出力 8-bit
//Body
//2-bit 左シフト
assign sh_y = {sh_a[5:0], 2’b00};
endmodule
32 ビットの 2 入力 1 出力セレクタモジュール
/**************/
/* mux32_32_32.v */
/**************/
// +----+
// d0[31:0]->| |
// d1[31:0]->| |->y[31:0]
// s->| |
// +----+
31
module mux32_32_32 (d0, d1, s, y); // 入出力ポート
input [31:0] d0; // 入力 32-bit d0
input [31:0] d1; // 入力 32-bit d1
input s; // 入力 1-bit s
output [31:0] y; // 出力 32-bit y
// Multiplexer body
// if (s == 0) y = d0; else y = d1;
// 出力ポートに対する代入は assign 文で行う
assign y = (s == 1’b0) ? d0 : d1;
endmodule
CPU 16 ビット入力 32 ビット出力の符号拡張モジュール
/******************/
/* signext16_32.v */
/******************/
// +----+
// a16[15:0]->| |->y32[31:0]
// +----+
module signext16_32 (a16, y32); // 入出力ポート
input [15:0] a16; // 入力 16-bit
output [31:0] y32; // 出力 32-bit
//Body
//符号拡張
assign y32 = {a16[15], a16[15], a16[15], a16[15],
a16[15], a16[15], a16[15], a16[15],
a16[15], a16[15], a16[15], a16[15],
a16[15], a16[15], a16[15], a16[15],
a16[15:0]};
endmodule
CPU 32 ビット ALU モジュール
/*********/
/* alu.v */
/*********/
// +----+
// alu_a[31:0]->| |
// alu_b[31:0]->| |->alu_y[31:0]
// alu_ctrl[2:0]->| |->alu_iszero
// +----+
// 命令セット
// lw(load word)
// sw(store word)
32
// add
// sub
// and
// or
// slt(set on less than)
// beq(blanch on equal)
// alu_ctrl[2:0], 実行する演算
// 010, add
// 110, sub
// 000, and
// 001, or
// 111, slt
‘define ADD 3’b010
‘define SUB 3’b110
‘define AND 3’b000
‘define OR 3’b001
‘define SLT 3’b111
module alu (alu_a, alu_b, alu_ctrl, alu_y, alu_iszero); // 入出力ポート
input [31:0] alu_a; // 入力 32-bit a
input [31:0] alu_b; // 入力 32-bit b
input [2:0] alu_ctrl; // 入力 3-bit ALU 制御コード
output [31:0] alu_y; // 出力 32-bit y
output alu_iszero; // 出力 1-bit iszero (y==0 ? 1:0)
reg [31:0] result;
reg iszero;
always @(alu_a or alu_b or alu_ctrl) begin
case (alu_ctrl)
‘ADD: begin
result = alu_a + alu_b;
end
‘SUB: begin
result = alu_a - alu_b;
end
‘AND: begin
result = alu_a & alu_b;
end
‘OR: begin
result = alu_a | alu_b;
end
‘SLT: begin
result = (alu_a < alu_b) ? 32’h00000001 : 32’h00000000;
end
default: begin
result = 0;
end
endcase
end
33
always @(alu_a or alu_b or alu_ctrl or result) begin
if (result == 0) begin
iszero = 1;
end else begin
iszero = 0;
end
end
assign alu_y = result;
assign alu_iszero = iszero;
endmodule
CPU PC 4 加算モジュール
/***********/
/* plus4.v */
/***********/
// +----+
// inc_a[7:0]->| |->inc_y[7:0]
// +----+
module plus4 (inc_a, inc_y); // 入出力ポート
input [7:0] inc_a; // 入力 8-bit
output [7:0] inc_y; // 出力 8-bit
assign inc_y = inc_a + 4;
endmodule
CPU PC モジュール
/********/
/* pc.v */
/********/
// +----+
// clock->| |
// reset->| |
// pc_next[7:0]->| |->pc[7:0]
// +----+
module pc (clock, reset, pc_next, pc); // 入出力ポート
input clock, reset; // 入力 クロック, リセット
input [7:0] pc_next; // 入力 8-bit 次に PC にセットする値
output [7:0] pc; // 出力 8-bit PC
reg [7:0] pc_reg; // PC 用レジスタ
// Always ブロック: プログラムカウンタ
34
// 入力: clock, reset, pc_next
// 出力: pc_reg
// レジスタ: pc_reg
always @(posedge clock or negedge reset) begin
if (reset == 1’b0) begin
pc_reg <= 8’b00000000;
end else begin
pc_reg <= pc_next;
end
end
assign pc = pc_reg;
endmodule
CPU 32 ビット × 16 ワードレジスタファイルモジュール
/***************/
/* registers.v */
/***************/
// +----+
// clock->| |
// reset->| |
// reg_read_idx1[3:0]->| |
// reg_read_idx2[3:0]->| |->reg_read_data1[31:0]
// reg_write_idx[3:0]->| |->reg_read_data2[31:0]
// reg_write_enable->| |
// reg_write_data[31:0]->| |
// +----+
module registers (clock, reset,
reg_read_idx1, reg_read_idx2,
reg_write_idx, reg_write_enable, reg_write_data,
reg_read_data1, reg_read_data2);
input clock, reset; // 入力 クロック, リセット
input [3:0] reg_read_idx1; // 読みアドレス 1
input [3:0] reg_read_idx2; // 読みアドレス 2
input [3:0] reg_write_idx; // 書き込みアドレス
input reg_write_enable; // 書き込み (1)/読み (0)
input [31:0] reg_write_data; // 書き込みデータ
output [31:0] reg_read_data1; // 読みデータ 1
output [31:0] reg_read_data2; // 読みデータ 2
// Registers (regs_0 = 0)
reg [31:0] regs_1; reg [31:0] regs_2;
reg [31:0] regs_3; reg [31:0] regs_4;
reg [31:0] regs_5; reg [31:0] regs_6;
reg [31:0] regs_7; reg [31:0] regs_8;
reg [31:0] regs_9; reg [31:0] regs_10;
reg [31:0] regs_11; reg [31:0] regs_12;
reg [31:0] regs_13; reg [31:0] regs_14;
35
reg [31:0] regs_15;
//
// 読み 1regs[0] は常に 0
// assign reg_read_data1 = regs[115];
//
assign reg_read_data1 = (reg_read_idx1 == 4’b0000) ? 0 : (
(reg_read_idx1 == 4’b0001) ? regs_1 : (
(reg_read_idx1 == 4’b0010) ? regs_2 : (
(reg_read_idx1 == 4’b0011) ? regs_3 : (
(reg_read_idx1 == 4’b0100) ? regs_4 : (
(reg_read_idx1 == 4’b0101) ? regs_5 : (
(reg_read_idx1 == 4’b0110) ? regs_6 : (
(reg_read_idx1 == 4’b0111) ? regs_7 : (
(reg_read_idx1 == 4’b1000) ? regs_8 : (
(reg_read_idx1 == 4’b1001) ? regs_9 : (
(reg_read_idx1 == 4’b1010) ? regs_10 : (
(reg_read_idx1 == 4’b1011) ? regs_11 : (
(reg_read_idx1 == 4’b1100) ? regs_12 : (
(reg_read_idx1 == 4’b1101) ? regs_13 : (
(reg_read_idx1 == 4’b1110) ? regs_14 : (regs_15)))))))))))))));
//
// 読み 2regs[0] は常に 0
// assign reg_read_data2 = regs[115];
//
assign reg_read_data2 = (reg_read_idx2 == 5’b00000) ? 0 : (
(reg_read_idx2 == 5’b00001) ? regs_1 : (
(reg_read_idx2 == 5’b00010) ? regs_2 : (
(reg_read_idx2 == 5’b00011) ? regs_3 : (
(reg_read_idx2 == 5’b00100) ? regs_4 : (
(reg_read_idx2 == 5’b00101) ? regs_5 : (
(reg_read_idx2 == 5’b00110) ? regs_6 : (
(reg_read_idx2 == 5’b00111) ? regs_7 : (
(reg_read_idx2 == 5’b01000) ? regs_8 : (
(reg_read_idx2 == 5’b01001) ? regs_9 : (
(reg_read_idx2 == 5’b01010) ? regs_10 : (
(reg_read_idx2 == 5’b01011) ? regs_11 : (
(reg_read_idx2 == 5’b01100) ? regs_12 : (
(reg_read_idx2 == 5’b01101) ? regs_13 : (
(reg_read_idx2 == 5’b01110) ? regs_14 : (regs_15)))))))))))))));
// Always ブロック: 書き込み
// 入力: clock, reset, reg_write_idx, reg_write_enable, reg_write_data
// 出力: regs_1regs_15
// レジスタ: regs_1regs_15
always @(posedge clock or negedge reset) begin
if (reset == 1’b0) begin
regs_1 <= 0; regs_2 <= 0; regs_3 <= 0; regs_4 <= 0;
regs_5 <= 0; regs_6 <= 0; regs_7 <= 0; regs_8 <= 0;
regs_9 <= 0; regs_10 <= 0; regs_11 <= 0; regs_12 <= 0;
regs_13 <= 0; regs_14 <= 0; regs_15 <= 0;
end else begin
if (reg_write_enable == 1’b1) begin
36
//
// 書き込み(regs[0] は常に 0
// regs[115] = reg_write_data;
//
if (reg_write_idx == 4’b0001) begin
regs_1 <= reg_write_data;
end if (reg_write_idx == 4’b0010) begin
regs_2 <= reg_write_data;
end if (reg_write_idx == 4’b0011) begin
regs_3 <= reg_write_data;
end if (reg_write_idx == 4’b0100) begin
regs_4 <= reg_write_data;
end if (reg_write_idx == 4’b0101) begin
regs_5 <= reg_write_data;
end if (reg_write_idx == 4’b0110) begin
regs_6 <= reg_write_data;
end if (reg_write_idx == 4’b0111) begin
regs_7 <= reg_write_data;
end if (reg_write_idx == 4’b1000) begin
regs_8 <= reg_write_data;
end if (reg_write_idx == 4’b1001) begin
regs_9 <= reg_write_data;
end if (reg_write_idx == 4’b1010) begin
regs_10 <= reg_write_data;
end if (reg_write_idx == 4’b1011) begin
regs_11 <= reg_write_data;
end if (reg_write_idx == 4’b1100) begin
regs_12 <= reg_write_data;
end if (reg_write_idx == 4’b1101) begin
regs_13 <= reg_write_data;
end if (reg_write_idx == 4’b1110) begin
regs_14 <= reg_write_data;
end if (reg_write_idx == 4’b1111) begin
regs_15 <= reg_write_data;
end
end
end // End: if (reg_write_enable == 1’b1) begin
end // End: always @(posedge clock or negedge reset) begin
endmodule
参考文献
[1] http://www.altera.co.jp/products/software/quartus-ii/modelsim/qts-model
sim-index.html Mentor Graphics ModelSim - Altera ソフトウェア.
[2] http://www.altera.co.jp/products/software/quartus-ii/web-edition/qts-we-
index.html Quartus II ソフトウェア ウェブ・エディション.
[3] VDEC 監修, 浅田邦博. ディジタル集積回路の設計と試作. 培風館, 2000.
[4] 深山正幸, 北川章夫, 秋田純一, 鈴木. HDL による VLSI 設計 Verilog-HDL
VHDL による CPU 設計 –. 共立出版株式会社, 1999.
[5] 白石肇. わかりやすいシステム LSI 入門. オーム社, 1999.
37
[6] 桜井至. HDL によるデジタル設計の基礎. テクノプレス, 1997.
[7] James O. Hamblen and Michael D. Furman. Rapid Prototyping of Digital Systems.
Kluwer Academic Publishers, 2000.
[8] パターソン&ヘネシー , 成田光彰 . ンピュータの構成と設計(上巻). 日経 BP
, 1999.
38