ハードウェア記述言語に よる FPGA設計の開発事例

コンピュータシステム実験
VHDLによる回路設計
守川和夫
(情報電子工学科)
MUXとDEMUX
4 to 1 MUXの設計

4 to 1 マルチプレクサ(セレクタ)をVHDLで
記述する.


RTレベルの記述
ゲートレベルの記述
4 to 1 MUX
library IEEE;
use IEEE.std_logic_1164.all;
entity MUX4to1 is
port (
A,B,C,D : in std_logic;
SEL : in std_logic_vector(1 downto 0);
Q : out std_logic );
end MUX4to1;
architecture RTL of MUX4to1 is
begin
process(A,B,C,D,SEL)
begin
case SEL is
when “00” => Q <= A;
when “01” => Q <= B;
when “10” => Q <= C;
when others => Q <= D;
end case;
end process;
end RTL;
architecture RTL of MUX4to1 is
begin
process(A,B,C,D,SEL)
begin
if (SEL = “00”) then
Q <= A;
elsif (SEL = “01”) then
Q <= B;
elsif (SEL = “10”) then
Q <= C;
else
Q <= D;
end if;
end process;
end RTL;
4 to 1 MUXの回路は...
A
B
C
D
SEL(1
)
SEL(0
)
Q
ゲートレベルのアーキテクチャ
architecture GATE of MUX4to1 is
begin
Q <= ( not SEL(1) and not SEL(0) and A )
or ( not SEL(1) and SEL(0) and B )
or ( SEL(1) and not SEL(0) and C )
or ( SEL(1) and SEL(0) and D );
end GATE;
FPGAの実装と動作確認


A,B,C,Dをデータスイッチ7,6,5,4に,SELを
データスイッチ1,0に,QをアドレスLED 0に
接続する.
回路を評価ボード(TeC5)上のFPGAにダウ
ンロードし,動作を確認する.

SELの値を変え,4 to 1のマルチプレクサと
なっているか?
3 to 8 デコーダの設計

3 to 8 デコーダをRTレベルのVHDLで記述
する.
3 to 8 デコーダ
library IEEE;
use IEEE.std_logic_1164.all;
entity DECODER3to8 is
port (
A,B,C : in std_logic;
Y : out std_logic_vector(7 downto 0));
end DECODER3to8;
architecture RTL of DECODER3to8 is
signal IN_DATA : std_logic_vector(2 downto 0);
begin
IN_DATA <= A & B & C;
process(IN_DATA)
begin
case IN_DATA is
when “000” => Y <= “00000001”;
when “001” => Y <= “00000010”;
when “010” => Y <= “00000100”;
when “011” => Y <= “00001000”;
when “100” => Y <= “00010000”;
when “101” => Y <= “00100000”;
when “110” => Y <= “01000000”;
when “111” => Y <= “10000000”;
when others => Y <= “XXXXXXXX”;
end case;
end process;
end RTL;
FPGAの実装と動作確認


A,B,Cをデータスイッチ2,1,0に,出力Yをア
ドレスLED 7~0に接続する.
回路を評価ボード上のFPGAにダウンロー
ドし,動作を確認する.

A,B,Cの値によって,3 to 8デコーダとなってい
るか?
8 to 3 エンコーダの設計

8 to 3 エンコーダをRTレベルのVHDLで記
述する.
8 to 3 エンコーダ
library IEEE;
use IEEE.std_logic_1164.all;
entity ENCODER8to3 is
port (
INPUT : in std_logic_vector(7 downto 0);
Y : out std_logic_vector(2 downto 0));
end ENCODER8to3;
architecture RTL of ENCODER8to3 is
begin
process(INPUT)
begin
case INPUT is
when “00000001” => Y <= “000”;
when “00000010” => Y <= “001”;
when “00000100” => Y <= “010”;
when “00001000” => Y <= “011”;
when “00010000” => Y <= “100”;
when “00100000” => Y <= “101”;
when “01000000” => Y <= “110”;
when “10000000” => Y <= “111”;
when others => Y <= “XXX”; -- don’t care
end case;
end process;
end RTL;
don’t careの出力

入力スイッチが2個以上‘1’になっているか
すべてのスイッチが‘0’になっているとき,
case文のwhen othersで不定の‘X’を代入
することで回路規模を小さくする(don’t
care出力)ことができる.
FPGAの実装と動作確認


