Posts Tagged with "FPGA"

既に発行済みのブログであっても適宜修正・追加することがあります。
We may make changes and additions to blogs already published.
posted by sakurai on July 16, 2018 #49

先にご紹介したサイトから得た、SVGAのタイミング表を以下に示します。

図49.1
図49.1 SVGAタイミング表
まず、ピクセルクロック(ドットクロックとも呼ばれる)はこの表より40.0MHzとします。これがタイミングの最小単位で、水平ラインの800dotはこのクロックが800クロック分となります。さらに水平期間はこれだけではなく、表示期間以外に3つの期間があり、それぞれフロントポーチ(FP)、同期パルス(SP)、バックポーチ(BP)に分かれます。

水平タイミングを例にとれば、それぞれHFP, HSP, HBPとなります。トータルでは表示期間であるHDPをすべて加えて、HFP+HSP+HBP+HDP=40+128+88+800=1056が水平期間(26.4us)となり、これをラインと呼びます。水平周波数は37.878787KHzとなります。

垂直タイミングはこのラインがひとつの単位となります。表示期間はVDP=600、その他非表示期間はVFP=1、VSP=4、VBP=23となり、トータルでは628ラインとなります。ラインが集まり一つのフレームを構成し、その周期は16.5792msec、垂直周波数は60.3165412083Hzとなります。

図%%.2
図49.2 SVGAタイミングタイミング設計図

左矢前のブログ 次のブログ右矢

posted by sakurai on July 1, 2018 #48

高機能なFPGAボードを使って、Lチカではあまりにつまらないため、次にグラフィックディスプレイコントローラの設計を行います。

グラフィックディスプレイの解像度は様々なものがあり、タイミング設計の際に参考になるサイトをご紹介します。
http://tinyvga.com/vga-timing

今回はSVGAのグラフィックディスプレイの設計を行います。
http://tinyvga.com/vga-timing/800x600@60Hz

基本的には、横800dotかける縦600dotかける色深度、例えば8色であれば3bitの情報を記憶するメモリが中心となります。これを通常VRAM (Video RAM)と呼びます。

少々問題になるのは、VRAMは2つのバスマスタによりアクセスされることです。第1にグラフィックディスプレイコントローラ(GDC)、第2に描画マスタであるCPU。ただし、描画マスタはCPUとは限らず、ハードウェアでも構いません。問題は、両者が同時に同じポートにアクセスすると、VRAMのポートがひとつしかない場合には待たされることになります。GDCはディスプレイのタイミングに合わせて画像を読み出す必要があるため、待たすことができません。従ってCPUを待たすことになります。

一方、VRAMのポートを増やして2つにすれば、この問題は解決することができます。これをデュアルポートメモリと呼びます。以下の図は非同期のデュアルポートメモリを用いたディスプレイ表示装置の例で、ブルーのクロックドメインとグリーンのクロックドメインの周波数は特に関係がありません。グリーンは前記のようにSVGAのタイミングで動作します。

図48.1
図48.1 クロックドメイン図

シングルポートメモリを2つ並列に実装し、書き込みは同じデータを両方のメモリに書くことでデュアルポートメモリと見せることができます。これは2つのマスタのうち、GDCは読み出しのみを行い、書き込みを行わないことから可能です。

デュアルポートメモリからの読み出しが安定して継続できるようにラインバッファを持つことを考えます。 これはFIFOにより実装します。具体的には2ラインのラインバッファを持ち、1ライン詰めたところで、書き込みと読み出しの平均スループットが同じになるように釣り合わせれば、FIFOオーバランもアンダーランも起きないと考えられます。


左矢前のブログ 次のブログ右矢

Lチカの実装 (8)

posted by sakurai on June 25, 2018 #47

Vivadoの操作

  1. 制約ファイル設定
    デザインの準備ができたので合成制約をかけます。制約の内容はLED端子に対するパッケージ端子の位置の決定と、LED端子のドライブ強度です。以下に制約ファイルの内容を示します。

