2017年1月12日木曜日

ド素人からはじめるFPGA ~ 論理シミュレーション 篇~

相変わらずFPGAプログラミング大全 Xilinx編をベースに勉強していますが、第3章の論理シミュレーションに関しては、ド頭から躓きました。

原因は、解説で用いられているディスプレイ関連の知識がないまま読み飛ばしつつ進めて来たことでした。正直、表示系に関しては付随する知識や経験度が求められるため、ある一定以上のレベルでないと理解は難しいかもしれません。

ですが、現時点で本質的に理解して進めるべきポイントは"論理シミュレーション"に関する知識であり、ツールや仕組み、何より"論理シミュレーション"が何故必要で、何をするものなのかを学ぶことだと考え、もう少し簡単な仕組みで試してみることにします。

今回参考にさせていただいたのは、Verilog入門の"Verilogの基礎と論理シミュレーション"の項となります。

シミュレーションする際に使うのは、
"Project Manager" - "Source" - "Simulation Sources" - "sim_1"の中にあるファイル、
となりますが、既に"Add Sources" - "Add or create design sources"でソースファイルを追加した際に、自動的に"Design Sources"と同一のファイルが追加されています。
シミュレーションファイルの読み込み、作成を行うことでここに指定ファイルが追加されます。

ゴチャゴチャ解説していると読み返すのが面倒なので、結果を出すまで一気に進めてみましょう。

ここでの作業の流れは以下の様になります。

・半加算器を回路の作成
・"論理シミュレーション"ファイルの作成
・テストベンチの動作確認
・XDCの作成
・ZYBOへので実装

まずは、半加算器の回路図です。


このXORとANDで組まれた回路をVerilogで再現します。
新しいプロジェクトを作成して、下記のソースコードを設定していきます。

"Project Manager" - "Add Sources" - "Add or create design sources"
で、以下のファイルを作成します。

half_adder.v
module half_adder ( in_A, in_B, out_C, out_S );

input in_A;
input in_B;
output out_C;
output out_S;

assign out_S = in_A ^ in_B; // XOR回路
assign out_C = in_A & in_B; // AND回路

endmodule

ここでは、XDCは作成せずシミュレーション用のファイルのみを用意します。

"Project Manager" - "Add Sources" - "Add or create simuration sources"
を選択してシミュレーション用ファイルを作成。

シミュレーション用の記述は以下の様に行います。
half_adder_test.v
// シミュレーションの時間設定 単位/精度
`timescale 1ns / 1ps

module half_adder_test; // シミュレーションでは外部接続しないのでポートの指定は行いません。

// 入力のある箇所は"reg"で設定します。
reg in_A;
reg in_B;

// 出力は"wire"で設定します。
wire out_C;
wire out_S;

/*
回路のモジュールを指定します。
モジュール名 インスタンス名 ( );で設定します。
モジュールとインスタンス名は同じでも異なっていても構いません。
.ポート名(ポートインスタンス名)で入出力の設定を行う。
*/
half_adder half_adder (
    .in_A (in_A),
    .in_B (in_B),
    .out_C (out_C),
    .out_S (out_S)
);

// シミュレーションの実行部分 "initial begin"から"end"まで
initial begin

    $monitor("A : %b + B : %b = CS : %b%b", in_A, in_B, out_C, out_S ); // コンソールに出力する設定

    in_A = 0;  in_B = 0; // シミュレーション初期値を指定
    #100; // 100タイムスケール(単位時間)待機する命令


    // 入力値を100タイムスケール(単位時間)で変化させる設定を行っています。
    in_A = 0; in_B = 1;
    #100;
    in_A = 1; in_B = 0;
    #100;
    in_A = 1; in_B = 1;
    #100;
end

endmodule

正常に認識される以下の様に表示されます。

シミュレーションを実行してみましょう。
"Simulation" - "Run Simulation" - "Run Behavioral Simulation"

実行が完了すると波形が表示されます。
波形の表示を色々と触ってみると100ns単位でA、B入力値、出力結果C、Sの値が変化している事が確認出来るかと思います。

Tcl Consoleにも"$monitor(~);"で設定した出力結果が表示されています。
以上が簡単な論理シミュレーションの手順となります。

同様の手順で、"Verilogの基礎と論理シミュレーション"の全加算器までを検証する事が出来ますが、とりあえず半加算器をZYBOに実装してみましょう。

実装用にXDCを以下の様に設定します。

half_adder.xdc
#LEDs
set_property PACKAGE_PIN M14 [get_ports {out_S}]
set_property IOSTANDARD LVCMOS33 [get_ports {out_S}]

set_property PACKAGE_PIN M15 [get_ports {out_C}]
set_property IOSTANDARD LVCMOS33 [get_ports {out_C}]

##Switches
set_property PACKAGE_PIN G15 [get_ports {in_A}]
set_property IOSTANDARD LVCMOS33 [get_ports {in_A}]

set_property PACKAGE_PIN P15 [get_ports {in_B}]
set_property IOSTANDARD LVCMOS33 [get_ports {in_B}]

コンパイルしてZYBOへ書き込みを行いシミュレーション結果と同じか動作確認してみましょう。

0 件のコメント:

コメントを投稿