INPUTをデータスイッチ7~0に,出力Yをア
ドレスLED 2~0に接続する.
回路を評価ボード上のFPGAにダウンロー
ドし,動作を確認する.


INPUTのどれかが‘1’になっているとき,8 to 3
エンコーダになっているか?
INPUTが2個以上‘1’になっているかすべて‘0’
になっているときは?
課題


1 to 4 デマルチプレクサをゲートレベルの
VHDLで記述する.
10進-BCDエンコーダをRTレベルの
VHDLで記述する.
1 to 4 DEMUX
library IEEE;
use IEEE.std_logic_1164.all;
entity DEMUX1to4 is
port (
IN : in std_logic;
SEL : in std_logic_vector(1 downto 0);
Q : out std_logic_vector(3 downto 0));
end DEMUX1to4;
architecture GATE of DEMUX1to4 is
begin
Q(3) <= IN and SEL(1) and SEL(0);
Q(2) <= IN and SEL(1) and not SEL(0);
Q(1) <= IN and not SEL(1) and SEL(0);
Q(0) <= IN and not SEL(1) and not SEL(0);
end GATE;
10進ーBCDエンコーダ
library IEEE;
use IEEE.std_logic_1164.all;
entity BCD_ENCODER is
port (
IN10 : in std_logic_vector(9 downto 0);
BCD : out std_logic_vector(3 downto 0));
end BCD_ENCODER;
architecture RTL of BCD_ENCODER is
begin
process(IN10)
begin
case IN10 is
when “0000000001” => Y <= “0000”;
when “0000000010” => Y <= “0001”;
when “0000000100” => Y <= “0010”;
when “0000001000” => Y <= “0011”;
when “0000010000” => Y <= “0100”;
when “0000100000” => Y <= “0101”;
when “0001000000” => Y <= “0110”;
when “0010000000” => Y <= “0111”;
when “0100000000” => Y <= “1000”;
when “1000000000” => Y <= “1001”;
when others => Y <= “XXXX”;
end case;
end process;
end RTL;
カウンタの設計


バイナリカウンタ
リングカウンタ
1秒クロックの生成

ボード上のシステムクロック(2.4576MHz)を分周
して1秒のクロックを作り出す回路をVHDLで記述
する.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity CLOCK is
port ( CLK_2M : in std_logic;
CLK_1 : out std_logic);
end CLOCK;
architecture RTL of CLOCK is
signal Q2M : std_logic_vector(20 downto 0);
signal QCLK : std_logic;
begin
CLK_1 <= QCLK; -- 1秒クロック
process( CLK_2M )
begin
if CLK_2M='1' and CLK_2M'event then
if Q2M=1228799 then -- CLK_2M/2-1
Q2M <= “000000000000000000000”;
-- Q2M <= (others => '0')
QCLK <= not QCLK;
else Q2M <= Q2M + '1';
end if;
end if;
end process;
end RTL;
1秒クロックの動作確認


CLK_2Mを2.4576MHz CLK(P91)に,1秒
クロックCLK_1をアドレスLED 0に接続する.
回路を評価ボード上のFPGAにダウンロー
ドし,動作を確認する.

アドレスLED 0が1秒周期で点滅しているか?
4ビットバイナリカウンタの設計

4ビットバイナリカウンタをVHDLで記述す
る.
4ビットバイナリカウンタ
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity COUNT4 is
port ( CLK,RESET : in std_logic;
COUNT : out std_logic_vector
(3 downto 0));
end COUNT4;
architecture RTL of COUNT4 is
signal CNT_IN : std_logic_vector(3 downto 0);
begin
COUNT <= CNT_IN;
process(CLK,RESET)
begin
if (RESET = ‘0’) then
-- RESETスイッチオン=‘0’
CNT_IN <= “0000”;
elsif (CLK’event and CLK = ‘1’) then
CNT_IN <= CNT_IN + ‘1’;
end if;
end process;
end RTL;
1秒ずつで動く4ビットバイナリ
カウンタCOUNT4_1の構成
RESET
CLK_2M
1秒クロック CLK_1
4ビット
生成
バイナリカウンタ
CLOCK
COUNT4
COUNT4_1
COUNT
4ビットバイナリカウンタの設計

