設計順序について簡単に説明します.まず最初に各命令の動作を記述します. なお,状態フラグは命令の動作記述後にまとめて定義します.
では,命令の動作を設計していきましょう.命令の選択には, 選択信号代入文 を用います.演算結果は,先ほど宣言したTMPに格納されますから, 下のようになります.
with ALUの選択信号 select TMP <= 加算の動作 when 加算命令を実行する条件 . . . "00000000000000000" when others;
なお,算術論理演算回路に予期せぬ命令が来た場合は,算術論理演算回路の出 力は全てゼロになるように設計しています.回路規模を考慮するのならばある 命令(例えば,加算命令)を記述せずにothersでその動作を記述する方が好ま しいでしょう.
算術演算には, 加算(IADD), 減算(ISUB), インクリメント(IINC),及び デクリメント(IDEC) があります.先ほど 入出力インタフェースの定義 で std_logic_arithというパッケージを宣言したため, std_logicによる加減算を行うことができます.キャリー(減算時 はボロー)が必要なければ簡単ですが,キャリーが必要な場合,非演算数と演 算数のビット幅を演算結果のビット幅に合わせなければなりません.1ビット 拡張するためには, & (連結演算子) を用います.ですから,加算は以下のようになります.以下の記述方法を参考 に減算,インクリメント,及びデクリメントの動作も記述してみましょう.な お,減算のボローは,加算のキャリーと同じ記述方法でTMPの最上 位ビットに格納されます.
('0' & DATA_A) + ('0' & DATA_B)
1ビットの定数には'0'のようにシングルクオートでビットを囲み,ベクタの定 数には"000"のようにダブルクオートでビット列を囲みます.
('0' & DATA_A) + ('0' & "0000000000000000")
('0' & DATA_A) + "0"
論理演算には, 論理和(IOR), 論理積(IAND), 排他的論理和(IEOR),及び 補元(INOT) があります.先ほど 入出力インタフェースの定義 でstd_logic_1164というパッケージを宣言したため,std_logicによる論理演 算を行うことができます.ただし,論理演算子を使う場合,非演算数,演算数 及び演算結果のビット幅が全て一緒でなければなりません.算術演算でキャリ (減算時はボロー)が必要なため,TMPは17ビット幅で宣言してあ りますから,論理演算の演算結果とTMPのビット幅に合わせなけれ ばなりません.1ビット拡張するためには, & (連結演算子) を用います.ですから,論理和は以下のようになります.以下の記述方法を参 考に論理積,排他的論理和,及び補元の動作も記述してみましょう.
'0' & (DATA_A or DATA_B)
論理演算子 にはorの他に,and,xor,notがあります.
シフト演算 には, 論理左シフト(ILSL), 算術左シフト(IASL), 論理右シフト(ILSR),及び 算術右シフト(IASR) があります.先ほど 入出力インタフェースの定義 で説明したstd_logic_arithというパッケージには,バレルシフタのための演算子(SHL, SHR)が用意されていますが,KITE-1マイクロプロセッサのシフト演算は1ビット単位で行 うため,これらの演算子は利用せず算術演算で使用した & (連結演算子)を用いて設計します.つまり,論理左シフトは以下のようにな ります.以下の記述方法を参考に他のシフト命令も設計してみましょう.
DATA_A(15) & (DATA_A(14 downto 0) & '0')
回転演算には, 左回転(IROL), 右回転(IROR),及び バイトスワップ(ISWP) があります.先ほど 入出力インタフェースの定義 で説明したstd_logic_arithというパッケージには,バレルシフタのための演算子(SHL, SHR)が用意されていますが,KITE-1マイクロプロセッサの回転演算は1ビット 単位で行うため,これらの演算子は利用せず算術演算で使用した & (連結演算子)を用いて設計します.つまり,左回転は以下のようになります. 以下の記述方法を参考に他の回転命令も設計してみましょう.
DATA_A(15) & (DATA_A(14 downto 0) & DATA_A(15))
動作の定義が終了したらTMP(15 downto 0)をALUの出力ポートであ るに 信号代入文 を用いて出力しましょう.
完成しましたか? では,次に状態フラグの動作定義を行いましょう.