Verilog ビデオ信号出力(アナログRGB)

忘れないように。
1920x1080@60fpsの場合
ビデオ期間とhsyncの関係
f:id:katakanan:20171114115612p:plain

ビデオ期間とvsyncの関係
f:id:katakanan:20171114115713p:plain:w400

50fpsだとフロントポーチ、バックポーチの各値が違う。
hが横方向のピクセルを、vを縦のラインを数えていくカウンターを用意して、
適当な値になったらvsyncやhsyncを上げればよさそう。

module main(
    clk,
    resetn,
    rout,
    gout,
    bout,
    vsync,
    hsync    
    );

    localparam HDISP = 1920;
    localparam HSSTART = 2008;
    localparam HSEND = 2052;
    localparam HTOTAL = 2200;

    localparam VDISP = 1080;
    localparam VSSTART = 1084;
    localparam VSEND = 1089;
    localparam VTOTAL = 1125;

    input wire clk;
    input wire resetn;
    output reg[7:0] rout;
    output reg[7:0] gout;
    output reg[7:0] bout;
    output reg vsync;
    output reg hsync;
    
    reg[10:0] vcounter;//0 ~ 1124
    reg[11:0] hcounter;//0 ~ 2199
    wire vcount;
    wire disp;
    
    assign vcount = (hcounter == HTOTAL-1)? 1:0;
    assign disp = ((hcounter < HDISP) && (vcounter < VDISP))?1:0; 

    always@(posedge clk)begin
        if(resetn == 1'b0)begin
            vcounter <= 12'b0;
            hcounter <= 12'b0;
    end
        else begin  
            hcounter <= hcounter + 1;

        
            if(hcounter == HTOTAL-1)begin
                hcounter <= 12'b0;
            end
            
            if(vcount == 1'b1)begin
                        vcounter <= vcounter + 1;
            
                        if(vcounter == VTOTAL-1)begin
                            vcounter <= 11'b0;
                        end
            end
            
        end
    end
        
    wire rpattern;
    wire gpattern;
    wire bpattern;
    
    wire vsync_b;
    wire hsync_b;
    
    ///<240 <480 <720 <960 <1200 <1440 <1680 <1920 hcounter
    //r 0    0     0    0   1      1     1     1
    //g 0    0     1    1   0      0     1     1
    //b 0    1     0    1   0      1     0     1
    
    assign rpattern =   ((960 <= hcounter)&&(hcounter < 1920))? 1:0;
    assign gpattern =   (((480  <= hcounter)&&(hcounter < 960))||
                        ((1440 <= hcounter)&&(hcounter < 1920)))? 1:0;
    assign bpattern =   (((240  <= hcounter)&&(hcounter < 480))||
                        ((720  <= hcounter)&&(hcounter < 960))||
                        ((1200  <= hcounter)&&(hcounter < 1440))||
                        ((1680  <= hcounter)&&(hcounter < 1920)))? 1:0;
    
    assign vsync_b = ((VSSTART <= vcounter) && (vcounter <  VSEND))? 1:0;
    assign hsync_b = ((HSSTART <= hcounter) && (hcounter <  HSEND))? 1:0;
    
    always@(posedge clk)begin
        if(resetn == 1'b0)begin
            vsync <= 1'b0;
            hsync <= 1'b0;
            rout <= 8'b0;
            gout <= 8'b0;
            bout <= 8'b0;
        end
        else begin
            vsync <= vsync_b;
            hsync <= hsync_b;
            
            if(disp == 1'b1)begin
                rout <= {8{rpattern}};
                gout <= {8{gpattern}};
                bout <= {8{bpattern}};
            end
            else begin
                rout <= 8'b0;
                gout <= 8'b0;
                bout <= 8'b0;
            end
            
        end
    end

endmodule

clkはFullHDのピクセルクロックの148.5MHzを入れる。
とりあえずカラーバーを表示。
f:id:katakanan:20171114120837p:plain
よさそう。
ここに8bitのDACなどをつければビデオが表示できるはず。