1秒クロック生成回路CLOCKと4ビットバイ
ナリカウンタCOUNT4を同じアーキテクチャ
に2つのprocessとして記述する.
4ビットバイナリカウンタ
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity COUNT4_1 is
port (CLK_2M,RESET : in std_logic;
COUNT : out std_logic_vector
(3 downto 0));
end COUNT4_1;
architecture RTL of COUNT4_1 is
signal CLK_1 : std_logic;
signal Q2M : std_logic_vector(20 downto 0);
signal CNT_IN : std_logic_vector(3 downto 0);
begin
process( CLK_2M )
begin
if CLK_2M='1' and CLK_2M'event then
if Q2M=1228799 then
Q2M <= ( others => '0');
CLK_1 <= not CLK_1;
else Q2M <= Q2M + '1';
end if;
end if;
end process;
COUNT <= CNT_IN;
process(CLK_1,RESET)
begin
if (RESET = ‘0’) then
CNT_IN <= “0000”;
elsif (CLK_1’event and CLK_1 = ‘1’) then
CNT_IN <= CNT_IN + ‘1’;
end if;
end process;
end RTL;
4ビットバイナリカウンタの
動作確認


CLK_2Mを2.4576MHz CLK(P91),RESET
をRESETスイッチ(P97)に,COUNTをアド
レスLED 3~0に接続する.
回路を評価ボード上のFPGAにダウンロー
ドし,動作を確認する.

アドレスLED 3~0がバイナリカウンタになって
いるか?
リングカウンタ
4ビットリングカウンタの動作表
Q(3) Q(2) Q(1) Q(0)
0
0
0
1
0
0
1
0
0
1
0
0
1
0
0
0
0
0
0
1
0
0
1
0
8ビットリングカウンタの設計

4ビットバイナリカウンタの設計と同様に,
1秒クロック生成回路CLOCKと8ビットリン
グカウンタRING8を同じアーキテクチャに
記述する.
8ビットリングカウンタ
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity RING8_1 is
port (CLK_2M,RESET : in std_logic;
COUNT : out std_logic_vector
(7 downto 0));
end RING8_1;
architecture RTL of RING8_1 is
signal CLK_1 : std_logic;
signal Q2M : std_logic_vector(20 downto 0);
signal CNT_IN : std_logic_vector(7 downto 0);
begin
process( CLK_2M )
begin
if CLK_2M='1' and CLK_2M'event then
if Q2M=1228799 then
Q2M <= ( others => '0');
CLK_1 <= not CLK_1;
else Q2M <= Q2M + '1';
end if;
end if;
end process;
COUNT <= CNT_IN;
process(CLK_1,RESET)
begin
if (RESET = ‘0’) then
CNT_IN <= “00000001”;
elsif (CLK_1’event and CLK_1 = ‘1’) then
CNT_IN(7 downto 1) <=
CNT_IN(6 downto 0);
CNT_IN(0) <= CNT_IN(7);
end if;
end process;
end RTL;
8ビットリングカウンタの
動作確認


CLK_2Mを2.4576MHz CLK(P91),RESET
をRESETスイッチ(P97)に,COUNTをアド
レスLED 7~0に接続する.
回路を評価ボード上のFPGAにダウンロー
ドし,動作を確認する.


アドレスLED 7~0がリングカウンタになってい
るか?
リングカウンタをもっと速く動かせるには?
課題

次のカウンタの動作表を示し,VHDLで記
述する.



