VGA 多分辨率

 REVIEW

        VGA 时序与实现-CSDN博客

        对于不同分辨率,每次使用都去查表比较麻烦;

        学习条件编译的使用,减轻后续调用的麻烦。

1.  条件编译格式

条件编译是当设计中满足某个条件时,将该条件下的一段代码编译进设计中。
因此,只需设置编译条件,并在对应的编译条件下编写正确的代码,就可以实现条件编译。
cnt_max.v
`define CASE_A
//`define CASE_B
`ifdef CASE_A
        `define CNT_MAX 2000
`elsif CASE_B
        `define CNT_MAX 2500
`endif

`include"cnt_max.v"

    cnt = `CNT_MAX;    //注意这里那个`

2.  VGA_parameter.v

        // 小梅哥视频23E 多分辨率适配VGA控制器设计_哔哩哔哩_bilibili

        包含RGB_MODE

/*
使用时根据实际工作需求选择几个预定义参数就可以
MODE_RGB888 和 MODE_RGB565 两个参数二选一,用来决定驱动工作在 16 位模式还是
24 位模式
针对小梅哥提供的一系列显示设备,各个设备参数如下所述
4.3 寸屏:16 位色 RGB565 模式
5 寸屏:16 位色 RGB565 模式
GM7123 模块使用 24 位色 RGB888 模式,
Resolution_xxxx 预定义用来决定显示设备分辨率,常见设备分辨率如下所述
4.3 寸 TFT 显示屏:Resolution_480x272
5 寸 TFT 显示屏:Resolution_800x480
VGA 常见分辨率:
Resolution_640x480
Resolution_800x600
Resolution_1024x768
Resolution_1280x720
Resolution_1920x1080
*/

//以下两行预定义根据实际使用的模式,选择一个使能,另外一个使用注释的方式屏蔽
`define MODE_RGB888
//`define MODE_RGB565


//以下 7 行预定义根据实际使用的分辨率,选择一个使能,另外 6 个使用注释的方式屏蔽
//`define Resolution_480x272 1 //时钟为 9MHz
`define Resolution_640x480 1 //时钟为 25.175MHz
//`define Resolution_800x480 1 //时钟为 33MHz
//`define Resolution_800x600 1 //时钟为 40MHz
//`define Resolution_1024x768 1 //时钟为 65MHz
//`define Resolution_1280x720 1 //时钟为 74.25MHz
//`define Resolution_1920x1080 1 //时钟为 148.5MHz

//定义不同的颜色深度
`ifdef MODE_RGB888
    `define Red_Bits 8
    `define Green_Bits 8
    `define Blue_Bits 8
`elsif MODE_RGB565
    `define Red_Bits 5
    `define Green_Bits 6
    `define Blue_Bits 5
`endif

//定义不同分辨率的时序参数
`ifdef Resolution_480x272
    `define H_Total_Time 12'd525
    `define H_Right_Border 12'd0
    `define H_Front_Porch 12'd2
    `define H_Sync_Time 12'd41
    `define H_Back_Porch 12'd2
    `define H_Left_Border 12'd0
    
    `define V_Total_Time 12'd286
    `define V_Bottom_Border 12'd0
    `define V_Front_Porch 12'd2
    `define V_Sync_Time 12'd10
    `define V_Back_Porch 12'd2
    `define V_Top_Border 12'd0
    
    
`elsif Resolution_640x480
    `define H_Total_Time 12'd800
    `define H_Right_Border 12'd8
    `define H_Front_Porch 12'd8
    `define H_Sync_Time 12'd96
    `define H_Back_Porch 12'd40
    `define H_Left_Border 12'd8
    
    `define V_Total_Time 12'd525
    `define V_Bottom_Border 12'd8
    `define V_Front_Porch 12'd2
    `define V_Sync_Time 12'd2
    `define V_Back_Porch 12'd25
    `define V_Top_Border 12'd8
    
    
`elsif Resolution_800x480
    `define H_Total_Time 12'd1056
    `define H_Right_Border 12'd0
    `define H_Front_Porch 12'd40
    `define H_Sync_Time 12'd128
    `define H_Back_Porch 12'd88
    `define H_Left_Border 12'd0
    
    `define V_Total_Time 12'd525
    `define V_Bottom_Border 12'd8
    `define V_Front_Porch 12'd2
    `define V_Sync_Time 12'd2
    `define V_Back_Porch 12'd25
    `define V_Top_Border 12'd8
    
    
