差し替え版 第 7 回マイクロプロセッサの VHDL 記述 マイクロプロセッサ全体および主要な内部ユニットの,VHDL 記述の例を示す. 1)MPU(Micro Processor Uit) Module 1MPU のエンティティ記述とコントローラの例以下は, 簡単な MPU の VHDL 記述の例である ただし, アーキテクチャ部分は, 命令読み込みと実行の状態遷移のみを実現したステートマシンである このままでプロセッサが作れるわけではないことに注意 リスト 7-1 プロセッサの VHDL 記述 RESET= 0 use IEEE.std_logic_usiged.all; etity MPU is port( CLK, RESET : i std_logic; -- クロックとリセット信号 A_BUS : out std_logic_vector(7 dowto 0 -- アドレス バス D_BUS : iout std_logic_vector(7 dowto 0 -- データ バス MR, MW : out std_logic ed MPU; -- 制御 バス RESET= 1 Idle Fetch Executio アイドル RESET= 1 メ ツ 命令フェッチ メモリリードイネーブル信号 MR= 0 に して命令をレジスタ IR にリード 命令実行 命令を実行し, 演算結果をメモリにライト するため MW= 0 に 次の命令をフェッチするため PC を +1 architecture RTL of MPU is sigal PC, IR : std_logic_vector(7 dowto 0 -- プログラム カウンタと命令レジスタ type type_state is (Idle, Fetch, Executio -- プロセッサの状態を表すデータ型を宣言 sigal state : type_state; -- state という状態を表わす信号を宣言 process(clk, RESET) -- プログラム カウンタ (PC) をプロセス文で記述 if (RESET = '0') the -- RESET=0 でリセット PC <= (others => '0' -- リセットがかかれば PC をゼロクリア elsif (CLK'evet ad CLK = '1') the -- クロック立上りで動作 if (state = Executio) the -- 実行 (Executio) 状態では, PC <= PC + 1; -- PC を1 増加, process(clk, RESET) if (RESET = '0') the state <= Idle; elsif (CLK'evet ad CLK = '1') the case state is whe Idle => if (RESET = '1') the state <= Fetch; -- プロセッサの状態を制御する回路をプロセス文で記述 -- リセットがかかったら, 待機 (Idle) 状態に -- 各状態での動作を whe 構文で記述 -- Idle 状態 -- RESET がかかっていなければ Fetch 状態に whe Fetch => -- Fetch 状態 IR <= D_BUS; --データバスのデータを命令レジスタ(IR) に入力 state <= Executio; -- 実行 (Executio) 状態に移行 whe Executio => -- Executio 状態 -- Executio Logic -- 命令実行用の回路を記述する ( ここでは省略 ) state <= Fetch; -- 命令実行が終わったら,Fetch 状態に移行 whe others => -- 上記以外の状態 state<=idle; ed case; A_BUS <= PC; 実行中は次に実行する命令の番地を指している 1 -- PC の内容はアドレス バスに接続 --メモリアクセス信号出力用マルチプレクサ MR <= '0' whe (state = Fetch) else -- メモリ リード (MR) は Fetch の際は 0 にする '1'; -- ( アクティブ ロー ) MW <= '0' whe (state = Executio) else -- メモリ ライト (MW) は Executio の際は 0 にする '1'; -- ( アクティブ ロー ) マイクロプロセッサとインタフェース講義資料 7-1
2ALU 以下はデータ幅 4ビットの ALU の例 加算, 減算,AND,OR の4つの演算を実行する 実際のプロセッサの ALU は, もっと多種類の演算が可能 リスト 7-2 ALU の VHDL 記述 M use IEEE.STD_LOGIC_1164.ALL; 00 : 加算 use IEEE.STD_LOGIC_ARITH.ALL; 01 : 減算 use IEEE.STD_LOGIC_SIGNED.ALL; M etity ALU4 is 10 : AND 4 2 11 : OR A, B : i std_logic_vector(3 dowto 0 -- データ入力 (4bit) A 1 M : i std_logic_vector(1 dowto 0 -- 制御入力 (2bit) S O : out std_logic_vector(3 dowto 0 -- 出力 (4bit) 4 ALU S : out std_logic -- 符号出力 (1bit) O 4 ed ALU4; B architecture RTL of ALU4 is sigal alu : std_logic_vector(4 dowto 0 -- ALU 内部データ (5bit に拡張 ) alu <= (A(3) & A) + (B(3) & B) whe (M = "00") else -- bit 拡張後に符号付き加算 (A(3) & A) - (B(3) & B) whe (M = "01") else -- bit 拡張後に符号付き減算 ('0' & A) ad ('0' & B) whe (M = "10") else -- AND 演算 ('0' & A) or ('0' & B O <= alu(3 dowto 0 S <= alu(4 -- OR 演算 演習問題 1. リスト 7-2 の ALU に 1~3 のデータを入力した時の出力信号 O 及び S を,ALU 制御信号 M の全ての組み 合わせに対して求めよ 1 A=0101,B=0001 2 A=1001,B=0010 3 A=1011,B=1101 解答欄 1 例 )A=0011,B=1111 のとき 00 0010 0 01 0100 0 10 0011 0 11 1111 0 2 3 7-2 マイクロプロセッサとインタフェース講義資料
2.ALU の VHDL 記述を,8 ビットデータ用に書き直せ ( 変更箇所のみ示すこと ) etity ALU8 is A, B : i std_logic_vector(7 dowto 0 -- データ入力 (8bit) M : i std_logic_vector(1 dowto 0 -- 制御入力 (2bit) O : out std_logic_vector(7 dowto 0 -- 出力 (8bit) S : out std_logic ed ALU8; -- 符号出力 (1bit) architecture RTL of ALU8 is sigal alu : std_logic_vector(8 dowto 0 -- ALU 内部データ (9bit に拡張 ) alu <= (A(7) & A) + (B(7) & B) whe (M = "00") else -- bit 拡張後に符号付き加算 (A(7) & A) - (B(7) & B) whe (M = "01") else -- bit 拡張後に符号付き減算 ('0' & A) ad ('0' & B) whe (M = "10") else -- AND 演算 ('0' & A) or ('0' & B O <= alu(7 dowto 0 S <= alu(8 -- OR 演算 3.[ 宿題 ] 2 つの ビットのデータに, 加減算や乗算などの演算を施すと, その結果は ビットには収まりきれないことがある そこで,ALU 内部では, 演算の前にデータのビット数を増やす これがビット拡張である なぜリスト 7-2 のような操作をしているか考察せよ 3N ビットレジスタ N ビット幅のレジスタ この回路記述は geeric 宣言を用いていて, サブルーチンのように呼び出して使 える 呼び出す側の回路でデータ幅 N を指定する 何も指定しない場合,N=8 とする リスト 7-3 N ビットレジスタ -- Auto-geerated module template: RegN -- etity RegN is geeric (N : iteger := 8 -- geeric 宣言, デフォルト値として N=8 CLK, EN : i std_logic; R : i std_logic_vector(n-1 dowto 0 Q : out std_logic_vector(n-1 dowto 0) ed RegN; architecture RTL of RegN is process(clk) if (CLK'evet ad CLK = '1') the if (EN = '1') the Q <= R; マイクロプロセッサとインタフェース講義資料 7-3
4 レジスタファイル N ビットレジスタが 2 M 個セットになったもの M ビットのアドレス入力により 1 つのレジスタを選択する リスト 7-4 レジスタファイル -- Auto-geerated module template: RegNxM use IEEE.std_logic_usiged.all; etity RegNxM is geeric (N : iteger := 8; M : iteger := 8-- geeric 宣言 ed RegNxM; CLK, WR : i std_logic; -- クロックと WR( 書込み ) 信号 A : i std_logic_vector(m-1 dowto 0 -- アドレス入力 (M bit) R : i std_logic_vector(n-1 dowto 0 -- データ入力 (N bit) Q : out std_logic_vector(n-1 dowto 0) -- データ出力 (N bit) architecture RTL of RegNxM is subtype REG is std_logic_vector(n-1 dowto 0 -- Nbit レジスタを REG とタイプ宣言 type ARRAY_REGS is array (0 to 2**M-1) of REG; -- 2 の M 乗個の REG sigal regfile : ARRAY_REGS; Q <= regfile(cov_iteger(a) -- Read, A を cov_iteger により整数に変換している process(clk) -- レジスタ動作のプロセス文による記述 if (CLK'evet ad CLK = '1') the if (WR = '1') the -- Write regfile(cov_iteger(a)) <= R; 5 プログラム カウンタ (re-loadable) プログラム カウンタ (PC) は, プロセッサが読み込む命令符号が格納されている番地を指定する 以下のリスト 7-5 では, リスト 7-1 の記述と異なり,LOAD 信号により PC の内容を上書きできるようになっている リスト 7-5 プログラム カウンタ -- Auto-geerated module template: PC use IEEE.std_logic_usiged.all; etity PC is geeric (N : iteger := 8 CLK, RESET, LOAD : i std_logic; D : i std_logic_vector(n-1 dowto 0 C : out std_logic_vector(n-1 dowto 0) ed PC; architecture RTL of PC is sigal cout : std_logic_vector(n-1 dowto 0 process(clk, RESET) if (RESET = '0') the cout <= (others => '0' elsif (CLK'evet ad CLK = '1') the if (LOAD = '0') the cout <= D; --LOAD= 0 のとき外部信号 D の値を PC にセット else cout <= cout + '1'; C <= cout; A W R R CLK N M 0 1 2 3 4 5 6 7 アドレス指定によりアクセス可能なレジスタ群 N Q 7-4 マイクロプロセッサとインタフェース講義資料
演習問題の解答例 1. リスト 7-2 の ALU に 1~3 のデータを入力した時の出力信号 O 及び S を,ALU 制御信号 M の全ての組み 合わせに対して求めよ 1 A=0101,B=0001 2 A=1001,B=0010 3 A=1011,B=1101 解答欄 1 A = 0101, B = 0001 00 1000 1 M=00( 加算 ): 1 1011 M=01( 減算 ): + 1 1101 01 1110 1 11 1000 10 1001 0 M=10(AND): 0 1011 M=11(OR): 11 1111 0 0 1101 0 1001 2.ALU の VHDL 記述を,8 ビットデータ用に書き直せ ( 変更箇所のみ示すこと ) リスト全体を示す コメント,etity 名,architecture 名などは合成される回路機能には関係ない etity ALU8 is A, B : i std_logic_vector(7 dowto 0 -- データ入力 (8bit) M : i std_logic_vector(1 dowto 0 O : out std_logic_vector(7 dowto 0 S : out std_logic ed ALU8; 00 0110 0 01 0100 0 10 0001 0 11 0101 0 2 A = 1001, B = 0010 00 1011 1 01 0111 1 10 0000 0 11 1011 0 3 A = 1011, B = 1101 -- 制御入力 (2bit) -- 出力 (8bit) -- 符号出力 (1bit) 例 )A=0011,B=1111 のとき 00 0010 0 01 0100 0 10 0011 0 11 1111 0 ビット拡張 A E = 0 0101, B E = 0 0001,B E の 2 の補数 :1 1111 M=00( 加算 ): 0 0101 M=01( 減算 ): + 0 0001 0 0110 M=10(AND): 0 0101 M=11(OR): 0 0001 0 0001 0 0101 + 1 1111 10 0100 0 0101 0 0001 0 0101 ビット拡張 A E = 1 1001, B E = 0 0010,B E の 2 の補数 :1 1110 M=00( 加算 ): 1 1001 M=01( 減算 ): + 0 0010 1 1011 M=10(AND): 0 1001 M=11(OR): 0 0010 0 0000 1 1001 + 1 1110 11 0111 0 1001 0 0010 0 1011 ビット拡張 A E = 1 1011, B E = 1 1101,B E の 2 の補数 :0 0011 1 1011 + 0 0011 1 1110 0 1011 0 1101 0 1111 architecture RTL of ALU8 is sigal alu : std_logic_vector(8 dowto 0 -- ALU 内部データ (9bit に拡張 ) alu <= (A(7) & A) + (B(7) & B) whe (M = "00") else (A(7) & A) - (B(7) & B) whe (M = "01") else ('0' & A) ad ('0' & B) whe (M = "10") else ('0' & A) or ('0' & B O <= alu(7 dowto 0 S <= alu(8 -- bit 拡張後に符号付き加算 -- bit 拡張後に符号付き減算 -- AND 演算 -- OR 演算 マイクロプロセッサとインタフェース講義資料 7-5
3.[ 宿題 ] 2 つの ビットのデータに, 加減算や乗算などの演算を施すと, その結果は ビットには収まりきれないことがある そこで,ALU 内部では, 演算の前にデータのビット数を増やす これがビット拡張である なぜリスト 7-2 のような操作をしているか考察せよ 解説ビット拡張では, もとの数値データの MSB(2 進数として考えたときの最も大きな桁 : 最上位ビット ) を拡張したいビット数分だけ並べたものを, データの上位に追加する これにより, もとのデータと同じ数値を表すデータが得られる 例 (4 ビットを 8 ビットに拡張 ):0100 0000 0100, 1011 1111 1011 今, ビットのデータが整数を表しているとしよう これを + m ビットに拡張する場合, 元のデータの MSB を v ビット並べたものをデータの頭に結合する この操作により, 元のデータの整数値を保ったままデータ幅が拡張される データを D 1D 2 D0 とし, 場合分けして考えると, ⅰ) データが正のとき D 1 = 0 であり, 表している整数値は, D 1 2 + D 2 + + D1 (1) これをビット拡張した, 00 0DD 2 D0 も,0 を加えているだけだから, 同じ値を表している ⅱ) データが負のとき D = 1 であり, 表している整数値は, D 2 + D 2 + + D1 2 (2) これをビット拡張した, 11 1D 1D D0 が表している整数値は, + m 1 + m 2 2 2 + + 2 + D 2 + D 2 + + D1 + 2 (3) である この式を変形していくと, m m 1 m 2 1 0 = D 2 + D 2 + + D 2 + D 2 (2 2 2 1) (4) 1 2 + D 2 + + D1 = D 2 (5) となり, ビットのときと同じ値を表していることがわかる ( ここで, 2 = (2 + 2 + + 1) + 1よ m m 1 り, 2 2 2 1 = 1 であることを用いた ) 2の補数について : ビットで整数を表す場合, 負の数の表現には, 2の補数 を用いる ( 正式には 2 の補数 と呼ぶべきものである ) x の 2の補数 とは 2 x のこと ( x と加算すると 2 になる数のこと ) + m m m 1 m 2 負の数 a を 2 a で表す MSB=0 のときは, そのままの2 進数, MSB=1 のときは その ままの2 進数 - 2 を表している = ( 2 8 = 256 ),-20 を 2 8 20 の2 進数で表す 例 : 8 のとき 2 の補数は ビット反転して 1 を加算 操作で求まる! ある整数 x の符号を反転する場合も,2 の補数 = 2 x を求める 補数 足りない分で負数を表現 2 の補数を使うと減算が加算と同じ方法でできる! 2の補数を用いる整数表現で加減算を行う場合, + 1 ビット目への桁上げは無視する ( ただし, 結果が ビットに収まる場合 ) 100 70 20-30 10 の補数 では 7-6 マイクロプロセッサとインタフェース講義資料