10進(BCD)カウンタ
8ビットジョンソンカウンタ
それぞれのカウンタはどんなところに応用
されるか?
10進(BCD)カウンタ
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity COUNTBCD is
port ( CLK,RESET : in std_logic;
COUNT : out std_logic_vector
(3 downto 0));
end COUNTBCD;
architecture RTL of COUNTBCD is
signal CNT_IN : std_logic_vector(3 downto 0);
begin
COUNT <= CNT_IN;
process(CLK,RESET)
begin
if (RESET = ‘1’) then
CNT_IN <= “0000”;
elsif (CLK’event and CLK = ‘1’) then
if (CNT_IN = 9) then -- CNT_IN = “1001”
CNT_IN <= “0000”;
else CNT_IN <= CNT_IN + ‘1’;
end if;
end if;
end process;
end RTL;
4ビットジョンソンカウンタの
動作表
Q(3)
0
0
0
0
1
1
1
1
Q(2)
0
0
0
1
1
1
1
0
Q(1)
0
0
1
1
1
1
0
0
Q(0)
0
1
1
1
1
0
0
0
8ビットジョンソンカウンタ
library IEEE;
use IEEE.std_logic_1164.all;
entity JOHNSON8 is
port ( CLK,RESET : in std_logic;
COUNT : out std_logic_vector
(7 downto 0));
end JOHNSON8;
architecture RTL of JOHNSON8 is
signal CNT_IN : std_logic_vector(7 downto 0);
begin
COUNT <= CNT_IN;
process(CLK,RESET)
begin
if (RESET = ‘1’) then
CNT_IN <= “00000000”;
elsif (CLK’event and CLK = ‘1’) then
CNT_IN(7) <= CNT_IN(6);
CNT_IN(6) <= CNT_IN(5);
CNT_IN(5) <= CNT_IN(4);
CNT_IN(4) <= CNT_IN(3);
CNT_IN(3) <= CNT_IN(2);
CNT_IN(2) <= CNT_IN(1);
CNT_IN(1) <= CNT_IN(0);
CNT_IN(0) <= not CNT_IN(7);
end if;
end process;
end RTL;
architecture RTL of JOHNSON8 is
signal CNT_IN : std_logic_vector(7 downto 0);
begin
COUNT <= CNT_IN;
process(CLK,RESET)
begin
if (RESET = ‘1’) then
CNT_IN <= “00000000”;
elsif (CLK’event and CLK = ‘1’) then
CNT_IN(7 downto 1) <= CNT_IN(6 downto 0);
-- ベクタのスライスで簡単に記述
CNT_IN(0) <= not CNT_IN(7);
end if;
end process;
end RTL;
レジスタの設計


レジスタ
シフトレジスタ
レジスタ

クロックに同期してデータをフリップフロップ
に記憶させる.
クリア付き8ビットレジスタ
library IEEE;
use IEEE.std_logic_1164.all;
entity REGISTER8 is
port (CLK,CLR : in std_logic;
D : in std_logic_vector(7 downto 0)
Q : out std_logic_vector(7 downto 0));
end REGISTER8;
architecture RTL of REGISTER8 is
begin
process(CLK,CLR)
begin
if (CLR = ‘1’) then -- クリア
Q <= “00000000”;
elsif (CLK_1’event and CLK_1 = ‘1’) then
Q <= D;
end if;
end process;
end RTL;
シフトレジスタ


クロックに同期してデータを1ビットずつ隣
のフリップフロップに移す(シフト).
シリアル(直列)-パラレル(並列),パラレ
ル-シリアル変換の機能を持っている.
シフトレジスタの機能
POUT
SOUT
SIN
シフトレジスタ
PIN
直列入力ー並列出力
8ビットシフトレジスタの設計

1秒クロック生成回路CLOCKと8ビットシフ
トレジスタSIN_POUT_SHIFTREG8を同じ
アーキテクチャに2つのprocessとして記述
する.
8ビットシフトレジスタ
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity SIN_POUT_SHIFTREG8 is
port (CLK_2M,SIN : in std_logic;
POUT : out std_logic_vector(7 downto
0));
end SIN_POUT_SHIFTREG8;
architecture RTL of SIN_POUT_SHIFTREG8 is
signal CLK_1 : std_logic;
signal Q2M : std_logic_vector(20 downto 0);
signal Q_IN : std_logic_vector(7 downto 0);
begin
-- 1秒クロック生成
process( CLK_2M )
begin
if CLK_2M='1' and CLK_2M'event then
if Q2M=1228799 then
Q2M <= ( others => '0');
CLK_1 <= not CLK_1;
else Q2M <= Q2M + '1';
end if;
end if;
end process;
POUT <= Q_IN;
process(CLK_1)
begin
if (CLK_1’event and CLK_1 = ‘1’) then
Q_IN <= Q_IN(6 downto 0) & SIN;
end if;
end process;
end RTL;
8ビットシフトレジスタの
動作確認


