RGB LCD drive

发布时间 2023-09-26 19:48:48作者: xgj_0817
module  lcd_drive
#(
parameter VBP= 31,//OK
parameter VFP= 11,//OK
parameter VSW= 3 ,//OK
parameter VDP= 480 ,

parameter HBP= 41,//ok
parameter HFP= 114,//ok
parameter HSW= 4 ,//ok
parameter HDP=640

)

(   
     clk_i             ,                //时钟输入

     rst_i             ,                //复位输入
     display_on        ,             //显示开关输入
     data_r_i          ,             //8位红色数据输入
     data_g_i          ,             //8位绿色数据输入
     data_b_i          ,             //8位蓝色数据输入
     data_rdy_o        ,             //数据输入请求信号输出

     hsync_o           ,              //行同步信号输出
     vsync_o           ,              //场同步信号输出
     enable_o          ,             //数据允许信号输出
     pclk_o            ,               //数据时钟输出
     data_r_o          ,               //8位红色数据输出
     data_g_o          ,               //8位绿色数据输出
     data_b_o          ,               //8位蓝色数据输出
     xpos_o            ,               //当前行计数输出
     ypos_o                           //当前列计数输出            
 );
                
input wire [0:0]  clk_i;

input wire [0:0]  rst_i;

input wire [0:0]  display_on;
input wire [7:0]  data_r_i;
input wire [7:0]  data_g_i;
input wire [7:0]  data_b_i;

output wire [0:0]  data_rdy_o;

output wire  [0:0]  hsync_o;
output wire  [0:0]  vsync_o;
output wire  [0:0]  enable_o;
output wire [0:0]   pclk_o;
output wire  [7:0] data_r_o;
output wire  [7:0] data_g_o;
output wire  [7:0] data_b_o;
output wire [15:0] xpos_o;
output wire [15:0] ypos_o;

reg [16:0]  H_CNT_R;  
reg [16:0]  V_CNT_R;   

reg hsync_r;
reg vsync_r;
reg enable_r;
reg [7:0]  red_r;
reg [7:0]  green_r;
reg [7:0]  blue_r;


