摂大・鹿間 論理回路
論理回路
(第15回)
特別講義: 言語を使った設計(
2)
2.1 HDL設計入門
2.2 FPGAボードの設計デモ
配布資料 「
VHDLの言語構造と基本文法」
鹿間 信介
摂南大学 理工学部 電気電子工学科
論理回路 摂大・鹿間2.1 HDL設計入門
②HDLコード記述 ④ 論理合成 ⑤ 配置配線 ⑦ ダウンロード ファイル作成 ⑧ ダウンロード ③ 論理シミュ レーション ⑥ 遅延シミュ レーション ⑨ 実機での 動作確認 FPGAベンダーが提供 (例:QuartusⅡ/Altera, ISE/Xilinx) ① 仕様設計 ① 仕様: 製作する回路機能を明確化 ② コード:VHDLによる記述 ③ 論理SIM: 実回路での遅延を考慮 しないSIM (小規模回路では省略) ④ 合成: 論理回路を生成する ⑤ 配置配線:FPGA内部構成用デー タを生成し,ピン割り当てを行う ⑥ 遅延SIM: 遅延を含めた動作SIM ⑦ ファイル作成:FPGAに転送する形 式のファイルを作成 ⑧ ダウンロード:PCよりファイル転送 ⑨ 実機動作:FPGAボードで実際の 動作を確認する EDAツール: メンター社製品が有名 FPGAベンダーのSW にも簡易機能あり 論理回路 摂大・鹿間2.2 FPGAボードの設計デモ
FPGAボード Altera EP1C3(5万ゲート相当)搭載設計ツール (QUARTSⅡ)
FPGA EP1C3 PC接続 コネクタ 7セグメント LED×3 プッシュSW ×4 単体LED 緑3,赤3 論理回路 摂大・鹿間FPGAボードのブロック図
FPGA Altera社EP1C3 7セグメントLED ×3 単体LED 緑×3, 赤×3 ダウンロード回路 (ByteBlasterMV) パソコンの パラレルポート 電源回路 1.5V, 3.3V DC入力 5~6V クロック発振器 33MHz プッシュ・スイッチ ×4 拡張ヘッダ (26I/O, オプション)論理回路 摂大・鹿間
QuartusⅡによるFPGA設計フロー
④ ダウンロード ① プロジェクトの作成 ② デザイン・エントリ (ソース・コード入力) ③ コンパイル プロジェクト名の指定 設計ファイルの指定 ターゲット・デバイスの指定 (サードパーティ・ツールの指定) プログラミング方式の指定 コンフィグレーション・ファイルの指定 プログラミングの実行 論理合成 配置配線 コンフィグレーション・データ生成 ピン配置 指定 論理回路 摂大・鹿間VHDLの基本構文
ライブラリ宣言
各種データ型や演 算子に関するライブ ラリを指定 エンティティ宣言
入出力端子(port) の設定 アーキテクチャ宣言
論理回路の機能・ 動作を記述 library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_unsigned.all; entity エンティティ名 is [エンティティ文] end [エンティティ名]; architecture アーキテクチャ名 of エンティティ名 is -- ノード宣言部 (外部には出力しない信号) signal, type 等 begin [アーキテクチャ文] end [アーキテクチャ名]; 論理回路 摂大・鹿間例題1:
LEDの点灯と消灯
LEDの点灯・消灯をピンの L/Hで制御 (負論理) LEDのアノードにはVcc (3.3V)が印加されている I/Oピンが”L”で点灯 I/Oピンが”H”で消灯 FPGAボードのLED周辺回路 EP1C3 560Ω×6 36 35 26 28 34 27 D4 D5 D6 D8 D9 D7 Vcc 3.3V ピン番号 ピンの名前36
led_out
LED(D9)を点灯するピン配置 論理回路 摂大・鹿間例題1:
LEDの点灯-- VHDLソースコード
library ieee; use ieee.std_logic_1164.all; entity practice1 is port (led_out: out std_logic); end practice1; architecture rtl of practice1 is begin -- led_outが ‘0’で LEDが点灯 -- led_outが ‘1’ でLEDが消灯 led_out <= '0'; end rtl; ライブラリ宣言 パッケージ呼び出し エンティティ宣言 (出力ポート設定) アーキテクチャ宣言 --- RTLレベルで 論理回路の動作記述
論理回路 摂大・鹿間
QuartusⅡの操作手順
(操作デモ概要)
プロジェクト名の指定 設計ファイルの指定 ターゲット・デバイスの指定 (サードパーティ・ツールの指定) Tools ⇒ Programmer 設定確認,Auto Detect (EP1C3認識)ファイル名指定(*.sof) ⇒ Start プリフィット(論理合成・配置配線) -- 回路規模,動作周波数チェック他 ポストフィット(書込みデータ生成) ④ ダウンロード ① プロジェクトの作成 ② デザイン・エントリ (ソース・コード入力) ③ コンパイル QuartusⅡの起動 EP1C3T100C8 ・ ピン配置指定 ・ 未使用ピン処理 (プルアップ&Hi-Z) 時間の関係上 既存qpfを開く (qdesigns¥quartus_usage) 論理回路 摂大・鹿間
例題
2: 3個のLEDで2進数を表示する
library ieee; use ieee.std_logic_1164.all; entity practice2 is port (led_out:out std_logic_vector(2 downto 0));
end practice2; architecture rtl of practice2 is begin -- led_outが ‘0’のビットはLED点灯 -- led_outが ‘1’のビットはLED消灯 -- 2進数ビット反転式で(5)10を表現 led_out <= "010"; end rtl; ライブラリ宣言 パッケージ呼び出し エンティティ宣言 (3ビットバス出力) アーキテクチャ宣言 --- RTLレベルで 論理回路の動作記述 論理回路 摂大・鹿間
例題3: 7セグメントLEDに16進数を表示する(1)
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity practice3 is port (led_out:out std_logic_vector(7 downto 0));
end practice3;
architecture rtl of practice3 is
signal counter : std_logic_vector(3 downto 0) := (others=>'0'); begin counter <= "0010"; -- 以下に続く ライブラリ宣言 エンティティ宣言 (8ビットバス出力) アーキテクチャ宣言 ノード”counter”定義 4ビットで7セグLED の表示数値を設定 パッケージ呼び出し 論理回路 摂大・鹿間
FPGAボードの
7セグメントLED回路
EP1C3 560Ω×8 25 22 21 24 26 23 20 5a
b
c
d
e
f
g
dp
Vcc (3.3V) comA comDP a b c d e f gD3
5 a led_out[7] 20 b led_out[6] 23 c led_out[5] 26 d led_out[4] 24 e led_out[3] 21 f led_out[2] 22 g led_out[1] 25 ピン番号 接続 ピンの名前 dp led_out[0] 7セグメントLED(D3)のピン配置 LED 表示 a b c d e f g 0 0 0 0 0 0 1 1 0 0 1 1 1 1 0 0 1 0 0 1 0 0 0 0 0 1 1 0 1 0 0 1 1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 1 1 1 0 0 1 0 1 0 0 0 0 1 0 0 1 1 0 0 0 0 0 1 1 1 0 0 0 アクティブLow信号論理回路 摂大・鹿間
例題
3: 7セグメントLEDに16進数を表示する(2)
process(counter) begin case counter is when "0000" => led_out <= "00000011"; when "0001" => led_out <= "10011111"; when "0010" => led_out <= "00100101"; when "0011" => led_out <= "00001101"; when "0100" => led_out <= "10011001"; when "0101" => led_out <= "01001001"; when "0110" => led_out <= "01000001"; when "0111" => led_out <= "00011111"; when "1000" => led_out <= "00000001"; when "1001" => led_out <= "00001001"; when "1010" => led_out <= "00010001"; when "1011" => led_out <= "11000001"; when "1100" => led_out <= "11100101"; when "1101" => led_out <= "10000101"; when "1110" => led_out <= "01100001"; when "1111" => led_out <= "01110001"; when others => null;end case; end process; end rtl; process文: 4ビット入力 値の変化による8ビット 出力値の変化を記述 (7セグ表示用デコーダ) case文:”when”条件 で場合分けし,”=>” の文を実行する (同時並列に実行) ・othersは「それ以 外のとき」,処理な しの場合’null’ ・省略しないこと 論理回路 摂大・鹿間
例題
4: 7セグメントLED表示を順次増加させる(1)
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity practice4 is port ( clk : in std_logic;led_out: out std_logic_vector(7 downto 0)); end practice4;
architecture rtl of practice4 is
signal counter : std_logic_vector(3 downto 0) := (others=>'0'); signal div_counter : std_logic_vector(24 downto 0) := (others=>'0'); signal div_clk : std_logic := '0';
ライブラリ宣言 エンティティ宣言 (クロック入力clk) アーキテクチャ宣言 分周用カウンタdiv_counter 分周用クロックdiv_clk パッケージ呼び出し 論理回路 摂大・鹿間
例題
4: 7セグメントLED表示を順次増加させる(2)
begin process (clk) begin -- if文で33MHz clkの立上がりを検出し,div_counterを進める if clk'event and clk='1' thendiv_counter <= div_counter + 1; end if; end process; -- div_clkが1Hzの分周クロックで,デコーダへのクロック入力 div_clk <= div_counter(24); process(div_clk) begin
if div_clk'event and div_clk='1' then counter <= counter + 1; end if; end process; Process文(分周回路): 33MHzのclkを分周し,1秒のclkを作成 (25bitカウンタのMSBは32M分周) Process文: div_clkの立上がり検出し, LED表示用counterを進める 論理回路 摂大・鹿間
例題
4: 7セグメントLED表示を順次増加させる(3)
process(counter) begin case counter is when "0000" => led_out <= "00000011"; when "0001" => led_out <= "10011111"; when "0010" => led_out <= "00100101"; when "0011" => led_out <= "00001101"; when "0100" => led_out <= "10011001"; when "0101" => led_out <= “01001001”; when "0110" => led_out <= "01000001"; when "0111" => led_out <= "00011111"; when "1000" => led_out <= "00000001"; when "1001" => led_out <= "00001001"; when "1010" => led_out <= "00010001"; when "1011" => led_out <= "11000001"; when "1100" => led_out <= "11100101"; when "1101" => led_out <= "10000101"; when "1110" => led_out <= "01100001"; when "1111" => led_out <= "01110001"; when others => null; end case; end process; end rtl; process文: 4ビット入力 値の変化による8ビット 出力値の変化を記述 (7セグ表示用デコーダ)論理回路 摂大・鹿間
3人による多数決の真理値表(論理回路基礎 第2回講義より)
入力変数A, B, Cとして,出力Yは
1
1
1
1
0
1
0
1
1
0
0
1
1
1
0
1
0
0
0
1
0
0
0
0
B
C
A
1
1
1
0
1
0
0
0
Y
A
B
C
ABC
C
AB
C
B
A
BC
A
Y
=
+
+
+
この論理式を順次簡単化
ABC
ABC
ABC
C
AB
C
B
A
BC
A
Y
=
+
+
+
+
+
)
(
)
(
)
(
A
A
AC
B
B
AB
C
C
BC
+
+
+
+
+
=
CA
BC
AB
+
+
=
論理回路 摂大・鹿間SW入力回路とチャタリング除去
SW1~SW4: 40~37番ピン (負論理) 10 clk 39 sw_in3 38 sw_in2 37 sw_in1 ピン番号 ピンの名前 36 led_out FPGAボードのSW入力回路 EP1C3 100Ω ×4 Vcc 3.3V SW1 SW2 SW3 SW4 37 38 39 40 2.2k ×4 1μ ×4 10 33Ω CK (33MHz) OFF ⇒ ON チャタリング (1ms位) ↓ CK波形(基本CKの分周波形) SW波形 理想 タイミング 1回目"H" タイミング 1 回目" L" タイミング #1 #1 #1 #2 #2 CK立上がりで SW信号取得 1回目の結果がマチマチでも、 2回目は”L" (周期msオーダ) 論理回路 摂大・鹿間例題51: 3個のスイッチによる多数決論理(1)
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity practice51 is-- div_bits is division bits number generic ( div_bits : integer :=15); port( clk : in std_logic; sw_in1 : in std_logic; sw_in2 : in std_logic; sw_in3 : in std_logic; led_out : out std_logic); end practice51; エンティティ宣言 ②入出力ポート設定 入力:SW1~3 出力:LED ① チャタリング除去用分周設定(※) - 15bit分周 (33MHz⇒1KHz) ※generic文:回路全体に適用可能なパラ メータ(アーキテクチャ部でも使用可) ライブラリ宣言& パッケージ呼び出し 論理回路 摂大・鹿間
例題51: 3個のスイッチによる多数決論理(2)
architecture rtl of practice51 issignal div_counter: std_logic_vector(div_bits-1 downto 0) := (others=>'0'); signal sw_in_node1, sw_in_node2, sw_in_node3 : std_logic; signal a, b, c, y : std_logic;
begin
-- チャタリング防止のためのクロック分周回路 process(clk)
begin
if clk‘event and clk = ’1‘ then -- CLKの立上がり検出 ⇒ カウントUP div_counter <= div_counter + 1; end if; end process; --分周信号でSW入力をラッチする回路(分周CKのMSBをCKにする) process (div_counter(div_bits-1)) begin -- process
if div_counter(div_bits-1)'event and div_counter(div_bits-1) ='1' then sw_in_node1 <= sw_in1; sw_in_node2 <= sw_in2; sw_in_node3 <= sw_in3; end if; end process; div_counterの最上位 ビットの立ち上がり検出 3個のSW入力 (多数決入力)
論理回路 摂大・鹿間
例題51: 3個のスイッチによる多数決論理(3)
a <= not sw_in_node1; b <= not sw_in_node2; c <= not sw_in_node3;
y <= (a and b) or (b and c) or (c and a); led_out <= not y; end rtl;