FC2カウンター FPGAの部屋 Spartan-6 FPGA SP605 評価キット
fc2ブログ

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

FPGAの部屋

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

SP605でキャラクタ・ディスプレイ・コントローラ4(CH7301C用のラッパー・ソースファイル)

一応、”SP605でキャラクタ・ディスプレイ・コントローラ3(実機でテスト)”の続き。
Yahooグループの方でリクエストがあったので、SP605でキャラクタ・ディスプレイ・コントローラのCH7301C用のラッパー・ソースファイルを貼っておく。

Clocking WizardのDCM_CLKGEN_S6は、下のように差動入力に設定して、200MHzから25MHzに落としてクロックとして、使っている。CLK_OUT2はCLK_OUT1より位相を90度ずらしている。
SP605_DVI_7_100623.png

SP605_DVI_9_100713.png

CharDispCtrlerTestは、”キャラクタ・ディスプレイ・コントローラのまとめ”からDCMを除いて、25MHzクロックで動作するようにしたものだ。display_enableは画像表示期間を示す信号だ。2つ下の階層のCharDispCtrler.vから、下のように引き出している。

assign display_enable = display_on_d2;


それ以外に変更はしていない(はず)。

CH7301Cのマニュアルを読むと分かるのだが、I2Cをいじらないデフォルト状態ではDouble Data Rateでデータを入れてやれば良い。DVIデジタルでも表示出来ている。

なお、いつも通りに、ソースファイルについて、一切の保証はしないので、ご承知おきください。

// CharDispCtrlerTest_SP605.v
// CharDispCtrlerTest.vのSP605用のラッパー、CH7301Cを使用する
//
// 2012/07/26 : ODDR2 のDDR_ALIGNMENTとSRTYPEを修正
//