set_property IOSTANDARD LVCMOS18 [get_ports [list {LED[*]}]]
set_property PACKAGE_PIN R7 [get_ports [list {LED[0]}]]
set_property PACKAGE_PIN T5 [get_ports [list {LED[1]}]]
set_property PACKAGE_PIN T7 [get_ports [list {LED[2]}]]
set_property PACKAGE_PIN T4 [get_ports [list {LED[3]}]]
set_property PACKAGE_PIN T3 [get_ports [list {LED[4]}]]
set_property PACKAGE_PIN U2 [get_ports [list {LED[5]}]]
set_property PACKAGE_PIN U6 [get_ports [list {LED[6]}]]
set_property PACKAGE_PIN U5 [get_ports [list {LED[7]}]]

Add Sourcesをクリックして下図のメニューを表示させ、Add or create contraintsのラジオボタンを選択。

図47.1
以下のように、blinkフォルダの下に用意してあったxdcファイルを選択し、OKをクリック。
図47.2
Add or Create Constraints画面がでるため、Finishをクリック。
図47.3
  1. RTLアナリシス
    合成、配置配線をかける前に、RTLが正しく読めているかどうかを回路図的に確認します。Flow NavigatorからRTL ANALYSISを選択し、Schematicをクリック。階層化されているブロックを適宜展開し、解析を行うと以下の図のようになります。
    図47.4
  2. RTL合成
    Run Synthesisをクリックし、論理合成を実施します。
  3. 実装
    Run Implementationをクリックし、配置配線を実施します。
  4. ビットストリームの作成
    Generate Bitstreamをクリックし、コンフィグファイルの作成を実施します。
  5. FPGAのコンフィギュレーション
    Open Targetをクリックし、Auto Connectを行います。以下の図のメニューが出てビットストリームファイルの選択となるため、そのままProgramを行います。
    図47.5
    FPGAのプログラムを行うことにより回路が自動的に起動します。以下の動画はLチカが動作しているところです。
    図47.6

左矢前のブログ 次のブログ右矢

Lチカの実装 (7)

posted by sakurai on June 20, 2018 #46

Vivadoの操作

  1. シミュレーション シミュレーションにより、動作が正しく行われるかを確認します。左のFlow NavigatorからSIMULATIONの下のRun Simulationをクリックし、Run Behavioral Simulationを実行します。
    図46.1

図46.2

図46.3
図46.4

しばらく待つと以下のようにシミュレーションが動作するが、リセットがうまく入っていないため、カウンタ値が不定となっています。PSからのリセットはソフトで指示しないとかからないのかもしれません。従って、シミュレーションで動作するようにワークアラウンドを行います。

図46.5
まず、ソースを以下のように開きます。
図46.6
design_1の階層でGoto Sourceをクリック。
図46.7
25行目の、blinkモジュールのXRST端子をPSからのリセットを削除し、~glbl.GSRをつなぎます。glblモジュールのGSRは100nsのみtrueとなる信号であるため、反転してXRST端子に入力します。
図46.8
以下の図のようにリセットが正常に入り、回路が動作しました。
図46.9
このままクロックを入れ続けても動作しますが、シミュレーション時間が非常にかかるため、短縮を行います。25bitカウンタを単純にカウントするのではなく、MAX値に近い値をロードした後にカウントを進めます。具体的にはTEST信号をtrueにし25bitカウンタにMAX値に近い値(例えば0x1ffff8)をロードします。この前提としてRTLの25bitカウンタを、TEST信号のtrueにより任意の値をロードできるように修正する必要があります。テスト回路を用いない方法としては、カウント値に強引に上記値をforceするやり方もあります。テスト回路は本番では不要であるため、こちらのほうが良いかもしれません。

tclウインドウから入力するコマンドを示します。

