FC2カウンター FPGAの部屋 ビットマップ・ディスプレイ・コントローラの作製21(画面にキャラクタを描画)
FC2ブログ

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

FPGAの部屋

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

ビットマップ・ディスプレイ・コントローラの作製21(画面にキャラクタを描画)

ビットマップ・ディスプレイ・コントローラの作製20(DDR2をMicroBlazeと接続)”の続き。

XPSプロジェクトには、キャラクタROMのAXI4 Lite IPが入っている。実は今回のビットマップ・ディスプレイ・コントローラをMircoBlazeからテストするためにキャラクタROMのAXI4 Lite IPを作った。(”AXI4 Lite Slave IPの作製”を参照のこと)
これをMicroBlazeから読みだして、MicroBlazeでDDR2 SDRAMのビデオ・フレームバッファに書き込めば、キャラクタを表示することが出来る。
SDKでソフトウェアを書いてやってみたらディスプレイにキャラクタを書くことに成功した。下にCのソフトウェアを示す。なお、xparameters.hのアドレス定義を使うとなぜか?うまくいかないので、アドレスは直書きしている。

/* * drawn_disp.c * *  Created on: 2012/08/23 *      Author: Masaaki */

// char_draw: アドレスとキャラクタコードを受け取ってそのキャラクタを描画する
// addr : 描画するキャラクタのスタートアドレス
// char_code : 描画するキャラクタのコード
// char_color : 描画するキャラクタのカラー、32ビットで表される、0RGBと8ビットずつで表す
// 戻り値:次のキャラクタの描画先頭アドレスを示す。
unsigned int *char_draw(unsigned int *addr, unsigned char char_code, unsigned int char_color){
    int i,j;
    unsigned int char_pattern;
    unsigned int char_code_int;
    unsigned int *cal_char_addr;
    unsigned int *return_addr;

    char_code_int = (unsigned int)(char_code);
    return_addr = addr + 8;
    cal_char_addr = 0x7f800000+((char_code_int<<3)<<2); // キャラジェネROMのデータは32ビット幅で下の8ビットだけ有効
    for(i=0; i<8; i++){
        char_pattern = *(volatile unsigned int *)(cal_char_addr); // キャラクタのパターンを読み出し
        for(j=0; j<8; j++){
            if(char_pattern & 0x1// 7ビット目が1の時はドットを描画
                *(volatile unsigned int *)((unsigned int)addr ^ 4) = char_color;
            else
                *(volatile unsigned int *)((unsigned int)addr ^ 4) = 0// 黒を描画
            addr++;
            char_pattern >>= 1// キャラクタのパターンを1ビット右シフト
        }
        addr -= 8// 行の最初のアドレスに戻す
        addr += 640// アドレスを1行下にする
        cal_char_addr++;
    }

    return return_addr;
}

int main()
{
    unsigned char char_code;
    unsigned int * ddr2_addr;
    unsigned int coler_code;
    unsigned int char_cnt;
    int i, j;

    for (ddr2_addr=0x20000000; ddr2_addr<0x2012C000; ddr2_addr++){
        *(volatile unsigned int *)((unsigned int)ddr2_addr ^ 4) = 0;
    }
    
    ddr2_addr = 0x20000000;
    char_cnt = 0;
    for(j=0; j<8; j++){
        for(i=1; i<8; i++){
            switch(i){
                case 1 :
                    coler_code = 0xff;
                    break;
                case 2 :
                    coler_code = 0xff00;
                    break;
                case 3 :
                    coler_code = 0xffff;
                    break;
                case 4 :
                    coler_code = 0xff0000;
                    break;
                case 5 :
                    coler_code = 0xff00ff;
                    break;
                case 6 :
                    coler_code = 0xffff00;
                    break;
                case 7 :
                    coler_code = 0xffffff;
            }
            
            for(char_code=0x21; char_code<0x80; char_code++){
                if(char_code >= 0x80// キャラクタコードが上限に達したら、一番下に戻す
                    char_code = 0x21;
                if (char_cnt!=0 && char_cnt%80==0)
                    ddr2_addr = (unsigned int)ddr2_addr + 640*4*7// 1行書き終わったので、下の行に、アドレスは640ドットx1ピクセル4バイトx7行
                ddr2_addr = char_draw(ddr2_addr, char_code, coler_code); // キャラクタを描画
                char_cnt++;
            }
        }
    }

    return 0;
}


このソフトウェアを実行した後のディスプレイの写真を下に示す。
BitMapDispCont_134_120826.png

(2012/08/28:追記)
なぜ、DDR2 SDRAMにデータを書く時に、4とXORを取っているかだが( *(volatile unsigned int *)((unsigned int)addr ^ 4) )、それは、AXI4バスはリトル・エンディアンだが、WriteとReadのデータバス幅が異なるFIFOのデータの出てくる順番はビック・エンディアンだからだ。(”Write側とRead側のデータ幅の異なるFIFOのシミュレーション2”を参照のこと)
MicroBlazeのデータバス幅は32ビット、ビットマップ・ディスプレイ・コントローラとMCBの接続されているAXI4バスのデータバス幅は64ビットで、その間をaxi2axi_connector で接続している。32ビット・データバスのMicroBlazeからDDR2 SDRAMにWriteする時に、Writeデータは64ビットの半分の32ビットで、リトル・エンディアンであるため、低いアドレスのデータはMSBの方の32ビットにWriteされる。ビットマップ・ディスプレイ・コントローラは64ビット・データバスでそのデータをReadして、ビック・エンディアンのWriteとReadのデータバス幅が異なるFIFOのデータでとり出すので、4バイト境界でアドレスが反対になる(MicroBlazeのデータWriteは4バイト長のみとする)。そこで、4とXORを取って4バイト境界のアドレスを反転して、MicroBlazeからデータをWriteしている。こうしないとキャラクタがうまく描画できないのだ。
  1. 2012年08月26日 06:10 |
  2. AXI4 Master IPの作製
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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