CLK_2Mを2.4576MHz CLK,SINをデータ
スイッチ0に,POUTをアドレスLED 7~0に
接続する.
回路を評価ボード上のFPGAにダウンロー
ドし,動作を確認する.

直列入力SINから‘0’, ‘1’を入力し,並列出力
POUTがシフトレジスタとして動いているか?
並列入力ー直列出力
8ビットシフトレジスタの設計

1秒クロック生成回路CLOCKと8ビットシフ
トレジスタPIN_SOUT_SHIFTREG8を同じ
アーキテクチャに記述する.
8ビットシフトレジスタ
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity PIN_SOUT_SHIFTREG8 is
port (CLK_2M,LOAD : in std_logic;
PIN : in std_logic_vector(7 downto 0);
SOUT : out std_logic;
POUT : out std_logic_vector(7 downto
0));
end PIN_SOUT_SHIFTREG8;
architecture RTL of SHFTREG8_1 is
signal CLK_1 : std_logic;
signal Q2M : std_logic_vector(20 downto 0);
signal Q_IN : std_logic_vector(7 downto 0);
begin
process( CLK_2M )
begin
if CLK_2M='1' and CLK_2M'event then
if Q2M=1228799 then
Q2M <= ( others => '0');
CLK_1 <= not CLK_1;
else Q2M <= Q2M + '1';
end if;
end if;
end process;
SOUT <= Q_IN(7);
POUT <= Q_IN;
process(CLK_1,LOAD,PIN)
begin
if (LOAD = ‘0’) then
Q_IN <= PIN;
elsif (CLK_1’event and CLK_1 = ‘1’) then
Q_IN <= Q_IN(6 downto 0) & ‘0’;
end if;
end process;
end RTL;
8ビットシフトレジスタの
動作確認


CLK_2Mを2.4576MHz CLK,LOADを
BREAKスイッチ(P98),PINをデータスイッ
チ7~0に,SOUTをG0 LED,POUTをアドレ
スLED 7~0に接続する.
回路を評価ボード上のFPGAにダウンロー
ドし,動作を確認する.

並列入力PINに適当なビットパターンをセットし,
LOADスイッチを押して並列データを入力する
と,直列出力SOUT(並列出力POUTも)がシフ
トレジスタとして動いているか?
7セグメントデコーダの設計

8の字型に並べられた7つの発光ダイオー
ド(7セグメントLED)を,入力した4ビットの
値に応じて16進数表示するように制御す
る.
a
f
b
g
e
c
d
d.p.
7セグメントLEDの16進数表示

16進数(0~9,A~F) が表示できるように
点灯するセグメントを決める.
7セグメントデコーダ
library IEEE;
use IEEE.std_logic_1164.all;
entity SEVEN_SEG_DECODER is
port (HEX : in std_logic_vector(3 downto 0);
SEG : out std_logic_vector(7 downto 0));
-- セグメント記号の割当d.p.,g,f,e,d,c,b,a
end SEVEN_SEG_DECODER;
7セグメントLEDのデコーダ
architecture RTL of SEVEN_SEG_DECODER is
begin
process(HEX)
begin
case HEX is
when “0000” => SEG <= “11000000”; -- 負論理
{中略}
when others => SEG <= “XXXXXXXX”;
end case;
end process;
end RTL;
case HEX is -- 7セグメントデコーダのcase全文
when “0000” => SEG <= “11000000”;
when “0001” => SEG <= “11111001”;
when “0010” => SEG <= “10100100”;
when “0011” => SEG <= “10110000”;
when “0100” => SEG <= “10011001”;
when “0101” => SEG <= “10010010”;
when “0110” => SEG <= “10000010”;
when “0111” => SEG <= “11111000”;
when “1000” => SEG <= “10000000”;
when “1001” => SEG <= “10010000”;
when “1010” => SEG <= “10001000”;
when “1011” => SEG <= “10000011”;
when “1100” => SEG <= “11000110”;
when “1101” => SEG <= “10100001”;
when “1110” => SEG <= “10000110”;
when “1111” => SEG <= “10001110”;
when others => SEG <= “XXXXXXXX”;
end case;
スイッチオン⇒‘1’
architecture RTL of SEVEN_SEG_DECODER is
signal INV_HEX : std_logic_vector(3 downto 0);
begin
INV_HEX <= not HEX;
process(INV_HEX)
begin
case INV_HEX is
when “0000” => SEG <= “11000000”;
{中略}
when others => SEG <= “XXXXXXXX”;
end case;
end process;
end RTL;
7セグメントデコーダの動作確認


