






- /*
- // 24'h000000 4324 9Mhz 480*272
- // 24'h800000 7084 33Mhz 800*480
- // 24'h008080 7016 50Mhz 1024*600
- // 24'h000080 4384 33Mhz 800*480
- // 24'h800080 1018 70Mhz 1280*800
- */
- module rd_id(
- input wire sys_clk ,
- input wire sys_rst_n ,
- input wire [23:0] lcd_rgb ,
- output reg [15:0] lcd_id
- );
- reg rd_flag ;
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- rd_flag <= 1'b1 ;
- else
- rd_flag <= 1'b0 ;
- end
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- lcd_id <= 24'd0 ;
- else if(rd_flag) begin
- case (lcd_rgb)
- 24'h000000: lcd_id <= 16'd4324 ;
- 24'h800000: lcd_id <= 16'd7084 ;
- 24'h008080: lcd_id <= 16'd7016 ;
- 24'h000080: lcd_id <= 16'd4384 ;
- 24'h800080: lcd_id <= 16'd1018 ;
- default : lcd_id <= 16'd1018 ;
- endcase
- end
- end
- endmodule
- module clk_div(
- input wire sys_clk ,
- input wire sys_rst_n ,
- input wire [15:0] lcd_id ,
-
- output reg clk_lcd ,
- output wire rst_n
- );
- wire clk_9Mhz ;
- wire clk_33Mhz ;
- wire clk_50Mhz ;
- wire clk_70Mhz ;
- wire locked ;
-
- assign rst_n = (sys_rst_n && locked) ;
-
- always @(*) begin
- case (lcd_id)
- 16'd4324: clk_lcd <= clk_9Mhz ;
- 16'd7084: clk_lcd <= clk_33Mhz ;
- 16'd7016: clk_lcd <= clk_50Mhz ;
- 16'd4384: clk_lcd <= clk_33Mhz ;
- 16'd1018: clk_lcd <= clk_70Mhz ;
- default : clk_lcd <= 1'b0 ;
- endcase
- end
-
- pll pll_inst(
- .clk_in ( sys_clk ) ,
- .resetn ( sys_rst_n ) ,
-
- .clk_9Mhz ( clk_9Mhz ) ,
- .clk_33Mhz ( clk_33Mhz ) ,
- .clk_50Mhz ( clk_50Mhz ) ,
- .clk_70Mhz ( clk_70Mhz ) ,
- .locked ( locked )
- );
-
- endmodule
- // 根据传进来的有效图像坐标信息,产生有效的像素数据。
- module lcd_display (
- input wire sys_clk ,
- input wire sys_rst_n ,
- input wire [10:0] axi_x ,
- input wire [10:0] axi_y ,
-
- input wire [10:0] H_SYNC ,
- input wire [10:0] H_BACK ,
- input wire [10:0] H_DISP ,
- input wire [10:0] V_SYNC ,
- input wire [10:0] V_BACK ,
- input wire [10:0] V_DISP ,
-
- output reg [23:0] pix_data
- );
- localparam BLACK = 24'h000000 , // 黑色
- WHITE = 24'hFFFFFF , // 白色
- RosyBrown = 24'hBC8F8F , // 玫瑰褐
- RED = 24'hFF0000 , // 红色
- APRICOT = 24'hE69966 , // 杏黄色
- VIOLET = 24'h8B00FF , // 紫罗兰色
- LINEN = 24'hFAF0E6 , // 亚麻色
- KHAKI = 24'h996B1F , // 卡其色
- PEACH = 24'hFFE5B4 , // 桃色
- GOLDEN = 24'hFFD700 , // 金色
- SkyBule = 24'h87CEEB ; // 天空蓝
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- pix_data <= BLACK ;
- else if((axi_y >= V_SYNC + V_BACK) && (axi_y <= V_SYNC + V_BACK + V_DISP - 1)) begin// 在场同步有效区间内
- if((axi_x >= H_SYNC + H_BACK) && (axi_x <= H_SYNC + H_BACK + H_DISP/10 - 1))
- pix_data <= WHITE ;
- else
- if((axi_x >= H_SYNC + H_BACK + H_DISP/10) && (axi_x <= H_SYNC + H_BACK + (H_DISP/10)*2 - 1))
- pix_data <= BLACK ;
- else
- if((axi_x >= H_SYNC + H_BACK + (H_DISP/10)*2) && (axi_x <= H_SYNC + H_BACK + (H_DISP/10)*3 - 1))
- pix_data <= RosyBrown ;
- else
- if((axi_x >= H_SYNC + H_BACK + (H_DISP/10)*3) && (axi_x <= H_SYNC + H_BACK + (H_DISP/10)*4 - 1))
- pix_data <= APRICOT ;
- else
- if((axi_x >= H_SYNC + H_BACK + (H_DISP/10)*4) && (axi_x <= H_SYNC + H_BACK + (H_DISP/10)*5 - 1))
- pix_data <= RED ;
- else
- if((axi_x >= H_SYNC + H_BACK + (H_DISP/10)*5) && (axi_x <= H_SYNC + H_BACK + (H_DISP/10)*6 - 1))
- pix_data <= VIOLET ;
- else
- if((axi_x >= H_SYNC + H_BACK + (H_DISP/10)*6) && (axi_x <= H_SYNC + H_BACK + (H_DISP/10)*7 - 1))
- pix_data <= KHAKI ;
- else
- if((axi_x >= H_SYNC + H_BACK + (H_DISP/10)*7) && (axi_x <= H_SYNC + H_BACK + (H_DISP/10)*8 - 1))
- pix_data <= PEACH ;
- else
- if((axi_x >= H_SYNC + H_BACK + (H_DISP/10)*8) && (axi_x <= H_SYNC + H_BACK + (H_DISP/10)*9 - 1))
- pix_data <= GOLDEN ;
- else
- if((axi_x >= H_SYNC + H_BACK + (H_DISP/10)*9) && (axi_x <= H_SYNC + H_BACK + (H_DISP/10)*10 - 1))
- pix_data <= SkyBule ;
- else
- pix_data <= BLACK ;
- end
- else
- pix_data <= BLACK ;
- end
-
- endmodule
- // 接口模块,产生接口时序。又名驱动模块。
- // 产生像素信息,有效信号。其余信号直接赋值1
- module lcd_driver (
- input wire sys_clk ,
- input wire sys_rst_n ,
- input wire [23:0] pix_data ,
- input wire [15:0] lcd_id ,
-
- output wire [10:0] H_SYNCtoDIS ,
- output wire [10:0] H_BACKtoDIS ,
- output wire [10:0] H_DISPtoDIS ,
- output wire [10:0] V_SYNCtoDIS ,
- output wire [10:0] V_BACKtoDIS ,
- output wire [10:0] V_DISPtoDIS ,
-
- output reg lcd_de ,
- output wire [23:0] lcd_rgb_out ,
- output wire lcd_bl ,
- output wire lcd_rstn ,
- output wire lcd_hsync ,
- output wire lcd_vsync ,
- output wire lcd_clk ,
- output wire [10:0] axi_x ,
- output wire [10:0] axi_y
- );
-
- // localparam
- // 4.3' 480*272
- localparam H_SYNC_4342 = 11'd41 ,
- H_BACK_4342 = 11'd2 ,
- H_DISP_4342 = 11'd480 ,
- H_FRONT_4342 = 11'd2 ,
- H_TOTAL_4342 = 11'd525 ,
-
- V_SYNC_4342 = 11'd10 ,
- V_BACK_4342 = 11'd2 ,
- V_DISP_4342 = 11'd272 ,
- V_FRONT_4342 = 11'd2 ,
- V_TOTAL_4342 = 11'd286 ,
-
- // 7' 800*480
- H_SYNC_7084 = 11'd128 ,
- H_BACK_7084 = 11'd88 ,
- H_DISP_7084 = 11'd800 ,
- H_FRONT_7084 = 11'd40 ,
- H_TOTAL_7084 = 11'd1056 ,
- V_SYNC_7084 = 11'd2 ,
- V_BACK_7084 = 11'd33 ,
- V_DISP_7084 = 11'd480 ,
- V_FRONT_7084 = 11'd10 ,
- V_TOTAL_7084 = 11'd525 ,
-
- // 7' 1024*600
- H_SYNC_7016 = 11'd20 ,
- H_BACK_7016 = 11'd140 ,
- H_DISP_7016 = 11'd1024 ,
- H_FRONT_7016 = 11'd160 ,
- H_TOTAL_7016 = 11'd1344 ,
-
- V_SYNC_7016 = 11'd3 ,
- V_BACK_7016 = 11'd20 ,
- V_DISP_7016 = 11'd600 ,
- V_FRONT_7016 = 11'd12 ,
- V_TOTAL_7016 = 11'd635 ,
-
- // 10.1' 1280*800
- H_SYNC_1018 = 11'd10 ,
- H_BACK_1018 = 11'd80 ,
- H_DISP_1018 = 11'd1280 ,
- H_FRONT_1018 = 11'd70 ,
- H_TOTAL_1018 = 11'd1440 ,
- V_SYNC_1018 = 11'd3 ,
- V_BACK_1018 = 11'd10 ,
- V_DISP_1018 = 11'd800 ,
- V_FRONT_1018 = 11'd10 ,
- V_TOTAL_1018 = 11'd823 ,
-
- // 4.3' 800*480
- H_SYNC_4384 = 11'd128 ,
- H_BACK_4384 = 11'd88 ,
- H_DISP_4384 = 11'd800 ,
- H_FRONT_4384 = 11'd40 ,
- H_TOTAL_4384 = 11'd1056 ,
-
- V_SYNC_4384 = 11'd2 ,
- V_BACK_4384 = 11'd33 ,
- V_DISP_4384 = 11'd480 ,
- V_FRONT_4384 = 11'd10 ,
- V_TOTAL_4384 = 11'd525 ;
- // 不同分辨率时序参数不同
- reg [10:0] H_SYNC ;
- reg [10:0] H_BACK ;
- reg [10:0] H_DISP ;
- reg [10:0] H_FRONT ;
- reg [10:0] H_TOTAL ;
- reg [10:0] V_SYNC ;
- reg [10:0] V_BACK ;
- reg [10:0] V_DISP ;
- reg [10:0] V_FRONT ;
- reg [10:0] V_TOTAL ;
- // reg signal define
- reg [10:0] cnt_row ; // 行计数器,记录一行中的第几列。行计数器归零,说明一行扫描完。
- reg [10:0] cnt_col ; // 列计数器,记录一列中的第几行。列计数器归零,说明一帧图像扫描完。
- // wire signal define
- wire valid_H ; // 行时序有效信号
- wire valid_V ; // 列时序有效信号
- wire valid_HV; // 图像有效信号,由于lcd_display模块中产生像素数据信息是时序逻辑,所以lcd_de信号要对图像有效信号打1拍。
- /******************************************************************************************
- ********************************************main code**************************************
- *******************************************************************************************/
- // 时序参数赋值
- always @(*) begin
- case(lcd_id)
- 16'd4324: begin
- H_SYNC = H_SYNC_4342 ;
- H_BACK = H_BACK_4342 ;
- H_DISP = H_DISP_4342 ;
- H_FRONT = H_FRONT_4342 ;
- H_TOTAL = H_TOTAL_4342 ;
- V_SYNC = V_SYNC_4342 ;
- V_BACK = V_BACK_4342 ;
- V_DISP = V_DISP_4342 ;
- V_FRONT = V_FRONT_4342 ;
- V_TOTAL = V_TOTAL_4342 ;
- end
- 16'd7084: begin
- H_SYNC = H_SYNC_7084 ;
- H_BACK = H_BACK_7084 ;
- H_DISP = H_DISP_7084 ;
- H_FRONT = H_FRONT_7084 ;
- H_TOTAL = H_TOTAL_7084 ;
- V_SYNC = V_SYNC_7084 ;
- V_BACK = V_BACK_7084 ;
- V_DISP = V_DISP_7084 ;
- V_FRONT = V_FRONT_7084 ;
- V_TOTAL = V_TOTAL_7084 ;
- end
- 16'd7016: begin
- H_SYNC = H_SYNC_7016 ;
- H_BACK = H_BACK_7016 ;
- H_DISP = H_DISP_7016 ;
- H_FRONT = H_FRONT_7016 ;
- H_TOTAL = H_TOTAL_7016 ;
- V_SYNC = V_SYNC_7016 ;
- V_BACK = V_BACK_7016 ;
- V_DISP = V_DISP_7016 ;
- V_FRONT = V_FRONT_7016 ;
- V_TOTAL = V_TOTAL_7016 ;
- end
- 16'd4384: begin
- H_SYNC = H_SYNC_4384 ;
- H_BACK = H_BACK_4384 ;
- H_DISP = H_DISP_4384 ;
- H_FRONT = H_FRONT_4384 ;
- H_TOTAL = H_TOTAL_4384 ;
- V_SYNC = V_SYNC_4384 ;
- V_BACK = V_BACK_4384 ;
- V_DISP = V_DISP_4384 ;
- V_FRONT = V_FRONT_4384 ;
- V_TOTAL = V_TOTAL_4384 ;
- end
- 16'd1018: begin
- H_SYNC = H_SYNC_1018 ;
- H_BACK = H_BACK_1018 ;
- H_DISP = H_DISP_1018 ;
- H_FRONT = H_FRONT_1018 ;
- H_TOTAL = H_TOTAL_1018 ;
- V_SYNC = V_SYNC_1018 ;
- V_BACK = V_BACK_1018 ;
- V_DISP = V_DISP_1018 ;
- V_FRONT = V_FRONT_1018 ;
- V_TOTAL = V_TOTAL_1018 ;
- end
- default : begin
- H_SYNC = H_SYNC_1018 ;
- H_BACK = H_BACK_1018 ;
- H_DISP = H_DISP_1018 ;
- H_FRONT = H_FRONT_1018 ;
- H_TOTAL = H_TOTAL_1018 ;
- V_SYNC = V_SYNC_1018 ;
- V_BACK = V_BACK_1018 ;
- V_DISP = V_DISP_1018 ;
- V_FRONT = V_FRONT_1018 ;
- V_TOTAL = V_TOTAL_1018 ;
- end
- endcase
- end
- // // reg signal define
- // reg [10:0] cnt_row ; // 行计数器,记录一行中的第几列。行计数器归零,说明一行扫描完。
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- cnt_row <= 11'd0 ;
- else if(cnt_row == (H_TOTAL - 1))
- cnt_row <= 11'd0 ;
- else
- cnt_row <= cnt_row + 1'b1 ;
- end
- // reg [10:0] cnt_col ; // 列计数器,记录一列中的第几行。列计数器归零,说明一帧图像扫描完。
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- cnt_col <= 11'd0 ;
- else if((cnt_col == (V_TOTAL - 1)) && (cnt_row == (H_TOTAL - 1)))
- cnt_col <= 11'd0 ;
- else if(cnt_row == (H_TOTAL - 1))
- cnt_col <= cnt_col + 1'b1 ;
- else
- cnt_col <= cnt_col ;
- end
- // // wire signal define
- // wire valid_H ; // 行时序有效信号
- assign valid_H = ((cnt_row >= H_SYNC + H_BACK) && (cnt_row <= H_SYNC + H_BACK + H_DISP - 1)) ? 1'b1 : 1'b0 ;
- // wire valid_V ; // 列时序有效信号
- assign valid_V = ((cnt_col >= V_SYNC + V_BACK) && (cnt_col <= V_SYNC + V_BACK + V_DISP - 1)) ? 1'b1 : 1'b0 ;
- // wire valid_HV; // 图像有效信号,由于lcd_display模块中产生像素数据信息是时序逻辑,所以lcd_de信号要对图像有效信号打1拍。
- assign valid_HV = (valid_H && valid_V) ;
- // output wire [10:0] axi_x ,
- assign axi_x = (valid_HV) ? cnt_row : 11'd0 ;
- // output wire [10:0] axi_y ,
- assign axi_y = (valid_HV) ? cnt_col : 11'd0 ;
- // output wire [23:0] lcd_rgb_out ,
- assign lcd_rgb_out = pix_data ;
- // output reg lcd_de ,
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- lcd_de <= 1'b0 ;
- else
- lcd_de <= valid_HV ;
- end
- // 本实验没用到的信号,赋值1;
- assign lcd_bl = 1'b1 ;
- assign lcd_rstn = 1'b1 ;
- assign lcd_hsync = 1'b1 ;
- assign lcd_vsync = 1'b1 ;
- assign lcd_clk = (sys_rst_n == 1'b1) ? sys_clk : 1'b0 ;
- // 传给像素数据生成模块的时序参数
- assign H_SYNCtoDIS = H_SYNC ;
- assign H_BACKtoDIS = H_BACK ;
- assign H_DISPtoDIS = H_DISP ;
- assign V_SYNCtoDIS = V_SYNC ;
- assign V_BACKtoDIS = V_BACK ;
- assign V_DISPtoDIS = V_DISP ;
- endmodule
- module top (
- input wire sys_clk ,
- input wire sys_rst_n ,
-
- inout wire [23:0] lcd_rgb ,
-
- output wire lcd_de ,
- output wire lcd_bl ,
- output wire lcd_rstn ,
- output wire lcd_hsync ,
- output wire lcd_vsync ,
- output wire lcd_clk
- );
- // inout
- wire [23:0] lcd_rgb_out ;
- wire [23:0] lcd_rgb_in ;
- assign lcd_rgb = (lcd_de) ? lcd_rgb_out : 24'dz ;
- assign lcd_rgb_in = lcd_rgb ;
- // 例化间连线
- wire [15:0] lcd_id ;
- wire clk_lcd ;
- wire rst_n ;
- wire [10:0] H_SYNCtoDIS ;
- wire [10:0] H_BACKtoDIS ;
- wire [10:0] H_DISPtoDIS ;
- wire [10:0] V_SYNCtoDIS ;
- wire [10:0] V_BACKtoDIS ;
- wire [10:0] V_DISPtoDIS ;
- wire [10:0] axi_x ;
- wire [10:0] axi_y ;
- wire [23:0] pix_data ;
-
- rd_id rd_id_inst(
- .sys_clk ( sys_clk ) ,
- .sys_rst_n ( sys_rst_n ) ,
- .lcd_rgb ( lcd_rgb_in ) ,
- .lcd_id ( lcd_id )
- );
- clk_div clk_div_inst(
- .sys_clk ( sys_clk ) ,
- .sys_rst_n ( sys_rst_n ) ,
- .lcd_id ( lcd_id ) ,
- .clk_lcd ( clk_lcd ) ,
- .rst_n ( rst_n )
- );
- lcd_driver lcd_driver_inst(
- .sys_clk ( clk_lcd ) ,
- .sys_rst_n ( rst_n ) ,
- .pix_data ( pix_data ) ,
- .lcd_id ( lcd_id ) ,
- .H_SYNCtoDIS ( H_SYNCtoDIS ) ,
- .H_BACKtoDIS ( H_BACKtoDIS ) ,
- .H_DISPtoDIS ( H_DISPtoDIS ) ,
- .V_SYNCtoDIS ( V_SYNCtoDIS ) ,
- .V_BACKtoDIS ( V_BACKtoDIS ) ,
- .V_DISPtoDIS ( V_DISPtoDIS ) ,
- .lcd_de ( lcd_de ) ,
- .lcd_rgb_out ( lcd_rgb_out ) ,
- .lcd_bl ( lcd_bl ) ,
- .lcd_rstn ( lcd_rstn ) ,
- .lcd_hsync ( lcd_hsync ) ,
- .lcd_vsync ( lcd_vsync ) ,
- .lcd_clk ( lcd_clk ) ,
- .axi_x ( axi_x ) ,
- .axi_y ( axi_y )
- );
- lcd_display lcd_display_inst(
- .sys_clk ( clk_lcd ) ,
- .sys_rst_n ( rst_n ) ,
- .axi_x ( axi_x ) ,
- .axi_y ( axi_y ) ,
- .H_SYNC ( H_SYNCtoDIS ) ,
- .H_BACK ( H_BACKtoDIS ) ,
- .H_DISP ( H_DISPtoDIS ) ,
- .V_SYNC ( V_SYNCtoDIS ) ,
- .V_BACK ( V_BACKtoDIS ) ,
- .V_DISP ( V_DISPtoDIS ) ,
- .pix_data ( pix_data )
- );
- endmodule
- `timescale 1ns/1ns
- module test_top();
- reg sys_clk ;
- reg sys_rst_n ;
-
- wire [23:0] lcd_rgb ;
-
- wire lcd_de ;
- wire lcd_bl ;
- wire lcd_rstn ;
- wire lcd_hsync ;
- wire lcd_vsync ;
- wire lcd_clk ;
-
- assign lcd_rgb = lcd_de ? {24{1'bz}} : 24'h80;
-
- top top_inst(
- .sys_clk ( sys_clk ) ,
- .sys_rst_n ( sys_rst_n ) ,
-
- .lcd_rgb ( lcd_rgb ) ,
-
- .lcd_de ( lcd_de ) ,
- .lcd_bl ( lcd_bl ) ,
- .lcd_rstn ( lcd_rstn ) ,
- .lcd_hsync ( lcd_hsync ) ,
- .lcd_vsync ( lcd_vsync ) ,
- .lcd_clk ( lcd_clk )
- );
-
- parameter CYCLE = 20 ;
-
- initial begin
- sys_clk = 1'b1 ;
- sys_rst_n <= 1'b0 ;
- #( CYCLE * 10 ) ;
- #2 ;
- sys_rst_n <= 1'b1 ;
- #( CYCLE * 1000 ) ;
- $stop ;
- end
- always #( CYCLE / 2 ) sys_clk = ~sys_clk ;
- endmodule