add_force {/design_1_wrapper/design_1_i/blink_0/inst/count25/LD} -radix hex {1fffff8 0ns}
add_force {/design_1_wrapper/design_1_i/blink_0/inst/count25/TEST} -radix hex {1 0ns}
run 10 ns
add_force {/design_1_wrapper/design_1_i/blink_0/inst/count25/TEST} -radix hex {0 0ns}
run 200ns

図46.10
このように動作したので、14進カウンタがすべてカウントするまでこのコマンドを入力します。
図46.11
正しく14進カウンタが動作し、かつLEDパターンが要件に従ったふるまいのとおりデコードされているのがわかります。

テスト回路自体は本来のパス(機能安全用語では主要機能)ではありませんが、このような長いカウンタのテスト容易化設計として常識の回路です。


左矢前のブログ 次のブログ右矢

Lチカの実装 (6)

posted by sakurai on June 13, 2018 #45

Vivadoの操作

  1. 最上位HDLラッパーの作成
    blinkモジュールが最上位となっているため、Zynqとblinkの両方を含む最上位モジュールを作成します。 PROJECT MANAGERをクリック。design_1で右クリックし、メニューを表示させる。ここからCreate HDL Wrapperをクリック。
    図45.1
    以下のようなメニューが出るため、OKをクリック。
    図45.2
    design_1_wrapperという階層が作成されました。
    図45.3
    ラッパーを作成しただけではまだblinkが最上位となっているため、右クリックしメニューを表示します。
    図45.4
    この中からSet as Topをクリック。
    図45.5
    正しくdesign_1_wrapperの下にZynqとblinkのモジュールが配置されました。

左矢前のブログ 次のブログ右矢

Lチカの実装 (5)

posted by sakurai on June 5, 2018 #44

Vivadoの操作

実際の操作方法を記述して行きます。

  1. Zynqブロック作成
    左端のFlow NavigatorよりIP INTEGRATORのCreate Block Designをクリック。以下のメニューでそのままOK。
    図44.1
    以下の画面で+をクリックしてIPを追加します。これによりZynq UltraScale+のPS領域を追加します。基本的にはハードのみで動作させ、ソフトは使用しないのでPSは不要ですが、今回はクロックとリセットのみを使用します。
    図44.2
    IPの選択画面が出るため、Search窓にzyと入力し、Zynq UltraScale+ MPSoCというIPをダブルクリック。
    図44.3
    下図のように、ブロック図にZynq UltraScale+のPS領域がインスタンスされます。
    図44.4
    空き端子があると正常に動作しないため、pl_clk0出力をmaxihpm0_lpd_ack入力に接続します。
    図44.5
  2. blinkモジュール作成
    下図のように、Flow NavigatorのPROJECT MANAGERメニューからAdd Sourcesをクリックし、Add or create design sourcesラジオボタンを選択し、Nextをクリック。
    図44.6
    blinkのフォルダの下にあらかじめverilog moduleとxdcを置いておきます。Add filesを選択し、次にverilogファイルを選択し、OKをクリック。
    図44.7
    下図のような画面となるため、Finishをクリック。
    図44.8
  3. blinkモジュールをモジュールとして追加
    blinkモジュールが読み込めたので、blinkモジュールをブロック図にモジュールとして追加します。 何もないところで右クリックし、Add Moduleをクリック。
    図44.9
    下図のように、モジュール選択画面が出るので、ここでblinkを選択し、OKをクリック。
    図44.10
    下図のように、blinkモジュールがblink_0としてインスタンスされます。
    図44.11
    blinkモジュールのCLK入力をZynqのpl_clk0出力に接続します。またXRST入力をpl_resetn0出力に接続します。
    図44.12
    LED出力ピンを右クリックし、メニューを表示します。ここでCreate Portとしてこの端子をポートに接続します。
    図44.13
    さらに何もないところで右クリックし、Regenerate Layoutをクリック。
    図44.14
    下図のようにblinkが正しく接続されました。
    図44.15