入力データHEXをデータスイッチ3~0に,7
セグメントLEDの信号SEGを拡張コネクタ
(セグメント記号とピン対応表を参照)に接
続する.
回路を評価ボード上のFPGAにダウンロー
ドし,動作を確認する.

HEXを“0000”から“1111”に変化させ, 7セグ
メントLEDが16進数0からFを正しく表示して
いるか?
セグメント記号とピン対応表
LED左
LED右
セグメント
a
b
ピン
P84
P83
セグメント
a
b
ピン
P55
P54
c
d
e
P82
P81
P80
c
d
e
P45
P47
P53
f
g
d.p.
P93
P86
P87
f
g
d.p.
P56
P46
P44
7セグメントLED2桁表示の構成
U0 : port map
HEX1
HEX SEVEN_SEG SEG
_DECODER
SEG1
U1 : port map
HEX2
HEX SEVEN_SEG SEG
_DECODER
SEVEN_SEG2
SEG2
7セグメントLEDの2桁表示
library IEEE;
use IEEE.std_logic_1164.all;
entity SEVEN_SEG2 is
port (HEX1 : in std_logic_vector(3 downto 0);
HEX2 : in std_logic_vector(3 downto 0);
SEG1 : out std_logic_vector(7 downto 0);
SEG2 : out std_logic_vector(7 downto 0));
end SEVEN_SEG2;
7セグメントLED_2の構造化記述
architecture RTL of SEVEN_SEG2 is
component SEVEN_SEG_DECODER
-- 下位のエンティティ宣言と同じ
port (HEX : in std_logic_vector(3 downto 0);
SEG : out std_logic_vector(7 downto 0));
end component;
begin
U0 : SEVEN_SEG_DECODER port map (HEX1,SEG1);
U1 : SEVEN_SEG_DECODER port map (HEX2,SEG2);
end RTL;
7セグメントデコーダ
library IEEE;
use IEEE.std_logic_1164.all;
entity SEVEN_SEG_DECODER is
port (HEX : in std_logic_vector(3 downto 0);
SEG : out std_logic_vector(7 downto 0));
end SEVEN_SEG_DECODER;
7セグメントLEDのデコーダ
architecture RTL of SEVEN_SEG_DECODER is
begin
process(HEX)
begin
case HEX is
when “0000” => SEG <= “11000000”;
{中略}
when others => SEG <= “XXXXXXXX”;
end case;
end process;
end RTL;
Project ⇒ Add Copy of Source
ALUの設計

算術演算,論理演算,シフト,ローテイト命
令を実現する.





ADD
XOR
SHRA
RL
ACC,MR
ACC,MR
ACC
ACC
(右算術シフト)
(左ローテイト)
フラグを設定する.

ZF(ゼロフラグ),SF(サインフラグ),CF(キャ
リーフラグ)をセットする.
4ビットALU
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity ALU4 is
port (
ACC,MR : in std_logic_vector(3 downto
0);
CODE : in std_logic_vector(1 downto 0);
DOUT : out std_logic_vector(3 downto 0);
ZF,SF,CF : out std_logic);
end ALU4;
architecture RTL of ALU4 is
signal TMP : std_logic_vector(4 downto 0);
-- キャリー出力ビットを付加
begin
process(ACC,MR,CODE)
begin
if (CODE = “00”) then
TMP <= (‘0’ & ACC) + (‘0’ & MR);
elsif (CODE = “01”) then
TMP <= (‘0’ & ACC) xor (‘0’ & MR);
elsif (CODE = “10”) then
TMP <= ACC(0) & ACC(3) & ACC(3 downto 1);
else
TMP <= ACC(3 downto 0) & ACC(3);
end if;
end process;
DOUT <= TMP(3 downto 0);
-- flag set
CF <= TMP(4);
SF <= TMP(3);
ZF <= not (TMP(3) or TMP(2) or TMP(1) or TMP(0));
end RTL;
-- RTレベルによるZFのセット
process(TMP)
begin
if (TMP(3 downto 0) = 0) then
ZF <= ‘1’;
else
ZF <= ‘0’;
end if;
end process;
4ビットALUの動作確認


ACCとMRをデータスイッチ7~4と3~0,
CODEをBREAK,STEPスイッチに,DOUTを
アドレスLED 3~0,フラグZF,SF,CFをZ
LED,S LED,C LEDに接続する.
回路を評価ボード上のFPGAにダウンロー
ドし,動作を確認する.

ACCとMRに適当な値をセットし,CODEを変化
させて,それぞれの演算結果とフラグの状態
がDOUTとZF,SF,CFに正しく求められている
か?
課題

次のシフト,ローテイト命令の操作をVHDL
で記述する.




SHRL ACC
SHLL ACC
RR
ACC
(右論理シフト)
(左論理シフト)
(右ローテイト)
次のフラグ設定を-- flag setの部分に
VHDLで記述する.

PF(パリティフラグ)

偶数パリティとする.
architecture RTL of ALU4 is
signal TMP : std_logic_vector(4 downto 0);
begin
process(ACC,MR,CODE)
begin
-- SHRL
ACC
TMP <= ACC(0) & ‘0’ & ACC(3 downto 1);
-- SHLL
ACC
TMP <= ACC(3 downto 0) & ‘0’;
-- RR
ACC
TMP <= ACC(0) & ACC(0) & ACC(3 downto 1);
end process;
DOUT <= TMP(3 downto 0);
-- flag set
PF <= not (TMP(3) xor TMP(2) xor TMP(1) xor
TMP(0));
ステートマシンのモデル
RESET=‘1
’
S0
OUT=“00”
A=‘1’
S1
OUT=“01”
B=‘1’
S3
OUT=“11”
S2
OUT=“10”
ステートマシンのモデル
library IEEE;
use IEEE.std_logic_1164.all;
entity STATE_MACHINE is
port ( RESET : in std_logic;
A,B : in std_logic;
OUT : out std_logic_vector(1 downto 0));
end STATE_MACHINE;
architecture RTL of STATE_MACHINE is
signal STATE : std_logic_vector(1 downto 0);
-- 4状態
begin
process(CLK,RESET)
begin
if (RESET = ‘1’) then
STATE <= “00”;
elsif (CLK’event and CLK = ‘1’) then
-- 状態遷移
case STATE is
when “00” =>
if (A = ‘1’) then
STATE <= “01”;
else STATE <= “00”;
end if;
when “01” =>
if (B = ‘1’) then
STATE <= “11”;
else STATE <= “10”;
end if;
when “10” =>
STATE <= “11”;
when “11” =>
STATE <= “00”;
when others =>
STATE <= “XX”;
end case;
end if;
end process;
-- 各状態時の出力信号
process(STATE)
begin
case STATE is
when “00” => OUT <= “00”;
when “01” => OUT <= “01”;
when “10” => OUT <= “10”;
when “11” => OUT <= “11”;
when others => OUT <= “XX”;
end case;
end process;
end RTL;
ステートマシンの設計
RESET=‘1
’
S0
OUT=“0000”
S1
OUT=“0001”
S2
OUT=“0010”
A=‘1’
B=‘1’
S4
OUT=“1000”
S3
OUT=“0100”
状態の遷移
RESET=‘1
’
S0
OUT=“0000”
S1
OUT=“0001”
S2
OUT=“0010”
S4
OUT=“1000”
S3
OUT=“0100”
状態の遷移(A=1)
RESET=‘1
’
S0
OUT=“0000”
S1
OUT=“0001”
S2
OUT=“0010”
A=‘1’
S4
OUT=“1000”
状態の遷移(B=1)
RESET=‘1
’
S0
OUT=“0000”
S1
OUT=“0001”
S2
OUT=“0010”
B=‘1’
S3
OUT=“0100”
1秒で動くステートマシンの構成
RESET
A
B
U : port map
CLK_2M
CLK
ステートマシン
CLK_1
STATE_MACHINE
OUT
ステートマシン
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity STATE_MACHINE is
port ( CLK_2M,RESET : in std_logic;
A,B : in std_logic;
OUT : out std_logic_vector(3 downto 0));
end STATE_MACHINE;
architecture RTL of STATE_MACHINE is
component CLK
port ( CLK_2M : in std_logic;
CLK_1 : out std_logic);
end component;
signal STATE : std_logic_vector(2 downto 0);
-- 5状態
signal CLK_1 : std_logic;
begin
U : CLK port map (CLK_2M,CLK_1);
process(CLK_1,RESET)
begin
if (RESET = ‘0’) then
STATE <= “000”;
elsif (CLK_1’event and CLK_1 = ‘1’) then
-- 状態遷移
case STATE is
when “000” =>
STATE <= “001”;
when “001” =>
STATE <= “010”;
when “010” =>
if (A = ‘1’) then
STATE <= “100”;
else STATE <= “011”;
end if;
when “011” =>
if (B = ‘1’) then
STATE <= “001”;
else STATE <= “100”;
end if;
when “100” =>
STATE <= “001”;
when others =>
STATE <= “XXX”;
end case;
end if;
end process;
-- 各状態時の出力信号
process(STATE)
begin
case STATE is
when “000” =>
OUT <= “0000”;
when “001” =>
OUT <= “0001”;
when “010” =>
OUT <= “0010”;
when “011” =>
OUT <= “0100”;
when “100” =>
OUT <= “1000”;
when others =>
OUT <= “XXXX”;
end case;
end process;
end RTL;
Project ⇒ Add Copy of Source
ステートマシンのI/Oピンの接続