`elsif Resolution_800x600
    `define H_Total_Time 12'd1056
    `define H_Right_Border 12'd0
    `define H_Front_Porch 12'd40
    `define H_Sync_Time 12'd128
    `define H_Back_Porch 12'd88
    `define H_Left_Border 12'd0
    
    `define V_Total_Time 12'd628
    `define V_Bottom_Border 12'd0
    `define V_Front_Porch 12'd1
    `define V_Sync_Time 12'd4
    `define V_Back_Porch 12'd23
    `define V_Top_Border 12'd0
    
    
`elsif Resolution_1024x768
    `define H_Total_Time 12'd1344
    `define H_Right_Border 12'd0
    `define H_Front_Porch 12'd24
    `define H_Sync_Time 12'd136
    `define H_Back_Porch 12'd160
    `define H_Left_Border 12'd0
    
    `define V_Total_Time 12'd806
    `define V_Bottom_Border 12'd0
    `define V_Front_Porch 12'd3
    `define V_Sync_Time 12'd6
    `define V_Back_Porch 12'd29
    `define V_Top_Border 12'd0
    
    
`elsif Resolution_1280x720
    `define H_Total_Time 12'd1650
    `define H_Right_Border 12'd0
    `define H_Front_Porch 12'd110
    `define H_Sync_Time 12'd40
    `define H_Back_Porch 12'd220
    `define H_Left_Border 12'd0
    
    `define V_Total_Time 12'd750
    `define V_Bottom_Border 12'd0
    `define V_Front_Porch 12'd5
    `define V_Sync_Time 12'd5
    `define V_Back_Porch 12'd20
    `define V_Top_Border 12'd0
    
    
`elsif Resolution_1920x1080
    `define H_Total_Time 12'd2200
    `define H_Right_Border 12'd0
    `define H_Front_Porch 12'd88
    `define H_Sync_Time 12'd44
    `define H_Back_Porch 12'd148
    `define H_Left_Border 12'd0
    
    `define V_Total_Time 12'd1125
    `define V_Bottom_Border 12'd0
    `define V_Front_Porch 12'd4
    `define V_Sync_Time 12'd5
    `define V_Back_Porch 12'd36
    `define V_Top_Border 12'd0
    
    
