組み込み

Xilinx社の無料FPGA開発ツールVivadoでCPUを自作する(導入編)

どうも、プロコアラです。

C言語のソフトウェアって、どう動くか説明できますか?

今回は組み込みエンジニアとして10年間エンジニアをしていたプロコアラが、ハードウェアエンジニア目線の電気回路レベルで理解するために、FPGAでCPUを作成していきたいと思います。

 

ソフトウェアはどう動くのか?

Webエンジニア、組み込みエンジニア、ハードエンジニアによって答えが違います。

これは見ている視点が違うためです。

 

ソフトウェアレベル(Webエンジニア)

電源が入ると、プログラムはmainから実行される。

プログラムはif文やfor文などの制御文で分岐するが、それ以外は上から順に実行されるだけ。

 

マイコンレベル(組み込みエンジニア)

CPUはReset例外が入ると、プログラムカウンタが0に例外ベクタにリセットされる。

CPUはプログラムカウンタから次の命令を取り出し(フェッチ)て解読(デコード)後、実行(エグゼキュート)する動作を繰り返す。

プログラムはコンパイラによって、アセンブリ言語に変換される。

if文やfor文などの制御文では、アセンブリ言語ではcmp命令後にブランチ命令でジャンプしている。プログラムはブランチ命令以外は基本的には順次命令を実行するだけ。

 

ハードウェアエンジニアは、より深い目線で考えている

ハードウェアエンジニアはより深いレイヤーでソフトウェアを見ています。

・デジタル回路レベル

・アナログ回路レベル

・電子レベル

フリップフリップ回路でプログラムカウンタで保存するなど、回路レベルで考える必要があります。

ソフトウェアエンジニアが学習することで、ハードウェアエンジニアとお話しできるようになります。

何より、CPUの動きを知ることで新たな視点が生まれて楽しいです。

今回使用する教材はこちら

 

 

その前に・・・

知っておきたい知識を紹介しておきます。

Vivado HLx Web pack Edition

Vivadoは、Xilinx社が提供しているFPGA開発ツールです。
今回使用するWeb pack Editionは無償版ですが、合成、配置配線、シミュレータ、ロジアナ、高位合成ができます。
よくわかりませんが、おそらくタダでスゴイということです。
Artix-7、Kinetis-7、Zynq-7000がサポートされています。

 

準備

Vivado HLx Web pack Editionを使用する準備をしていきます。

ダウンロード

こちらからダウンロード。
アカウントを作成後にログインすれば、ダウンロードできます。

スクリーンショット 2016-07-05 6.45.46

Macはサポートされていないみたいですので、Windows版をダウンロードしました。

Windows7 32bit PCが眠っておりましたが、Windows7 32bit PCではVivadoが動作しないそうです。

幸運にも、Windows10無償アップデートでWindows10 64bit PCにアップデートしました。

