FC2カウンター FPGAの部屋 DVI、HDMIの勉強5(キャラクタ・ディスプレイ・コントローラをDVI出力にする Verilog編2)
FC2ブログ

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

FPGAの部屋

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

DVI、HDMIの勉強5(キャラクタ・ディスプレイ・コントローラをDVI出力にする Verilog編2)

現在、VHDL版を作成中だが、”DVI、HDMIの勉強4(キャラクタ・ディスプレイ・コントローラをDVI出力にする Verilog編)”のポートをVHDL版に合わせて変更した。TMDS信号の配列だけで、どのポートがどの色に対応するという情報があったほうが良いと思った。

インプリメントして、動作チェックをしたら問題なく動作した。

まずは、dvi_disp.v のポートマップから下に貼っておく。

// dvi_disp.v 
// DVI表示ユニット
// 

`default_nettype none

module dvi_disp #(
    parameter PLL_CLKFBOUT_MULT    = 20,    // VGA解像度 PLL VCO Freq=400MHz ~ 1000MHz
    parameter PLL_CLKIN_PERIOD     = 40.0,    // VGA ピクセルクロック周期
    parameter PLL_CLKOUT0_DIVIDE    = 2,    // ピクセルクロックX10
    parameter PLL_CLKOUT1_DIVIDE    = 20,    // ピクセルクロック
    parameter PLL_CLKOUT2_DIVIDE    = 10)    // ピクセルクロックX2
(
    input    wire    pixclk,                // pixel clock
    input    wire    reset_in,            // active high
    input    wire    [7:0]    red_in,        // RED入力
    input    wire    [7:0]    green_in,    // GREEN入力
    input    wire    [7:0]    blue_in,    // BLUE入力
    input    wire    hsync,
    input    wire    vsync,
    input    wire    display_enable,        // 表示が有効
    output    wire    TMDS_tx_clk_p,        // Clock
    output    wire    TMDS_tx_clk_n,
    output    wire    TMDS_tx_2_G_p,        // Green
    output    wire    TMDS_tx_2_G_n,
    output    wire    TMDS_tx_1_R_p,        // Red
    output    wire    TMDS_tx_1_R_n,
    output    wire    TMDS_tx_0_B_p,        // Blue
    output    wire    TMDS_tx_0_B_n
);


次に、CharDispCtrlerTest_HDMI.v を下に示す。
PLLのVCOの動作周波数は、Spartan-6の-2デバイスでは400MHz~1000MHzであるので、25MHzを10倍しても250MHzにしかならない。よって、最低動作周波数を下回ってしまう。そのため、PLLのVCOの動作周波数は、20倍して500MHzとしている。PLLのVCOの動作周波数範囲からSpartan-6の-2デバイスではSXGA(ピクセルクロック108MHz)の出力は難しいことがわかる。10倍すると1080MHzとなり、規格を超過してしまう。Spartan-6の通常の入出力ポートを使用したDVI出力でSXGAを出力するためには、-3のスピードグレードのSpartan-6が必要となる。(参考文献:Spartan-6 FPGA データシート : DC 特性およびスイッチ特性 v3.0 (日本語版)(PDF, ver 3.0, 2.09 MB )、58ページの表52 PLL仕様(続き))

// CharDispCtrlerTest_HDMI.v
// CharDispCtrlerTest.vのHDMI用のラッパー、HDMIコネクタから出力する

`default_nettype none