左矢前のブログ 次のブログ右矢

Lチカの実装 (4)

posted by sakurai on May 29, 2018 #43

Vivadoの操作

実際の操作方法を記述して行きます。

  1. プロジェクト作成
    Quick StartからCreate Projectをクリック。
    図43.1
    次の図でNextをクリック。
    図43.2
    Project nameの入力する欄でblinkと入力。
    図43.3
    OK、OKと入力していき、Default Partの画面においてはBoardsをクリックし、Avnet UltraZed-3EG IO Carrier Cardを選択し、Nextをクリック。 ボードファイルはツールには付属していないため、別途入手し、所定の場所に配置しておく必要があります。
    図43.4
    下図のように、プロジェクトが生成されます。
    図43.5

左矢前のブログ 次のブログ右矢

Lチカの実装 (3)

posted by sakurai on May 21, 2018 #42

RTL

以下にRTLを掲載します。元の要求を3分割し、アーキテクチャ設計として3つのエレメントの直列系により、目標となる要件を満足することができました。仕様を満たす動作をするかどうかはシミュレーションにより確認することができます。ただし、長いカウンタはシミュレーションを工夫しなければ、シミュレーション時間が非常に長時間になってしまいます。従って、任意の値をロードするようなテスト回路を挿入する工夫が必要となります。まずは基本の記述を掲載します。

Blinkモジュール

blinkモジュールは以下に示す、25bitカウンタ、14進カウンタ、LEDデコーダの3つのモジュールを含みます。

//
// LED blinking
//
module blink (
input CLK,
input XRST,
output [7:0] LED
);

wire CE;
wire [3:0] C14;

count25 count25(
.CLK(CLK),
.XRST(XRST),
.CE(CE)
);

count14 count14(
.CLK(CLK),
.XRST(XRST),
.CE(CE),
.C14(C14)
);

decoder decoder(
.C14(C14),
.LED(LED)
);

endmodule

25bitカウンタ

/* system clock division */
module count25 (
input CLK,
input XRST,
output CE
);

reg [24:0] count25;
always @(posedge CLK) begin
if (~XRST)
count25 <= 25'h0;
else
count25 <= count25 + 1'h1;
end