64bit OSにも無償でアップデートできるんですね、すごい。(´<_`  )

 

インストール

インストールは、簡単です。

ダウンロードしたインストーラを実行するだけです。雑!笑

「Vivado WebPack」を選択して、インストールしてください。

今回使用しないと思いますが、「Software Development Kit」を選択しておきましょう。

 

ライセンスの登録

インストールが完了すると、Vivado License Managerを起動されます。

「Get Free License」を選択し、「Connect Now」をクリックします。

Xilinx社のホームページに飛びますので、ログインしてライセンスを入手します。

取得したライセンスは、License Managerの「Load License」から「Copy License」を選択します。

Version License Statusでライセンス状況を確認できます。

 

CPU自作

ここからは、実際にVivadoを使用していきます。

ルールとしては、「CPUの創りかた」に習い、ゲート素子とフリップフロップでCPUを作成していきます。

面倒な配線作業のみをFPGAで簡素化します。

実際に配線作業をすると、僕の性格を考えると挫折するはず。

上手くいったとしても、CPUを4bitから8bitに変更したい場合に面倒で詰んでしまうはず。

 

作成例

Vivadoで回路を作成する例を説明します。

「Add Sources」から「Add or create design sources」をクリック。

QS_20160706-121914

「Create File」を選択し、任意のファイル名を入力します。
Verilogで書いていきます。

QS_20160706-122022

あっという間に、雛形となるファイルが出来上がります。

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2016/07/03 18:13:24
// Design Name: 
// Module Name: kgcpu
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////

module (


      );
endmodule

 

さて、ここからCPUを作ることになります。
CPUの中で使用される加算器は以下のように記載できます。

module adder4(in_data1, in_data2, out_data, cy);
    input [3:0] in_data1, in_data2;
    output [3:0] out_data;
    output cy;
    
    wire  rslt;
    
    assign rslt     = in_data1 + in_data2;
    assign cy       = rslt;
    assign out_data = rslt[3:0];
    
endmodule

 

ソースを作成後、「RTL Analysis」の「Elaborated Design」から「Reload Design」を選択します。

QS_20160706-122245

「Schematic」を選択すると、先ほど記載したコードの回路図が表示されます。

QS_20160705-122818

簡単ですね!
けれど、今回やりたいことはCPUを作成することではありません。
CPUをゲート素子で自作することです。
配線作業のみを簡略化するために、FPGAを作成するだけです。
よって、もっと泥臭い方法をとります!

 

 

ゲート素子作成

まずは、ベースとなるゲート素子を作成していきます。
今回の主役、CPUを構成する戦士たちです。

 

AND

// AND 7408
module gate_and(in_data1, in_data2, out_data);
    input in_data1;
    input in_data2;
    output out_data;
    
    assign out_data = in_data1 & in_data2;
   
endmodule
QS_20160706-122212

OR

// OR 7432
module gate_or(in_data1, in_data2, out_data);
    input in_data1;
    input in_data2;
    output out_data;
    
    assign out_data = in_data1 | in_data2;
   
endmodule
QS_20160706-122508

NOT

// NOT 7404
module gate_not(in_data, out_data);
    input in_data;
    output out_data;
    
    assign out_data = ~in_data;
   
endmodule
QS_20160706-122417

XOR

// XOR 7486
module gate_xor(in_data1, in_data2, out_data);
    input in_data1, in_data2;
    output out_data;
    
    assign out_data = in_data1 ^ in_data2;
   
endmodule
QS_20160706-122804

D-FF

// D-FF
module dff(clk, d, q);
    input clk, d;
    output q;
    
    // 記憶機能付き内部信号
    reg q;
    
    // 内部動作定義
    always @(posedge clk) begin
        q <= d;
    end
endmodule
QS_20160706-122140

NANDとNORは、省略します。

 

配線

作成したゲート素子は以下のようにして接続していきます。
オブジェクト指向と似ていますね。

module test_top(in_data, out_data);
    input in_data;
    output out_data;

    wire tmp;
        
    gate_not gnot1(in_data, tmp);
    gate_not gnot2(tmp, out_data);
    
endmodule

 

ゲート素子が配線できました。
これなら、配線作業が簡単にでき、回路を色々作成できそうですね!

QS_20160705-124205

それぞれのブロックは展開でき、ゲート素子が確認できます。
よし、この方法で作成していきましょう!

QS_20160705-124217

ちなみに

今回の方法は、FPGAの使用方法とは逸脱しています。
Vivadoでは、簡単にCPUを作成できます。

「IP Integrator」から「Create Block Design」を選択します。

QS_20160705-121641

「Zynq」を選択すれば、ARM Cortex-A9のCPUが作成できます。

QS_20160705-121852

CPUのセッティングも簡単にできます。
しかも、今回自作するCPUの100000000倍は高性能です!

QS_20160705-121905

次回からは、「CPUの創りかた」を参考に、FPGA内でゲート素子を使用して、CPUを自作していきます。
では!(^^)/

ABOUT ME
律野桜哉
RPAコンサルタントのプロコアラです。長年のエンジニア経験を活かしてして外資系コンサルファームでRPAコンサルしてます。 転職ノウハウ、プログラミング、英語の勉強方法など分かりやすいように解説していきます。