論理回路設計
- 実習:VHDLによるデジタル回路設計 -
東京理科大学
基礎工学部電子応用工学科
(非常勤講師)
藤岡 督也
【2017年度前期 集中講義】
講座の目的
実習を通して、専門分野の問題発見・解決の能力を修得する
- LSI設計の基礎知識を得る - 言語:VHDLによる設計手法を実習する - EDAツールの操作を経験する - FPGAを搭載した評価ボードで動作を確認する目 次
1.実習環境の説明
2. 課題1: 『4ビット加算器』
-
【参考資料】
EDAツールの付加情報
- VHDLの概要
3. 課題2: 『自分の名前を表示しよう』
4. 課題3: 『1分時計』
5. 課題4: 『追加仕様版加算器』
集中講義の日程
1日目
2日目
3日目
4日目
6月17日(土)
2~5時限
6月24日(土)
2~5時限
7月01日(土)
2~5時限
7月08日(土)
2~4時限
【課題1】 加算器
- Quartus Ⅱの操作と
作業手順の習得
・ 回路図/VHDL
による設計
・ ピンアサイン
・ 実機での動作確認
【課題1】 加算器
- ModelSimの操作と
作業手順の習得
・シミュレーション
に設計機能の確認
・テストベンチの
作成&実行方法
【課題2】 自分の名前の
表示させよう
【課題3】 1分時計
【課題4】 追加仕様版加算器
(追加仕様) ・10進表示への変更 ・ビット拡張 ・乗算機能の追加- 設計の実践&動作確認
- 言語設計の理解
(実習で使用する環境)[EDAツール]
Quartus Ⅱ(Altera社)、 ModelSim (Mentor社: VHDLシミュレータ)
実習の内容
各課題を設計して、シミュレーションで機能確認後、
実機を使って動作を確認する。
1.課題を理解し、設計仕様にまとめる
→ 入力、出力、機能、性能を決める
→ 設計手法を選択する:
回路図入力/言語設計/両者の混在等
→ 検証内容(シミュレーション内容等)を決める
2.選択した設計手法で回路設計を行う
→ QuartusⅡ: 回路図入力/VHDL設計/両者の混在
→ ModelSim : VHDL設計
3.シミュレーションで機能確認を行う
→ VHDLシミュレータ:ModelSimを使う
→ 波形入力 or テストベンチを使って実行する
4.評価ボード:DE0を使って、実機確認を行う
実習の設計フロー
デザインエントリ
ダウンロード
コンパイル
端子割り当て
コンパイル
FPGAの接続データ
(実行モジュール)を作成する
実行モジュールをPCから
FPGAに書き込む
- ModelSim
- QuartusⅡ
- DE0
デザインエントリ
コンパイル
- QuartusⅡ
シミュレーション
仕様に基づき、
回路を設計する
仕様に基づき、
回路を設計する
回路の動作を確認する
記述をチェックして、論理合成する
設計エントリー: QuartusⅡ
【EDAツール】
- 回路図入力、VHDL入力、論理合成(Cyclone用)
VHDLシミュレータ: ModelSim
【EDAツール】
- VHDL入力 → 機能/論理シミュレーション
評価ボード:DE0の外観
7seg LED
スライド・スイッチ
ボタン・スイッチ
FPGA
(Altera)
電源スイッチ
USB端子
1.搭載FPGA:
(Family)
Cyclone Ⅲ
(name)
EP3C16F484C6
[Package]
FBGA
(Fine pitch Ball Grid Array)
[Pin count]
484
[speed grade]
6
2.入力機能
1) ボタンスイッチ: 3個 (Button0~2)
・a接点スイッチ [← b接点スイッチとの違いを理解]
2) スライドスイッチ:10個 (SW0~SW9)
・上方にスライド(logic”1”)、下方にスライド(logic”0”)
3.出力機能
- 7seg LED: 4個 (HEX0~3)
・アノードコモン型 [← カソードコモン型との違いを理解]
(- 液晶パネルを搭載することも可能)
4.実行モジュールのダウンロード
- USBケーブルを接続して、Quartus Ⅱから実行する
評価ボード:DE0の概要
[詳細は、授業HP上のマニュアル(英文)参照]評価ボード:DE0のブロック図
USB端子
FPGA
7seg LED
ボタンスイッチ
スライドスイッチ
DE0のボタンスイッチの動作
a接点: スイッチを押すと接点が繋がり電流が流れる
a接点スイッチ
push push通常の入力信号: BS
反転入力信号: not BS
A RST BDE0のスライドスイッチの動作
Logic “1”
Logic “0”
D2 E4 E3 H7 J7 G5 G4 H6 H5 J6
SW9 SW8 SW7 SW6 SW5 SW4 SW3 SW2 SW1 SW0
(PIN番号) (SW番号) 上方にスライド 下方にスライド通常の入力信号: SS
反転入力信号: not SS
=a b c e d f g dp
DE0の7seg LEDの動作
a b c d e f g dpHEX0
E11
F11
H12
H13
G12
F12
F13
D13
(PIN番号) (ピン名)端子割り当て表
LED0[7]
LED0[6]
LED0[5]
LED0[4]
LED0[3]
LED0[2]
LED0[1]
LED0[0]
⇐
ピンとPADの整合
- アノードコモン型 -
7seg LEDの動作タイプ
[参考]端子割り当て
FPGAチップ
- FPGAチップはパッケージングされている ⇒ PADはPINに接続されている
- パッケージはボード上に実装されている ⇒ ボード上部品と接続されている
(PAD=)PINから先の接続は変更できない
FPGAパッケージ
FPGA
FPGA搭載ボード
- 入力信号は、決まったPINから入力する
- 出力信号は、決まったPINへ出力する
設計回路
[テキスト図1-55参照]設計端子名 入出力 FPGAピン番号 備考
A Input PIN_H2 BUTTON0
B Input PIN_F1 BUTTON2
clk Input PIN_G21 クロック入力
EQUAL Input PIN_J6 SW0
reset Input PIN_G3 BUTTON1
LED0[7] Output PIN_E11 HEX0_a
LED0[6] Output PIN_F11 HEX0_b
LED0[5] Output PIN_H12 HEX0_c
LED0[4] Output PIN_H13 HEX0_d
LED0[3] Output PIN_G12 HEX0_e
LED0[2] Output PIN_F12 HEX0_f
LED0[1] Output PIN_F13 HEX0_g
LED0[0] Output PIN_D13 HEX0_dp
LED1[7] Output PIN_A13 HEX1_a
ピン割り当て表
2.課題1: 『4ビット加算器』
- 第1日目 & 第2日目 -
キー入力 検出回路 キー入力 保持回路 キー入力 検出回路 キー入力 保持回路 加算器 キー入力 検出回路 キー入力 保持回路 信号選 択 & LED 表示制 御 LED3 被加数 加数 -= -クリア LED2 LED1 5 4 4 8 8 8 LED0 8
『4ビット加算器』の設計回路
[課題]
と全体回路
全体回路
→ FPGAへダウンロード- 全体回路は、設計回路と周辺回路から構成される
- 周辺回路は、回路図シンボルとperipheral_DE0.vhdで準備されている
- 設計回路と周辺回路を使って、全体回路を設計する
設計回路
周辺回路
評価ボード:DE0を使って、4ビット加算器を設計する。
1.入力データ: ボタンスイッチを使って、押下回数を入力数とする。
Button0 : 加数の入力。 HEX0へ16進表示。 0~Fをトグルする。
Button2 : 被加数の入力。 HEX3へ16進表示。 0~Fをトグルする。
Button1 : リセッの入力。 button0とbutton2を同時にリセットする。
2.出力データ: 加算結果を7segLEDに表示する。
加算結果は、hex表とする( 00~1E; 4ビット加算 → 加算結果は5ビット)
HEX0 : 加算結果の下位桁を16進表示する。
HEX1 : 加算結果の上位桁を16進表示する。
HEX2 : ”=”を表示する。
HEX3 : ”=”を表示する。
3.モード切替: スライドスイッチを使って、入力/出力表示を切り替える。
SW0 : 0(入力モード): 被加数と加数を表示する。
1(出力モード): 加算結果を表示する。
『4ビット加算器』の開発仕様
実習の進め方
【第1日目】 課題1を回路図とVHDLで設計して、
実機(DE0)で評価する
- QuartusⅡ上で、課題を回路図で入力して設計する (テキスト: 5 ~ 41頁)
- 端子割り当て後、実行モジュール(*.sof)を作成し、
実機にダウンロードして、動作を確認する (テキスト: 42 ~ 49頁)
- 回路図で設計した同じ回路をQuartus Ⅱ上で、
VHDLを使って再設計して、実機で動作を確認する (テキスト: 50 ~ 72頁)
【第2日目】 課題1のVHDLをシミュレーションを
実行して、機能を確認する
(テキスト: 73 ~110頁)
- 入力パターンを「Apply Wave」で設定して、
シミュレーションを実行して、機能を確認する (テキスト: 82 ~100頁)
- テストベンチを記述して、シミュレーションを実行して、
機能を確認する (テキスト:101 ~110頁)
『4ビット加算器』の設計内容
4ビット加算器
(トップモジュール)
加算演算部
(加算モジュール)
(実機用周辺回路)
peripheral_DE0
(Sim用周辺回路)
peripheral_sim
コンパイル
動作確認
実行 モジュールダウンロード
[QuartusⅡ]
テストベンチを記述
してシミュレーション
を実行
波形エディタから
入力パターンの設定
[1日目]
[2日目]
+
回路図&
VHDL記述
(VHDL記述)
シミュレーションによる
機能検証
実機による検証
- 設計で用いる設計記述の組み合わせ -
回路図&
VHDL記述
[ModelSim]
コンパイル
シミュレーションによる検証
【参考資料】
QuartusⅡのプロジェクトへのファイルの追加
プロジェクトをオープンした状態で
“File → New” を選択すると”New“画面がポップアップされるので、
“VHDL File”を選択する
“VHDL File”選択後、編集画面が表示
されるので、持ち込みたい VHDL記述を
pasteして、“Save As”で保存する
QuartusⅡのプロジェクト・ディレクトリ
“file → open”後のポップアップ画面
プロジェクト[ adder_4bit ]をオープンした時のディレクトリ下のファイル一覧
・ファイル名と更新日時が正しいかを常にチェックする
・ファイル名(拡張子以外の部分)は、異なる名前にする
→ 古い版を保存したい場合は、”*_old1.vhd”のようにする
・複雑になった場合は、新しいプロジェクトを作って、別に管理する
QuartusⅡのプロジェクトメンバー
現在のプロジェクトメンバーの一覧
・リストされているファイルを正しく管理する
→ 同名のモジュール名は避ける
QuartusⅡのプロジェクトメンバーの変更
1.オープンしているファイルをメンバーに追加する:
“Project → Add current file to Project”
2.プロジェクトディレクトリ下のファイルを使って変更する
“Project → Add/Remove files to Project”
ModelSimのプロジェクトへのファイルの持ち込み
“File → Source → VHDL” の操作で編集ウィンドウ
が開くので、vhdl記述をpasteし、“Save As”で保存する。
ModelSimのプロジェクト・ディレクトリ
プロジェクト・ディレクトリ下のファイル一覧
(プロジェクトメンバーの候補)
ModelSimのプロジェクト・メンバー
プロジェクト・メンバーの一覧
- トップモジュール以下の全モジュールがリストされている
(リストされるように管理する)
Project画面内で右クリック
- “Add to Project” を使って、変更する
VHDLの歴史
- VHDL: VHSIC Hardware Description Language の略称
- 1981年 米国国防総省(国防高等研究計画局:DARPA
(Defense
Advanced Research Projects Agency)
のVHSIC委員会が提唱
・VHSIC: Very High Speed Integrated circuit
・ICの大規模/高機能化に伴った、明確に仕様を記述する
仕様記述言語
- 1986年 Version 7.2 リリース
IEEEの標準化作業スタート
・VASG
(VHDL Analysis & Standardization Group)
委員会
- 1987年 LRM(言語仕様書; Language Reference Manual ) 作成
IEEE Std 1076-1987として承認
- 1993年 IEEE 1164を採用: 9値のstd_logic
- その後 IEEE 1076-1993、 IEEE 1076-2000、 IEEE 1076-2002、
IEEE 1076-2008
(最新版)
ハードウェア記述言語: HDL
- Hardware Description Language; HDL
- デジタル回路、特に集積回路を設計するためのコンピュータ言語
- ハードウェアの動作仕様を記述するための言語で、電子回路の
経時的動作と空間的構造を表現し、構文
(syntax)
や意味
(semantics)
は、
ハードウェアの基本的属性である時間や並行性を記述。
- 処理を検証するテストベンチ記述ができ、シミュレーションが可能。
- 論理合成が可能
- Verilog HDL と VHDL が、主要な言語 (IEEEで標準化を推進)
RTL
(Register Transfer Level)とは?
・ レジスタ間の転送関係を
表現したレベル
・ 機能を、代入、if、case等で
表現したもの
・ クロックを意識した記述
ゲートレベル とは?
・ ゲート回路やフリップフロップ等の
接続関係を表現したもの
( → 素子と等電位点の列挙 )
・ ネットリストとも言う
論理
合成
VHDLの基本構造①
回路記述: ・論理合成に適した記述をする
・回路の種類ごとに適した記述スタイルがある
テストベンチ: ・文法を満たしていれば、どんな記述でもよい
・記述のテクニックを駆使できる
VHDLの文法
回路記述
テストベンチ
ライブラリ記述
論理合成可能
論理合成不可
シミュレーション可能
architecture
architecture
architecture
process C
process B
一つの entityに
複数の architectureを
書ける
library …複数のライブラリ
use
entity ….1つ
port
一つの entityに複数の architectureを書ける
一つの architectureに複数のprocessを書ける
VHDLの基本構造②
process A
一つの architectureに
複数のprocessを書ける
VHDLの基本構造③
合成用の記述に使用するもの
シミュレーション・テストベクタ記述に
Library …
Entity …
port …
Architecture ……
この部分の信号割当ては、process文の外なのでSLSも イベントもない。
コンカレント(非同期, 即時代入, 即時信号割り当て)実行される。
- <= 非同期で即時,コンカレント信号代入,
- 条件文 when-else, with-select(others文で全条件記述)
- 反復文 generate
Process
…
()がない場合は,process文内の処理を永遠に継続制御反復文
loop
for loop
while loop
wait for
wait on
wait until
Process
(センシティビティー・リスト信号;:
SLS
)
- <=
SLS
のイベントに
同期
し
同時に
信号代入
- :=
SLS
のイベントに
同期
し
シーケンシャルに
信号代入
(:=の左辺は,variable文で定義した変数)
- 条件文
VHDLの基本構造④
- 階層化記述 -
Library …
Entity …
Architecture …
動作記述
構造記述
Configuration …
Library …
Entity …
port …
Architecture …
動作記述
構造記述
Library …
Entity …
port …
Architecture …
動作記述
構造記述
テストベンチ
設計回路のトップ階層
設計回路の下位階層
38
全体構造と記述例
「パッケージ」の指定
entity エンティティ名 is
end エンティティ名;
architecture アーキテクチャ名 is
bigin
end アーキテクチャ名;
入出力ポート宣言
signal 他の宣言
VHDL本体
- 動作、機能の記述
-- 半加算器の記述例
library IEEE;
use IEEE.std_logic_1164.all;
entity half_adder is
port(A,B: in std_logic;
S,CO: out std_logic);
end half_adder;
architecture RTL of half_adder is
signal sig1, sig2: std_logic;
begin
sig1 <= A nand B;
sig2 <= A or B;
CO <= not sig1;
S <= sig1 and sig2;
end RTL;
of エンティティ名
VHDL記述&コンパイル時の注意点
1.規約どおりに記述する
- 構文規則を覚えて、キーワードとパラメータを正確に記述する
・代入文の右辺と左辺でデータイプは同じでなければならない
signal s1: std_logic_vector(2 downto 0);
signal n1: integer range 0 to;
×
s1 <= 0
⇒ ○ s1 <= “000”
《 Error (10517): VHDL type mismatch error at half_adder_bh.vhd(23): 》 《 std_logic type does not match integer literal 》
×
n1 <= s1
⇒ ○ n1 <= CONV_INTEGER(s1);
・サブプログラムの戻り値も同じデータタイプでなければならない
・std_logicの論理値は、9値である
→ 0、1、X、L、H、W、Z、U(uninitialize)、-(don’t care)
- “)”や”;”の数を間違えない
・()は必ず対になっている
・”;”は、必要な場所と必要ない場所を正確に把握する
- 未定義の変数は使えない(必ず事前定義)
2.コンパル時のエラーは、しっかり読む
- 必ずしも、的確な記述間違いをメッセージしてくれる訳ではない
半加算器の回路図とVHDL記述
VHDL記述(図2-7参照) [図2-9] 回路図入力(図1-24参照) O -- 半加算器の記述例 library IEEE; use IEEE.std_logic_1164.all; entity half_adder is port(A,B: in std_logic; S,CO: out std_logic); end half_adder;architecture RTL of half_adder is signal sig1, sig2: std_logic; begin
sig1 <= A nand B; sig2 <= A or B; CO <= not sig1;
S <= sig1 and sig2; end RTL; 機能のゲート記述 A B S CO 0 0 0 0 1 0 1 0 0 1 1 0 1 1 1 1 architecture RTL of half_adder_bh is
signal AB : std_logic_vector (1 downto 0); begin
AB <= A & B; process(A,B) begin
if(AB=“00”) then S<='0'; CO<='0'; elsif(AB="01") then S<='1'; CO<='0'; elsif(AB="10") then S<='1'; CO<='0'; 機能の動作記述
階層化記述例
A
C
B
X
Z
Y
L
library IEEE;
use IEEE.std_logic_1164.all;
entity X is
port (A, B : in std_logic;
C : out std_logic);
end X;
architecture RTL of X is
component Y
port( A : in std_logic;
D : out std_logic);
end component;
component Z
port( B, D : in std_logic;
C : out std_logic);
end component;
signal L : std_logic;
begin
U0 : Y port map ( A => A, D => L );
U1 : Z port map ( D => L, B => B, C=> C );
end RTL;
コンポネント インスタンス コンポーネント 宣言(定義) コンポーネント 宣言(定義)[図2-14]
library IEEE;
use IEEE.std_logic_1164.all; entity full_adder is
port(A,B,CIN : in std_logic; S,CO: out std_logic); end full_adder;
architecture RTL of full_adder is component half_adder
port(A,B : in std_logic; S,CO: out std_logic); end component;
signal sig1, sig2, sig3 : std_logic; begin
H1: half_adder port map (A,B,sig2,sig1);
H2: half_adder port map (sig2, CIN, S, sig3); CO <= sig1 or sig3;
全加算器の回路図とVHDL記述
ライブラリ記述
エンティティ記述
アーキテクチャ
コンポーネント宣言
コンポーネント呼び出し
(コンポーネント・インスタンス)
[図2-15]library IEEE;
use IEEE.std_logic_1164.all;
entity M_BEHAVIOR is
port (SELS : in bit_vector(0 to 1);
A,B,C,D : in bit;
M : out bit);
end;
architecture DSELS of M_BEHAVIOR is
begin
process(SELS,A,B,C,D)
begin
case SELS is
when ”00” => M <= A;
when ”01” => M <= B;
when ”10” => M <= C;
when others => M <= D;
end case;
end process;
end DSELS;
case 文
M
SELS
D
A
B
C
if then else/elsif 文
library IEEE;
use IEEE.std_logic_1164.all;
entity S_BEHAVIOR is
port(SELS: in bit_vector(0 to 1);
A,B,C,D: in bit;
M: out bit);
end;
architecture DSELS of S_BEHAVIOR is
begin
process(SELS,A,B,C,D)
begin
if (SELS = "00") then M <= A;
elsif (SELS = "01") then M <= B;
elsif (SELS = "10") then M <= C;
else M <= D;
end if;
end process;
end DSELS;
library IEEE;
use IEEE.std_logic_1164.all;
entity N_BEHAVIOR is
port(SELS: in bit_vector(0 to 1);
A,B,C,D: in bit;
M: out bit);
end;
architecture DSELS of N_BEHAVIOR is
begin
process(SELS,A,B,C,D) begin
if (SELS = “00”) then M <= A;
if (SELS = "01") then M <= B;
if (SELS = "10") then M <= C;
else M <= D;
end if;
end if;
end if;
end process;
M
D
A
B
C
when else 文
entity J_BEHAVIOR is
port (A,B,SEL : in boolean;
M : out boolean);
end;
architecture DSEL of J_BEHAVIOR is
begin
M <=
A when SEL else B;
end DSEL;
M
A
B
SEL
entity K_BEHAVIOR is
port (SELS : in bit_vector(0 to 1);
A,B,C,D : in bit; M : out bit);
end;
architecture DSELS of K_BEHAVIOR is begin
M <= A when (SELS="00") else
B when (SELS="01") else
C when (SELS="10") else D ;
end DSELS;
M
SELS
A
B
C
D
library IEEE;
use IEEE.std_logic_1164.all;
entity M_BEHAVIOR is
port (SELS : in
bit_vector(0 to 1)
;
A,B,C,D : in bit; M : out bit);
end;
architecture DSELS of M_BEHAVIOR
begin
with SELS select
M <=
A when ”00”,
B when ”01”,
C when ”10”,
D when ”11”;
end DSELS;
with select 文
library IEEE;
use IEEE.std_logic_1164.all;
entity M_BEHAVIOR is
port (SELS : in
std_logic_vector(0 to 1)
;
A,B,C,D : in bit; M : out bit);
end;
architecture DSELS of M_BEHAVIOR
begin
with SELS select
M <=
A when ”00”,
B when ”01”,
C when ”10”,
D when ”
11
”;
end DSELS;
この記述を、
D when
others;
M
SELS
D
A
B
C
この宣言のとき、 SELSは、9x9=81値となり,, 左の記述ではエラーテストベンチの構造
「パッケージ」の指定
entity エンティティ名 is
end エンティティ名;
architecture アーキテクチャ名 is
bigin
end アーキテクチャ名;
-
DUTの宣言
-
入出力の宣言
-
DUTの呼び出し
-
波形記述
configuration
コンフィグレーション名
is
for アーキテクチャ名
end for;
end コンフィグレーション名;
ライブラリ記述
ポートリストの無いエンティティ記述
アーキテクチャ名 of エンティティ名
テストモジュール(DUT
)のコンポーネント宣言
DUTの入出力信号宣言
整数の定義(クロック周期等)
DUTの呼び出し宣言(インスタンス)
入力信号の入力波形記述
(期待値照合も可能)
コンフィグレーション名を定義
→ コンフィグレーション名 of エンティティ名
⇓
このコンフィグレーション名でシミュレーターの
実行モジュールが作られる
テストベンチでの入力波形記述例
constant STEP: time := 100 ns ; begin
U0: COUNT4LD port map( CLK, RST, LD, D, Q );
-- 入力;CLK、RST、LD、D
process begin -- クロックの記述
CLK <=‘0’; wait for STEP/2; -- STEP/2毎に“01”を繰り返す
CLK <=‘1’; wait for STEP/2; -- 無限にループする
end process ;
process begin
D <=“0000”; -- 入力Dに”0000”をセット
wait for STEP; RST <=‘1’; -- 1クロック後、リセットをon
wait for STEP; RST <=‘0’; -- 1クロック後、リセットをoff
wait for STEP*20; -- 20クロック進める
D <=“1001”; LD <=‘1’; -- ロードをonして、Dに9をロード
wait for STEP; LD <=‘0’; -- ロードをoff
wait for STEP*8; -- 8クロック進める
D <=“0110”; LD <=‘1’; -- ロードをonして、Dに6をロード
wait for STEP; LD <=‘0’; -- ロードをoff
wait for STEP*12 ; -- 12クロック進める
assert false severity failure; -- シミュレーションの強制終了
3.課題2:
『自分の名前を表示させよう』
- 第3日目 -
0123456789_I_AM_TOKUYA_FUJIOKA.
自分の名前
[注] 31文字なので、5ビット化(32文字)が可能
M _ T O
←・・
←・・
[各文字と各セグメントの表示は、
テキストpp111、112を参照]
[実現機能] 4個の7segLEDに、1秒毎に左に流れるように、0~9の数字を
表示させた後に、自分の名前をアルファベットで表示する。
[ボタン仕様]
Button0(stop): 押下毎に停止/再開の動作を繰り返す
停止: 押下時点での表示をそのまま継続する
再開: 表示状態から次の表示を再開する
Button1(reset): 初期状態に戻る(0表示から始める)
[LED表示]
HEX0 : 0123456789_I_am_(各人の名前をアルファベットで表示
HEX1/2/3 : -1/-2/-3秒遅れて、HEX0を同じ内容を表示
[モジュール構成]
- peripheral_moji: 準備されている。 ボタン動作に従って、1MHz周期
(Sim用)のカウント信号(0~31)が出力される: deco0~3[5_0]
実機用には、1Hz周期になるように変更する。
- conversion_ascii: カウント信号をascii文字コードに変換
『名前表示』の開発仕様
実習の進め方
【第3日目】 VHDLで設計して、シミュレーションを実行して
機能確認後、実機で動作を確認する。
[ Modelsim ]
(テキスト: 116 ~ 130頁)
① 新規プロジェクト(moji_deco)を作成する
② conversion_ascii.vhd
(各自で記述内容が異なる)
moji_deco.vhd
(全員の記述内容が同じ)
を設計する。
③ moji_deco_top.vhd トップ回路をVHDLで設計する
④ テストベンチでシミュレーションを実行し、機能確認する
[QuartusⅡ]
(テキスト: 131 ~ 137頁)
⑤ 新規プロジェクト(moji_deco_DE0)を作成する
⑥ 実機用回路に修正し(図4-24)、コンパイルする
⇒ 修正後のデータをエラーフリーにする
⑦ 端子割り当て後、コンパイルして実行モジュールを作成する
⑧ 実機で動作を確認する
conversion_ascii
『名前表示』のSim用モジュール構成
- 図4-5 実習課題概要 -
deco0 0 1 2 3 4 5 6 7 8 9 ・・・ 30 31 deco1 31 0 1 2 3 4 5 6 7 8 ・・・ 29 30 deco2 30 31 0 1 2 3 4 5 6 7 ・・・ 28 29 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 _ I _ a m _ (ascii) CNV0 DEC0 CLK STOP RESET conversion_ascii decoder_7seg CNV1 DEC1 CNV2 DEC2 CNV3 DEC3 S0(5) A0(7) S1(5) A1(7) S2(5) A2(7) S3(5) A3(7) LED0 LED1 LED2 LED3 HEX0 HEX1 HEX2 HEX3 PERI deco0 deco1 deco2 deco3moji_deco_top
peripheral_moji (配付モジュール)今回設計する部分
CLK STOP RESET LED0 LED1 LED2 LED3 HEX0 HEX1 HEX2 HEX3
moji_deco_DE0
clk LED0(7..0) I3: moji_deco_top stop reset LED1(7..0) LED2(7..0) LED3(7..0) clk I1: chattering SW_in SW_out clk I2: chattering SW_in SW_out chat_STP chat_RST『名前表示』の実機用モジュール構成
- 図4-24 実機評価用最上位回路: moji_deco_DE0 -
- 入力信号の雑音を削除 ⇒ チャタリング防止回路の挿入
- 表示周期を1秒(=1Hz)に変更
⇒ moji_deco_top内のperipheral_mojiの一部を変更
『名前表示』のシミュレーション
1.シミュレーション用回路の設計
1)図4-5に従って、
conversion_ascii, decoder_7seg, moji_deco_top を設計する
2)peripheral_mojiは、シミュレーション用にカスタマイズする(されている)
・シミュレーションでは、雑音等は削除してよい
・シミュレーションの効率化を図る
⇒ 出力:deco0/1/2/3を1MHz(=1us)周期に設定
3)テストベンチを記述して、シミュレーションを実行する
2.シミュレーション後の確認内容
1)decoのカウント数に従って、所望の文字列が発生されているか?
2)カウント数が、asciiコードに正しく変換されているか?
3)7segLEDの信号が正しく生成されているか?
4)resetが正しく動作しているか?
5)stop信号が正しく動作しているか?
--Testbench for module: moji_deco_top library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; entity moji_deco_top_tb is end moji_deco_top_tb;
architecture SIM of moji_deco_top_tb is component moji_deco_top
port( CLK, STOP, RESET: in std_logic;
LED0 : out std_logic_vector (7 downto 0); LED1 : out std_logic_vector (7 downto 0); LED2 : out std_logic_vector (7 downto 0); LED3 : out std_logic_vector (7 downto 0)); end component;
signal CLK: std_logic := '0' ;
signal STOP, RESET: std_logic := '1' ;
signal LED0, LED1: std_logic_vector (7 downto 0); signal LED2, LED3: std_logic_vector (7 downto 0); constant STEP: time := 20 ns ;
begin
U0: moji_deco_top port map
(clk, reset, stop, LED0, LED1, LED2, LED3 );
process begin
clk <= '0'; wait for STEP/2; clk <= '1'; wait for STEP/2; end process;
process begin
wait for 10.3 us ; RESET <= '0'; wait for 4.5 us ; RESET <= '1'; wait for 30.7 us ; STOP <= '0'; wait for 2.0 us ; STOP <= '1'; wait for 8.2 us ; STOP <= '0'; wait for 3.8 us ; STOP <= '1'; wait for 20.5 us ;
assert false severity failure; end process; end SIM; configuration cfg_moji_deco_top_tb of moji_deco_top_tb is for SIM end for; end cfg_moji_deco_top_tb;
『名前表示』のテストベンチ記述例
clk生成 RESET/ STOP生成U0: moji_deco_top
- シミュレーション用回路
『名前表示』のシミュレーション結果(1)
『名前表示』のシミュレーション結果(2)
『名前表示』のシミュレーション結果(3)
4.課題3: 『1分時計』
- 第3/4日目 -
[実現機能] 1/100秒まで表示する1分時計を作る。60秒でトグルする。
(表示例) 12.34
[秒桁に、ドットを表示する]
[ボタン仕様]
Button0(reset): 初期状態に戻る(00.00秒表示に戻る)
[LED表示]
HEX0 : 1/100秒
HEX1 : 1/10秒
HEX2 : 1秒 ←
“ドット”を表示させる
HEX3 : 10秒
[モジュール構成]
- one_min_clock_top: 1分時計の最上位回路
- Div_10ms: 50MHz(20ns)→100Hz(10ms)への分周回路。
- chattering: チャタリング防止回路(既設計。手法1、2どちらでも可)
- CNT10: カウントアップ機能付き10進カウンタ
- CNT06: 6進カウンタ (カウントアップ機能は無し)
- BCD_7segLED: BCDコードを7segLED信号にデコード
『1分時計』の開発仕様
実習の進め方
【第3/4日目】 シミュレーションは、サブ回路で実行する。
実機用回路を設計して、動作を確認する。
[ Modelsim ]
(テキスト: 142 ~ 146頁)
① 新規プロジェクト(one_min_clock)を作成する
② Div_10ms: Sim用に、分周は、
10us
で設計する
CNT10 : カウントアップ機能付き10進カウンター を設計する
③ Parts : サブ回路のトップモジュールを設計する
④ テストベンチでシミュレーションを実行し、機能確認する
[QuartusⅡ]
(テキスト: 146 ~ 1148頁)
⑤ 新規プロジェクト( one_min_clock )を作成する
⑥ 実機用回路(図5-8)を設計する ⇐ 分周は、
10ms
にする
⇒ コンパイルで設計データをエラーフリーにする
⑦ 端子割り当て後、コンパイルして実行モジュールを作成する
⑧ 実機で動作を確認する
『1分時計』のトップ回路図
[入力]
- CLK: 50Mhz(20ns)
-
非同期
reset
[出力]
1 2.
3
4
1/100単位 ドットを付ける 60秒で繰り返す ドット表示clk
reset
LED0
LED1
LED2
LED3
HEX0
HEX1
HEX2
HEX3
one_minute_top
[チャタリング防止回路]chattering
chat_rst clk_10ms clk_100msBCD_7segLED
[分周回路]Div_10ms
bcd seg
bcd seg
bcd seg
bcd seg
clk clk_div
clk_sig
reset
bcd
up_sig
10進 カウンタclk_sig
reset
bcd
up_sig
10進 カウンタclk_sig
reset
bcd
up_sig
10進 カウンタclk_sig
reset
bcd
up_sig
6進 カウンタ clk_1s clk_10s bcd0_sig bcd1_sig bcd2sig bcd3_sig- 図5-8 『1分時計』のブロック図 -
clk
Parts
clk_10msclk_100ms
[分周回路]Div_10ms
clk_sig
reset
bcd
up_sig
[10進カウンタ]CNT10
clk clk_div
bcd(3..0)
reset
▼ ▼ ▼ ▼ ▼ 9 1 9 1シミュレーション用サブ回路
図5-8の回路全体をシミュレーションするのは、非効率
⇒ サブ回路で、シミュレーションを実行
⇒ Div_10msとCNT10の動作を確認
⇒ 図5-10のサブ回路:Partsでシミュレーション実行
- 分周は、10ms→
10us
にする(1/1000にして、シミュレーション)
- 図5-10 サブ回路:Partsのブロック図 -
システムクロック: 50MHzbegin
DUT: Parts port map (clk, reset, clk_100ms, bcd);
process begin
clk <= '1'; wait for 10 ns ; clk <= '0'; wait for 10 ns ; end process;
process begin
wait for 3215 ns; reset <= '0'; wait for 2.0 us; reset <= '1'; wait for 500 us;
assert false severity failure; end process;
end SIM;
configuration cfg_parts_tb of parts_tb is for SIM end for; end cfg_parts_tb; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity parts_tb is end parts_tb;
architecture SIM of parts_tb is component parts port
(clk, reset : in std_logic; clk_100ms : out std_logic;
bcd : out std_logic_vector(3 downto 0) ); end component;
signal clk, reset, clk_100ms : std_logic :='1'; signal bcd : std_logic_vector(3 downto 0);
『1分時計』のサブ回路のテストベンチ
- 分周周波数は、
10us
でシミュレーションを実行
clk生成
reset生成
3215nsから2us間 reset後、 500us実行して、 強制終了Sim継続時間
サブ回路:Partsのシミュレーション結果①
[reset機能の確認]
サブ回路:Partsのシミュレーション結果②
[CNT10の出力:clk_100msの確認]
5.課題4: 『追加仕様版加算器』
[追加仕様1]
4ビット加算器の表示を16進表示 ⇒ 10進表示に変更する
- “1100”(=C
H) ⇒ [BCDコード] “0001_0010”(=12
10)
[追加仕様2]
追加仕様1の4ビット
(0~15)
を7ビット
(0~127)
へ拡張する。
-入力信号AとB: 0~99まで入力可。 99から0に戻る。
-加算結果は、HEX0/1/2に10進数で、HEX/3には“=”を表示する。
(表示例) “=005”、“=034”、“=198” 等
[追加仕様3]
追加仕様2に乗算機能を追加する
-99x99=9801 ⇒ HEX0/1/2/3に表示可)
-乗算機能は、単純に、MUL <= A * B; で実現する
-MULの表示は、SW1を使う。 SW1=’1’の時に、HEX3~0に表示する。
SW0とSW1が同時に’1’の時は、SW1を優先する。
『4ビット加算器』への追加仕様
実習の進め方
【第4日目】 以下の手順で設計して、シミュレーションで確認後、
実機用回路を設計して、動作を確認する。
[ Modelsim ]
① 新規プロジェクト(adder_expand)を作成する
② プロジェクト:adder_4bit に、
・4ビットカウンター: Counter_4bit.vhd
・BCD化モジュール:Binary2bcd.vhd
・表示信号の選択回路: Selector.vhd を追加する
③ 全体回路を整合し、テストベンチでシミュレーションを実行し、
機能確認する
[QuartusⅡ]
④ 新規プロジェクト( adder_expand_DE0 )を作成する
⑤ 実機用回路を設計する(チャッタリング防止回路の追加)
⑥ 端子割り当て後、コンパイルして実行モジュールを作成する
⑦ 実機で動作を確認する
☆ 追加仕様2/3も同様の手順で作業する。
A B RESET EQUAL システムクロック (50MHz) カウンター 波 形 整 形 (チ ャ タ リ ン グ ) SW0 0 加算 回路 BCD化 BCD化 BCD化 カウンター Hex0 Hex1 Hex2 Hex3 1 表 示 信 号 の 選 択 BCD_ 7segLED
(Hex3) (Hex2) (Hex1) (Hex0)
『追加仕様版_加算器』のブロック図
adder_expand_DE0
図6-1 追加仕様版1の加算器ブロック図
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; entity Binary2bcd isport( bin_in : in std_logic_vector(4 downto 0); bcd1 : out std_logic_vector(3 downto 0); bcd2 : out std_logic_vector(3 downto 0)); end Binary2bcd ;
architecture RTL of Binary2bcd is
signal Num,N1,N2: integer range 0 to 63; begin
Num <= CONV_INTEGER(bin_in); N1 <= Num - (Num/10)*10; N2 <= (Num/10) mod 10;
関数名
機能内容
std_logic_1164パッケージ内
To_stdlogicvector(A)
bit_vectorからstd_logic_vectorへの変換
To_bitvector(A)
std_logic_vectorからbit_vectorへの変換
To_stdlogic(A)
bitからstd_logicへの変換
To_bit(A)
std_logicからbitへの変換
std_logic_arithパッケージ内
CONV_std_logic_vector(A、ビット幅)
integer、unsigned、signedから
std_logic_vectorへの変換
CONV_INTEGER(A)
unsigned、signedからintegerへの変換
std_logic_unsignedパッケージ内
CONV_INTEGER(A)
std_logic_vectorからintegerへの変換
『型の変換』の関数
【参考資料】
- 7segLEDのデコード回路 -
(ドット表示on/off機能付)
7segLEDのデコーダ: BCD_7seg.vhd
library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity BCD_7seg is
port( dot : in std_logic;
led : in std_logic_vector(3 downto 0); seg : out std_logic_vector(7 downto 0)); end BCD_7seg; architecture RTL of BCD_7seg is begin process(led) begin if dot='0' then case led is when "0000" => seg<="00000011"; -- 0 when "0001" => seg<="10011111"; -- 1 when "0010" => seg<="00100101"; -- 2 when "0011" => seg<="00001101"; -- 3 when "0100" => seg<="10011001"; -- 4 when "0101" => seg<="01001001"; -- 5 when "0110" => seg<="01000001"; -- 6 when "0111" => seg<="00011011"; -- 7 when "1000" => seg<="00000001"; -- 8 when "1001" => seg<="00001001"; -- 9 when others => seg<="11111111";
end case; else case led is when "0000" => seg<="00000010"; -- 0 when "0001" => seg<="10011110"; -- 1 when "0010" => seg<="00100100"; -- 2 when "0011" => seg<="00001100"; -- 3 when "0100" => seg<="10011000"; -- 4 when "0101" => seg<="01001000"; -- 5 when "0110" => seg<="01000000"; -- 6 when "0111" => seg<="00011010"; -- 7 when "1000" => seg<="00000000"; -- 8 when "1001" => seg<="00001000"; -- 9 when others => seg<="11111110";
end case; end if; end process; end RTL;
DUT: BCD_7seg
- 7seg LEDのデコーダー
- 入力: 0 ~ 9(BCD
)- ドット表示の有無で場合分け
library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity BCD_7seg_tb is
end BCD_7seg_tb;
architecture SIM of BCD_7seg_tb is component BCD_7seg
port( dot : in std_logic;
led : in std_logic_vector(3 downto 0); seg : out std_logic_vector(7 downto 0)); end component;
signal dot : std_logic;
signal led : std_logic_vector(3 downto 0):="0000"; signal seg : std_logic_vector(7 downto 0);
constant STEP: time := 1 us; begin
DUT: BCD_7seg port map (dot, led, seg);
end SIM;
configuration cfg_BCD_7seg_tb of BCD_7seg_tb is for SIM
ポートリストの無いエンティティ記述
テストモジュール:BCD_7segのコンポーネント宣言
BCD_7segの入出力信号で定義する
定数を定義する
BCD_7segをDUTとしてインスタンスする
コンフィグレーションを定義する
入力信号の波形を定義する
(- 出力波形を記述し期待値照合を行う)
波形記述
ライブラリ記述
BCD_7segのテストベンチ記述例①
constant STEP: time := 1 us; begin
DUT: BCD_7seg port map (dot, led, seg);