清霜一梦

单色VGA显示verilogHDL通用代码

0
阅读(1900)

今天做VGA,真是拼凑了好久啊。唉,总算完成了。

  本来想偷懒移植,最后还是自己写的代码。

//2015/12/13
//designer : pengxiaoen 
//function : vga control
/*备注:
    1,三个test pin 是用来测试pll是否工作
    2,r,g,b 三色分别对应三个不同的key 以及三个led进行显示
    3,因为这个板子的 r ,g ,b  分别只有一个pin ,显示色彩有限
*/
module vga_top (
                clock ,
                rst_n ,
                key_r,key_g,key_b ,
                
                clk_vga ,clk_board, clk_500k ,  //test pin  
                led_r ,led_g,led_b ,
                
                vga_hs ,vga_vs,vga_r,vga_g,vga_b 
                
                );
input clock ; 
input rst_n ; 
input key_r,key_g,key_b ; 

output vga_hs ; 
output vga_vs ; 
output vga_r ; 
output vga_g ; 
output vga_b ; 

output  clk_vga ; 
output  clk_board ; 
output  clk_500k ; 
output  led_r,led_g,led_b ; 

wire clk_65m ; 

altera_pll_peng  pll_U(
                        .areset (!rst_n),
                        .inclk0 (clock),
                        .c0  (clk_65m),
                        .c1  (clk_500k)
                        );
                            
                            

 vga_driver vga_dri_U
                (
                .pix_clk  (clk_65m),
                .rst_n    (rst_n),
                .key_r      (key_r),
                .key_g    (key_g),
                .key_b    (key_b),
                
                .vga_r    (vga_r),
                .vga_g    (vga_g),
                .vga_b    (vga_b),
                .vga_hs   (vga_hs),
                .vga_vs   (vga_vs)
                ); 

                
// for  test  or display
assign clk_board = clock ; 
assign clk_vga = clk_65m ; 
assign led_r = key_r ; 
assign led_g = key_g ; 
assign led_b = key_b ; 

endmodule

子模块

module vga_driver
                (
                pix_clk ,
                rst_n ,
                key_r,
                key_g,
                key_b,
                
                vga_r,
                vga_g,
                vga_b,
                vga_hs,
                vga_vs
                ); 
input   pix_clk ;   // VGA像素时钟
input   rst_n ;      // 异步复位信号
input     key_b,key_g,key_r ; 

output      vga_r ; 
output      vga_g ;
output      vga_b ; 
output   vga_hs ;  // VGA管脚 行同步
output   vga_vs ;  // VGA管脚 场同步

//定义VGA_1024_768_65M_60HZ显示协议标准 
//  pix_clk  65m

parameter H_SYNC  = 16'd136;   // 同步脉冲      vga_hs
parameter H_BACK  = 16'd160;    // 显示后沿 
parameter H_DISP  = 16'd1024;   // 显示时序
parameter H_FRONT = 16'd24;    // 显示前沿
parameter H_TOTAL = 16'd1344;  // 时序帧长   ---hs_cnt 

parameter V_SYNC  = 16'd6;     // 同步脉冲      vga_vs
parameter V_BACK  = 16'd29;    // 显示后沿
parameter V_DISP  = 16'd768;   // 显示时序 
parameter V_FRONT = 16'd3;    // 显示前沿
parameter V_TOTAL = 16'd806;   // 时序帧长   --- vs_cnt 
//------------------------------------------
reg [15:0] hs_cnt ; 
reg [15:0] vs_cnt ;
always @ (posedge pix_clk )
    if(!rst_n) hs_cnt <= 16'd0; 
    else if(hs_cnt == H_TOTAL-1) hs_cnt <= 16'd0 ; 
    else     hs_cnt <= hs_cnt + 16'd1 ; 
always @(posedge pix_clk)
    if(!rst_n) vs_cnt <= 16'd0 ; 
    else if (vs_cnt == V_TOTAL-1) vs_cnt <= 16'd0 ; 
    else if (hs_cnt == H_TOTAL-1) vs_cnt <= vs_cnt + 16'd1 ; 
    
reg hsync_r,vsync_r;    //同步信号
//------------------------------------------------- 
always @ (posedge pix_clk)
    if(!rst_n) hsync_r <= 1'b1;                                
    else if(hs_cnt == 16'd0)    hsync_r <= 1'b0;    //产生hsync信号
    else if(hs_cnt == H_SYNC-1) hsync_r <= 1'b1;

always @ (posedge pix_clk )
    if(!rst_n) vsync_r <= 1'b1;                              
    else if(vs_cnt == 16'd0)    vsync_r <= 1'b0;    //产生vsync信号
    else if(vs_cnt == V_SYNC-1) vsync_r <= 1'b1;

assign vga_hs = hsync_r;
assign vga_vs = vsync_r;

//--------------------------------------------------------------------------
//有效信号范围
reg     x_en ,y_en ; 
always @ (posedge pix_clk)
    if(!rst_n) x_en  <= 1'd0 ; 
    else if (hs_cnt==(H_SYNC + H_BACK)) x_en  <= 1'd1 ; 
    else if (hs_cnt==(H_SYNC + H_BACK + H_DISP)) x_en  <= 1'd0 ; 

always @ (posedge pix_clk)
    if(!rst_n) y_en <= 1'd0 ; 
    else if (vs_cnt == (V_SYNC + V_BACK)) y_en <= 1'd1 ; 
    else if (vs_cnt == (V_SYNC + V_BACK + V_DISP)) y_en <= 1'd0 ; 

    
assign vga_r = (x_en&y_en) ? key_r: 1'd0 ; 
assign vga_g = (x_en&y_en) ? key_g: 1'd0 ; 
assign vga_b = (x_en&y_en) ? key_b: 1'd0 ; 
    
endmodule