`default_nettype none

module CharDispCtrlerTest_SP605 (
    input    wire            sysclk_p, sysclk_n,
    input    wire            reset_sw,
    output    wire            dvi_xclk_p, dvi_xclk_n,
    output    reg                dvi_de, dvi_h, dvi_v,
    output    wire    [11:0]    dvi_d,
    output    wire            dvi_reset_b,
    output    wire            dvi_sda,
    output    wire            dvi_scl
);
    wire clk, clkb;
    wire clk90, clk90b;
    wire clkdv;
    wire reset;
    wire locked;
    wire vga_red, vga_green, vga_blue;
    wire vga_hsync, vga_vsync;
    wire display_enable;
    
    DCM_CLKGEN_S6 clk200_DCM (
        .CLK_IN1_P          (sysclk_p),    // IN
        .CLK_IN1_N          (sysclk_n),    // IN
        // Clock out ports
        .CLK_OUT1           (clk),     // OUT
        .CLK_OUT2           (clk90),     // OUT
        // Status and control signals
        .RESET              (reset_sw),        // IN
        .LOCKED             (locked)      // OUT
    );
    assign reset = !locked;
    assign clkb = !clk;
    assign clk90b = !clk90;
//    assign dvi_reset_b = locked;
    assign dvi_reset_b = 1'b1;
    
    CharDispCtrlerTest CharDispCtrlerTest_inst (
        .clk(clk),
        .reset(reset),
        .VGA_RED(vga_red),
        .VGA_GREEN(vga_green),
        .VGA_BLUE(vga_blue),
        .VGA_HSYNC(vga_hsync),
        .VGA_VSYNC(vga_vsync),
        .display_enable(display_enable)
    );
    
    always @(posedge clk) begin
        if (reset) begin
            dvi_de <= 1'b0;
            dvi_h <= 1'b1;
            dvi_v <= 1'b1;
        end else begin
            dvi_de <= display_enable;
            dvi_h <= vga_hsync;
            dvi_v <= vga_vsync;
        end
    end
    
    // dvi_xclk_p : clkbと同位相
    ODDR2  #(
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_xclk_p  (
        .Q(dvi_xclk_p),            //  1-bit  DDR  output  data
        .C0(clk90),                //  1-bit  clock  input
        .C1(clk90b),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(1'b1),                //  1-bit  data  input  (associated  with  C0)    
        .D1(1'b0),                //  1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    // dvi_xclk_n : clkと同位相
    ODDR2  #(
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b1),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_xclk_n  (
        .Q(dvi_xclk_n),            //  1-bit  DDR  output  data
        .C0(clk90),                //  1-bit  clock  input
        .C1(clk90b),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(1'b0),                //  1-bit  data  input  (associated  with  C0)    
        .D1(1'b1),                //  1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    // DVI_D// DVI_D[0]
    ODDR2  #( 
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D0  (
        .Q(dvi_d[0]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_blue),            //  B0[0], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_green),            //  G0[4], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[1]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D1  (
        .Q(dvi_d[1]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_blue),            //  B0[1], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_green),            //  G0[5], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[2]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D2  (
        .Q(dvi_d[2]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_blue),            //  B0[2], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_green),            //  G0[6], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[3]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D3  (
        .Q(dvi_d[3]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_blue),            //  B0[3], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_green),            //  G0[7], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[4]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D4  (
        .Q(dvi_d[4]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_blue),            //  B0[4], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_red),            //  R0[0], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[5]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D5  (
        .Q(dvi_d[5]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_blue),            //  B0[5], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_red),            //  R0[1], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[6]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D6  (
        .Q(dvi_d[6]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_blue),            //  B0[6], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_red),            //  R0[2], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[7]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D7  (
        .Q(dvi_d[7]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_blue),            //  B0[7], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_red),            //  R0[3], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[8]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D8  (
        .Q(dvi_d[8]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_green),            //  G0[0], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_red),            //  R0[4], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[9]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D9  (
        .Q(dvi_d[9]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_green),            //  G0[1], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_red),            //  R0[5], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[10]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D10  (
        .Q(dvi_d[10]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_green),            //  G0[2], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_red),            //  R0[6], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );    
    
    ODDR2  #( // DVI_D[11]
        .DDR_ALIGNMENT("C0"),    //  Sets  output  alignment  to  "NONE",  "C0"  or  "C1"
        .INIT(1'b0),            //  Sets  initial  state  of  the  Q  output  to  1’b0  or  1’b1
        .SRTYPE("ASYNC")            //  Specifies  "SYNC"  or  "ASYNC"  set/reset
    )  ODDR2_D11  (
        .Q(dvi_d[11]),            //  1-bit  DDR  output  data
        .C0(clk),                //  1-bit  clock  input
        .C1(clkb),                //  1-bit  clock  input
        .CE(1'b1),                //  1-bit  clock  enable  input
        .D0(vga_green),            //  G0[3], 1-bit  data  input  (associated  with  C0)    
        .D1(vga_red),            //  R0[7], 1-bit  data  input  (associated  with  C1)
        .R(reset),                //  1-bit  reset  input
        .S(1'b0)                //  1-bit  set  input
    );
    
    SCCB_Reg_Controller I2C_Setting_inst (
        .clk(clk),
        .reset(reset),
        .SCL(dvi_scl),
        .SDA(dvi_sda)
    );
    
endmodule    


(2012/07/26:Verilogソースを修正)
ただし、Virtex-6では、ODDR2プリミティブではなく、ODDRプリミティブだったはずだ。

(2011/04/25:追記)
SP605では、CH7301Cの設定レジスタがコンフィグROMで初期化されていたようです。初期化されていないXUPV5-LX110Tでは、CH7301Cの設定レジスタを設定しないとディスプレイに表示できなかったです。
CH7301Cの設定レジスタを設定する必要があります。

(2011/04/26:追記)
現在使用しているCH7301Cの設定レジスタの設定値は、”XPS Thin Film Transistor(TFT) Controller (v2.00a)”の6ページの”Table 2: Chrontel CH-7301 Configuration Register Description”と同一の設定値を使用している。Table 2: Chrontel CH-7301 Configuration Register Descriptionを下に引用する。
XUPV5-LX110T_CDispC_1_110426.png

CH7301Cの設定レジスタを設定する回路は、OV7670のSCCB設定レジスタの設定回路のID_ADDRESSを0xECに変更して使用した。
SCCB設定レジスタ設定回路の資料。
SCCBインタフェース回路の実装1(タイミングチャート)
SCCBインタフェース回路の実装2(ブロック図の作成)
SCCBインタフェース回路の実装3(シミュレーション)
SCCBインターフェース回路の説明1(SCCB_Reg_Controller.vhd)
SCCBインターフェース回路の説明2(freqdiv.vhd、SCCB_reg_values_ROM.vhd)
SCCBインターフェース回路の説明3(One_Transaction_SCCB.vhd)

更に、OV9655のID_ADDRESSに書き換えたときの参考資料がここにある。

(2011/06/02:追記)
dvi_de, dvi_h, dvi_v の出力用FFがIOBにマップされないと画面が表示されないので、Verilogソースに(* IOB = "FORCE" *)制約を追加した。
  1. 2010年07月13日 20:45 |
  2. Spartan-6 FPGA SP605 評価キット
  3. | トラックバック:0
  4. | コメント:0

SP605のIBRETデザイン

SP605 GTP IBERT デザインの生成 (XTP066)”を見ながら、IBRETデザインを試してみた。
SP605 GTP IBERT デザインの生成 (XTP066)の11ページで紹介されていたSMAケーブルは、秋月電子から両端SMAケーブル RG-316(1.5m)を購入した。1本700円でとても安かった。多分、普通の値段の1/10くらいじゃないだろうか?これでも(と行っては失礼か?)ケーブルの特性的には3GHzまで通るそうだ。ということは6GbpsまでOKということか?
取り敢えず、12、13ページの用にSP605のSMAコネクタのJ32とJ34、J33とJ35をSMAケーブルで接続した。
14ページのOptical Loopback Adapterは買っていないので、このままやることにした。
IBERT_4_100703.jpg

ChipScope Pro (以下ChipScope)から、sp605_ibert.bitをコンフィギュレーションして、sp650_ibert.cpjのプロジェクトをロードする。
20ページで、GTPA1_DUAL_X0Y0_0とGTPA1_DUAL_X1Y0_1に近端PMAループバックを設定したつもりだったが、プロジェクトのデフォルト設定のままにしたら、近端PCSループバックだった。それで出たのが下の画像だ。
SP605_IBERT_1_100701.png

GTPA1_DUAL_X1Y0_0がNo Linkになっている。どうやらここが、SPFコネクタ/ケージのGTPトランシーバのようだ。GTPA1_DUAL_X0Y0_1がSMAケーブルで接続したGTPトランシーバらしいが、安いケーブルでも無事に2.5Gbpsでエラーなしに通信ができている。
あれ、やっているときは気がつかなかったが、両端の2つのGTPトランシーバは近端PCSループバックになっている。近端PMAループバックにするのを忘れてしまった。でも両端ともエラーはない。
さて、GTPA1_DUAL_X1Y0_0を近端PCSループバックにしてみた。だが、他のGTPトランシーバに比べて、RX Bit ErrorRatioが悪く、RX Received Bit Countもかなり出ている。(下図)どうしてだろうか?
SP605_IBERT_2_100701.png

GTPA1_DUAL_X1Y0_0を近端PMAループバックにしてみた。(下図)エラーはなくなってしまった。
SP605_IBERT_3_100701.png

どうしてだろうか?そこで、Spartan-6 FPGA GTPトランシーバ・ユーザーズガイド Ver.2.0 で調べてみた。67ページのループバックによると、近端PCSループバックが一番浅い所のループバック①で近端PMAループバックがそのつぎ②、遠端は通信相手のGTPトランシーバでループバック③、④する。下に英語版のFigure 2-14: Loopback Testing Overviewを引用する。
SP605_IBERT_4_100703.png

しかし、近端PCSループバックでエラーが出て、近端PMAループバックでエラーなしというのはどういう訳だろう?ループバックの部分が悪いのか?謎だ?でも近端PMAループバックでエラーなしなので、取り敢えずGTPトランシーバの動作には問題ないだろう?と思う。良かった。

(2010/07/13追記)
Xilinxのアンサーに”34203 - 11.x ChipScope - IBERT - Spartan-6、Virtex-5、Virtex-6 - PCS ループバックでエラー レートが増加する”というアンサーがあった。やはり、既知のバグのようです。
  1. 2010年07月03日 05:45 |
  2. Spartan-6 FPGA SP605 評価キット
  3. | トラックバック:0
  4. | コメント:0

SP605でキャラクタ・ディスプレイ・コントローラ3(実機でテスト)

SP605でキャラクタ・ディスプレイ・コントローラ2(シミュレーション)”で、SP605用のキャラクタ・ディスプレイ・コントローラのシミュレーションが終わったので、今度は実機でインプリメントして実機でテストしみた。

SP605は200MHzのLVDS出力のオシレータを使っているので、それをClocking WizardのIPで25MHzに落としているのだが、PLLと2種類のDCMのうちのどれを使っているかがわからない?
SP605_DVI_7_100623.png

そこでインプリメント後にどれを使っているのかを調べてみた。
SP605_DVI_8_100623.png

PLL_ADVが使われているようだ。
できたビットファイルをiMPACTでSP605にダウンロードし、液晶ディスプレイをVGAポートで接続した。
SP605_DVI_5_100623.jpg

しかし、真っ暗で同期も取れていない。つまり信号が出ていないみたい。
がっくりしたが、どうなっているかを見るためにChipScopeをいれた。ChipScopeをみたところ、HSYNCもVSYNCもvga_red, vga_green, vga_blueもしっかり出ている。おかしいと思って、液晶ディスプレイを見てみるとキャラクタが表示されていた。どういうこと?
SP605_DVI_6_100623.jpg

同じビットファイルをiMPACTでもう一度やってみると、真っ暗。ということはiMPACTでだめでChipScopeからダウンロードするとOK???
念のため、ChipScopeのILAコアを抜いてやってみたが、やはりiMPACTでだめでChipScopeからダウンロードするとOK。。。
なぜ~???ということで色々やってみた。ある時、リセットボタンを押すと画面が真っ暗になることがわかった。でもChipScopeでみると映像用の信号は出ている。ということは、CH7301Cへのリセットが怪しい?
早速、CH7301Cへのリセット記述を、

assign dvi_reset_b = locked;


から、

assign dvi_reset_b = 1'b1;


に変更して、リセットを止めた。すると、iMPACTでダウンロードしてもキャラクタが表示されるようになった。
図に示すと下のようになる。
SP605_DVI_block_fig_100625.png

最初はPLL_BASEのLOCKED端子からDVI_RESET_B(CH7301CのRESET*)に出力していたが、それをやめて、DVI_RESET_Bは1レベルに固定した。

データシートには、リセットの詳しい記述が無かったが、リセットの掛け具合が問題なんだろうか?もしかするとI2Cでリセットする必要があるんだろうか?取り敢えずリセットを外したらOKなので、これで行くことにする。
これでCH7301Cも今まで同様な信号をDDRで入れれば良いことがわかった。これからの展開が楽になった。

次は、SMAケーブルを秋月から購入したので、MGTトランシーバをテストしてみたい。

(2010/07/07:追記)
アナログVGA信号接続でキャラクタが表示されたが、デジタルのDVIでも問題なくキャラクタが表示できた。
これで、VGA信号を入れれば、アナログVGAポート、デジタルのDVIポート両方共、問題なく表示できることがわかった。
  1. 2010年06月25日 04:39 |
  2. Spartan-6 FPGA SP605 評価キット
  3. | トラックバック:0
  4. | コメント:0

SP605でキャラクタ・ディスプレイ・コントローラ2(シミュレーション)

SP605でキャラクタ・ディスプレイ・コントローラ1”で試みていたシミュレーションができて、動作が確認できた。
やはり、キャラクタ・ディスプレイ・コントローラの文字を書いていくスピードは、人間が目で追えるくらいにしているので、そのままでシミュレーションすると20msecシミュレーションしてもデータがほんの少ししか見えない。そこで、文字を書いていくスピードを早くすることにした。
CharDispCtrlerTest.vでは、

parameter ENABLE_COUNT = 23'd250000; // インプリメント


としているが、一番上のテストベンチからdefparamで小さい値に書き換えている。

defparam uut.CharDispCtrlerTest_inst.ENABLE_COUNT = 23'd000004; // シミュレーション


これでシミュレーションを実行した。(Verilogは上の階層からdefparamで書き換えられるのが便利だが、書き換えたのを忘れてしまうと、どうしてそうなるのかが分かりにくくなるのが欠点か?)
SP605_DVI_4_100623.png

dvi_xclk_p, dvi_xclk_nから90度位相がずれて、dvi_d[11:0]が出力されているのが見える。
これでシミュレーションは取り敢えず完了ということにして、実機で確認してみることにする。
  1. 2010年06月24日 05:14 |
  2. Spartan-6 FPGA SP605 評価キット
  3. | トラックバック:0
  4. | コメント:4

SP605でキャラクタ・ディスプレイ・コントローラ1

SP605でCH7301Cを使用してキャラクタ・ディスプレイ・コントローラを作ろうとしている。
以前、Spartan-3 Starter Kit用に作ったキャラクタ・ディスプレイ・コントローラをSP605のCH7301Cを使用するように改造した。
一応、Verilogの構文エラーは修正して、ISEでインプリメントすることができた。
SP605_DVI_1_100623.png

いきなりSP605にダウンロードして試すのは不安なので、シミュレーションをすることにした。シミュレータはSecureIPでないので、久しぶりにVeritakを使用することにした。最新のBasic版、Ver.3.80Aをダウンロードして、起動し、プロジェクトを生成した。コンパイルしてみたが、今のところglbl.vがトップになってしまう。
SP605_DVI_2_100623.png

現在、原因を調査中だ。久しぶりにVeritakを使ったので、使い方を忘れてしまった。自分の過去ブログ記事を参照しながらトラブルシュートすることにする。

(追加)
今、眺めていたら気がつきました。テストベンチのファイルを入れていなかった。。。大失敗。家に帰ったら入れてやってみます。

(もう一度追記)
テストベンチを入れて、プロジェクトからunisimsとXilinxcoreLibを抜いて、Xilinx Lib SettingでXilinxCoreLibにチェックを入れたら、うまく行きました。
SP605_DVI_3_100623.png

  1. 2010年06月23日 05:49 |
  2. Spartan-6 FPGA SP605 評価キット
  3. | トラックバック:0
  4. | コメント:0

CH7301C DVI Transmitter Device

Spartan-6 FPGA SP605評価キットに搭載されているCH7301C DVI Transmitter Deviceの使い方をマニュアルで調べてみた。SP605にCMOSカメラをつないで、DVIかVGAからディスプレイに出力してみたい。また、DVI、VGAに出力できると、SP605をパーソナルコンピュータ・システムとすることが出来そうだ。CH7301CはRGBやYCrCbデータをDVIやVGA信号に変換するICだ。

はじめは何が何だかわからなかったが、読み進めていくうちに、大体わかったような気になってきた。CH7301CはCMOSカメラと同様にI2Cで設定をするようになっている。データバスはD[11:0]の12ビット、H (Horizontal Sync), V (Vertical Sync), DE (Data Enable) の入力がある。データバスが12ビットでRGB、8ビット×3 = 24ビットの半分であるため、データはDDRで入れるか、クロックを2倍にする。
RGBのデータは24ビットのモードもあるが、16ビット、15ビット、更にはYCrCbで入れるモードもある。データシートの8ページから引用する。

IDF Description
0  12-bit multiplexed RGB input (24-bit color), (multiplex scheme 1)
1  12-bit multiplexed RGB2 input (24-bit color), (multiplex scheme 2)
2  8-bit multiplexed RGB input (16-bit color, 565)
3  8-bit multiplexed RGB input (15-bit color, 555)
4  8-bit multiplexed YCrCb input (24-bit color), (Y, Cr and Cb are multiplexed)


デフォルトのIDF=0でOK。他も見た限りはデフォルトでOKのようだ。
ちなみにレジスタの設定方法はアプリケーション・ノートがある。
だいたいプロトコルは、基本的なプロトコルは前回のCMOSカメラのSCCBプロトコルと同様かな?と思う。デバイスアドレスを変更すれば良いような気がする。まあ~、取り敢えずデフォルトで行って、まずかったらレジスタの値を変更することにする。
SCCB_timing_chart_091215.png

キャラクタ・ディスプレイ・コントローラ回路を改造して、SP605に載せてみて、ディスプレイに表示出来るかを試してみることにする。
  1. 2010年06月19日 20:28 |
  2. Spartan-6 FPGA SP605 評価キット
  3. | トラックバック:0
  4. | コメント:0

SP605でPCIe Coreを生成してみる3(PCIeユーザーズガイドを調べる)

SP605でPCIe Coreを生成してみる2(シミュレーション)”の続き。

ISimのログには、Running default test {sample_smoke_test0}......と表示されていた。”Spartan-6 FPGA PCI Express 用インテグレイテッド エンドポイント ブロック ユーザー ガイド (英語版)”のRoot Port Model Test BenchのTest Selection (114ページ) には、sample_smoke_test0, sample_smoke_test1, pio_writeReadBack_test0, pio_testByteEnables_test0 ,pio_memTestDataBus...のテストが並んでいる。そのうち、前回、デフォルトでは、sample_smoke_test0を行ったわけだ。
sample_smoke_test0は、 PCI Type 0 Configuration Read TLPを発行して、completion TLPを待つそうだ。これはRoot Port Model側の動作になる。Readを要求するのは、Device/Vendor ID valueだ。
sample_smoke_test0のテストベンチが記述されているのは、s6_pcie_v1_3\simulation\testsフォルダのtests.vだった。ここには、sample_smoke_test1も記述されている。sample_smoke_test1はsample_smoke_test0をforkを使って、2スレッドにしたものだそうだ。
sample_smoke_test0とsample_smoke_test1をどうやって切り替えるかだが、$value$plusargsを使って切り替えている。(これ以前、たっくさんにお聞きしたような?Veritakのテストで使われていたと思った)
$value$plusargsを使用すると、ISimを起動するコマンドラインから、テストベンチを指定できる。つまり、リコンパイルしないでテストベンチを切り替えることができる。
s6_pcie_v1_3\simulation\testsフォルダのtests.vの関連する記述を一部下に引用する。

  initial begin
    if ($value$plusargs("TESTNAME=%s", testname))
      $display("Running test {%0s}......", testname);
    else
    begin
      testname = "sample_smoke_test0";
      $display("Running default test {%0s}......", testname);
    end


TESTNAME=で指定されたテストベンチを実行し、TESTNAME=がなければ、sample_smoke_test0を実行して、そうでなければ、TESTNAME=で指定されたテストベンチを実行するわけだ。下のように記述すると、GUIモードで、sample_smoke_test1を実行する。

demo_tb.exe -gui -testplusarg TESTNAME=sample_smoke_test1


下に実行した時のログを示す。

Simulator is doing circuit initialization process.
Running test {sample_smoke_test1}......
[ 0] : System Reset Asserted...
Finished circuit initialization process.
[ 399600000] : System Reset De-asserted...
[ 960680600] : Transaction Reset Is De-asserted...
board.EP.s6_pcie_v1_3_i.PCIE_A1.B_PCIE_A1_INST.SHIP.SHELL.BUT.pcie_pcie_inv.pcie_pcie.pcie_core.xil_pcie_sa_mod18.xil_pcie_sa_mod19.com.tlm.u_tlm_rx.xil_pcie_sa_mod75 checking
[ 1894626600] : Transaction Link Is Up...
[ 1895816600] : TSK_PARSE_FRAME on Transmit
[ 2233396600] : TSK_PARSE_FRAME on Receive
[ 2295792600] : Check Device/Vendor ID - PASSED
[ 2296992600] : TSK_PARSE_FRAME on Transmit
[ 2559776600] : TSK_PARSE_FRAME on Receive
[ 2696968600] : Check CMPS ID - PASSED
[ 2696968600] : SYSTEM CHECK PASSED
[ 2696968600] : Reading from PCI/PCI-Express Configuration Register 0x00
[ 2696968600] : Expected Device/Vendor ID = 000710ee
[ 2698168600] : TSK_PARSE_FRAME on Transmit
[ 2962954600] : TSK_PARSE_FRAME on Receive
[ 2962954600] : Received CPLD --- Tag 0x00
[ 2962954600] : TEST PASSED --- Finished transmission of PCI-Express TLPs
[ 2963354800] : Reading Cfg Addr [0x00000001]
[ 2966951800] : Writing Cfg Addr [0x00000001]
[ 2970552600] : Reading Cfg Addr [0x00000001]
Stopped at time : 29734527 ps : File "H:/HDL/FndtnISEWork/Spartan6/sp605_pcie_ISE121/s6_pcie_v1_3/simulation/tests/tests.v" Line 205


この使い方は、ISim シミュレーション実行ファイル コマンドのオプションに書いてあった。
しかし、上に書いたpio_writeReadBack_test0, pio_testByteEnables_test0 ,pio_memTestDataBus...のテスト項目はtests.vにはなかった。どこにあるんだろうか?
もしかして、WebPACKだからなのか?フルバージョンで確かめてみることにする。
  1. 2010年05月20日 05:51 |
  2. Spartan-6 FPGA SP605 評価キット
  3. | トラックバック:0
  4. | コメント:0
»