RGB LCD 彩条显示实验 —1
TFT-LCD 的全称是 Thin Film Transistor-Liquid Crystal Display,即薄膜晶体管液晶显示屏,它显示的每个像素点都是由集成在液晶后面的薄膜晶体管独立驱动,因此 TFT-LCD 具有较高的响应速度以及较好的图像质量。
我们对于 LCD屏幕其实并不需要掌握其 实现的具体原理 我们只需要从使用的角度了解几个重点的东西
 1080p 是 1920 x 1080
 2K 是 2560 x 1440
 4K 是 3840 x 2160
上面讲了一个像素点就相当于一个 RGB 小灯,通过控制 R、G、B 这三种颜色的亮度就可以显示出各种各样的色彩。那该如何控制 R、G、B 这三种颜色的显示亮度呢?一般一个 R、G、B 这三部分分别使用8bit 的数据,那么一个像素点就是 8bit*3=24bit,也就是说一个像素点 3 个字节,这种像素格式称为 RGB888。当然常用的像素点格式还有 RGB565,只需要两个字节,但在色彩鲜艳度上较差一些。我们领航者开发板上的 RGB TFT-LCD 接口采用的 RGB888 的像素格式,共需要 24 位,每一位对应 RGB 的颜色分量如下图所示:
 
一个像素点占用 3 个字节,其中 bit23~bit16 是 RED 通道,bit15~bit8 是 GREEN 通道,bit7~bit0 是 BLUE 通道。所以红色对应的值就是 24’hFF0000,绿色对应的值就是 24’h00FF00,蓝色对应的值为 24’h0000FF。通过调节 R、G、B 的比例可以产生其它的颜色,比如 24’hFFFF00 就是黄色,24’h000000就是黑色,24’hFFFFFF 就是白色
RGB LCD 接口的信号线
 
R[7:0]、G[7:0]和 B[7:0]是 24 位数据,DE、VSYNC、HSYNC 和PCLK 是四个控制信号
本次实验用到了 ATK-7016 RGB LCD模块
 其实我们在之前的SOC 实验中 做过这样子的 大体设计
 我们再复习一下
 
我们来看一下 LCD 是怎么扫描显示一帧图像的。一帧图像也是由一行一行组成的。HSYNC 是水平同步信号,也叫做行同步信号,当产生此信号的话就表示开始显示新的一行了,所以此信号都是在图 29.1.6 的最左边。VSYNC 信号是垂直同步信号,也叫做帧同步信号,当产生此信号的话就表示开始显示新的一帧图像了
RGB LCD 屏幕时序
 
HSYNC:行同步信号,当此信号有效的时候就表示开始显示新的一行数据,查阅所使用的 LCD 数据手
 册可以知道此信号是低电平有效还是高电平有效,图 29.1.7 为低电平有效。
 HSPW:行同步信号宽度,也就是 HSYNC 信号持续时间。HSYNC 信号不是一个脉冲,而是需要持续
 一段时间才是有效的,单位为 CLK。
 HBP:行显示后沿(或后肩),单位是 CLK。
 HOZVAL:行有效显示区域,即显示一行数据所需的时间,假如屏幕分辨率为 1024*600,那么 HOZVAL
 就是 1024,单位为 CLK。
 HFP:行显示前沿(或前肩),单位是 CLK。
 当 HSYNC 信号发出以后,需要等待 HSPW+HBP 个 CLK 时间才会接收到真正有效的像素数据。当显示完一行数据以后需要等待 HFP 个 CLK 时间才能发出下一个 HSYNC 信号,所以显示一行所需要的时间就是:HSPW + HBP + HOZVAL + HFP。
 
VSYNC:帧(场)同步信号,当此信号有效的时候就表示开始显示新的一帧数据,查阅所使用的 LCD
 数据手册可以知道此信号是低电平有效还是高电平有效,图 29.1.8 为低电平有效。
 VSPW:帧同步信号宽度,也就是 VSYNC 信号持续时间,单位为 1 行的时间。
 VBP:帧显示后沿(或后肩),单位为 1 行的时间。
 LINE:帧有效显示区域,即显示一帧数据所需的时间,假如屏幕分辨率为 1024*600,那么 LINE 就是
 600 行的时间。
 VFP:帧显示前沿(或前肩),单位为 1 行的时间。
 显示一帧所需要的时间就是:VSPW+VBP+LINE+VFP 个行时间,最终的计算公式:
 T = (VSPW+VBP+LINE+VFP) * (HSPW + HBP + HOZVAL + HFP)
 因此我们在配置一款 RGB LCD 屏的时候需要知道这几个参数:HSPW(行同步)、HBP(行显示后沿)、
 HOZVAL(行有效显示区域)、HFP(行显示前沿)、VSPW(场同步)、VBP(场显示后沿)、LINE(场有效
 显示区域)和 VFP(场显示后沿)。
 RGB LCD 液晶屏一般有两种数据同步方式,一种是行场同步模式(HV Mode),另一种是数据使能同步模式(DE Mode)。当选择行场同步模式时,LCD 接口的时序与 VGA 接口的时序图非常相似,只是参数不同。如图 29.1.7 和图 29.1.8 中的行同步信号(HSYNC)和场同步信号(VSYNC)作为数据的同步信号,此时数据使能信号(DE)必须为低电平。当选择 DE 同步模式时,LCD 的 DE 信号作为数据的有效信号,如图 29.1.7 和图 29.1.8 的 DE 信号所示。只有同时扫描到帧有效显示区域和行有效显示区域时,DE 信号才有效(高电平)。当选择 DE 同步模式时,此时行场同步信号 VS 和 HS 必须为高电平。由于 RGB LCD 液晶屏一般都支持 DE 模式,因此本章我们采用 DE 同步的方式驱动 LCD 液晶屏。
像素时钟 :
 
像素时钟就是 RGB LCD 的时钟信号,以 ATK7016 这款屏幕为例,显示一帧图像所需要的时钟数就是:
 N(CLK)= (VSPW+VBP+LINE+VFP) * (HSPW + HBP + HOZVAL + HFP)= (3 + 20 + 600 + 12) * (20 + 140 + 1024 + 160) = 635 * 1344 = 853440
 显示一帧图像需要 853440 个时钟数,那么显示 60 帧就是:853440 * 60=51206400≈51.2M,所以像素时钟就是 51.2MHz。
 我们选用 50MHz
领航者开发板 RGB TFT-LCD 接口原理图
 
从上图中可以看到,FPGA 管脚输出的颜色数据位宽为 24bit,数据格式为 RGB888,即数据高 8 位表示红色,中间 8 位表示绿色,低 8 位表示蓝色。由于这 24 位数据不仅仅作为输出给 LCD 屏的颜色数据,同时 LCD_R7、LCD_G7 和 LCD_B7 也用来获取 LCD 屏的 ID,因此这 24 位颜色数据对 ZYNQ 开发板来说,是一个双向的引脚。另外,RGBLCD 模块支持触摸功能,图中以字母 T 开头的 5 个信号(T_PEN、T_SCK 等)与模块上的触摸芯片相连接。由于本次实验不涉及触摸功能的实现,因此这些信号并未用到。需要说明的是,LCD 液晶屏有一个复位信号(LCD_RST),当 LCD_RST 为低电平时,可对 LCD 屏进行复位。
实验任务 :
 使用正点原子 ZYNQ 开发板上的 RGB TFT-LCD 接口,驱动 RGB LCD 液晶屏(支持目前推出的所有 RGB LCD 屏),并显示出彩条。
下面是我自己改写的代码
 我觉得他把本应该 分开写的 输出和 控制模块全部写到一个led_driver 模块中 不妥当 我把它拆分成前控制模块 和 单个输出模块
 因为 更好的给大家比照学习的机会 ( 内心os : 不想写 testbench
 所以我的变量名字都是用同样的写法
下面展示我自己的完整的逻辑框图
 可能写的不明白 但是 初步介绍一下
 
第一个 Read 模块
 主要是读取 参数 确定 究竟用的是什么屏幕
 
第二个是 clk 时钟分频模块
 主要是 读取 ID之后 将根据 ID 的 不同把不同的 频率 分配完成 输出给下一级
 
下面一个是我自己的独立于它的LCD驱动模块
 我这个模块的主要作用是 接收型号的传递之后告诉我下一级display 该怎么显示 显示什么样的东西
再下一个是显示模块
 就是传入数据究竟是怎么样的一种格式
最后一个部分是输出模块 out
我们先来写read模块
我们读模块 ID 读取 ID 模块根据输入的 lcd_rgb 值来寄存 LCD 屏的 ID,lcd_rgb[7](B7)、lcd_rgb[15](G7)和 lcd_rgb[23](R7)分别对应 M2、M1 和 M0。
 除此之外,为了方便将 LCD 的 ID 和分辨率对应起来,这里对 M2、M1 和 M0 的值做了一个译码。如3’b000 译码成 16’h4342,表示当前连接的是 4.3 寸屏,分辨率为 480*272。
 
还有一件事 区分一下 高位和低位
 
其中 bit23~bit16 是 RED 通道,bit15~bit8 是 GREEN 通道,bit7~bit0 是 BLUE 通道。
ok
 代码和结构在最后统一展示
 下面介绍时钟模块
 时钟模块 主要在于接收上游发送的lcd_id 之后 对应输出 不同的时钟频率
 
我们现在按照要求 要输出一个 2分频和4分频
 超链接一下 我上次 写的 分频器的章节
 因为偶数频率相对来说好做一点 对于奇数频率 大家可以相对的去学习一下
 偶数频率N 在于 取 N/2 - 1 的 clk 反转
ok
下一步 我这里和正点原子不同了
 我希望我这个模块 只是用来将 不同的 分辨率 lcd 究竟该如何作画 区分开来
 
我们了解到了原理可以知道 红色框框是 整个屏幕 而 黑色的是 框框的 画布 我们会在上面进行作画 注意左上角的是 端点(0,0)
 整个总长其实包括了 下面的几个部分

 而 画布的长度其实就是其中数据 显示的 HOZVAL 假设 1024*600 其实就是1024
 而总列长 我们可以通过 利用帧同步信号进行计算
 每完成1行到头 + 1 加到多少 就是多少
 这里有一个误区
 因为这一的单位是 1行的时间 所以我们不去细究数据 的 大小 可能数据量上会小一点
 所以 我们每走完一整行 再控制这个列的数字 + 1 这才是 我们需要注意到的 因为单位是 一整行
注意点说完了 下面开始代码构造 都放到了下面统一讲述了
 下面演示主要代码
 ----------------------------------------------------------------------------read_id .v
module rd_id(input                   clk    ,    //时钟input                   rst_n  ,    //复位,低电平有效input           [23:0]  lcd_rgb,    //RGB LCD像素数据,用于读取IDoutput   reg    [15:0]  lcd_id     //LCD屏ID);//reg definereg            rd_flag;  //读ID标志//*****************************************************//**                    main code//*****************************************************//获取LCD ID   M2:B7  M1:G7  M0:R7always @(posedge clk or negedge rst_n)beginif(!rst_n)beginrd_flag <= 1'b0;lcd_id <= 16'd0;endelsebeginif(rd_flag == 1'b0)beginrd_flag <= 1'b1;case({lcd_rgb[7],lcd_rgb[15],lcd_rgb[23]})3'b000 :lcd_id <= 16'h4342;    //4.3' RGB LCD  RES:480x2723'b001 :lcd_id <= 16'h7084;    //7'   RGB LCD  RES:800x4803'b010 :lcd_id <= 16'h7016;    //7'   RGB LCD  RES:1024x6003'b100 :lcd_id <= 16'h4384;    //4.3' RGB LCD  RES:800x4803'b101 :lcd_id <= 16'h1018;    //10'  RGB LCD  RES:1280x800default :lcd_id <= 16'd0;endcaseendendendendmodule
 
----------------------------------------------------------------------------clk.v
module clk_id(input               clk      ,input               rst_n    ,input     [15:0]    lcd_id   ,output    reg       lcd_pclk);reg          clk_25m;reg          clk_12_5m;reg          div_4_cnt;//时钟2分频 输出25MHz时钟always @(posedge clk or negedge rst_n)beginif(!rst_n)clk_25m <= 1'b0;elseclk_25m <= ~clk_25m;end//时钟4分频 输出12.5MHz时钟always @(posedge clk or negedge rst_n)beginif(!rst_n)begindiv_4_cnt <= 1'b0;clk_12_5m <= 1'b0;endelsebegindiv_4_cnt <= div_4_cnt + 1'b1;if(div_4_cnt == 1'b1)clk_12_5m <= ~clk_12_5m;endendalways @(*)begincase(lcd_id)16'h4342 :lcd_pclk = clk_12_5m;16'h7084 :lcd_pclk = clk_25m;16'h7016 :lcd_pclk = clk;16'h4384 :lcd_pclk = clk_25m;16'h1018 :lcd_pclk = clk;default :lcd_pclk = 1'b0;endcaseendendmodule
 
---------------------------------------------------------------------------lcd_set.v
module lcd_set(input                    clk        ,input                    rst_n      ,input        [15:0]      lcd_id     ,output       [10:0]      pixel_xpos ,  // x 轴 对于点的移动坐标output       [10:0]      pixel_ypos ,  // y 轴 对于点的移动坐标output  reg  [10:0]      h_disp     ,  // it is 480*272   - 480output  reg  [10:0]      v_disp        //                 - 272);//  ============================================  \\//    we define signal  and parameter             \\//  ============================================  \\
// next is copy// 4.3' 480*272parameter  H_SYNC_4342   =  11'd41;     //行同步parameter  H_BACK_4342   =  11'd2;      //行显示后沿parameter  H_DISP_4342   =  11'd480;    //行有效数据parameter  H_FRONT_4342  =  11'd2;      //行显示前沿parameter  H_TOTAL_4342  =  11'd525;    //行扫描周期parameter  V_SYNC_4342   =  11'd10;     //场同步parameter  V_BACK_4342   =  11'd2;      //场显示后沿parameter  V_DISP_4342   =  11'd272;    //场有效数据parameter  V_FRONT_4342  =  11'd2;      //场显示前沿parameter  V_TOTAL_4342  =  11'd286;    //场扫描周期// 7' 800*480parameter  H_SYNC_7084   =  11'd128;    //行同步parameter  H_BACK_7084   =  11'd88;     //行显示后沿parameter  H_DISP_7084   =  11'd800;    //行有效数据parameter  H_FRONT_7084  =  11'd40;     //行显示前沿parameter  H_TOTAL_7084  =  11'd1056;   //行扫描周期parameter  V_SYNC_7084   =  11'd2;      //场同步parameter  V_BACK_7084   =  11'd33;     //场显示后沿parameter  V_DISP_7084   =  11'd480;    //场有效数据parameter  V_FRONT_7084  =  11'd10;     //场显示前沿parameter  V_TOTAL_7084  =  11'd525;    //场扫描周期// 7' 1024*600parameter  H_SYNC_7016   =  11'd20;     //行同步parameter  H_BACK_7016   =  11'd140;    //行显示后沿parameter  H_DISP_7016   =  11'd1024;   //行有效数据parameter  H_FRONT_7016  =  11'd160;    //行显示前沿parameter  H_TOTAL_7016  =  11'd1344;   //行扫描周期parameter  V_SYNC_7016   =  11'd3;      //场同步parameter  V_BACK_7016   =  11'd20;     //场显示后沿parameter  V_DISP_7016   =  11'd600;    //场有效数据parameter  V_FRONT_7016  =  11'd12;     //场显示前沿parameter  V_TOTAL_7016  =  11'd635;    //场扫描周期// 10.1' 1280*800parameter  H_SYNC_1018   =  11'd10;     //行同步parameter  H_BACK_1018   =  11'd80;     //行显示后沿parameter  H_DISP_1018   =  11'd1280;   //行有效数据parameter  H_FRONT_1018  =  11'd70;     //行显示前沿parameter  H_TOTAL_1018  =  11'd1440;   //行扫描周期parameter  V_SYNC_1018   =  11'd3;      //场同步parameter  V_BACK_1018   =  11'd10;     //场显示后沿parameter  V_DISP_1018   =  11'd800;    //场有效数据parameter  V_FRONT_1018  =  11'd10;     //场显示前沿parameter  V_TOTAL_1018  =  11'd823;    //场扫描周期// 4.3' 800*480parameter  H_SYNC_4384   =  11'd128;    //行同步parameter  H_BACK_4384   =  11'd88;     //行显示后沿parameter  H_DISP_4384   =  11'd800;    //行有效数据parameter  H_FRONT_4384  =  11'd40;     //行显示前沿parameter  H_TOTAL_4384  =  11'd1056;   //行扫描周期parameter  V_SYNC_4384   =  11'd2;      //场同步parameter  V_BACK_4384   =  11'd33;     //场显示后沿parameter  V_DISP_4384   =  11'd480;    //场有效数据parameter  V_FRONT_4384  =  11'd10;     //场显示前沿parameter  V_TOTAL_4384  =  11'd525;    //场扫描周期// define 便于后面的使用 调用reg  [10:0] h_sync ;reg  [10:0] h_back ;reg  [10:0] h_total;reg  [10:0] v_sync ;reg  [10:0] v_back ;reg  [10:0] v_total;reg  [10:0] h_cnt  ;reg  [10:0] v_cnt  ;// ==================================================  \\//         next is  main code                          \\// ==================================================  \\
always @(*)begincase(lcd_id)16'h4342 :beginh_sync  = H_SYNC_4342;h_back  = H_BACK_4342;h_disp  = H_DISP_4342;h_total = H_TOTAL_4342;v_sync  = V_SYNC_4342;v_back  = V_BACK_4342;v_disp  = V_DISP_4342;v_total = V_TOTAL_4342;end16'h7084 :beginh_sync  = H_SYNC_7084;h_back  = H_BACK_7084;h_disp  = H_DISP_7084;h_total = H_TOTAL_7084;v_sync  = V_SYNC_7084;v_back  = V_BACK_7084;v_disp  = V_DISP_7084;v_total = V_TOTAL_7084;end16'h7016 :beginh_sync  = H_SYNC_7016;h_back  = H_BACK_7016;h_disp  = H_DISP_7016;h_total = H_TOTAL_7016;v_sync  = V_SYNC_7016;v_back  = V_BACK_7016;v_disp  = V_DISP_7016;v_total = V_TOTAL_7016;end16'h4384 :beginh_sync  = H_SYNC_4384;h_back  = H_BACK_4384;h_disp  = H_DISP_4384;h_total = H_TOTAL_4384;v_sync  = V_SYNC_4384;v_back  = V_BACK_4384;v_disp  = V_DISP_4384;v_total = V_TOTAL_4384;end16'h1018 :beginh_sync  = H_SYNC_1018;h_back  = H_BACK_1018;h_disp  = H_DISP_1018;h_total = H_TOTAL_1018;v_sync  = V_SYNC_1018;v_back  = V_BACK_1018;v_disp  = V_DISP_1018;v_total = V_TOTAL_1018;enddefault :beginh_sync  = H_SYNC_4342;h_back  = H_BACK_4342;h_disp  = H_DISP_4342;h_total = H_TOTAL_4342;v_sync  = V_SYNC_4342;v_back  = V_BACK_4342;v_disp  = V_DISP_4342;v_total = V_TOTAL_4342;endendcaseend// 下一步 我们想要确定整个画布的长度计数//因为 我们配置 x y 其实是为了下一步 display 而用的 我们这里的 配置的 计数//  是用来显示 总长度的计数 而 x y 的计数 是总长度计数 要减去 头尾的多余always@ (posedge clk or negedge rst_n)beginif(!rst_n)h_cnt <= 11'd0;elsebeginif(h_cnt == h_total - 1'b1)h_cnt <= 11'd0;elseh_cnt <= h_cnt + 1'b1;endend// 其实这个控制的是 总长 现在我们确定一下 列长always@ (posedge clk or negedge rst_n)beginif(!rst_n)v_cnt <= 11'd0;elsebeginif(h_cnt == h_total - 1'b1)beginif(v_cnt == v_total - 1'b1)v_cnt <= 11'd0;elsev_cnt <= v_cnt + 1'b1;endendend//  接下来 我们配置 x y 坐标// 我不太懂它 正点原子的什么鬼 我不知道为什么对于 data_reg 他非要 做一个减1 的操作// 也许是上面的那个说 data_reg 其实是有接口的但是要比 lcd_reg 少一个 clk 也许是这个原因// copy 一下//请求像素点颜色数据输入assign data_req = ((h_cnt >= h_sync + h_back - 1'b1) && (h_cnt < h_sync + h_back + h_disp - 1'b1)&& (v_cnt >= v_sync + v_back) && (v_cnt < v_sync + v_back + v_disp))? 1'b1 : 1'b0;//像素点坐标assign pixel_xpos = data_req ? (h_cnt - (h_sync + h_back - 1'b1)) : 11'd0;assign pixel_ypos = data_req ? (v_cnt - (v_sync + v_back - 1'b1)) : 11'd0;endmodule
 
----------------------------------------------------------------------------------- display.v
module lcd_display(input              lcd_pclk        ,input                     rst_n           ,input          [10:0]     pixel_xpos      ,input          [10:0]     pixel_ypos      ,input          [10:0]     h_disp          ,input          [10:0]     v_disp          ,output  reg    [23:0]     pixel_data);//parameter defineparameter WHITE =    24'hFFFFFF; //白色parameter BLACK =    24'h000000; //黑色parameter RED   =    24'hFF0000; //红色parameter GREEN =    24'h00FF00; //绿色parameter BLUE  =    24'h0000FF; //蓝// ==========================================  \\//              next   is  main  code          \\//==============================================\\always @(posedge lcd_pclk or negedge rst_n)beginif(!rst_n)pixel_data <= BLACK;elsebeginif((pixel_xpos >= 11'd0) && (pixel_xpos < h_disp/5*1))pixel_data <= WHITE;else if((pixel_xpos >= h_disp/5*1) && (pixel_xpos < h_disp/5*2))pixel_data <= BLACK;else if((pixel_xpos >= h_disp/5*2) && (pixel_xpos < h_disp/5*3))pixel_data <= RED;else if((pixel_xpos >= h_disp/5*3) && (pixel_xpos < h_disp/5*4))pixel_data <= GREEN;elsepixel_data <= BLUE;endendendmodule
 
-------------------------------------------------------------------------------------- lastout.v
module last_out(input                           lcd_pclk        ,input                           rst_n           ,input             [15:0]        lcd_id          ,input             [23:0]        pixel_data      ,output                          lcd_de          ,     //LCD 数据使能信号output                          lcd_hs          ,     //LCD 行同步信号output                          lcd_vs          ,     //LCD 场同步信号output                          lcd_bl          ,     //LCD 背光控制信号output                          lcd_clk         ,     //LCD 像素时钟output                          lcd_rst         ,     //LCD复位output            [23:0]        lcd_rgb               //LCD RGB888颜色数据);//parameter define// 4.3' 480*272parameter  H_SYNC_4342   =  11'd41;     //行同步parameter  H_BACK_4342   =  11'd2;      //行显示后沿parameter  H_DISP_4342   =  11'd480;    //行有效数据parameter  H_FRONT_4342  =  11'd2;      //行显示前沿parameter  H_TOTAL_4342  =  11'd525;    //行扫描周期parameter  V_SYNC_4342   =  11'd10;     //场同步parameter  V_BACK_4342   =  11'd2;      //场显示后沿parameter  V_DISP_4342   =  11'd272;    //场有效数据parameter  V_FRONT_4342  =  11'd2;      //场显示前沿parameter  V_TOTAL_4342  =  11'd286;    //场扫描周期// 7' 800*480parameter  H_SYNC_7084   =  11'd128;    //行同步parameter  H_BACK_7084   =  11'd88;     //行显示后沿parameter  H_DISP_7084   =  11'd800;    //行有效数据parameter  H_FRONT_7084  =  11'd40;     //行显示前沿parameter  H_TOTAL_7084  =  11'd1056;   //行扫描周期parameter  V_SYNC_7084   =  11'd2;      //场同步parameter  V_BACK_7084   =  11'd33;     //场显示后沿parameter  V_DISP_7084   =  11'd480;    //场有效数据parameter  V_FRONT_7084  =  11'd10;     //场显示前沿parameter  V_TOTAL_7084  =  11'd525;    //场扫描周期// 7' 1024*600parameter  H_SYNC_7016   =  11'd20;     //行同步parameter  H_BACK_7016   =  11'd140;    //行显示后沿parameter  H_DISP_7016   =  11'd1024;   //行有效数据parameter  H_FRONT_7016  =  11'd160;    //行显示前沿parameter  H_TOTAL_7016  =  11'd1344;   //行扫描周期parameter  V_SYNC_7016   =  11'd3;      //场同步parameter  V_BACK_7016   =  11'd20;     //场显示后沿parameter  V_DISP_7016   =  11'd600;    //场有效数据parameter  V_FRONT_7016  =  11'd12;     //场显示前沿parameter  V_TOTAL_7016  =  11'd635;    //场扫描周期// 10.1' 1280*800parameter  H_SYNC_1018   =  11'd10;     //行同步parameter  H_BACK_1018   =  11'd80;     //行显示后沿parameter  H_DISP_1018   =  11'd1280;   //行有效数据parameter  H_FRONT_1018  =  11'd70;     //行显示前沿parameter  H_TOTAL_1018  =  11'd1440;   //行扫描周期parameter  V_SYNC_1018   =  11'd3;      //场同步parameter  V_BACK_1018   =  11'd10;     //场显示后沿parameter  V_DISP_1018   =  11'd800;    //场有效数据parameter  V_FRONT_1018  =  11'd10;     //场显示前沿parameter  V_TOTAL_1018  =  11'd823;    //场扫描周期// 4.3' 800*480parameter  H_SYNC_4384   =  11'd128;    //行同步parameter  H_BACK_4384   =  11'd88;     //行显示后沿parameter  H_DISP_4384   =  11'd800;    //行有效数据parameter  H_FRONT_4384  =  11'd40;     //行显示前沿parameter  H_TOTAL_4384  =  11'd1056;   //行扫描周期parameter  V_SYNC_4384   =  11'd2;      //场同步parameter  V_BACK_4384   =  11'd33;     //场显示后沿parameter  V_DISP_4384   =  11'd480;    //场有效数据parameter  V_FRONT_4384  =  11'd10;     //场显示前沿parameter  V_TOTAL_4384  =  11'd525;    //场扫描周期//reg definereg  [10:0] h_sync ;reg  [10:0] h_back ;reg  [10:0] h_total;reg  [10:0] v_sync ;reg  [10:0] v_back ;reg  [10:0] v_total;reg  [10:0] h_cnt  ;reg  [10:0] v_cnt  ;//wire definewire        lcd_en;reg [10:0]   h_disp ;reg   [10:0]   v_disp ;// 全是copy//行场时序参数always @(*)begincase(lcd_id)16'h4342 :beginh_sync  = H_SYNC_4342;h_back  = H_BACK_4342;h_disp  = H_DISP_4342;h_total = H_TOTAL_4342;v_sync  = V_SYNC_4342;v_back  = V_BACK_4342;v_disp  = V_DISP_4342;v_total = V_TOTAL_4342;end16'h7084 :beginh_sync  = H_SYNC_7084;h_back  = H_BACK_7084;h_disp  = H_DISP_7084;h_total = H_TOTAL_7084;v_sync  = V_SYNC_7084;v_back  = V_BACK_7084;v_disp  = V_DISP_7084;v_total = V_TOTAL_7084;end16'h7016 :beginh_sync  = H_SYNC_7016;h_back  = H_BACK_7016;h_disp  = H_DISP_7016;h_total = H_TOTAL_7016;v_sync  = V_SYNC_7016;v_back  = V_BACK_7016;v_disp  = V_DISP_7016;v_total = V_TOTAL_7016;end16'h4384 :beginh_sync  = H_SYNC_4384;h_back  = H_BACK_4384;h_disp  = H_DISP_4384;h_total = H_TOTAL_4384;v_sync  = V_SYNC_4384;v_back  = V_BACK_4384;v_disp  = V_DISP_4384;v_total = V_TOTAL_4384;end16'h1018 :beginh_sync  = H_SYNC_1018;h_back  = H_BACK_1018;h_disp  = H_DISP_1018;h_total = H_TOTAL_1018;v_sync  = V_SYNC_1018;v_back  = V_BACK_1018;v_disp  = V_DISP_1018;v_total = V_TOTAL_1018;enddefault :beginh_sync  = H_SYNC_4342;h_back  = H_BACK_4342;h_disp  = H_DISP_4342;h_total = H_TOTAL_4342;v_sync  = V_SYNC_4342;v_back  = V_BACK_4342;v_disp  = V_DISP_4342;v_total = V_TOTAL_4342;endendcaseend//行计数器对像素时钟计数always@ (posedge lcd_pclk or negedge rst_n)beginif(!rst_n)h_cnt <= 11'd0;elsebeginif(h_cnt == h_total - 1'b1)h_cnt <= 11'd0;elseh_cnt <= h_cnt + 1'b1;endend//场计数器对行计数always@ (posedge lcd_pclk or negedge rst_n)beginif(!rst_n)v_cnt <= 11'd0;elsebeginif(h_cnt == h_total - 1'b1)beginif(v_cnt == v_total - 1'b1)v_cnt <= 11'd0;elsev_cnt <= v_cnt + 1'b1;endendend// 这里要开始对最终的 结果进行说明了// lcd_de     //LCD 数据使能信号// lcd_hs     //LCD 行同步信号// lcd_vs     //LCD 场同步信号// lcd_bl     //LCD 背光控制信号// lcd_clk    //LCD 像素时钟// lcd_rst    //LCD复位// lcd_rgb    //LCD RGB888颜色数据assign  lcd_de = lcd_en;      //LCD数据有效信号//使能RGB888数据输出assign  lcd_en = ((h_cnt >= h_sync + h_back) && (h_cnt < h_sync + h_back + h_disp)&& (v_cnt >= v_sync + v_back) && (v_cnt < v_sync + v_back + v_disp)) ? 1'b1 : 1'b0;assign  lcd_hs  = 1'b1       ;        //LCD行同步信号assign  lcd_vs  = 1'b1       ;        //LCD场同步信号assign  lcd_bl  = 1'b1       ;        //LCD背光控制信号assign  lcd_clk = lcd_pclk   ;   //LCD像素时钟assign  lcd_rst = 1'b1       ;        //LCD复位//RGB888数据输出
assign lcd_rgb = lcd_en ? pixel_data : 24'd0;endmodule 
 
---------------------------------------------------------------------------- top.v
module dig_top (input                sys_clk,     //系统时钟input                sys_rst_n,   //系统复位//RGB LCD接口output               lcd_de,      //LCD 数据使能信号output               lcd_hs,      //LCD 行同步信号output               lcd_vs,      //LCD 场同步信号output               lcd_bl,      //LCD 背光控制信号output               lcd_clk,     //LCD 像素时钟output               lcd_rst,     //LCD 复位inout        [23:0]  lcd_rgb      //LCD RGB888颜色数据);//  ============================================  \\//       Next is define  and signal parameter     \\//  ============================================  \\wire   [15 : 0]    lcd_id     ;wire               lcd_pclk   ;wire   [10 : 0]    pixel_xpos ;wire   [10 : 0]    pixel_ypos ;wire   [10 : 0]    h_disp     ;wire   [10 : 0]    v_disp     ;wire   [23 : 0]    pixel_data ;wire  [23:0]  lcd_rgb_o ;    //输出的像素数据wire  [23:0]  lcd_rgb_i ;    //输入的像素数据assign lcd_rgb = lcd_de ?  lcd_rgb_o :  {24{1'bz}};assign lcd_rgb_i = lcd_rgb;// ================================================ \\
//                next   is  main  code             \\
//================================================  \\
rd_id u_read_id(.clk      ( sys_clk      ),.rst_n    (  sys_rst_n    ),.lcd_rgb  ( lcd_rgb  ),.lcd_id   ( lcd_id   )
);clk_id u_clk_id(.clk     ( sys_clk     ),.rst_n   ( sys_rst_n   ),.lcd_id  ( lcd_id  ),.lcd_pclk  ( lcd_pclk  )
);lcd_set u_lcd_set(.clk         ( lcd_pclk         ),.rst_n       ( sys_rst_n       ),.lcd_id      ( lcd_id      ),.pixel_xpos  ( pixel_xpos  ),.pixel_ypos  ( pixel_ypos  ),.h_disp      ( h_disp      ),.v_disp      ( v_disp      )
);lcd_display u_lcd_display(.lcd_pclk    ( lcd_pclk    ),.rst_n       ( sys_rst_n       ),.pixel_xpos  ( pixel_xpos  ),.pixel_ypos  ( pixel_ypos  ),.h_disp      ( h_disp      ),.v_disp      ( v_disp      ),.pixel_data  ( pixel_data  )
);last_out u_last_out(.lcd_pclk    ( lcd_pclk    ),.rst_n       ( sys_rst_n       ),.lcd_id      ( lcd_id      ),.pixel_data  ( pixel_data  ),.lcd_de      ( lcd_de      ),.lcd_hs      ( lcd_hs      ),.lcd_vs      ( lcd_vs      ),.lcd_bl      ( lcd_bl      ),.lcd_clk     ( lcd_clk     ),.lcd_rst     ( lcd_rst     ),.lcd_rgb     ( lcd_rgb     )
);endmodule 
 
// ================================================ testbench.v
`timescale 1ns / 1nsmodule tb_lcd_rgb_colorbar();//reg definereg sys_clk;reg sys_rst_n; //wire definewire lcd_de ;wire lcd_hs ;wire lcd_vs ;wire lcd_bl ;wire lcd_clk;wire [23:0] lcd_rgb;always #10 sys_clk = ~sys_clk;assign lcd_rgb = 24'h0;initial beginsys_clk = 1'b0;sys_rst_n = 1'b0;#200sys_rst_n = 1'b1;enddig_top u_dig_top(.sys_clk   ( sys_clk   ),.sys_rst_n ( sys_rst_n ),.lcd_de    ( lcd_de    ),.lcd_hs    ( lcd_hs    ),.lcd_vs    ( lcd_vs    ),.lcd_bl    ( lcd_bl    ),.lcd_clk   ( lcd_clk   ),.lcd_rst   ( lcd_rst   ),.lcd_rgb  (   lcd_rgb  )
);endmodule