FC2カウンター FPGAの部屋 2019年01月27日
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

Ultra96のDisplayPortを使用するためのプロジェクトを作成する5(HD解像度のテストパターン)

Ultra96のDisplayPortを使用するためのプロジェクトを作成する4(完成)”の続き。

前回は、デバック結果を元にVerilog HDL ソースコードを修正して、テストパターンの表示を行って成功した。だが、前回の回路では、XGA解像度では、テストパターンを表示できても、HD解像度では、パターン生成回路やAXI4-Stream の動作周波数が 100 MHz で、HD解像度の 148.5 MHz で動作する回路のスループットを満たせずにテストパターンが表示できなかった。今回は、HD解像度のテストパターンを表示してする。

まずは、Zynq UltraSclae+ MPSoC のpl_clk0 のクロック周波数を 200 MHz 程度にしたいということで、設定しようとしたが、 AXI4-Stream のクロック周波数が 100 MHz でだめと言われてpl_clk0 のクロック周波数を 200 MHz 程度にできなかったので、axis2video_out IP のIP Package をやり直すことにした。
Package IP - axi22video_out のウインドウのPorts and Interface で、axis を右クリックし、右クリックメニューからAssciate Clock... を選択する。
DisplayPort_test_117_19027.png

Assciate Clocks ダイアログで、axi_clk にチェックを入れる。
DisplayPort_test_122_19027.png

これで、pl_clk0 のクロック周波数を 200 MHz 程度に設定できるようになったので、Zynq UltraSclae+ MPSoC をダブルクリックして、ダイアログを表示する。
DisplayPort_test_115_19027.png

Page Navigator のClock Configuration をクリックして、Output Clocks -> Low Power Domain Clocks -> PL Fabric Clocks のPL0 のRequested Freq(MHz) を220 に設定した。Actial Frequency (MHz) は 214.285721 MHz となった。
DisplayPort_test_116_19027.png

これで、論理合成、インプリメンテーション、ビットストリームの生成を行った。結果を示す。
DisplayPort_test_118_19027.png

なお、pl_clk0 と disp_clk はFalse Path を設定してある。
displayport_test.xdc を示す。

create_clock -period 6.734 -name disp_clk -waveform {0.000 3.367} [get_pins displayport_test_i/zynq_ultra_ps_e_0/dp_video_ref_clk]

#set_property PACKAGE_PIN D7 [get_ports {red[0]}]
#set_property PACKAGE_PIN F8 [get_ports {red[1]}]
#set_property PACKAGE_PIN F7 [get_ports {red[2]}]
#set_property PACKAGE_PIN G7 [get_ports {red[3]}]
#set_property PACKAGE_PIN F6 [get_ports {blue[0]}]
#set_property PACKAGE_PIN G5 [get_ports {blue[1]}]
#set_property PACKAGE_PIN A6 [get_ports {blue[2]}]
#set_property PACKAGE_PIN A7 [get_ports {blue[3]}]
#set_property PACKAGE_PIN G6 [get_ports {green[0]}]
#set_property PACKAGE_PIN E6 [get_ports {green[1]}]
#set_property PACKAGE_PIN E5 [get_ports {green[2]}]
#set_property PACKAGE_PIN D6 [get_ports {green[3]}]
#set_property PACKAGE_PIN D5 [get_ports {hsyncx[0]}]
#set_property PACKAGE_PIN C7 [get_ports {vsyncx[0]}]

#set_property IOSTANDARD LVCMOS18 [get_ports {blue[3]}]
#set_property IOSTANDARD LVCMOS18 [get_ports {blue[2]}]
#set_property IOSTANDARD LVCMOS18 [get_ports {blue[1]}]
#set_property IOSTANDARD LVCMOS18 [get_ports {blue[0]}]
#set_property IOSTANDARD LVCMOS18 [get_ports {hsyncx[0]}]
#set_property IOSTANDARD LVCMOS18 [get_ports {vsyncx[0]}]
#set_property IOSTANDARD LVCMOS18 [get_ports {green[3]}]
#set_property IOSTANDARD LVCMOS18 [get_ports {green[2]}]
#set_property IOSTANDARD LVCMOS18 [get_ports {green[1]}]
#set_property IOSTANDARD LVCMOS18 [get_ports {green[0]}]
#set_property IOSTANDARD LVCMOS18 [get_ports {red[3]}]
#set_property IOSTANDARD LVCMOS18 [get_ports {red[2]}]
#set_property IOSTANDARD LVCMOS18 [get_ports {red[1]}]
#set_property IOSTANDARD LVCMOS18 [get_ports {red[0]}]

