【【RGB LCD 彩条显示实验 ---1】】

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像素数据,用于读取ID
    output   reg    [15:0]  lcd_id     //LCD屏ID
  );

  //reg define
  reg            rd_flag;  //读ID标志

  //*****************************************************
  //**                    main code
  //*****************************************************

  //获取LCD ID   M2:B7  M1:G7  M0:R7
  always @(posedge clk or negedge rst_n)
  begin
    if(!rst_n)
    begin
      rd_flag <= 1'b0;
      lcd_id <= 16'd0;
    end
    else
    begin
      if(rd_flag == 1'b0)
      begin
        rd_flag <= 1'b1;
        case({lcd_rgb[7],lcd_rgb[15],lcd_rgb[23]})
          3'b000 :
            lcd_id <= 16'h4342;    //4.3' RGB LCD  RES:480x272
          3'b001 :
            lcd_id <= 16'h7084;    //7'   RGB LCD  RES:800x480
          3'b010 :
            lcd_id <= 16'h7016;    //7'   RGB LCD  RES:1024x600
          3'b100 :
            lcd_id <= 16'h4384;    //4.3' RGB LCD  RES:800x480
          3'b101 :
            lcd_id <= 16'h1018;    //10'  RGB LCD  RES:1280x800
          default :
            lcd_id <= 16'd0;
        endcase
      end
    end
  end

endmodule

----------------------------------------------------------------------------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)
  begin
    if(!rst_n)
      clk_25m <= 1'b0;
    else
      clk_25m <= ~clk_25m;
  end

  //时钟4分频 输出12.5MHz时钟
  always @(posedge clk or negedge rst_n)
  begin
    if(!rst_n)
    begin
      div_4_cnt <= 1'b0;
      clk_12_5m <= 1'b0;
    end
    else
    begin
      div_4_cnt <= div_4_cnt + 1'b1;
      if(div_4_cnt == 1'b1)
        clk_12_5m <= ~clk_12_5m;
    end
  end

  always @(*)
  begin
    case(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;
    endcase
  end

endmodule

---------------------------------------------------------------------------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   - 480
    output  reg  [10:0]      v_disp        //                 - 272
  );


  //  ============================================  \\
  //    we define signal  and parameter             \\
  //  ============================================  \\

  // next is copy
  // 4.3' 480*272
  parameter  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*480
  parameter  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*600
  parameter  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*800
  parameter  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*480
  parameter  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 @(*)
  begin
    case(lcd_id)
      16'h4342 :
      begin
        h_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;
      end
      16'h7084 :
      begin
        h_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;
      end
      16'h7016 :
      begin
        h_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;
      end
      16'h4384 :
      begin
        h_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;
      end
      16'h1018 :
      begin
        h_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;
      end
      default :
      begin
        h_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;
      end
    endcase
  end
  // 下一步 我们想要确定整个画布的长度计数
  //因为 我们配置 x y 其实是为了下一步 display 而用的 我们这里的 配置的 计数
  //  是用来显示 总长度的计数 而 x y 的计数 是总长度计数 要减去 头尾的多余
  always@ (posedge clk or negedge rst_n)
  begin
    if(!rst_n)
      h_cnt <= 11'd0;
    else
    begin
      if(h_cnt == h_total - 1'b1)
        h_cnt <= 11'd0;
      else
        h_cnt <= h_cnt + 1'b1;
    end
  end

  // 其实这个控制的是 总长 现在我们确定一下 列长
  always@ (posedge clk or negedge rst_n)
  begin
    if(!rst_n)
      v_cnt <= 11'd0;
    else
    begin
      if(h_cnt == h_total - 1'b1)
      begin
        if(v_cnt == v_total - 1'b1)
          v_cnt <= 11'd0;
        else
          v_cnt <= v_cnt + 1'b1;
      end
    end
  end

  //  接下来 我们配置 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 define
  parameter 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)
  begin
    if(!rst_n)
      pixel_data <= BLACK;
    else
    begin
      if((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;
      else
        pixel_data <= BLUE;
    end
  end

endmodule

-------------------------------------------------------------------------------------- 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*272
  parameter  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*480
  parameter  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*600
  parameter  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*800
  parameter  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*480
  parameter  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 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  ;




  //wire define
  wire        lcd_en;
  reg [10:0]   h_disp ;
 reg   [10:0]   v_disp ;




  // 全是copy
  //行场时序参数
   always @(*)
   begin
     case(lcd_id)
       16'h4342 :
       begin
         h_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;
       end
       16'h7084 :
       begin
         h_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;
       end
       16'h7016 :
       begin
         h_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;
       end
       16'h4384 :
       begin
         h_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;
       end
       16'h1018 :
       begin
         h_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;
       end
       default :
       begin
         h_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;
       end
     endcase
   end

   //行计数器对像素时钟计数
   always@ (posedge lcd_pclk or negedge rst_n)
   begin
     if(!rst_n)
       h_cnt <= 11'd0;
     else
     begin
       if(h_cnt == h_total - 1'b1)
         h_cnt <= 11'd0;
       else
         h_cnt <= h_cnt + 1'b1;
     end
   end

   //场计数器对行计数
   always@ (posedge lcd_pclk or negedge rst_n)
   begin
     if(!rst_n)
       v_cnt <= 11'd0;
     else
     begin
       if(h_cnt == h_total - 1'b1)
       begin
         if(v_cnt == v_total - 1'b1)
           v_cnt <= 11'd0;
         else
           v_cnt <= v_cnt + 1'b1;
       end
     end
   end






   // 这里要开始对最终的 结果进行说明了
   // 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 / 1ns
 
 module tb_lcd_rgb_colorbar();
 
 //reg define
 reg sys_clk;
 reg sys_rst_n; 
 
 //wire define
  wire 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 begin
  sys_clk = 1'b0;
  sys_rst_n = 1'b0;
  #200
  sys_rst_n = 1'b1;
  end
  

dig_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 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/224994.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于JAVA+SpringBoot+微信小程序的宠物领养平台

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着人们生活水平的提…

Linux挂载配置本地yum源

1.vi /etc/yum.repos.d/redhat.repo 2. [baseos] namebaseos baseurlfile:///mnt/BaseOS #enabled:默认为1 enabled1 gpgcheck0 [appstream] nameappstream baseurlfile:///mnt/AppStream enabled1 gpgcheck0 3. mount /dev/sr0 /mnt/ 4.yum clean all 5.yum makecache

Java 简易版 UDP 多人聊天室

服务端 import java.io.*; import java.net.*; import java.util.ArrayList; public class Server{public static ServerSocket server_socket;public static ArrayList<Socket> socketListnew ArrayList<Socket>(); public static void main(String []args){try{…

校园跑腿小程序源码系统 源码完全开源可二开,在线下单 附带完整的搭建教程

随着互联网的快速发展&#xff0c;人们的生活方式也在不断改变。特别是在校园内&#xff0c;由于学习、生活等各种原因&#xff0c;学生们需要处理许多琐碎的事情。而校园跑腿服务正是在这样的背景下应运而生&#xff0c;它能够为学生们提供便捷、快速、个性化的服务&#xff0…

LeetCode题:931下降路径最小和

目录 一、题目要求 二、解题思路 &#xff08;1&#xff09;状态表示 &#xff08;2&#xff09;状态转移方程 &#xff08;3&#xff09;初始化 &#xff08;4&#xff09;填表顺序 &#xff08;5&#xff09;返回值 三、代码 一、题目要求 931. 下降路径最小和 给你…

统信UOS_麒麟KYLINOS上使用WeekToDo

原文链接&#xff1a;统信UOS/麒麟KYLINOS上使用WeekToDo hello&#xff0c;大家好啊&#xff0c;今天给大家带来一篇在统信UOS/麒麟KYLINOS上使用WeekToDo的介绍。在忙碌的工作和生活中&#xff0c;有效地管理时间和任务是非常重要的。WeekToDo作为一个免费和开源的每周计划器…

python实现pdf转word、word转pdf

我的博客 文章首发于公众号&#xff1a;小肖学数据分析 Python自动化办公通常对常用的办公软件文档格式进行操作&#xff0c;比如Word和PDF。 很多软件都需要付费&#xff0c;作为程序员&#xff0c;怎么可能付费。 下面是一个简单示例&#xff0c;如何在Python中将Word文档…

Java网络编程——非阻塞通信

对于用ServerSocket以及Socket编写的服务器程序和客户程序&#xff0c;它们在运行过程中常常会阻塞。例如当一个线程执行ServerSocket的accept()方法时&#xff0c;假如没有客户连接&#xff0c;该线程就会一直等到有了客户连接才从accept()方法返回。再例如当线程执行Socket的…

跨境电商做自己养号做测评,收货地址怎么解决?

近期有很多朋友问我&#xff0c;自己在做自媒体的时候&#xff0c;物流方面的问题该怎么解决&#xff1f;其实这个问题很简单&#xff0c;下面我就给大家分享一些解决物流问题的方法。 首先&#xff0c;如果你是自己发货&#xff0c;可以选择直接找物流商购买单号或者发空包。这…

基于ssm人事管理信息系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本人事管理信息系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

题目:谈判(蓝桥OJ 545)

题目描述&#xff1a; 解题思路&#xff1a; 本题采用贪心的思想&#xff0c;与蓝桥的合并果子题思路一样。可以使用优先对列&#xff0c;输入进去后自动排序。将两个最小的合并再放入对列中&#xff0c;并将值加入到ans&#xff0c;最终结果即ans。如下图&#xff1a;xy为4&a…

布隆过滤器及其在Java中的实际应用

前言 布隆过滤器一直是面试中的重点&#xff0c;本篇文章将深入探讨Java中的布隆过滤器的底层思想&#xff0c;包括它的工作原理、优缺点等。同时&#xff0c;我们将结合一个小实际案例&#xff0c;来给大家展示布隆过滤器在解决实际问题中的应用。 布隆过滤器简单介绍 在数…

观海微电子---触控显示模组一体化效果方案

随着车载电子后视镜及智能魔镜的普及类似镜面一体化要求的产品越来越多&#xff0c;行业熟知的木纹、一体黑、镜面显示都属于触控显示一体化效果。 一体化效果是指显示模组灭屏状态下玻璃盖板显示区域与非显示区域无明显的色差可见的效果&#xff0c;显示模组亮屏后显示仍可见&…

台灯应该买什么样的才能护眼?学生护眼必备护眼台灯推荐

10月26日&#xff0c;教育部召开新闻发布会&#xff0c;介绍综合防控儿童青少年近视工作情况。全国综合防控儿童青少年近视工作联席会议机制办公室主任、教育部体育卫生与艺术教育司司长王登峰介绍&#xff0c;2018年全国儿童青少年的总体近视率53.6%&#xff0c;2019年总体近视…

内存性能测试

内存带宽 内存带宽计算公式&#xff1a;带宽&#xff1d;内存时钟频率内存总线位数倍增系数&#xff0f;8。 STREAM测试及相关说明 STREAM测试工具是由时为美国Delaware大学教授 John McCalpin提出和完成的, 现在随着John McCalpin教授的工作变动&#xff0c; 负责 STREAM 的…

uniapp使用v-html调用接口,富文本图片 视频自适应大小

前端获取到后台数据 不做处理 就会出现下面问题 图片 视频超出视图显示不全 处理 //info 是富文本 <view v-ifinfo v-htmlreplaceWhite(info)></view>调用下面方法 replaceWhite(html) { // 处理富文本默认图片&#xff0c;视频大小let newContent html.replace…

【开源】基于Vue+SpringBoot的教学过程管理系统

项目编号&#xff1a; S 054 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S054&#xff0c;文末获取源码。} 项目编号&#xff1a;S054&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 教师端2.2 学生端2.3 微信小程序端2…

luceda ipkiss教程 40:获取版图中任意形状elements的面积

在ipkiss中&#xff0c;通过Polygon可以直接获取任意shape的面积&#xff1a; from si_fab import all as pdk import ipkiss3.all as i3 from shapely.geometry import Polygonclass Shape(i3.PCell):class Layout(i3.LayoutView):def _generate_elements(self, elems):elem…

如何申请GeoTrust通配符证书?

GeoTrust通配符证书可以保护一个域名下的所有子域名和所有下一级域名。这意味着&#xff0c;当您购买并安装了一个GeoTrust通配符证书后&#xff0c;您的主域名以及所有子域名都将得到SSL加密保护。这对于那些拥有多个子域名的网站来说&#xff0c;无疑是一种非常实用且高效的解…

实例解析关于兔鲜登录tab栏切换案例详细讲解!

文章目录 文章目录 效果图展示 整体制作的一个思路 代码展示 技术细节 小结 效果图展示 点击账户登录显示登录的模块&#xff0c;点击二维码登录显示二维码的模块 整体制作的一个思路 点击哪个模块哪个显示&#xff0c;另外一个模块让它隐藏即可&#xff01; 代码展示 <!…