|
如果您还没有注册本论坛,将无法下载论坛中附件,但是注册论坛非常简单,使用微 信 扫码即可注册。
也可以在小梅哥任意一个Q群内直接索取邀请码使用邀请码注册,小梅哥创建的任意一个群都可以。 |
以前自己写过单独的VGA控制器和TFT屏控制器,那些都是分开写的,每个设备(4.3寸显示屏、5寸显示屏、VGA输出等),甚至每个分辨率都要单独写一个驱动模块,那样实用不方便,也不利于工程版本的管理,给自己的例程发布和更新带来了非常大的麻烦,因此小梅哥今天痛定思痛,采用条件编译的方式,设计了一个通用的驱动模块,该模块只需要在代码中选择不同的编译参数,就能够实现不同分辨率的时序输出。用起来非常方便。
注意,每个分辨率对应的像素时钟频率是不一样的,因此需要针对不同的分辨率,给ClkDisp提供不同频率的时钟。每个分辨率对应的参数已经在条件编译的代码部分通过注释的方式提示了。
ac620_vga_ctrl_gm7123.rar
(79.79 KB, 下载次数: 761)
- module VGA_CTRL_test(
- Clk, //50MHZ时钟
- Rst_n,
- VGA_RGB,//TFT数据输出
- VGA_HS, //TFT行同步信号
- VGA_VS, //TFT场同步信号
- VGA_BLK, //VGA 场消隐信号
- VGA_CLK //VGA DAC输出时钟
- );
- input Clk;
- input Rst_n;
- output [23:0]VGA_RGB;
- output VGA_HS;
- output VGA_VS;
- output VGA_BLK; //VGA 场消隐信号
- output VGA_CLK; //VGA DAC输出时钟
-
- reg [23:0]disp_data;
- wire [11:0]hcount;
- wire [11:0]vcount;
- wire ClkDisp;
-
- vga_test_pll vga_test_pll(
- .inclk0(Clk),
- .c0(ClkDisp)
- );
-
- disp_driver disp_driver(
- .ClkDisp(ClkDisp),
- .Rst_n(Rst_n),
- .Data(disp_data),
- .DataReq(),
- .H_Addr(hcount),
- .V_Addr(vcount),
- .Disp_HS(VGA_HS),
- .Disp_VS(VGA_VS),
- .Disp_Red(VGA_RGB[23:16]),
- .Disp_Green(VGA_RGB[15:8]),
- .Disp_Blue(VGA_RGB[7:0]),
- .Disp_DE(VGA_BLK),
- .Disp_PCLK(VGA_CLK)
- );
- /*
- VGA_CTRL VGA_CTRL(
- .Clk25M(ClkDisp), //系统输入时钟25MHZ
- .Rst_n(Rst_n),
- .data_in(disp_data), //待显示数据
- .hcount(hcount), //VGA行扫描计数器
- .vcount(vcount), //VGA场扫描计数器
- .VGA_RGB(VGA_RGB), //VGA数据输出
- .VGA_HS(VGA_HS), //VGA行同步信号
- .VGA_VS(VGA_VS), //VGA场同步信号
- .VGA_BLK(VGA_BLK), //VGA 场消隐信号
- .VGA_CLK(VGA_CLK) //VGA DAC输出时钟
- );
- */
-
- //定义颜色编码
- localparam
- BLACK = 24'h000000, //黑色
- BLUE = 24'h0000FF, //蓝色
- RED = 24'hFF0000, //红色
- PURPPLE = 24'hFF00FF, //紫色
- GREEN = 24'h00FF00, //绿色
- CYAN = 24'h00FFFF, //青色
- YELLOW = 24'hFFFF00, //黄色
- WHITE = 24'hFFFFFF; //白色
-
- //定义每个像素块的默认显示颜色值
- localparam
- R0_C0 = BLACK, //第0行0列像素块
- R0_C1 = BLUE, //第0行1列像素块
- R1_C0 = RED, //第1行0列像素块
- R1_C1 = PURPPLE,//第1行1列像素块
- R2_C0 = GREEN, //第2行0列像素块
- R2_C1 = CYAN, //第2行1列像素块
- R3_C0 = YELLOW, //第3行0列像素块
- R3_C1 = WHITE; //第3行1列像素块
- wire R0_act = vcount >= 0 && vcount < 120; //正在扫描第0行
- wire R1_act = vcount >= 120 && vcount < 240;//正在扫描第1行
- wire R2_act = vcount >= 240 && vcount < 360;//正在扫描第2行
- wire R3_act = vcount >= 360 && vcount < 480;//正在扫描第3行
-
- wire C0_act = hcount >= 0 && hcount < 320; //正在扫描第0列
- wire C1_act = hcount >= 320 && hcount < 640;//正在扫描第1列
-
- wire R0_C0_act = R0_act & C0_act; //第0行0列像素块处于被扫描中标志信号
- wire R0_C1_act = R0_act & C1_act; //第0行1列像素块处于被扫描中标志信号
- wire R1_C0_act = R1_act & C0_act; //第1行0列像素块处于被扫描中标志信号
- wire R1_C1_act = R1_act & C1_act; //第1行1列像素块处于被扫描中标志信号
- wire R2_C0_act = R2_act & C0_act; //第2行0列像素块处于被扫描中标志信号
- wire R2_C1_act = R2_act & C1_act; //第2行1列像素块处于被扫描中标志信号
- wire R3_C0_act = R3_act & C0_act; //第3行0列像素块处于被扫描中标志信号
- wire R3_C1_act = R3_act & C1_act; //第3行1列像素块处于被扫描中标志信号
-
- always@(*)
- case({R3_C1_act,R3_C0_act,R2_C1_act,R2_C0_act,
- R1_C1_act,R1_C0_act,R0_C1_act,R0_C0_act})
- 8'b0000_0001:disp_data = R0_C0;
- 8'b0000_0010:disp_data = R0_C1;
- 8'b0000_0100:disp_data = R1_C0;
- 8'b0000_1000:disp_data = R1_C1;
- 8'b0001_0000:disp_data = R2_C0;
- 8'b0010_0000:disp_data = R2_C1;
- 8'b0100_0000:disp_data = R3_C0;
- 8'b1000_0000:disp_data = R3_C1;
- default:disp_data = R1_C0;
- endcase
-
- endmodule
复制代码- /*============================================================================
- *
- * LOGIC CORE: 显示设备驱动模块
- * MODULE NAME: disp_driver()
- * COMPANY: 武汉芯路恒科技有限公司
- * [url]http://xiaomeige.taobao.com[/url]
- * author: 小梅哥
- * Website: www.corecourse.cn
- * REVISION HISTORY:
- *
- * Revision 1.0 04/10/2019 Description: Initial Release.
- *
- * FUNCTIONAL DESCRIPTION:
- ===========================================================================*/
- `include "disp_parameter_cfg.v"
- module disp_driver(
- ClkDisp,
- Rst_n,
-
- Data,
- DataReq,
-
- H_Addr,
- V_Addr,
-
- Disp_HS,
- Disp_VS,
- Disp_Red,
- Disp_Green,
- Disp_Blue,
- Disp_DE,
- Disp_PCLK
- );
- input ClkDisp;
- input Rst_n;
- input [`Red_Bits + `Green_Bits + `Blue_Bits - 1:0] Data;
- output DataReq;
-
- output [11:0] H_Addr;
- output [11:0] V_Addr;
-
- output reg Disp_HS;
- output reg Disp_VS;
- output reg [`Red_Bits - 1 :0]Disp_Red;
- output reg [`Green_Bits - 1 :0]Disp_Green;
- output reg [`Blue_Bits - 1 :0]Disp_Blue;
-
- output reg Disp_DE;
- output Disp_PCLK;
-
- wire hcount_ov;
- wire vcount_ov;
-
- //----------------内部寄存器定义----------------
- reg [11:0] hcount_r; //行扫描计数器
- reg [11:0] vcount_r; //场扫描计数器
-
- assign Disp_PCLK = ~ClkDisp;
- assign DataReq = Disp_DE;
-
- parameter hdat_begin = `H_Sync_Time + `H_Back_Porch + `H_Left_Border - 1'b1;
- parameter hdat_end = `H_Total_Time - `H_Right_Border - `H_Front_Porch - 1'b1;
-
- parameter vdat_begin = `V_Sync_Time + `V_Back_Porch + `V_Top_Border - 1'b1;
- parameter vdat_end = `V_Total_Time - `V_Bottom_Border - `V_Front_Porch - 1'b1;
-
- assign H_Addr = Disp_DE?(hcount_r - hdat_begin):12'd0;
- assign V_Addr = Disp_DE?(vcount_r - vdat_begin):12'd0;
- //行扫描
- assign hcount_ov = (hcount_r >= `H_Total_Time - 1);
-
- always@(posedge ClkDisp or negedge Rst_n)
- if(!Rst_n)
- hcount_r <= 0;
- else if(hcount_ov)
- hcount_r <= 0;
- else
- hcount_r <= hcount_r + 1'b1;
- //场扫描
- assign vcount_ov = (vcount_r >= `V_Total_Time - 1);
- always@(posedge ClkDisp or negedge Rst_n)
- if(!Rst_n)
- vcount_r <= 0;
- else if(hcount_ov) begin
- if(vcount_ov)
- vcount_r <= 0;
- else
- vcount_r <= vcount_r + 1'd1;
- end
- else
- vcount_r <= vcount_r;
-
- always@(posedge ClkDisp)
- Disp_DE <= ((hcount_r >= hdat_begin)&&(hcount_r < hdat_end))
- &&((vcount_r >= vdat_begin)&&(vcount_r < vdat_end));
-
- always@(posedge ClkDisp) begin
- Disp_HS <= (hcount_r > `H_Sync_Time - 1);
- Disp_VS <= (vcount_r > `V_Sync_Time - 1);
- {Disp_Red,Disp_Green,Disp_Blue} <= (Disp_DE)?Data:1'd0;
- end
-
- endmodule
复制代码
|
|