module CharDispCtrlerTest_HDMI (
    input    wire    sysclk,
    input    wire    reset_sw,
    output    wire    TMDS_tx_clk_p,        // Clock
    output    wire    TMDS_tx_clk_n,
    output    wire    TMDS_tx_2_G_p,        // Green
    output    wire    TMDS_tx_2_G_n,
    output    wire    TMDS_tx_1_R_p,        // Red
    output    wire    TMDS_tx_1_R_n,
    output    wire    TMDS_tx_0_B_p,        // Blue
    output    wire    TMDS_tx_0_B_n
);
    wire clk_100;
    wire pixclk;
    wire reset;
    wire locked;
    wire vga_red, vga_green, vga_blue;
    wire vga_hsync, vga_vsync;
    wire display_enable;
    
    pixclk_gen pixclk_gen_inst
    (// Clock in ports
        .CLK_IN1(sysclk),      // IN
        // Clock out ports
        .CLK_OUT1(clk_100),     // OUT
        .CLK_OUT2(pixclk),     // OUT
        // Status and control signals
        .RESET(reset_sw),// IN
        .LOCKED(locked)      // OUT
    );
    
    assign reset = !locked;
    
    CharDispCtrlerTest CharDispCtrlerTest_inst (
        .clk(pixclk),
        .reset(reset),
        .VGA_RED(vga_red),        // 1bit
        .VGA_GREEN(vga_green),    // 1bit
        .VGA_BLUE(vga_blue),    // 1bit
        .VGA_HSYNC(vga_hsync),
        .VGA_VSYNC(vga_vsync),
        .display_enable(display_enable)
    );

    // VGA解像度 PLL VCO Freq=400MHz ~ 1000MHz なので、25MHz入力クロックだと最初に20倍する必要がある。
    dvi_disp #(
        .PLL_CLKFBOUT_MULT(20),
        .PLL_CLKIN_PERIOD(40.0),
        .PLL_CLKOUT0_DIVIDE(2),
        .PLL_CLKOUT1_DIVIDE(20),
        .PLL_CLKOUT2_DIVIDE(10))
    dvi_disp_inst (
        .pixclk(pixclk),
        .reset_in(reset),
        .red_in({8{vga_red}}),
        .green_in({8{vga_green}}),
        .blue_in({8{vga_blue}}),
        .hsync(vga_hsync),
        .vsync(vga_vsync),
        .display_enable(display_enable),
        .TMDS_tx_clk_p(TMDS_tx_clk_p),
        .TMDS_tx_clk_n(TMDS_tx_clk_n),
        .TMDS_tx_2_G_p(TMDS_tx_2_G_p),
        .TMDS_tx_2_G_n(TMDS_tx_2_G_n),
        .TMDS_tx_1_R_p(TMDS_tx_1_R_p),
        .TMDS_tx_1_R_n(TMDS_tx_1_R_n),
        .TMDS_tx_0_B_p(TMDS_tx_0_B_p),
        .TMDS_tx_0_B_n(TMDS_tx_0_B_n)
    );
endmodule    

`default_nettype wire


CharDispCtrlerTest_HDMI_tb.v を下に貼っておく。

module CharDispCtrlerTest_HDMI_tb;

    // Inputs
    reg sysclk;
    reg reset_sw;

    // Outputs
    wire    TMDS_tx_clk_p;        // Clock
    wire    TMDS_tx_clk_n;
    wire    TMDS_tx_2_G_p;        // Green
    wire    TMDS_tx_2_G_n;
    wire    TMDS_tx_1_R_p;        // Red
    wire    TMDS_tx_1_R_n;
    wire    TMDS_tx_0_B_p;        // Blue
    wire    TMDS_tx_0_B_n;

    // Instantiate the Unit Under Test (UUT)
    CharDispCtrlerTest_HDMI uut (
        .sysclk(sysclk), 
        .reset_sw(reset_sw), 
        .TMDS_tx_clk_p(TMDS_tx_clk_p),
        .TMDS_tx_clk_n(TMDS_tx_clk_n),
        .TMDS_tx_2_G_p(TMDS_tx_2_G_p),
        .TMDS_tx_2_G_n(TMDS_tx_2_G_n),
        .TMDS_tx_1_R_p(TMDS_tx_1_R_p),
        .TMDS_tx_1_R_n(TMDS_tx_1_R_n),
        .TMDS_tx_0_B_p(TMDS_tx_0_B_p),
        .TMDS_tx_0_B_n(TMDS_tx_0_B_n)
    );

    parameter PERIOD = 10;
    parameter real DUTY_CYCLE = 0.5;
    parameter OFFSET = 0;

    initial    // Clock process for clk
    begin
        #OFFSET;
        forever
        begin
            sysclk = 1'b0;
            #(PERIOD-(PERIOD*DUTY_CYCLE)) sysclk = 1'b1;
            #(PERIOD*DUTY_CYCLE);
        end
    end

    // Instantiate the Unit Under Test (UUT)
    defparam uut.CharDispCtrlerTest_inst.ENABLE_COUNT = 23'd000004; // シミュレーション

    initial begin
        // Initialize Inputs
        reset_sw = 1'b1;

        // Wait 100 ns for global reset to finish
        #100;
        reset_sw = 1'b0;
        
        // Add stimulus here
        #20000000    $stop;
    end
      
endmodule

  1. 2012年02月20日 04:49 |
  2. DVI, HDMI
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
http://marsee101.blog.fc2.com/tb.php/2069-bf653e8f
この記事にトラックバックする(FC2ブログユーザー)