効能
FPGAに書き込むと、FPGAでVTLを使うことが出来るようになります。
元ネタ
スクラッチからでは能力的にも時間がかかりそうなので、下記サイトのものをベースに使わせてもらっています。
[■[fpga] CPUの創りかた TD4 を Spartan-3A で]
※許諾については記載が無いので、黙って使わせていただいておりますが、問題あれば取り下げます。
当初は気付かなかったが、フェッチと演算が非同期、命令処理が同期式の、2段パイプライン?になっていました。
方針(方向性)
メモリは身の丈に合ったサイズで
これを作る前に、下記を参考に(パクッて)32bitバージョンを作成した。
[独自CPUを作る(Verilog HDL版)]
1.命令語長 32bit
2.レジスタ 16bit(A-Z)
3.実行速度 50Mhz - 90Mhz
4.ハード Xilix xc6slx9(Papilio)
5.処理構成 3段パイプライン(元ネタの性能です)
機能的には今回のものと同程度に仕上がったが、オブジェクト効率が悪いため放置。
※コンパイラソースが8KB、機械語オブジェクトが16KB、オブジェクトがスカスカで悲しい。
但し、処理は早く「A=B」を1clockで実行できた。
FPGAは小さく、安くがよろしい
つらつら考える。
1.Papilioもよくできているが、もう少し小さく(安く)てもいいではないか。
2.spaltan6はXilinxに切り捨てられ、継子扱い。
3.alteraの旧世代を使った中華製のボードがEbayで見つかる。
「そうだ、CycloneIVが有るじゃないか」とEP4CE6に趣旨替えをする(だがメモリは少ない!)。
ハードウェア
Ebayで下記のボードを購入(\4975ナリ)
「EP4CE6 FPGA Board with Programmer Altera Cyclone IV NIOS II」
使用例がここに有りました。
[[FPGA] EP4CE6 Starter Board]
ボードの解説がここに有ります。
[EP4CE6-Starter-Board-Docs]
※プレビューエラーとなるがダウンロードは可能
USBブラスター機能もついていて、パソコンとUSBケーブルで繋げは即開発可能。
全体的にショボく、もう少し頑張ってほしい部分もあるが、値段を考えればこんなものか。
開発内容
1.4bitを8bitに拡張(TD4x2)、さらに16bitに拡張(TD4x4)。名前も拡張したがセンスが..。
2.VTLのコンパイル後の機械語命令を想定し、まずは単純な命令から、必要となる機械語を算出。
C=B+1 ; VTLソースの例
↓
LD Ra,B ; 機械語
LD Rb,#1 ;
ADD Ra,Rb ;
ST C,Ra ;
3.実行ロジックをverilogでしこしこ書き出す。
個々の命令にcase文で分解して、個別の処理をはめ込んでいく。
begin regx[regno] <= regx[varno]; PC <= PC + 1; end // LD Rx,Vx
4.演算はFPGAにおまかせで処理する。
assign ALU = (calno == 5'd1) ? regx[0] + regx[1] : // ragA=ragA + regB
※まさか割り算が使えないとは気が付かなった。(泣く泣くソフトで処理)
5.複雑な命令はなるべくコンパイラで分解、それでもだめならシーケンス処理。
4'b0100, 4'b0101: // LDM Ra,(Ra).b,w
case(op_cycl)
0: begin SP <= SP + 1; mwe <= 0; memsel <= 2; op_cyclm <= 10; op_holdct <= 9; end
1: begin SP <= SP + 1; end
2: begin SP <= SP + 1; regw[15:8] <= memout; end // 配列先頭読み出し
6.ロジックが完成したら、シミュレーターで単体機能の動作を確認する。
7.動作OKならコンパイルし、実機にのRAMにロードして確認する。
8.実機OKなら、実機に書き込む。書き込み方法は2種類有る。
(1)ASモード 接続コネクタが2個あり(JTAG,AS)、差し替えて書き込む方法
(2)JICモード jicファイルを作成し、1つのコネクタで書き込む方法
※場所を取りますが、JICへのコンバートと、JICの書き込み画面を表示。(少しはまったので)
コンパイル
Quartus Prime ライト・エディション(17.1)でコンパイラしています。(18.0でも問題ないと思われる)
[ダウンロード・センター]
プログラムソースはこちらに上げています。
[TD4X4]
※通信モード 115200bps 8.n.1
TD4x4 命令一覧
TD4x4はの命令語長は3種類
1.1byte 計算命令、レジスタへのロード/ストア
2.2byte 8bitの数値ロード
3.3byte 16bitの数値ロード、ジャンプ、メモリアクセス等
※命令一覧の更新漏れが有るかも
下記の命令を実装(しているはずです)
---------------+---------------+---------------------------------------------------------------
命令 ビット構成 動作
---------------+---------------+---------------------------------------------------------------
計算 Ra,Rb 0000CCCC Ra <- RaとRb間で計算 CCCCC=
___ ADD SUB AND OR_ ^__ MUL SR_ EQU GT GE LT LE NE NEG NOP
0010CCCC (未定義)
00010xxx (未定義)
LD Rs,Rx 00m11000 m:条件=0:$18:SP -> A =1:$38:SP <- A
LD Rx,Rx 00m11001 m:条件=0:$19:A -> B =1:$39:A <- B
XAB Ra,Rb 00011010 $1A レジスタ交換 A <-> B
00m11xxx
IN/OUT 00m11111 M:条件=0:Input($1F) =1:Output($3F)
LD Rx,Vx 01RVVVVV $40+R+V Rx <- Vx Rx=regA/B Vx(変数)=regA/B,A-Z($1B)/%/&/*/_
ST Vx,Rx 10RVVVVV $80+R+V Vx <- Rx
1100000m (未定義)
RTS 1100001b $C2+b(0)
LDM Ra,(Ra) 1100010b $C4+b メモリ読み出し b:バイト数=0:1byte =1:2byte
LDM (Ra),Rb 1100011b $C6+b メモリ書き込み
PE/PO (SP) 11001mxx $C8+m regAと(SP+xx*2)でデータ交換 m:条件=0:Read =1:Write
PUSH/POP Rx 1110mxxx $Ex m:条件=0:$E0:POP =1:$E8:PUSH xxx=0:regA 1:regB 2-7:A-F
JPx xxyy 1101JJJJ+xx+yy $Dx 条件成立時ジャンプ JJJJ=0($D0):JZ =1($D1)JNZ
JPx xxyy 11011JJJ+xx+yy $Dx($D6/D7/F6/F7除外) 条件ジャンプ JJJ=0:$D8:JZ 1:$D9:JNZ
11111xxx+xx+yy $Fx($D6/D7/F6/F7除外)
JSR 11011110+xx+yy $D6/$DE
JMP 11111110+xx+yy $F6/$FE
LDI Rx,xxyy 11R1b111+xx+yy Rx <- #xxxx b:バイト数 =1:$DF/$FF(2byte) =0:$D7/$F7(1byte)
---------------+---------------+---------------------------------------------------------------
その他
とりあえず動いているのレベルであり、状況によっては動かない可能性が有ります。
上記記載のハード、ソフトは無保証であり、各自の責任においてご利用願います。