CLK_2Mを2.4576MHz CLK(P91),RESET
をRESETスイッチ(P97),AとBをINCAス
イッチとDECAスイッチ(いすれも押しボタン
スイッチで,スイッチオン=‘1’であるP8,
P10)に,OUTをアドレスLED 3~0に接続す
る.
ステートマシンの動作確認

回路を評価ボード上のFPGAにダウンロー
ドし,動作を確認する.



RESET後,状態がS1,S2,S3,S4を繰返しな
がら遷移し,OUTのアドレスLEDがA0,A1,A2,
A3と表示しているか?
Aスイッチを押していると,S1,S2,S4と状態が
遷移しているか?
Bスイッチを押していると,S1,S2,S3と状態が
遷移しているか?
課題:ステートマシンの設計
RESET=‘1
’
S0
CNT = 0
DEC=‘1’
S2
CNT DEC
INC=‘1’
DEC=‘1’
INC=‘1’
S1
CNT INC
ステートマシン
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity STATE_MACHINE is
port ( CLK_2M,RESET : in std_logic;
INC,DEC : in std_logic;
OUT : out std_logic_vector(3 downto 0));
end STATE_MACHINE;
architecture RTL of STATE_MACHINE is
component CLK
port ( CLK_2M : in std_logic;
CLK_1 : out std_logic);
end component;
signal STATE : std_logic_vector(1 downto 0);
signal CNT_IN : std_logic_vector(3 downto 0);
signal CLK_1 : std_logic;
begin
U : CLK port map (CLK_2M,CLK_1);
process(CLK_1,RESET)
begin
if (RESET = ‘0’) then
STATE <= “00”;
elsif (CLK_1’event and CLK_1 = ‘1’) then
case STATE is
when “00” =>
if (INC = ‘1’) then
STATE <= “01”;
elsif (DEC = ‘1’) then
STATE <= “10”;
else
STATE <= “00”;
end if;
when “01” =>
if (DEC = ‘1’) then
STATE <= “10”;
else STATE <= “01”;
end if;
when “10” =>
if (INC = ‘1’) then
STATE <= “01”;
else STATE <= “10”;
end if;
when others =>
STATE <= “XX”;
end case;
end if;
end process;
OUT <= CNT_IN;
process(CLK_1,STATE)
begin
if (CLK_1’event and CLK_1 = ‘1’) then
case STATE is
when “00” =>
CNT_IN <= “0000”;
when “01” =>
CNT_IN <= CNT_IN +‘1’;
when “10” =>
CNT_IN <= CNT_IN - ‘1’;
when others =>
CNT_IN <= “XXXX”;
end case;
end if;
end process;
end RTL;
自由課題


班番号,班員
タイトル




特徴
機能
概略構成
設計分担