set_false_path -from [get_clocks clk_pl_0] -to [get_clocks disp_clk]
set_false_path -from [get_clocks disp_clk] -to [get_clocks clk_pl_0]


ハードウェアをエクスポートして、SDK を立ち上げた。そうするとHDF ファイルを展開してdisplayport_test_wrapper_hw_platform_0 ディスプレイを作成してくれるので、ビットファイルがその下に生成されている。
そのビットファイルからbin ファイルを生成し、Ultra96 にSFTP する。

Ultra96 のDebian では、クロック周波数が変更になるので、fclk0-zynqmp.dts を変更する必要がある。(これを忘れていて1日潰しました。。。)
fclk0-zynqmp.dts のクロック周波数を 200 MHz に変更した。

/dts-v1/;/plugin/;
/ {
    fragment@0 {
        target-path = "/amba";
        __overlay__ {
            fclk0 {
                compatible    = "ikwzm,fclkcfg-0.10.a";
                clocks        = <&clk 0x47>;
                insert-rate   = "200000000";
                insert-enable = <1>;
                remove-rate   = "1000000";
                remove-enable = <0>;
            };
        };
    };
};


dts ファイルを ./dtc_script.sh でコンパイルした。
./dtc_script.sh を示す。

#!/bin/bash

dtc -I dts -O dtb -o fpga-load.dtb fpga-load.dts
dtc -I dts -O dtb -o fclk0-zynqmp.dtb fclk0-zynqmp.dts
dtc -I dts -O dtb -o pattern_gen_axis.dtb pattern_gen_axis.dts


./lddtovray.sh を起動して、デバイスツリーをロードした。
DisplayPort_test_112_19027.png

その時のシリアルポートのレポートを示す。
DisplayPort_test_113_19027.png

クロック周波数が 214.285713 MHz になっているのが分かる。

./pattern_gen_axis2 を起動して、HD解像度の 1920 x 1080 ピクセルに設定した。
./disp_pattern.sh を起動した。
DisplayPort_test_114_19027.png

HD解像度のテストパターンが表示された。
DisplayPort_test_121_19027.jpg

2019/02/07 追記: テスト・パターンの色が違っています。詳しくは、”Zynq UltraScale+ MPSoC のDisplayPort のLiveVideo のピクセルデータ”を参照ください)

Vivado Analyzer の波形を貼っておく。
まずは、disp_clk の 148.5 MHz でキャプチャしたディスプレイの同期信号やDE 信号を示す。
DisplayPort_test_119_19027.png

DE 信号の 1 の間隔は 1920 クロックだった。

次に、axi_clk の 214.285713 MHz でキャプチャした波形を示す。
DisplayPort_test_120_19027.png

DE 信号の 1 の間隔は 2770 クロックだった。
計算をしてみよう。
1920 × (214.285713÷148.5) = 2770.5628 クロックということで、計測値とだいたい合っている。

最後に、pattern_gen_axis2.c を貼っておく。

// pattern_gen_axis.c
// 2019/01/18 by marsee
//

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>

int main(){
    int fd1;
    volatile unsigned *pga;
    int i, val;

    // uio initialize (uio1)
    fd1 = open("/dev/uio1", O_RDWR|O_SYNC); // pattern_gen_axis IP
    if (fd1 < 1){
        fprintf(stderr, "/dev/uio1 (pattern_gen_axis) open error\n");
        exit(1);
    }
    pga = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd1, 0);
    if (!pga){
        fprintf(stderr, "pattern_gen_axis mmap error\n");
        exit(1);
    }
    
    pga[8] = 0x1; // init_done = 1

    while(1){
        printf("h_size = ");
        scanf("%d", &val);
        if(val == 9999)
            break;
        pga[6] = val; // h_size
        
        printf("v_size = ");
        scanf("%d", &val);
        pga[4] = val;
        printf("v_size = %d, h_size = %d\n\n", pga[4], pga[6]);
    }
    
    munmap((void *)pga, 0x10000);
    close(fd1);
    
    return(0);
}

  1. 2019年01月27日 05:47 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0