assign CE = (count25 == 25'h1ffffff);

endmodule

14進カウンタ

/* 14 advance counter for LED */
module count14 (
input CLK,
input XRST,
input CE,
output [3:0] C14
);

reg [3:0] count14;
always @(posedge CLK) begin
if (~XRST)
count14 <= 14'h0;
else if (CE)
if (count14 == 13)
count14 <= 0;
else
count14 <= count14 + 1'h1;

end
assign C14 = count14;

endmodule

LEDデコーダ

/* LED Decoder */
module decoder (
input [3:0] C14,
output reg [7:0] LED
);

always @* begin
case (C14)
0: LED = 8'b00000001;
1: LED = 8'b00000010;
2: LED = 8'b00000100;
3: LED = 8'b00001000;
4: LED = 8'b00010000;
5: LED = 8'b00100000;
6: LED = 8'b01000000;
7: LED = 8'b10000000;
8: LED = 8'b01000000;
9: LED = 8'b00100000;
10: LED = 8'b00010000;
11: LED = 8'b00001000;
12: LED = 8'b00000100;
13: LED = 8'b00000010;
endcase
end
endmodule


左矢前のブログ 次のブログ右矢

Lチカの実装 (2)

posted by sakurai on May 14, 2018 #41

RTL設計仕様

複雑な演算や制御を含む振る舞いは高位合成したくなりますが、このようなレベルであればRTLで十分でしょう。従ってVerilogで言うモジュールの要求を以下のようにブレークダウンします。これはLチカは要求であって実装可能な手段ではないため、実装可能な手段に分割することを意味します。

  1. 高速なクロックを分周し、目で見えるレベルの低速クロックとすること
  2. 低速クロックをカウントし、流れるパターンをひとつずつ表示すること
  3. 流れるパターンは14通りであるため、13を数えたら次は0とすること
  4. カウント値をデコードし、1つのLEDが点灯しているパターンとすること

1.の要求はNbitのカウンタで実装することができます。何ビットにするかは後程設計計算を行います。 2と3の要求は14進カウンタで実装することができます。一つの要求で一つのモジュールとは限りません。 4の要求はLEDデコーダとして実装することができます。以上でモジュール分割ができたことになります。

モジュール

名称: blink

インタフェース

次の表に、モジュール全体としてのインタフェース(入力及び出力)を示します。基本的にクロックとリセットが必要であり、後はどのLEDを点灯させるかを示す信号があるのみです。

表41.1
インタフェース信号名 インタフェース信号内容
CLK 入力、100MHz
XRST 入力、リセット信号、負論理を想定
LED[7:0] 出力、8bit、正論理、LEDへの出力信号

サブモジュール

(1) Nbitカウンタ
100MHzで点滅すると人間の目に見えないため、見える範囲にまでカウントします。最後の桁上げの際に次段のカウンタを1だけ増加させます。これにより元のクロックが$2^N$分周されることになります。 0からアップカウントし、Nbitの全てのビットが1になった場合に次段のカウンタイネーブルをtrueとします。

前記のように人間の目で見える範囲内に入れるためには、例えば周期を0.5secから1.0sec未満の範囲として以下の不等式を解くことになります。 \[ 0.5\le \frac{2^N}{1e8} \lt 1.0 \] この不等式が成立する整数解Nはただ一つであることが保証され、これを解くとN=25[bit]となります。これは非機能要求である性能要求による設計計算を実施し、仕様が決定したことになります。

(2)14進カウンタ
最右のLEDが点灯しているパターンから左にシフトし、さらに右に戻ってくるまでのパターンが以下の表に示すように14パターンあるため、14進カウンタを設けます。14進カウンタのイネーブルは前記Nbitカウンタからのカウンタイネーブルを接続します。

表41.2
カウント値 パターン
0 8'b00000001
1 8'b00000010
2 8'b00000100
3 8'b00001000
4 8'b00010000
5 8'b00100000
6 8'b01000000
7 8'b10000000
8 8'b01000000
9 8'b00100000
10 8'b00010000
11 8'b00001000
12 8'b00000100
13 8'b00000010

(3)デコーダ
14進カウンタの出力はバイナリ出力のため、表41.2のビットパターンとなるようにデコーダを設けます。

今回の設計ではアップカウンタのみで構成しましたが、デコーダを倹約してアップダウンカウンタで構成することも可能です。結局のところ、設計とは新しいことを生み出すというよりも、実装できるレベルの小規模のサイズに分割し、そのトレードオフを最適化することにほかなりません。


左矢前のブログ 次のブログ右矢

Lチカの実装

posted by sakurai on May 7, 2018 #40

要求

「Lチカを実現すること」

いわゆるLチカとは評価ボード上のLEDが点滅することで、回路が思い通りに動作していることを示す振る舞いの一例です。LEDの点滅は機能要求ですが、暗黙の非機能要求があります。例えば点滅の周期です。評価ボードは内部クロックは100MHzという高速のクロックで動作しますから、単純にON/OFFさせると人間の目には点滅に見えません。従って点滅と書かれている段階で点滅に見えることが暗黙の非機能要求であり、例えば、点灯を0.5sec、消灯を0.5secのように連続させる必要があります。

PLに接続されているLEDは8bitあるので、右から左に1bitずつずらしながら点灯し、最左端に来たら左から右へ1bitずつ点灯することを要件とします。下図において、赤は点灯、灰色は消灯を意味するものとします。

Lチカ振る舞い説明図
図40.1 Lチカ振る舞い説明図

左矢前のブログ 次のブログ右矢


ページ: