FPGA_TFT屏彩条实验

本文详细介绍了使用Verilog设计的VGA时序控制模块,包括行和场计数器、时钟生成、TFT显示控制以及图像数据生成。通过实例展示了如何实现TFT像素时钟、数据使能和背光信号的控制。最后,给出了一个完整的TFT800x480控制器的顶层模块和仿真测试环境。
摘要由CSDN通过智能技术生成

1.了解VGA的大致时序

2.Verilog设计模块

3.时钟产生--使用Clocking IP核

根据不同的屏幕、刷新速率,产生对应所需的时钟

4.TFT显示时序控制模块

A.行和场计数器

B.rgb_valid(有效请求信号)

`timescale 1ns / 1ps
module tft_ctrl(
    Clk33_3M,//输入时钟,频率
    Reset_n,
    pix_data,
    pix_x,
    pix_y,
    rgb_tft,
    hsync,
    vsync,
    tft_clk,
    tft_de,
    tft_bl
    );
    input Clk33_3M;//输入时钟,频率
    input Reset_n;//复位信号
    input [15:0] pix_data;//待显示数据
    output [9:0] pix_x;   //有效显示区像素点x轴坐标
    output [9:0] pix_y;   //有效显示区像素点y轴坐标
    output [15:0] rgb_tft;//TFT显示数据
    output hsync;         //行同步信号
    output vsync;         //场同步信号
    output tft_clk;       //像素时钟
    output tft_de;        //数据使能信号
    output tft_bl;        //TFT背光信号
//行扫描——参数定义 parameter define
parameter H_SYNC = 10'd128,//行同步信号
           H_BACK = 10'd88,//行时序后沿
           H_VALID = 10'd800,//行有效
           H_FRONT = 10'd40,//行前沿
           H_TOTAL = 11'd1056;//行扫描周期 
//场扫描——参数定义 parameter define    
parameter V_SYNC = 10'd2,  //场同步信号
           V_BACK = 10'd33,   //场时序后沿
           V_VALID = 10'd480, //场有效
           V_FRONT = 10'd10,  //场前沿
           V_TOTAL = 11'd525;//场扫描周期
//wire define
wire rgb_valid;//VGA有效显示区域
wire pix_data_req;//像素点色彩信息请求信号
//tft_clk,tft_de,tft_bl:TFT像素时钟、数据使能、背光信号
assign tft_clk = Clk33_3M ;
assign tft_de = rgb_valid ;
assign tft_bl = Reset_n ;
//reg define 
reg [12:0]cnt_h;     //行扫描计数器
reg [12:0]cnt_v;     //场扫描计数器
//cnt_h:行同步信号计数器
always@(posedge Clk33_3M or negedge Reset_n)
if(!Reset_n)
cnt_h <= 10'd0 ;
else if(cnt_h == H_TOTAL - 1'd1)
cnt_h <= 10'd0 ;
else
cnt_h <= cnt_h + 1'd1 ;

//hsync:行同步信号
assign hsync = (cnt_h <= H_SYNC - 1'd1) ? 1'b1 : 1'b0 ;

//cnt_v:场同步信号计数器
always@(posedge Clk33_3M or negedge Reset_n)
if(!Reset_n)
cnt_v <= 10'd0 ;
else if((cnt_v == V_TOTAL - 1'd1) && (cnt_h == H_TOTAL-1'd1))
cnt_v <= 10'd0 ;
else if(cnt_h == H_TOTAL - 1'd1)
cnt_v <= cnt_v + 1'd1 ;
else
cnt_v <= cnt_v ;

//vsync:场同步信号
assign vsync = (cnt_v <= V_SYNC - 1'd1) ? 1'b1 : 1'b0 ;

//rgb_valid:VGA有效显示区域
assign rgb_valid = (((cnt_h >= H_SYNC + H_BACK)
&& (cnt_h < H_SYNC + H_BACK + H_VALID))
&&((cnt_v >= V_SYNC + V_BACK)
&& (cnt_v < V_SYNC + V_BACK + V_VALID)))
? 1'b1 : 1'b0;

//pix_data_req:像素点色彩信息请求信号,超前rgb_valid信号一个时钟周期
assign pix_data_req = (((cnt_h >= H_SYNC + H_BACK - 1'b1)
&& (cnt_h < H_SYNC + H_BACK + H_VALID - 1'b1))
&&((cnt_v >= V_SYNC + V_BACK)
&& (cnt_v < V_SYNC + V_BACK + V_VALID)))
? 1'b1 : 1'b0;

//pix_x,pix_y:VGA有效显示区域像素点坐标
assign pix_x = (pix_data_req == 1'b1)
? (cnt_h - (H_SYNC + H_BACK - 1'b1)) : 10'h3ff;
assign pix_y = (pix_data_req == 1'b1)
? (cnt_v - (V_SYNC + V_BACK )) : 10'h3ff;

//rgb_tft:输出像素点色彩信息
assign rgb_tft = (rgb_valid == 1'b1) ? pix_data : 16'b0 ;

endmodule
`timescale 1ns / 1ps
module tft_ctrl_tb();
    reg Clk;    //系统时钟
    wire Clk33_3M;//输入时钟,频率
    reg Reset_n;//复位信号
    wire tft_reset_n;
    reg [15:0] pix_data;//待显示数据
    wire [9:0] pix_x;   //有效显示区像素点x轴坐标
    wire [9:0] pix_y;   //有效显示区像素点y轴坐标
    wire [15:0] rgb_tft;//TFT显示数据
    wire hsync;         //行同步信号
    wire vsync;         //场同步信号
    wire tft_clk;       //像素时钟
    wire tft_de;        //数据使能信号
    wire tft_bl;        //TFT背光信号
    wire locked ;
clk_gen_0 clk_gen_0_inst0
 (
    .clk_in1(Clk),
    .reset(!Reset_n),   
    .tft_clock(Clk33_3M),
    .locked(locked)
 );
tft_ctrl tft_ctrl_inst0(
    .Clk33_3M(Clk33_3M),//输入时钟,频率
    .Reset_n(Reset_n),
    .pix_data(pix_data),
    .pix_x(pix_x),
    .pix_y(pix_y),
    .rgb_tft(rgb_tft),
    .hsync(hsync),
    .vsync(vsync),
    .tft_clk(tft_clk),
    .tft_de(tft_de),
    .tft_bl(tft_bl)
    );

  //rst_n:VGA模块复位信号
 assign tft_reset_n = (Reset_n & locked);
//产生时钟
 initial Clk = 1;
 always #10 Clk = ~Clk;
 
 //pix_data:输入像素点色彩信息
 always@(posedge Clk33_3M or negedge Reset_n)
 if(!Reset_n)
    pix_data <= 16'h0;
 else
    pix_data <= 16'hffff;
    
    initial begin
        Reset_n = 0;
        #300;
        Reset_n = 1;
        #2000_000;
    end

endmodule

5.图像数据生成模块

`timescale 1ns / 1ps
module tft_pic(
    Clk33_3M,//输入时钟,频率
    Reset_n,
    pix_x,
    pix_y,
    pix_data
);
input Clk33_3M;//输入时钟,频率
input Reset_n;
input [9:0]pix_x;
input [9:0]pix_y;
output reg[15:0]pix_data;

parameter H_VALID = 10'd800;//行有效数据
parameter V_VALID = 10'd480;//场有效数据

 parameter RED = 16'hF800, //红色
 ORANGE = 16'hFC00, //橙色
 YELLOW = 16'hFFE0, //黄色
 GREEN = 16'h07E0, //绿色
 CYAN = 16'h07FF, //青色
 BLUE = 16'h001F, //蓝色
 PURPPLE = 16'hF81F, //紫色
 BLACK = 16'h0000, //黑色
 WHITE = 16'hFFFF, //白色
 GRAY = 16'hD69A; //灰色
 //pix_data:输出像素点色彩信息,根据当前像素点坐标指定当前像素点颜色数据
 always@(posedge Clk33_3M or negedge Reset_n)
 if(!Reset_n)
 pix_data <= 16'd0;
 else if((pix_x >= 0) && (pix_x < (H_VALID/10)*1))
 pix_data <= RED;
 else if((pix_x >= (H_VALID/10)*1) && (pix_x < (H_VALID/10)*2))
 pix_data <= ORANGE;
 else if((pix_x >= (H_VALID/10)*2) && (pix_x < (H_VALID/10)*3))
 pix_data <= YELLOW;
 else if((pix_x >= (H_VALID/10)*3) && (pix_x < (H_VALID/10)*4))
 pix_data <= GREEN;
 else if((pix_x >= (H_VALID/10)*4) && (pix_x < (H_VALID/10)*5))
 pix_data <= CYAN;
 else if((pix_x >= (H_VALID/10)*5) && (pix_x < (H_VALID/10)*6))
 pix_data <= BLUE;
 else if((pix_x >= (H_VALID/10)*6) && (pix_x < (H_VALID/10)*7))
 pix_data <= PURPPLE;
 else if((pix_x >= (H_VALID/10)*7) && (pix_x < (H_VALID/10)*8))
 pix_data <= BLACK;
 else if((pix_x >= (H_VALID/10)*8) && (pix_x < (H_VALID/10)*9))
 pix_data <= WHITE;
 else if((pix_x >= (H_VALID/10)*9) && (pix_x < H_VALID))
 pix_data <= GRAY;
 else
 pix_data <= BLACK;

endmodule

6.顶层模块

`timescale 1ns / 1ps
module TFT800x480_ctrl(
    Clk , //输入工作时钟,频率50MHz
    Reset_n , //输入复位信号,低电平有效
    rgb_tft , //输出像素信息
    hsync , //输出行同步信号
    vsync , //输出场同步信号
    tft_clk , //输出TFT时钟信号
    tft_de , //输出TFT使能信号
    tft_bl //输出背光信号
    );
    input Clk;
    input Reset_n;
    output [15:0]rgb_tft; //输出像素信息
    output hsync ;//输出行同步信号
    output vsync ;//输出场同步信号
    output tft_clk; //输出TFT时钟信号
    output tft_de ;//输出TFT使能信号
    output tft_bl ;//输出背光信号
    //wire define
 wire Clk33_3M ; //TFT工作时钟,频率33.3MHz
 wire locked ; //PLL locked信号
 wire rst_n ; //TFT模块复位信号
 wire [9:0] pix_x ; //TFT有效显示区域X轴坐标
 wire [9:0] pix_y ; //TFT有效显示区域Y轴坐标
 wire [15:0] pix_data ; //TFT像素点色彩信息

 //rst_n:TFT模块复位信号
 assign rst_n = (Reset_n & locked);
 //------------- clk_gen_inst -------------
clk_gen_0 clk_gen_0_inst0
 (
    .clk_in1(Clk),
    .reset(!Reset_n),   
    .tft_clock(Clk33_3M),
    .locked(locked)
 );
 //------------- tft_ctrl_inst -------------
tft_ctrl tft_ctrl_inst0(
    .Clk33_3M(Clk33_3M),//输入时钟,频率
    .Reset_n(Reset_n),
    .pix_data(pix_data),
    .pix_x(pix_x),
    .pix_y(pix_y),
    .rgb_tft(rgb_tft),
    .hsync(hsync),
    .vsync(vsync),
    .tft_clk(tft_clk),
    .tft_de(tft_de),
    .tft_bl(tft_bl)
    );
 //------------- tft_pic_inst -------------
tft_pic tft_pic_inst0(
    .Clk33_3M(Clk33_3M),//输入时钟,频率
    .Reset_n(Reset_n),
    .pix_x(pix_x),
    .pix_y(pix_y),
    .pix_data(pix_data)
);
endmodule

仿真tb

`timescale 1ns / 1ps
module TFT800x480_ctrl_tb();
reg Clk;        //输入工作时钟,频率50MHz
reg Reset_n;    //输入复位信号,低电平有效
wire [15:0]rgb_tft; //输出像素信息
wire hsync;   //输出行同步信号
wire vsync;   //输出场同步信号
wire tft_clk; //输出TFT时钟信号
wire tft_de;  //输出TFT使能信号
wire tft_bl;  //输出背光信号
TFT800x480_ctrl TFT800x480_ctrl_inst0(
    .Clk(Clk),          //输入工作时钟,频率50MHz
    .Reset_n(Reset_n), //输入复位信号,低电平有效
    .rgb_tft(rgb_tft), //输出像素信息
    .hsync(hsync),     //输出行同步信号
    .vsync(vsync),     //输出场同步信号
    .tft_clk(tft_clk), //输出TFT时钟信号
    .tft_de(tft_de),  //输出TFT使能信号
    .tft_bl(tft_bl)   //输出背光信号
    );
    initial Clk=1;
    always#10 Clk = ~Clk;
    initial begin
        Reset_n = 0;
        #210;
        Reset_n = 1;
        #3000_000_000;
        #3000_000_000;
        $stop;            
    end
endmodule

7.效果图

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值