`endif

3.  对vga增加行列位置信息

`include"vga_parameter.v"
module vga(
            input clk , 
            input reset_n ,
            input [`Red_Bits + `Green_Bits + `Blue_Bits - 1:0]data ,
            output reg data_req ,
            output reg VGA_HS ,
            output reg VGA_VS , 
            output reg VGA_BLK ,
            output reg [`Red_Bits - 1 :0]VGA_R ,
            output reg [`Green_Bits - 1 :0]VGA_G ,
            output reg [`Blue_Bits - 1 :0]VGA_B ,
            output reg [11:0]H_addr , 
            output reg [11:0]V_addr 
             );
            
     localparam VGA_HS_end = `H_Sync_Time - 1'b1 ;
     localparam Hdat_begin = `H_Sync_Time + `H_Back_Porch + `H_Left_Border - 1'b1 ;
     localparam Hdat_end = `H_Total_Time - `H_Right_Border - `H_Front_Porch - 1'b1 ;
     localparam Hpixel_end = `H_Total_Time - 1'b1 ;
     localparam VGA_VS_end = `V_Sync_Time - 1'b1 ;
     localparam Vdat_begin = `V_Sync_Time + `V_Back_Porch + `V_Top_Border - 1'b1 ;
     localparam Vdat_end = `V_Total_Time - `V_Bottom_Border - `V_Front_Porch - 1'b1 ;
     localparam Vline_end = `V_Total_Time - 1'b1 ;
     
    //行计数器
    reg[11:0]H_cnt;
    always@(posedge clk or negedge reset_n)
    if(!reset_n)    H_cnt <= 0 ;
    else if(H_cnt == Hpixel_end)
        H_cnt <= 0 ;
    else 
        H_cnt <= H_cnt + 1'b1 ;
    
    // 场计数器
    reg[11:0]V_cnt;
    always@(posedge clk or negedge reset_n)
    if(!reset_n)    V_cnt <= 0 ;
    else if(H_cnt == Hpixel_end)
        if(V_cnt == Vline_end)
            V_cnt <= 0 ;
        else 
            V_cnt <= V_cnt + 1'b1 ;
    else 
        V_cnt <= V_cnt ;
        
      //     VGA_HS
    always@(posedge clk or negedge reset_n)
    if(!reset_n)  VGA_HS <= 1;
    else if(H_cnt == 0) VGA_HS <= 0;
    else if(H_cnt > VGA_HS_end) VGA_HS <= 1;
    
    //     VGA_VS
    always@(posedge clk or negedge reset_n)
    if(!reset_n)  VGA_VS <= 1;
    else if(V_cnt == 0) VGA_VS <= 0;
    else if(V_cnt > VGA_VS_end) VGA_VS <= 1;  
        
    //     data_req
    always@(posedge clk or negedge reset_n)
    if(!reset_n)    data_req <= 0 ;
    else data_req <= ((H_cnt >= Hdat_begin)&&(H_cnt < Hdat_end)&&(V_cnt >= Vdat_begin)&&(V_cnt <= Vdat_end)) ? 1 : 0;
    
     //     VGA_BLK
    always@(posedge clk or negedge reset_n)
    if(!reset_n)    VGA_BLK <= 0 ;
    else VGA_BLK <= data_req ;
    
    //     VGA_RGB
    always@(posedge clk )
    if(data_req) 
        {VGA_R,VGA_G,VGA_B} <= data;
    else
        {VGA_R,VGA_G,VGA_B} <= 0;
        
    //address
    always@(posedge clk )
    if(data_req)
     begin
        H_addr <= H_cnt - Hdat_begin;
        V_addr <= V_cnt - Vdat_begin;
     end
     else
       begin
        H_addr <= 0;
        V_addr <= 0;
     end
endmodule

4. tb

`timescale 1ns / 1ns
module vga_tb(    );   
        
        reg clk , reset_n;
        reg [`Red_Bits + `Green_Bits + `Blue_Bits - 1'b1:0]data;
        wire data_req ,VGA_HS ,VGA_VS ,VGA_BLK;
        wire [`Red_Bits- 1'b1:0]VGA_R;
        wire [`Green_Bits- 1'b1:0]VGA_G;
        wire [`Blue_Bits- 1'b1:0]VGA_B;
        wire [11:0]H_addr ;
        wire [11:0]V_addr ;
   vga     vga_(
              clk , 
              reset_n ,
              data ,
              data_req ,
              VGA_HS ,
              VGA_VS , 
              VGA_BLK ,
              VGA_R ,
              VGA_G ,
              VGA_B ,
              H_addr , 
              V_addr 
             );
        
    initial clk = 1 ;
    always#20 clk = ~clk ;
    
    initial
        begin
            reset_n = 0 ;
            #201 ;
            reset_n = 1 ;
            #40000000;
            $stop;
        end    
      always@(posedge clk or negedge reset_n)
      if(!reset_n)    data <= 20'b11110000000100000001 ;
      else if(data_req) data <= data + 1'b1 ;
      else data <= data ;
endmodule

5.  运行结果

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值