FC2カウンター FPGAの部屋 VivadoでZYBOのAXI4 Slave キャラクタ・ディスプレイ・コントローラ12(Verilog HDLソース2)
FC2ブログ

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

FPGAの部屋

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

VivadoでZYBOのAXI4 Slave キャラクタ・ディスプレイ・コントローラ12(Verilog HDLソース2)

VivadoでZYBOのAXI4 Slave キャラクタ・ディスプレイ・コントローラ11(Verilog HDLソース1)”の続き。

Verilog HDLのソースコードの第2弾。CharDispCtrler.v から貼っておく。

// CharDispCtrler.v
// キャラクタ ディスレイ コントローラ
// processor_dout, display_doutのビット構成 bit9 - RED, bit8 - GREEN, bit7 - BLUE, bit6〜0 : キャラクタデータ
//
// 2010/06/21 : Ver.1.1 : display_enableを追加
// 2012/02/24 : R 3bit, G 3bit, B 3bit, キャラクタ 7bitの16ビットに変更した。
// 2012/02/25 : プロセッサ側のクロックと画像表示用クロックを分けた。

`default_nettype none
`timescale 1ns / 1ps

module CharDispCtrler # (
        parameter integer RESOLUTION    = 1    // SVGA
    )
    (axi4clk, pixclk, reset_axi, reset_pix, processor_addr, processor_din, processor_dout, processor_we, VGA_RED, VGA_GREEN, VGA_BLUE, VGA_HSYNC, VGA_VSYNC, display_enable);
    `include "video_timing_param.vh"
    `include "convenient_functions.vh"

    input wire axi4clk;
    input wire pixclk;
    input wire reset_axi;
    input wire reset_pix;
    input wire [log2(ALL_CHAR_SIZE)-1:0] processor_addr;
    input wire [15:0] processor_din;
    output wire [15:0] processor_dout;
    input wire processor_we;

    output [COLOR_ATTRIB_WIDHT-1 : 0]    VGA_RED;
    output [COLOR_ATTRIB_WIDHT-1 : 0]    VGA_GREEN;
    output [COLOR_ATTRIB_WIDHT-1 : 0]    VGA_BLUE;
    output VGA_HSYNC;
    output VGA_VSYNC;
    output wire display_enable;

    wire [COLOR_ATTRIB_WIDHT-1 : 0]    VGA_RED;
    wire [COLOR_ATTRIB_WIDHT-1 : 0]    VGA_GREEN;
    wire [COLOR_ATTRIB_WIDHT-1 : 0]    VGA_BLUE;
    wire VGA_HSYNC;
    wire VGA_VSYNC;

    wire [log2(H_SUM)-1:0] h_addr; // 水平のドットアドレス
    wire [log2(V_SUM)-1:0] v_addr; // 垂直のドットアドレス
    wire h_sync_pulse;
    reg [COLOR_ATTRIB_WIDHT-1 : 0]    red_node, green_node, blue_node;
    reg [6:0] char_data_node;
    reg [log2(ALL_CHAR_SIZE)-1:0] temp_pointer;
    wire page_start, display_on;
    wire h_sync_0, v_sync_0;
    reg h_sync_1, v_sync_1;
    reg h_sync_2, v_sync_2;
    reg h_sync_3, v_sync_3;
    reg [log2(ALL_CHAR_SIZE)-1:0] display_addr;
    wire [15:0] display_dout;
    wire [7:0] char_data;
    reg [RED_DOT_POS:BLUE_DOT_POS-COLOR_ATTRIB_WIDHT+1] temp_color;
    reg display_on_d1, display_on_d2;

    frame_buffer #(
        .RESOLUTION(RESOLUTION)
    ) frame_buffer_inst (
        .clka(axi4clk),
        .clkb(pixclk),
        .reset_a(reset_axi),
        .reset_b(reset_pix),
        .processor_addr(processor_addr),
        .processor_din(processor_din),
        .processor_dout(processor_dout),
        .processor_we(processor_we),
        .display_addr(display_addr),
        .display_dout(display_dout)
    );

    char_gen_rom char_gen_rom_inst (
        .clk(pixclk),
        .reset(reset_pix),
        .char_addr(display_dout[6:0]),
        .row_addr(v_addr[2:0]),
        .dout(char_data)
    );

    disp_timing #(
        .RESOLUTION(RESOLUTION)
    ) disp_timing_inst (
        .clk(pixclk),
        .reset(reset_pix),
        .page_start(page_start),
        .display_on(display_on),
        .h_addr(h_addr),
        .v_addr(v_addr),
        .h_sync(h_sync_0),
        .h_sync_pulse(h_sync_pulse),
        .v_sync(v_sync_0)
    );

    always @(posedge pixclk) begin // display_onを2クロック遅延する。下の表示部分はframe_buffer, キャラジェネROMで2クロックデータが遅延している。それを吸収するためにdisplay_onを2クロック遅延した信号を作る
        if (reset_pix) begin
            display_on_d1 <= 1'b0;
            display_on_d2 <= 1'b0;
        end else begin
            display_on_d1 <= display_on;
            display_on_d2 <= display_on_d1;
        end
    end
    assign display_enable = display_on_d2;

    always @(posedge pixclk) begin // キャラジェネROM、赤、緑、青のビット
        if (reset_pix) begin
            red_node <= 3'b111;
            green_node <= 3'b111;
            blue_node <= 3'b111;
            char_data_node <= 0;
            temp_color <= 0;
        end else begin
            if (h_addr[2:0] == 3'd2) begin // 最初の時、なぜ2かと言うと0でframe_bufferのアドレスが変化して、データが出るのが1クロック後、さらにそのデータからキャラクタROMのデータが出るのが更に1クロック後だから
                char_data_node <= char_data[7:1];
                temp_color <= display_dout[RED_DOT_POS : BLUE_DOT_POS-COLOR_ATTRIB_WIDHT+1]; // 最後に色データがなくなってしまうのでとりあえず保存しておく
                if (char_data[0]==1'b1 && display_on_d2==1'b1) begin // 最初はシフトレジスタにロードするのと同時なので直接0ビット目を判定する。表示領域のときだけ映像信号を出力
                    red_node <= display_dout[RED_DOT_POS : RED_DOT_POS-COLOR_ATTRIB_WIDHT+1];
                    green_node <= display_dout[GREEN_DOT_POS : GREEN_DOT_POS-COLOR_ATTRIB_WIDHT+1];
                    blue_node <= display_dout[BLUE_DOT_POS : BLUE_DOT_POS-COLOR_ATTRIB_WIDHT+1];
                end else begin
                    red_node <= 3'b000;
                    green_node <= 3'b000;
                    blue_node <= 3'b000;
                end
            end else begin
                char_data_node <= {1'b0, char_data_node[6:1]}; // 1ビット右シフト
                if (char_data_node[0]==1'b1 && display_on_d2==1'b1) begin // シフトデータを判定
                    red_node <= temp_color[RED_DOT_POS : RED_DOT_POS-COLOR_ATTRIB_WIDHT+1]; // 以降は保存した色データから判断
                    green_node <= temp_color[GREEN_DOT_POS : GREEN_DOT_POS-COLOR_ATTRIB_WIDHT+1];
                    blue_node <= temp_color[BLUE_DOT_POS : BLUE_DOT_POS-COLOR_ATTRIB_WIDHT+1];
                end else begin
                    red_node <= 3'b000;
                    green_node <= 3'b000;
                    blue_node <= 3'b000;
                end
            end
        end
    end
    assign VGA_RED = red_node;
    assign VGA_GREEN = green_node;
    assign VGA_BLUE = blue_node;

    always @(posedge pixclk) begin // 表示するフレームバッファのアドレスを生成
        if (reset_pix) begin
            display_addr <= 0;
            temp_pointer <= 0;
        end else begin
            if (display_on == 1'b1)  begin // 1キャラクタのラスタが終了のときにアドレスを+1
                if (h_addr[2:0] == 3'd7) // 1キャラクタのラスタが終了のときにアドレスを+1
                    display_addr <= display_addr + 1;
            end else begin // 非表示領域
                if (v_sync_0 == 1'b1) begin // 垂直同期のときはdisplay_addrを0クリア
                    display_addr <= 0;
                    temp_pointer <= 0;
                end else if (h_sync_pulse == 1'b1) begin // 水平同期のとき
                    if (v_addr[2:0] == 3'd7) // 最後のラスタ
                        temp_pointer <= display_addr; // 現在のアドレス値+1になっているので、そのままtemp_pointerに入れる
                    else // それ以外のラスタのとき
                        display_addr <= temp_pointer;
                end
            end
        end
    end

    always @(posedge pixclk) begin // 同期信号の位相を合わせる
        if (reset_pix) begin
            h_sync_1 <= 1'b0;
            v_sync_1 <= 1'b0;
            h_sync_2 <= 1'b0;
            v_sync_2 <= 1'b0;
            h_sync_3 <= 1'b0;
            v_sync_3 <= 1'b0;
        end else begin
            h_sync_1 <= h_sync_0;
            v_sync_1 <= v_sync_0;
            h_sync_2 <= h_sync_1;
            v_sync_2 <= v_sync_1;
            h_sync_3 <= h_sync_2;
            v_sync_3 <= v_sync_2;
        end
    end
    assign VGA_HSYNC = !h_sync_3;
    assign VGA_VSYNC = !v_sync_3;
endmodule

`default_nettype wire


次に、char_gen_rom.v を貼っておく。

// キャラクタジェネレータ用ROM

`default_nettype none
`timescale 1ns / 1ps

module char_gen_rom(clk, reset, char_addr, row_addr, dout);
    input clk;
    input reset;
    input [6:0] char_addr;
    input [2:0] row_addr;
    output [7:0] dout;
    
    wire clk;
    wire reset;
    wire [6:0] char_addr;
    wire [2:0] row_addr;
    wire [7:0] dout;
    
    wire [10:0] addr;
    
    assign addr = {1'b0, char_addr, row_addr};
    
    RAMB16_S9 #(
        .INIT_00(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_01(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_02(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_03(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_04(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_05(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_06(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_07(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_08(256'h0014147F147F1414000000000012243600080008080808080000000000000000), // #,",!, 
        .INIT_09(256'h0000000000081018004C322254081408002152240812254200083E483E093E08), // ',&,%,$
        .INIT_0A(256'h000808087F08080800492A1C7F1C2A4900040810101008040020100808081020), // +,*,),(
        .INIT_0B(256'h00010204081020400006060000000000000000007F0000000002040600000000), // /,.,-,,
        .INIT_0C(256'h001C22201820221C003E02041820221C001C080808080C080018244242422418), // 3,2,1,0
        .INIT_0D(256'h001010202040407E003C42423E02423C001E20201E02023E0020207E22242830), // 7,6,5,4
        .INIT_0E(256'h0004080C00000C000000000C00000C00003C42407C42423C003C42423C42423C), // ;,:,9,8
        .INIT_0F(256'h000800081020221C00040810201008040000003E003E00000020100804081020), // ?,>,=,<
        .INIT_10(256'h001C22010101221C003F41413F41413F0041417F2236141C005C2A155549221E), // C,B,A,@
        .INIT_11(256'h001C22710101221C000101013F01017F007F01013F01017F001F21414141211F), // G,F,E,D
        .INIT_12(256'h0022120A060A1222000E11101010103E001C08080808081C004141417F414141), // K,J,I,H
        .INIT_13(256'h001C22414141221C00416151494543410041414149556341003E020202020202),// O,N,M,L
        .INIT_14(256'h003C42403C02423C002111093F41413F005C26594141221C000101013F41413F), // S,R,Q,P
        .INIT_15(256'h00225555554949490008141422224141001C224141414141000808080808087F), // W,V,U,T
        .INIT_16(256'h0038080808080838003F02040810203F00080808081422410041221408142241), // [,Z,Y,X
        .INIT_17(256'h007F0000000000000000000000221408001C10101010101C0008083E083E1422), // _,^,],\
        .INIT_18(256'h0038040438000000001E22221E020200003C223C201C00000000000000180810), // c,b,a,`
        .INIT_19(256'h001C221C0C122C00000808081C081000001C021E221C0000003C22223C202000), // g,f,e,d
        .INIT_1A(256'h0024140C14240400000C1210100010000008080800080000002424241C040400), // k,j,i,h
        .INIT_1B(256'h0018242424180000002828282814000000545454542A00000018080808080800), // o,n,m,l
        .INIT_1C(256'h0018201804180000000404040C34000000202038243800000004041C241C0000), // s,r,q,p
        .INIT_1D(256'h00142A2A2A2200000008141422220000001824242424000000180808081C0800), // w,v,u,t
        .INIT_1E(256'h001008080C080810003E0408103E000000020408142200000022140814220000), // {,z,y,x
        .INIT_1F(256'h0000000000000000000000000000142800040808180808040008080808080808), //  ,~,},|
        .INIT_20(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_21(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_22(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_23(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_24(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_25(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_26(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_27(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_28(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_29(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_2A(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_2B(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_2C(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_2D(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_2E(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_2F(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_31(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_32(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_33(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_34(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_35(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_36(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_37(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_38(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_39(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_3A(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_3B(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_3C(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_3D(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_3E(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INIT_3F(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INITP_00(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INITP_01(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INITP_02(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INITP_03(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INITP_04(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INITP_05(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INITP_06(256'h0000000000000000000000000000000000000000000000000000000000000000),
        .INITP_07(256'h0000000000000000000000000000000000000000000000000000000000000000)
    ) CHAR_GEN_ROM_INST (
        .DO(dout),
        .DOP(),
        .ADDR(addr),
        .CLK(clk),
        .DI(8'd0),
        .DIP(1'b0),
        .EN(1'b1),
        .SSR(reset),
        .WE(1'b0)
    );
endmodule


VivadoでZYBOのAXI4 Slave キャラクタ・ディスプレイ・コントローラ13(Verilog HDLソース3)”に続く。
  1. 2014年06月29日 06:48 |
  2. ZYBO
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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