リスト 4-1 バイナリカウンタ
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity B_CNT is port( RST,CLK: in std_logic;Q: out std_logic_vector(3 downto 0) );
end B_CNT;
architecture Behavioral of B_CNT is signal CNT: std_logic_vector(3 downto 0); begin Q <= not CNT; process(RST,CLK) begin if RST = '0' then CNT <= (others => '0'); else
if CLK'event and CLK = '1' then if CNT = “1111” then CNT <= “0000”; else CNT <= CNT +1; end if; end if; end if; end process; end Behavioral;
第4回 VHDL 演習 2 プロセス文とステートマシン
プロセス文を用いるステートマシンの記述について学ぶ。
回路 6 バイナリカウンタ(Fig.4-1)
バイナリカウンタを設計し,クロック信号に同期して動作する同期式回路の動作を学ぶ。
ⅰ)リスト 4-1 のコードを理解してから,コンパイル,ダウンロードする。
ⅱ ) 実 験 基 板 上 の デ ィ ッ プ ス イ ッ チ を 用 い て , 発 生 す る ク ロ ッ ク 周 波 数 を 1 Hz に 指 定 す る 。
SW12(RESET)が RST の入力となる。LED の出力からカウンタの動作を確認せよ。
(
「情報科学実習Ⅱ・デジタルシステムの開発」の課題 7 とは,VHDL コードが若干異なる。)
■同期式回路の記述 クロック信号の立ち上がり時に動作する回路は,process 文の中で以下の様に記述するif クロック信号’event and クロック信号=’1’ then クロック信号立ち上がり時の動作を記述する文; end if; クロックの立ち下り時に動作する場合は’1’を’0’とする ■クロック周波数の指定 実験基盤では,基板上のディップスイッチで発生するク ロック周波数を変更することができる 周波数 1Hz の場合 SW3 ,SW4 を OFF, それ以外を ON
CLK
Q[3:0]
4
RST
4-Bit
Register
Increment
■std_logic_vector 型への全て同じ値の代入 std_logic_vector 型の信号に全て同じ値を代入したい場 合,以下の様に記述する 信号名 <= (others=>’値’); 記述を再利用する際など,ビット幅が変化しても記述を 変化させずに 0 を示す値などを代入することができる■if then else構文
if 条件 then 条件成立の時の処理
else 条件不成立の時の処理 ;
end if ;
二者択一の条件判断処理に使う
■if then else構文
if 条件 then 条件成立の時の処理
else 条件不成立の時の処理 ;
end if ;
二者択一の条件判断処理に使う
Fig4-1 バイナリカウンタ
■if then else構文 その2
if 条件1 then 条件1成立の時の処理 ;
elsif 条件2 条件2成立の時の処理 ;
elsif 条件3 条件3成立の時の処理 ;
・・・・・・・・・・・・・・
elsif 条件n 条件n成立の時の処理 ;
else 条件1~n 全て不成立の時の処理 ;
■if then else構文 その2
if 条件1 then 条件1成立の時の処理 ;
elsif 条件2 条件2成立の時の処理 ;
elsif 条件3 条件3成立の時の処理 ;
・・・・・・・・・・・・・・
elsif 条件n 条件n成立の時の処理 ;
else 条件1~n 全て不成立の時の処理 ;
入力データを保持するのに用いる記憶素子。使用用途として,マイクロプロセッサ内部で演算や実行
状態の保持に用いられる。Fig4-2 のレジスタは,クロック信号の立ち上がり時かつ EN 信号が’1’のとき
に外部からの 1 ビットデータ R をレジスタ内部に取り込み,後続のデータが取り込まれるまでレジスタ
内部状態を保持する。
Fig4-2 レジスタ
表 4-1 レジスタの状態遷移表
リスト 4-2 レジスタの VHDL コード
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity Register isport(CLK, EN, R, RST : in std_logic; Q : out std_logic
); end Register;
architecture Behavioral of Register is begin
process(CLK,RST) begin
if RST=’0’ then Q<=’0’;
elsif CLK’event and CLK=’1’ then if EN=’1’ then Q<=R; else Q<=Q; end if; end if; end process; end Behavioral;
R S T
C L K
E N
Q
0
×
×
0
1
↑
0
Q
1
↑
1
R
1
↑ 以 外
×
Q
R
EN
CLK
Q
Register
RST
クロック信号 CLK の立ち上がり時に
EN 信号が’1’であれば,外部信号 R を
取り込み,そうでなければ取り込んだ
値を保持する!
演習 1
リスト 4-3 に示す VHDL コードが示すハードウェアの回路図を完成させよ。
リスト 4-3 演習 4 のハードウェア
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity Hard is port ( CLK: in std_logic; RST: in std_logic; EN : in std_logic; D : in std_logic; SEL: in std_logic; Q0, Q1, Q2, Q3 : out std_logic); end Hard;architecture Behavioral of Hard is signal din, e, f, g, h, i : std_logic; begin
process(CLK,RST) -- register0 begin
if RST='0' then e<='0';
elsif CLK'event and CLK='1' then if EN='1' then e<=din; else e<=e; end if; end if; end process; process(CLK,RST) -- register1 begin if RST='0' then f<='0';
elsif CLK'event and CLK='1' then if EN='1' then f<=e; else f<=f; end if; end if; end process; process(CLK,RST) -- register2 begin if RST='0' then g<='0';
elsif CLK'event and CLK='1' then if EN='1' then g<=f; else g<=g; end if; end if; end process; process(CLK,RST) -- register3 begin if RST='0' then h<='0';
elsif CLK'event and CLK='1' then if EN='1' then h<=g; else h<=h; end if; end if; end process; process(SEL,D,i) -- multiplexer begin if SEL='1' then din <= D; else din <= i; end if; end process; i <= h; Q0 <= e; Q1 <= f; Q2 <= g; Q3 <= h; end Behavioral; Register0 SEL D RST EN CLK
Register1 Register2 Register3
R EN CLK Q R EN CLK Q R EN CLK Q R EN CLK Q i din
マルチプレクサ
h e f g 続くステートマシン(状態遷移回路)は,外部信号によって内部の状態が遷移する順序回路である。マイ
クロプロセッサ等の各種デジタルシステムに搭載されている制御回路はステートマシンで実現される。
回路8 ステートマシンを用いた 2 ビットのアップダウンカウンタ
リスト 4-4 ステートマシンを用いた 2 ビットの
アップダウンカウンタの VHDL コード
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity State_cnt isport ( CLK, UP_DOWN : in std_logic;
CNT : out std_logic_vector(1 downto 0) ); end State_cnt;
architecture RTL of State_cnt is
signal sel : std_logic_vector(1 downto 0); signal state : std_logic_vector(1 downto 0); begin
process(CLK) begin
if CLK'event and CLK='1' then case state is when "00" => if UP_DOWN='1' then state <="01"; else state <="11"; end if; when "01" => if UP_DOWN='1' then state <="10"; else state <="00"; end if; when "10" => if UP_DOWN='1' then state <="11"; else state <="01"; end if; when "11" => if UP_DOWN='1' then state <="00"; else state <="10"; end if; when others => state <="00"; end case; end if; end process; sel<= state; process(sel) begin case sel is when "00" => CNT<="00"; when "01" => CNT <="01"; when "10" => CNT <="10"; when "11" => CNT <="11"; when others=> CNT <="00"; end case; end process; end RTL;
00
01
10
11
CNT=3 を出力
CNT=2 を出力
CNT=1 を出力
CNT=0 を出力
UP_DOWN='1' UP_DOWN='1' UP_DOWN='1' UP_DOWN='0' UP_DOWN='0' UP_DOWN='0' UP_DOWN='0' UP_DOWN='1' 状態の値を保持するステートレジスタ これを操作してアップ/ダウン カウントを切り替えるFig4-4 リスト 4-4 の状態遷移図
状態に従って CNT に信号を出力する デコーダステートマシン
の記述
演習 2
Fig.4-5 はタイマーシステムの構成図である。このタイマーシステムは,1~8 までの数字キーを押し
て時間を設定した後 START ボタンを押すとカウントダウンが行われ残り時間が 7 セグメント LED に表示
される。設定時間が経過するとスピーカからアラーム音が鳴る。アラーム音は 10 回断続的に鳴るか STOP
ボタンを押すかで,鳴り止む。その後再度数字キーにより時間を設定後,START ボタンを押せばタイマ
ー機能が同様に繰り返される。また,RST ボタンを押すと全ての機能動作がリセットされる。
Fig.4-6 はタイマーシステムの内部構成である。その中の制御回路(State_timer)は周辺回路全体の制
御を行う。この制御回路を実現するためにステートマシン導入し,VHDL により設計した。制御回路の
VHDL コードをリスト 4-5 に示す。
タイマーの入出力信号の説明
CLK:外部から入力する基準クロック信号
[入力,1ビット]
VAL:数字キーインタフェースからの設置値入力
[入力,3ビット]
START:タイマーのスタートボタン入力
[入力,1ビット]
STOP:タイマーのストップボタン入力
[入力,1ビット]
RST:タイマーのリセットボタン入力
[入力,1ビット]
TIMER:タイマー表示出力
[出力,4ビット]
ALARM_EN:アラーム許可信号
[出力,1ビット]
(スピーカ回路は ALARM_EN=1 で鳴るように設計されている)
START STOP 1 2 3 4 5 6 7 8 RSTFig.4-5 タイマーシステム
制御回路(State_timer) CLK RST START STOP VAL TIMER ALARM_EN 数字キー 7 -S E G L E D D e c o d e r START STOP RST クロック 生成回路Fig.4-6 タイマーシステムの内部構成
Library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity State_timer is Port ( CLK : in std_logic; RST : in std_logic; START : in std_logic; STOP : in std_logic;
VAL : in std_logic_vector(2 downto 0); TIMER : out std_logic_vector(3 downto 0); ALARM_EN : out std_logic);
end State_timer;
architecture Behavioral of State_timer is
signal state : std_logic_vector(1 downto 0); signal t_cnt_en : std_logic;
signal t_cnt : std_logic_vector(2 downto 0); signal a_cnt_en : std_logic;
signal a_cnt : std_logic_vector(3 downto 0); signal rd_en : std_logic;
begin
process(CLK,RST) begin
if RST='1' then state<=(others=>'0');
elsif CLK'event and CLK='1' then case state is when "00" => if START='1' then state<="01"; else state<="00"; end if; when "01" => if t_cnt="000" then state<="10"; else state<="01"; end if; when "10" => if STOP='1' then state<="00"; else state<="11"; end if; when "11" =>
if STOP='1' or a_cnt="1001" then state<="00"; else state<="10"; end if; when others => state<="00"; end case; end process; process(CLK,rd_en,VAL) begin if rd_en='1' then t_cnt<=VAL;
elsif CLK'event and CLK='1' then if t_cnt_en='1' then if t_cnt="000" then t_cnt<=t_cnt; else t_cnt<=t_cnt-'1'; end if; else t_cnt<=t_cnt; end if; end if; end process;
rd_en <= '1' when state="00" else '0'; t_cnt_en<='1' when state="01" else '0'; TIMER <=t_cnt;
process(CLK,RST) begin
if RST='1' then
a_cnt<= (others=>'0'); elsif CLK'event and CLK='1' then
if a_cnt_en = '1' then if a_cnt = "1001" then a_cnt <= (others=>'0'); else a_cnt <= a_cnt+'1'; end if; else a_cnt <= a_cnt; end if; end if; end process;
a_cnt_en <='1' when state="11" else '0'; ALARM_EN<='1' when state="10" else '0'; end Behavioral;