//行计数
always @(posedge clk_i or negedge rst_i )
     begin
        if(rst_i==1'b0 || display_on==1'b0 )
          begin
            H_CNT_R<=17'd0;
          end
        else if(H_CNT_R>=(HBP+HFP+HSW+HDP-1'D1))
                begin
                    H_CNT_R<=17'd0;
                end
             else
                begin
                    H_CNT_R<=H_CNT_R+1'd1;
                end
            
     end  
     
//列计数
always @(posedge clk_i or negedge rst_i )
     begin
        if(rst_i==1'b0 || display_on==1'b0 )
                    V_CNT_R<=17'd0;
        else if((V_CNT_R>=(VBP+VFP+VSW+VDP-1'D1)) && (H_CNT_R>=(HBP+HFP+HSW+HDP-1'D1)))
                    V_CNT_R<=17'D0;
        else if(H_CNT_R>=(HBP+HFP+HSW+HDP-1'D1))
                    V_CNT_R<=V_CNT_R+1'd1;
             else
                    V_CNT_R<=V_CNT_R;
            
     end  

//输出VSYNC信号
always @(posedge clk_i or negedge rst_i )
     begin
        if(rst_i==1'b0 )
            vsync_r<=1'b0;
        else if((V_CNT_R>=(VBP+VFP+VSW+VDP-1'D1)) && (H_CNT_R>=(HBP+HFP+HSW+HDP-1'D1))) 
            vsync_r<=1'b0;
        else if((V_CNT_R>=(VSW-1'd1))&&(H_CNT_R>=(HBP+HFP+HSW+HDP-1'D1)))
            vsync_r<=1'b1;
        else 
            vsync_r<=vsync_r;
     
     end
     

//输出HSYNC信号
always @(posedge clk_i or negedge rst_i )
     begin
        if(rst_i==1'b0 )
            hsync_r<=1'b0;
        else if((H_CNT_R<HSW-1'd1) ||(H_CNT_R>=(HBP+HFP+HSW+HDP-1'd1))) 
            hsync_r<=1'b0;
        else
            hsync_r<=1'b1;
     
     end     
     
//输出ENABLE信号
always @(posedge clk_i or negedge rst_i )
     begin  
        if(rst_i==1'b0 )
            enable_r<=1'b0;
        else if((H_CNT_R>(HSW+HBP-2'd2)) && (H_CNT_R<(HSW+HBP+HDP-1'd1)) && (V_CNT_R>(VSW+VBP-1'd1)) && (V_CNT_R<=(VSW+VBP+VDP-1'd1)))
            enable_r<=1'b1;          
        else 
            enable_r<=1'b0;     
     end
     
  

          
//向外发出数据输入请求
assign data_rdy_o=((H_CNT_R>(HSW+HBP-2'd2)) && (H_CNT_R<(HSW+HBP+HDP-1'd1)) && (V_CNT_R>(VSW+VBP-1'd1)) && (V_CNT_R<=(VSW+VBP+VDP-1'd1)))? 1'b1:1'b0;    
 
//输出当前行计数
//assign xpos_o = (data_rdy_o) ? (H_CNT_R-HSW-HBP):16'd0;

reg [15:0]xpos_r;
always @(posedge clk_i or negedge rst_i  )
     begin
         if(rst_i==1'b0 )
             xpos_r<=16'd0;
         else if((H_CNT_R>(HSW+HBP-2'd2)) && (H_CNT_R<(HSW+HBP+HDP-1'd1)) && (V_CNT_R>(VSW+VBP-1'd1)) && (V_CNT_R<=(VSW+VBP+VDP-1'd1)))
             xpos_r<=(H_CNT_R+16'd2)-HSW-HBP;
         else 
            xpos_r<=16'd0;
     
     end
//输出当前列计数
//assign ypos_o = (data_rdy_o) ? (V_CNT_R-VSW-VBP):16'd0; 
reg [15:0] ypos_r;
always @(posedge clk_i or negedge rst_i  )
     begin
         if(rst_i==1'b0 )
             ypos_r<=16'd0;
         else if((H_CNT_R>=(HSW+HBP-2'd2)) && (H_CNT_R<(HSW+HBP+HDP-1'd1)) && (V_CNT_R>(VSW+VBP-2'd2)) && (V_CNT_R<=(VSW+VBP+VDP-1'd1)))
                 ypos_r<=V_CNT_R-VSW-VBP;
         else 
            ypos_r<=16'd0;
     
     end




//输出显示数据
always @(posedge clk_i or negedge rst_i )
     begin
        if(rst_i==1'b0 )
            begin                
                red_r<=8'b0;
                green_r<=8'b0;
                blue_r<=8'b0;
               end
        else if((H_CNT_R>(HSW+HBP-2'd2)) && (H_CNT_R<(HSW+HBP+HDP-1'd1)) && (V_CNT_R>(VSW+VBP-1'd1)) && (V_CNT_R<=(VSW+VBP+VDP-1'd1)))
            begin
                 red_r<=data_r_i;
                 green_r<=data_g_i;
                 blue_r<=data_b_i;
                 
            end
        else
            begin                
                red_r<=red_r;
                green_r<=green_r;
                blue_r<=blue_r;
               end
     
     end    


assign hsync_o=(display_on==1'b1 )? hsync_r:1'bz ;
assign vsync_o=(display_on==1'b1 )? vsync_r:1'bz ;
assign enable_o=(display_on==1'b1 )? enable_r:1'bz ;

assign data_r_o=(display_on==1'b1 )? red_r:8'bz ;
assign data_g_o=(display_on==1'b1 )? green_r:8'bz ;
assign data_b_o=(display_on==1'b1 )? blue_r:8'bz ;
//输出PCLK信号
assign pclk_o=(display_on==1'b1 )? clk_i:16'bz ; 
assign xpos_o=(display_on==1'b1 )? xpos_r:16'bz ;
assign ypos_o=(display_on==1'b1 )? ypos_r:16'bz ;
     
    


endmodule