SFLで作るPICO-16プロセッサ/第1回
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
[[SFLで作るPICO-16プロセッサ]]
*ALUの設計 [#bc8b64df]
まずは簡単な回路で、シミュレーションまでの流れを覚えましょう。
今回設計するALUは2つの16ビットの入力を用いて、論理積(AND)、論理和(OR)、排他的論理和(XOR)、論理否定(NOT)、加算(ADD)、減算(SUB)、左シフト(SHL)、右シフト(SHR)の演算をサポートします。~
PICO-16プロセッサに必要な演算は、全てこのALUに実装された8種類の演算を用いて実現することができます。
**コンテンツ [#f5a16f16]
#contents
*仕様 [#ja205ed0]
今回設計するALUの仕様を確認します。
CENTER:&ref(alu.png);
**入出力 [#ke3c761e]
-入力
--演算対象のデータ1(16ビット)
--演算対象のデータ2(16ビット)
-出力
--演算結果(16ビット)
**機能 [#te6015fe]
今回実装する機能は全部で8つあります。
|機能|意味|動作|
|AND|論理積|out = in1 & in2|
|OR|論理和|out = in1 | in2|
|XOR|排他的論理和|out = in1 @ in2|
|NOT|論理否定|out = ^in2|
|ADD|加算|out = in1 + in2|
|SUB|減算|out = in1 + in2|
|SHL|左シフト(SHift Left)|out = in2 << 1|
|SHR|右シフト(SHift Right)|out = in2 >> 1|
AND、OR、XOR、ADD、SUBの命令はin1とin2を使って演算を行いますが、NOT、SHL、SHRはin2だけを使って演算を行います。
*実装 [#wf985494]
ファイル名はalu.sfl及び、alu.hとします。
**ヘッダ [#f6156165]
ヘッダには、ALUの入出力と制御入出力、制御入力の仮引数を定義する必要があります。
これらの情報は全て仕様定義で明らかになっているので、以下のように書くことができます。
declare alu {
input in1<16>;
input in2<16>;
output out<16>;
instrin AND;
instrin OR;
instrin XOR;
instrin NOT;
instrin ADD;
instrin SUB;
instrin SHL;
instrin SHR;
instr_arg AND(in1, in2);
instr_arg OR (in1, in2);
instr_arg XOR(in1, in2);
instr_arg NOT(in2);
instr_arg ADD(in1, in2);
instr_arg SUB(in1, in2);
instr_arg SHL(in2);
instr_arg SHR(in2);
}
ヘッダは既に完成しているので、alu.hの内容としてコピーして保存してください。
**モジュール [#m6c3910a]
モジュールには、ALUの入出力、制御入出力、動作を記述する必要があります。
スケルトンを用意しました。入出力と制御入力は仕様定義やヘッダで既に決まっているので、以下のような記述になります。~
足りない部分は各制御入力に対応する動作なので、正しく動作するように該当部分を記述してください。
module alu {
input in1<16>;
input in2<16>;
output out<16>;
instrin AND;
instrin OR;
instrin XOR;
instrin NOT;
instrin ADD;
instrin SUB;
instrin SHL;
instrin SHR;
instruct AND /* ここに動作を記述する */
instruct OR /* ここに動作を記述する */
instruct XOR /* ここに動作を記述する */
instruct NOT /* ここに動作を記述する */
instruct ADD /* ここに動作を記述する */
instruct SUB /* ここに動作を記述する */
instruct SHL /* ここに動作を記述する */
instruct SHR /* ここに動作を記述する */
}
SFLで使える演算子の動作を復習しましょう。
*論理シミュレーション [#yd146ba7]
回路が正しく動作しているかどうかを確認します。
+&ref(ex01.tar.gz);をダウンロードする。~
~
解凍方法)
% tar zxvf ex01.tar.gz
+alu.h、alu.sflを作成し、ex01ディレクトリに入れる。
--alu.hは、[[ここ>#f6156165]]から内容をコピーする。
--alu.sflは、[[ここ>#m6c3910a]]から内容をコピーして、記述を完成させる。
+シミュレーションを行う。
--シミュレーションには次のコマンドを使います。
% make
もしくは、
% make sim
--シミュレーションの結果はsim.logに出力されます。正しく動作していると&ref(sim.log.txt);のようになります。
--余裕があればテストベンチを自由に改変してみましょう。
+波形を観察する。
--波形ビューワの起動には次のコマンドを使います。
% make wave
--
+ファイルをクリーンする。
--ファイルのクリーンには次のコマンドを使います。
% make clean
--シミュレーションや波形ビューワで生成されたファイルのサイズが大きいときもあるので、全て終わったら余計なファイルを削除しておきましょう。
**シミュレーション結果 [#o1a30298]
正しく動作していれば、次のような結果が出ます。16進数同士の計算の確認にはgcalctoolを起動後に"Control + S"で科学計算モードにして使うと便利です。
|演算の種類|in1|in2|out|
|AND|0f0f|f0f0|0000|
|~|f0f0|0f0f|0000|
|~|ffff|ffff|ffff|
|~|d8a3|b8d4|9880|
|~|63b9|d6f2|42b0|
|OR|0f0f|f0f0|ffff|
|~|f0f0|0f0f|ffff|
|~|ffff|ffff|ffff|
|~|d8a3|b8d4|f8f7|
|~|63b9|d6f2|f7fb|
|XOR|0f0f|f0f0|ffff|
|~|f0f0|0f0f|ffff|
|~|ffff|ffff|0000|
|~|d8a3|b8d4|6077|
|~|63b9|d6f2|b54b|
|NOT|0000|f0f0|0f0f|
|~|0000|0f0f|f0f0|
|~|0000|ffff|0000|
|~|0000|b8d4|472b|
|~|0000|d6f2|290d|
|ADD|0f0f|f0f0|ffff|
|~|f0f0|0f0f|ffff|
|~|ffff|ffff|fffe|
|~|d8a3|b8d4|9177|
|~|63b9|d6f2|3aab|
|SUB|0f0f|f0f0|1e1f|
|~|f0f0|0f0f|e1e1|
|~|ffff|ffff|0000|
|~|d8a3|b8d4|1fcf|
|~|63b9|d6f2|8cc7|
|SHL|0000|f0f0|e1e0|
|~|0000|0f0f|1e1e|
|~|0000|ffff|fffe|
|~|0000|b8d4|71a8|
|~|0000|d6f2|ade4|
|SHR|0000|f0f0|7878|
|~|0000|0f0f|0787|
|~|0000|ffff|7fff|
|~|0000|b8d4|5c6a|
|~|0000|d6f2|6b79|
**テストベンチ [#u47f87b1]
配布したテストベンチは、ALUの各演算が簡単にできるようにtask(C言語でいう関数によく似た構文)を用いた記述を採用してます。~
今回のテストベンチで使っているtaskは全部で8つあり、これにテストデータを渡すとALUのテストが行えます。
-do_and~
論理積(AND)のテストを行います。演算する2つのデータを渡します。~
~
使用例)
do_and(16'hd8a3, 16'hb8d4);
do_and(16'h63b9, 16'hd6f2);
-do_or~
論理和(OR)のテストを行います。演算する2つのデータを渡します。~
~
使用例)
do_or(16'hd8a3, 16'hb8d4);
do_or(16'h63b9, 16'hd6f2);
-do_xor~
排他的論理和(XOR)のテストを行います。演算する2つのデータを渡します。~
~
使用例)
do_xor(16'hd8a3, 16'hb8d4);
do_xor(16'h63b9, 16'hd6f2);
-do_not~
論理否定(NOT)のテストを行います。演算する1つのデータを渡します。~
~
使用例)
do_not(16'hb8d4);
do_not(16'hd6f2);
-do_add~
加算(ADD)のテストを行います。演算する2つのデータを渡します。~
~
使用例)
do_add(16'hd8a3, 16'hb8d4);
do_add(16'h63b9, 16'hd6f2);
-do_sub~
減算(SUB)のテストを行います。演算する2つのデータを渡します。~
~
使用例)
do_sub(16'hd8a3, 16'hb8d4);
do_sub(16'h63b9, 16'hd6f2);
-do_shl~
左シフト(SHL)のテストを行います。演算する1つのデータを渡します。~
~
使用例)
do_shl(16'hb8d4);
do_shl(16'hd6f2);
-do_shr~
右シフト(SHR)のテストを行います。演算する1つのデータを渡します。~
~
使用例)
do_shr(16'hb8d4);
do_shr(16'hd6f2);
これらのtaskを使ってシミュレーションのデータを用意しているのがtestbench.vです。ファイルの後半にinitial beginで始まりendで終わるブロックで実際にこれらのタスクを使用しています。
*ヒントと豆知識 [#hbb9c950]
ここでは、今回の演習に関わる豆知識やヒントを紹介します。
**SFLで使用可能な演算子 [#vc685100]
PARTHENONで合成するために一部の演算子は制限が設けられていますが、今回は気にしなくても良いです。
|優先度|演算子|機能|記述例|備考|
|高|<n:m>|ビット切り出し|a<2:1>||
|~|<n>|ビット切り出し|a<2>||
|中|^|否定(NOT)|^a||
|~|/||桁方向の論理和(OR)|/|a|a<0>|a<1>|...という意味になる|
|~|/&|桁方向の論理積(AND)|/&a|a<0>&a<1>&...という意味になる|
|~|/@|桁方向の排他的論理和(XOR)|/@a|a<0>@a<1>@...という意味になる|
|~|#|符号拡張|8#a|指定した数字のビット数になる|
|低|||論理和(OR)|a | b||
|~|&|論理積(AND)|a & b||
|~|@|排他的論理和(XOR)|a @ b||
|~||||連結|a || b|aとbが連結した信号になる|
|~|+|加算|A + B||
|~|-|減算|A - B||
|~|>>|ビット右シフト|A >> 0x3||
|~|<<|ビット左シフト|A << 0x3||
|~|==|一致判定|a == b||
これ以外にもsfl2vl独自拡張で使用できる演算子がいくつか存在しますが、今回は割愛します。
**makeコマンドの動作 [#f524622d]
makeコマンドはMakefileに記述してあるルールに従って、複雑なコマンドを簡単に動作させることができます。
本来は、論理シミュレーションまで以下のような手順が必要になります。
+sfl2vlでSFLをVerilog-HDLに変換。
+テストベンチと回路記述をiverilogでコンパイル。
+vvpで論理シミュレーションを行う。
論理シミュレーションを行うために、毎回一つ一つコマンドを入力していくのは面倒です。そんなときにMakefileは役に立つと思います。
**テストベンチの内容 [#b1db36fa]
テストベンチはVerilog-HDLを使って記述しています。作成したモジュールに必要なテストデータを入力するのが目的ですが、簡単にデータの操作ができるように少し特殊な書き方をしています。
全体的な流れとしては、以下のような構成となっています。
+モジュールの宣言
+レジスタ、ワイヤの宣言
+サブモジュールの宣言(今回ならALU)
+taskの宣言
+波形データの出力ファイル指定
+テストデータの入力(taskを使用)
簡単にテストデータを作成できるように、taskを使ってVerilog-HDLの構文をなるべく隠蔽しています。~
initial beginからendの中で用意されたtaskを使うだけで、簡単にテストデータを選べるようにしました。
終了行:
[[SFLで作るPICO-16プロセッサ]]
*ALUの設計 [#bc8b64df]
まずは簡単な回路で、シミュレーションまでの流れを覚えましょう。
今回設計するALUは2つの16ビットの入力を用いて、論理積(AND)、論理和(OR)、排他的論理和(XOR)、論理否定(NOT)、加算(ADD)、減算(SUB)、左シフト(SHL)、右シフト(SHR)の演算をサポートします。~
PICO-16プロセッサに必要な演算は、全てこのALUに実装された8種類の演算を用いて実現することができます。
**コンテンツ [#f5a16f16]
#contents
*仕様 [#ja205ed0]
今回設計するALUの仕様を確認します。
CENTER:&ref(alu.png);
**入出力 [#ke3c761e]
-入力
--演算対象のデータ1(16ビット)
--演算対象のデータ2(16ビット)
-出力
--演算結果(16ビット)
**機能 [#te6015fe]
今回実装する機能は全部で8つあります。
|機能|意味|動作|
|AND|論理積|out = in1 & in2|
|OR|論理和|out = in1 | in2|
|XOR|排他的論理和|out = in1 @ in2|
|NOT|論理否定|out = ^in2|
|ADD|加算|out = in1 + in2|
|SUB|減算|out = in1 + in2|
|SHL|左シフト(SHift Left)|out = in2 << 1|
|SHR|右シフト(SHift Right)|out = in2 >> 1|
AND、OR、XOR、ADD、SUBの命令はin1とin2を使って演算を行いますが、NOT、SHL、SHRはin2だけを使って演算を行います。
*実装 [#wf985494]
ファイル名はalu.sfl及び、alu.hとします。
**ヘッダ [#f6156165]
ヘッダには、ALUの入出力と制御入出力、制御入力の仮引数を定義する必要があります。
これらの情報は全て仕様定義で明らかになっているので、以下のように書くことができます。
declare alu {
input in1<16>;
input in2<16>;
output out<16>;
instrin AND;
instrin OR;
instrin XOR;
instrin NOT;
instrin ADD;
instrin SUB;
instrin SHL;
instrin SHR;
instr_arg AND(in1, in2);
instr_arg OR (in1, in2);
instr_arg XOR(in1, in2);
instr_arg NOT(in2);
instr_arg ADD(in1, in2);
instr_arg SUB(in1, in2);
instr_arg SHL(in2);
instr_arg SHR(in2);
}
ヘッダは既に完成しているので、alu.hの内容としてコピーして保存してください。
**モジュール [#m6c3910a]
モジュールには、ALUの入出力、制御入出力、動作を記述する必要があります。
スケルトンを用意しました。入出力と制御入力は仕様定義やヘッダで既に決まっているので、以下のような記述になります。~
足りない部分は各制御入力に対応する動作なので、正しく動作するように該当部分を記述してください。
module alu {
input in1<16>;
input in2<16>;
output out<16>;
instrin AND;
instrin OR;
instrin XOR;
instrin NOT;
instrin ADD;
instrin SUB;
instrin SHL;
instrin SHR;
instruct AND /* ここに動作を記述する */
instruct OR /* ここに動作を記述する */
instruct XOR /* ここに動作を記述する */
instruct NOT /* ここに動作を記述する */
instruct ADD /* ここに動作を記述する */
instruct SUB /* ここに動作を記述する */
instruct SHL /* ここに動作を記述する */
instruct SHR /* ここに動作を記述する */
}
SFLで使える演算子の動作を復習しましょう。
*論理シミュレーション [#yd146ba7]
回路が正しく動作しているかどうかを確認します。
+&ref(ex01.tar.gz);をダウンロードする。~
~
解凍方法)
% tar zxvf ex01.tar.gz
+alu.h、alu.sflを作成し、ex01ディレクトリに入れる。
--alu.hは、[[ここ>#f6156165]]から内容をコピーする。
--alu.sflは、[[ここ>#m6c3910a]]から内容をコピーして、記述を完成させる。
+シミュレーションを行う。
--シミュレーションには次のコマンドを使います。
% make
もしくは、
% make sim
--シミュレーションの結果はsim.logに出力されます。正しく動作していると&ref(sim.log.txt);のようになります。
--余裕があればテストベンチを自由に改変してみましょう。
+波形を観察する。
--波形ビューワの起動には次のコマンドを使います。
% make wave
--
+ファイルをクリーンする。
--ファイルのクリーンには次のコマンドを使います。
% make clean
--シミュレーションや波形ビューワで生成されたファイルのサイズが大きいときもあるので、全て終わったら余計なファイルを削除しておきましょう。
**シミュレーション結果 [#o1a30298]
正しく動作していれば、次のような結果が出ます。16進数同士の計算の確認にはgcalctoolを起動後に"Control + S"で科学計算モードにして使うと便利です。
|演算の種類|in1|in2|out|
|AND|0f0f|f0f0|0000|
|~|f0f0|0f0f|0000|
|~|ffff|ffff|ffff|
|~|d8a3|b8d4|9880|
|~|63b9|d6f2|42b0|
|OR|0f0f|f0f0|ffff|
|~|f0f0|0f0f|ffff|
|~|ffff|ffff|ffff|
|~|d8a3|b8d4|f8f7|
|~|63b9|d6f2|f7fb|
|XOR|0f0f|f0f0|ffff|
|~|f0f0|0f0f|ffff|
|~|ffff|ffff|0000|
|~|d8a3|b8d4|6077|
|~|63b9|d6f2|b54b|
|NOT|0000|f0f0|0f0f|
|~|0000|0f0f|f0f0|
|~|0000|ffff|0000|
|~|0000|b8d4|472b|
|~|0000|d6f2|290d|
|ADD|0f0f|f0f0|ffff|
|~|f0f0|0f0f|ffff|
|~|ffff|ffff|fffe|
|~|d8a3|b8d4|9177|
|~|63b9|d6f2|3aab|
|SUB|0f0f|f0f0|1e1f|
|~|f0f0|0f0f|e1e1|
|~|ffff|ffff|0000|
|~|d8a3|b8d4|1fcf|
|~|63b9|d6f2|8cc7|
|SHL|0000|f0f0|e1e0|
|~|0000|0f0f|1e1e|
|~|0000|ffff|fffe|
|~|0000|b8d4|71a8|
|~|0000|d6f2|ade4|
|SHR|0000|f0f0|7878|
|~|0000|0f0f|0787|
|~|0000|ffff|7fff|
|~|0000|b8d4|5c6a|
|~|0000|d6f2|6b79|
**テストベンチ [#u47f87b1]
配布したテストベンチは、ALUの各演算が簡単にできるようにtask(C言語でいう関数によく似た構文)を用いた記述を採用してます。~
今回のテストベンチで使っているtaskは全部で8つあり、これにテストデータを渡すとALUのテストが行えます。
-do_and~
論理積(AND)のテストを行います。演算する2つのデータを渡します。~
~
使用例)
do_and(16'hd8a3, 16'hb8d4);
do_and(16'h63b9, 16'hd6f2);
-do_or~
論理和(OR)のテストを行います。演算する2つのデータを渡します。~
~
使用例)
do_or(16'hd8a3, 16'hb8d4);
do_or(16'h63b9, 16'hd6f2);
-do_xor~
排他的論理和(XOR)のテストを行います。演算する2つのデータを渡します。~
~
使用例)
do_xor(16'hd8a3, 16'hb8d4);
do_xor(16'h63b9, 16'hd6f2);
-do_not~
論理否定(NOT)のテストを行います。演算する1つのデータを渡します。~
~
使用例)
do_not(16'hb8d4);
do_not(16'hd6f2);
-do_add~
加算(ADD)のテストを行います。演算する2つのデータを渡します。~
~
使用例)
do_add(16'hd8a3, 16'hb8d4);
do_add(16'h63b9, 16'hd6f2);
-do_sub~
減算(SUB)のテストを行います。演算する2つのデータを渡します。~
~
使用例)
do_sub(16'hd8a3, 16'hb8d4);
do_sub(16'h63b9, 16'hd6f2);
-do_shl~
左シフト(SHL)のテストを行います。演算する1つのデータを渡します。~
~
使用例)
do_shl(16'hb8d4);
do_shl(16'hd6f2);
-do_shr~
右シフト(SHR)のテストを行います。演算する1つのデータを渡します。~
~
使用例)
do_shr(16'hb8d4);
do_shr(16'hd6f2);
これらのtaskを使ってシミュレーションのデータを用意しているのがtestbench.vです。ファイルの後半にinitial beginで始まりendで終わるブロックで実際にこれらのタスクを使用しています。
*ヒントと豆知識 [#hbb9c950]
ここでは、今回の演習に関わる豆知識やヒントを紹介します。
**SFLで使用可能な演算子 [#vc685100]
PARTHENONで合成するために一部の演算子は制限が設けられていますが、今回は気にしなくても良いです。
|優先度|演算子|機能|記述例|備考|
|高|<n:m>|ビット切り出し|a<2:1>||
|~|<n>|ビット切り出し|a<2>||
|中|^|否定(NOT)|^a||
|~|/||桁方向の論理和(OR)|/|a|a<0>|a<1>|...という意味になる|
|~|/&|桁方向の論理積(AND)|/&a|a<0>&a<1>&...という意味になる|
|~|/@|桁方向の排他的論理和(XOR)|/@a|a<0>@a<1>@...という意味になる|
|~|#|符号拡張|8#a|指定した数字のビット数になる|
|低|||論理和(OR)|a | b||
|~|&|論理積(AND)|a & b||
|~|@|排他的論理和(XOR)|a @ b||
|~||||連結|a || b|aとbが連結した信号になる|
|~|+|加算|A + B||
|~|-|減算|A - B||
|~|>>|ビット右シフト|A >> 0x3||
|~|<<|ビット左シフト|A << 0x3||
|~|==|一致判定|a == b||
これ以外にもsfl2vl独自拡張で使用できる演算子がいくつか存在しますが、今回は割愛します。
**makeコマンドの動作 [#f524622d]
makeコマンドはMakefileに記述してあるルールに従って、複雑なコマンドを簡単に動作させることができます。
本来は、論理シミュレーションまで以下のような手順が必要になります。
+sfl2vlでSFLをVerilog-HDLに変換。
+テストベンチと回路記述をiverilogでコンパイル。
+vvpで論理シミュレーションを行う。
論理シミュレーションを行うために、毎回一つ一つコマンドを入力していくのは面倒です。そんなときにMakefileは役に立つと思います。
**テストベンチの内容 [#b1db36fa]
テストベンチはVerilog-HDLを使って記述しています。作成したモジュールに必要なテストデータを入力するのが目的ですが、簡単にデータの操作ができるように少し特殊な書き方をしています。
全体的な流れとしては、以下のような構成となっています。
+モジュールの宣言
+レジスタ、ワイヤの宣言
+サブモジュールの宣言(今回ならALU)
+taskの宣言
+波形データの出力ファイル指定
+テストデータの入力(taskを使用)
簡単にテストデータを作成できるように、taskを使ってVerilog-HDLの構文をなるべく隠蔽しています。~
initial beginからendの中で用意されたtaskを使うだけで、簡単にテストデータを選べるようにしました。
ページ名: