見出し画像

Tang Nano 9K で Gowin Video Frame Buffer with PSRAM IP のリファレンスデザインを動かしてみる

GOWIN Semiconductor 社が提供している、PSRAM を使ったフレームバッファのリファレンスデザインは、DK-GoAI-GW2AR18_QN88P 開発ボード用なので、Tang Nano 9K で動くように書き換えてみました。

ユーザーガイドとリファレンスデザインの入手

ユーザーガイドとリファレンスデザインは、GOWIN のサポートページから入手できます。最初にユーザ登録が必要です。

video を検索し、Gowin Video Frame Buffer with PSRAM IP User Guide と Gowin Video Frame Buffer Reference Design をダウンロードします。

ドキュメンテーション・データベース

プロジェクトの確認

Gowin_Video_Frame_Buffer_RefDesign.zip には、四つの RAM 形式(SDRAM、PSRAM、HyperRAM、DDR3)のリファレンスデザインが入っています。今回は、PSRAM 用の Gowin_VFB_PSRAM_RefDesign を使います。

Gowin IDE を起動し、project フォルダの dk_video.gprj を開きます。
Device は、GW2AR-LV18QN88PC8/I7 になっています。
そのまま、Run All してみます。警告が三つほど出ますが、タイミング制約ファイルの記述に漏れがあるためで、問題ありません。

リファレンスデザインをそのまま合成、配置

Tang Nano 9K 用に変更

Tang Nano 9K で動くように、書き換えていきます。

Device の変更

Project メニューの Set Device を選択し、Part Number を GW1NR-LV9QN88PC6/I5 に変更します。

Device の変更

IP の確認

使用されている IP の設定を確認します。
Tool メニューの IP Core Generator を選択します。

IP Core Generator

Target Device の横のフォルダアイコン (Open IP config file) をクリックします。

Open IP config file

dvi_tx_top フォルダの中の、dvi_tx_top.ipc ファイルを開きます。

dvi_tx_top.ipc

設定内容を記録しておきます。
.ipc ファイルをテキストエディタで開いて内容を調べても良いです。

[General]
ipc_version=4
file=dvi_tx_top
module=DVI_TX_Top
target_device=gw2ar18c-011
type=dvi_tx
version=1.0

[Config]
DISABLE_IO_INSERTION=true
LANG=0
RX_CLOCK_IN_FREQUENCY=40
Synthesis_tool=Synplify Pro
USING_EXTERNAL_CLOCK=true

dvi_tx_top.ipc

他の IP の設定も同様に調べておきます。
.ipc ファイルをテキストエディタで開いて確認することもできます。

IP の再作成

LV9QN88PC6/I5 用の IP を作り直します。
DVI TX を例に、詳しく手順を示します。
IP Core Generator ウィンドウの Soft IP Core -> Multimedia -> DVI TX をダブルクリックします。

DVI TX

先ほど調べた、.ipc ファイルの内容に従って設定を変更します。

  • Using External Clock のチェックボックスを ON にします。

  • IO Setting は ELVDS を選択します。
    元の設定 TLVDS と異なるのは、Tang Nano 9K では、DVI 用の LVDS 端子が、エミュレート LVDS ピン (ELVDS) に割り当てられているためです。

OK をクリックします。

Generation success

生成したファイルをプロジェクトに追加するか尋ねられるので、OK をクリックします。
元の IP (dvi_tx_top.v) は、削除します。

Remove

同様に、他の IP も再作成します。

gowin_rpll は、Hard Module -> CLOCK -> rPLL を使います。

  • Module Name を gowin_rpll に変更します。

  • CLKIN の Clock Frequency を 27.000 に変更します。

  • CLKOUT の Expected Frequency を 162.000 に変更します。

  • Enable LOCK のチェックボックスを ON にします。

  • 元のファイルに上書きします。

TMDS_PLL は、Hard Module -> CLOCK -> rPLL を使います。

  • File Name を TMDS_PLL に変更します。

  • Module Name を TMDS_PLL に変更します。

  • PLL Phase And Duty Cycle Adjustment を Static に変更します。

  • CLKIN の Clock Frequency を 27.000 に変更します。

  • CLKOUT の Expected Frequency を 371.250 に変更します。

  • Enable LOCK のチェックボックスを ON にします。

  • 元のファイルに上書きします。

psram_memory_interfece_hs は、Soft IP Core -> Memory Control -> PSRAM Memory Interface -> PSRAM Memory Interface HS を使います。

  • Memory Clock を 162 MHz に変更します。

  • Option タブの Burst Mode を 128 に変更します。

  • Shift Delay はデフォルト 192 のままにします。

  • 元のファイルに上書きします。

video_frame_buffer は、Soft IP Core -> Multimedia -> Video Frame Buffer を使います。

  • Data Width を 64 に変更します。

  • 元のファイルに上書きします。

ここまでの修正が終わったら、一旦、Synthesis してみます。
エラーがでる場合、何か間違いがあるので修正します。

デザイン制約ファイルの修正

dk_video.cst を Tang Nano 9K のピン配置に従って修正します。

  • I_clk は 52 ピン

  • I_rst_n は SW1 の 4 ビン

  • O_led[0] は LED0 の 10 ピン

  • O_led[1] は LED1 の 11 ピン

  • O_tmds_clk は、69 と 68 ピン

  • O_tmds_data_p[0] は、71 と 70 ピン

  • O_tmds_data_p[1] は、73 と 72 ピン

  • O_tmds_data_p[2] は、75 と 74 ピン

IO_LOC "O_tmds_clk_p" 69,68;
IO_PORT "O_tmds_clk_p" IO_TYPE=LVCMOS33D PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "O_tmds_data_p[0]" 71,70;
IO_PORT "O_tmds_data_p[0]" IO_TYPE=LVCMOS33D PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "O_tmds_data_p[1]" 73,72;
IO_PORT "O_tmds_data_p[1]" IO_TYPE=LVCMOS33D PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "O_tmds_data_p[2]" 75,74;
IO_PORT "O_tmds_data_p[2]" IO_TYPE=LVCMOS33D PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "O_led[1]" 11;
IO_PORT "O_led[1]" IO_TYPE=LVCMOS18 PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8;
IO_LOC "O_led[0]" 10;
IO_PORT "O_led[0]" IO_TYPE=LVCMOS18 PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8;
IO_LOC "I_rst_n" 4;
IO_PORT "I_rst_n" IO_TYPE=LVCMOS18 PULL_MODE=UP BANK_VCCIO=1.8;
IO_LOC "I_clk" 52;
IO_PORT "I_clk" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3;

Place & Route を実行します。
警告が出ますが、後で修正することにします。

WARN  (TA1117) : Can't calculate clocks' relationship between: "dma_clk" and "u_clkdiv/CLKOUT.default_gen_clk"
WARN  (TA1117) : Can't calculate clocks' relationship between: "u_clkdiv/CLKOUT.default_gen_clk" and "dma_clk"

書き込みと実行

Programmer を起動し、ビットストリームを書き込みます。
8 色のカラーバー、赤のグリッド、グレーのグラデーション、チェッカーボードが交互に表示されます。
SW1 を押すと、カラーバーに戻ります。

カラーバー
グリッド
グラデーション
チェッカーボード

タイミングの修正

動作しますが、Timing Analysis Report を見ると、Max Frequency と Setup Paths に制約違反が出ています。

クロックの変更

Max Frequency の制約を満たすように、dma_clk と u_clkdiv/CLKOUT.default_gen_clk を下げます。

dma_clk は、PSRAM Memory を使う時のクロックで、周波数は memory_clk の 1/2 です。memory_clk は、gowin_rpll で生成されています。
dma_clk を、54 MHz にするために、gowin_rpll の CLKOUT と psram_memory_interfece_hs の Memory Clock を 108 MHz に変更します。

u_clkdiv/CLKOUT.default_gen_clk は、Video 出力の画素クロック pix_clk です。pix_clk の周波数は u_ckldiv で serial_clk の 1/5 に設定されています。serial_clk は TMDS_PLL で生成されています。
pix_clk を 36 MHz にするために、TMDS_PLL の CLKOUT を 180 MHz に変更します。

ビデオ出力解像度の変更

画素クロックを 36 MHz にしたため、Video 出力も対応する SVGA 800 x 600 @ 56Hz に変更します。
video_top.v の 274 行目からを以下のように修正します。

  • I_h_total:1024

  • I_h_sync:72

  • I_h_bporch:128

  • I_h_res:800

  • I_v_total:625

  • I_v_sync:2

  • I_v_bporch:22

  • I_v_res:600

syn_gen syn_gen_inst
(                                   
    .I_pxl_clk   (pix_clk         ),//40MHz      //65MHz      //74.25MHz    //148.5
    .I_rst_n     (hdmi_rst_n      ),//800x600    //1024x768   //1280x720    //1920x1080    
    .I_h_total   (16'd1024        ),// 16'd1056  // 16'd1344  // 16'd1650   // 16'd2200  
    .I_h_sync    (16'd72          ),// 16'd128   // 16'd136   // 16'd40     // 16'd44   
    .I_h_bporch  (16'd128         ),// 16'd88    // 16'd160   // 16'd220    // 16'd148   
    .I_h_res     (16'd800         ),// 16'd800   // 16'd1024  // 16'd1280   // 16'd1920  
    .I_v_total   (16'd625         ),// 16'd628   // 16'd806   // 16'd750    // 16'd1125   
    .I_v_sync    (16'd2           ),// 16'd4     // 16'd6     // 16'd5      // 16'd5      
    .I_v_bporch  (16'd22          ),// 16'd23    // 16'd29    // 16'd20     // 16'd36      
    .I_v_res     (16'd600         ),// 16'd600   // 16'd768   // 16'd720    // 16'd1080   
    .I_rd_hres   (16'd800         ),
    .I_rd_vres   (16'd600         ),
    .I_hs_pol    (1'b1            ),//HS polarity , 0:负极性,1:正极性
    .I_vs_pol    (1'b1            ),//VS polarity , 0:负极性,1:正极性
    .O_rden      (syn_off0_re     ),
    .O_de        (out_de          ),   
    .O_hs        (syn_off0_hs     ),
    .O_vs        (syn_off0_vs     )
);

タイミング制約ファイルの修正

dk_video.sdc を修正します。

  • I_clk:Tang Nano 9K のクロック:27 MHz

  • memory_clk:I_clk の 4 倍

  • dma_clk:memory_clk の 1/2

  • serial_clk:I_clk の 20/3 倍

  • pix_clk:serial_clk の 1/5

create_clock -name I_clk -period 37.037 -waveform {0 18.518} [get_ports {I_clk}] -add
create_generated_clock -name memory_clk -source [get_ports {I_clk}] -master_clock I_clk -multiply_by 4 -add [get_nets {memory_clk}]
create_generated_clock -name dma_clk -source [get_nets {memory_clk}] -master_clock memory_clk -divide_by 2 -add [get_nets {dma_clk}]
create_generated_clock -name serial_clk -source [get_ports {I_clk}] -master_clock I_clk -divide_by 3 -multiply_by 20 -add [get_nets {serial_clk}]
create_generated_clock -name pix_clk -source [get_nets {serial_clk}] -master_clock serial_clk -divide_by 5 -add [get_nets {pix_clk}]
set_clock_groups -asynchronous -group [get_clocks {I_clk}] -group [get_clocks {dma_clk}] -group [get_clocks {memory_clk}]

警告は全て解消されました。

修正後の表示


この記事が気に入ったらサポートをしてみませんか?