Display pictures based on fpga (VGA)

Displayed at a resolution of 640*480@60Hz (meaning that a maximum size of 640*480 can be displayed), first, the image displayed through FPGA's VGA includes four parts: frequency division module, vga driver module, display module, and top-level module.

1. Frequency division module, using xilinx spartan_6 board, output crystal oscillator 50M; 640*480@60Hz clock is 25MHz (800*525*60). Simply count and flip the frequency division, the effect is as follows:

2.VGA driver module

Display order: from top to bottom, left to right.

Timing diagram: Row timing is divided into 5 processes (a. Row address reset b. Row address reset completed, ready to enter data c. Data display d. Ready to reset row address)


The field timing is divided into four processes: (a. Field address reset b. Field address reset complete and ready to enter data c. Data display d. Ready to reset field address)

! ! ! ! For the driving part inspection, first look at the timing diagram: the inversion of one field signal contains multiple line signals (multiple lines are scanned in one field)


`timescale 1ns / 1ps
`define H_FRONT 11'd16
`define H_SYNC  11'd96
`define H_BACK  11'd48
`define H_DIP   11'd640
`define H_TOTAL 11'd800


`define V_FRONT 11'd10
`define V_SYNC  11'd2
`define V_BACK 11'd33
`define V_DIP   11'd480
`define V_TOTAL 11'd525
//////////////////////////////////////////////////////////////////////////////////
//640*480@60hz
//
//////////////////////////////////////////////////////////////////////////////////
module driver(
clk,
reset,
lcd_hs,
lcd_vs,
lcd_en,
lcd_xpos,
lcd_ypos
);
input clk,reset;//VGA_clk
output lcd_hs,lcd_vs,lcd_en;
output[10:0] lcd_xpos,lcd_ypos;
wire lcd_request;
reg[11:0] h_cnt;//Line scan unit count
reg[11:0] v_cnt;//Column scan unit count




// ////////////////////////////
//Line scan unit count
always@(posedge clk or negedge reset)
begin
if(!reset )begin h_cnt<=11'd0; end
else 
  begin
if(h_cnt<`H_TOTAL-1'b1) begin h_cnt<=h_cnt+1'b1;end
else h_cnt<=11'd0;
end
end
assign lcd_hs=(h_cnt< =`H_SYNC-1'b1)?1'b0:1'b1; //Line sync signal
/////////////////////////// ////
//Column scan unit count
always@(posedge clk or negedge reset)
begin
if(!reset)begin v_cnt<=11'd0; end
else if(h_cnt==`H_TOTAL-1'b1)//Sweep finished
  begin
if(v_cnt<`V_TOTAL-1'b1)begin v_cnt<=v_cnt+1'b1;end
else v_cnt<=11'd0;
end
end
assign lcd_vs=(v_cnt<=`V_SYNC-1'b1)?1'b0:1'b1; //场同步信号                                              
////////////////////////////////
//数据使能信号
assign lcd_en=(h_cnt >= `H_SYNC + `H_BACK  && h_cnt < `H_SYNC + `H_BACK + `H_DIP) &&
              (v_cnt >= `V_SYNC + `V_BACK  && v_cnt < `V_SYNC + `V_BACK + `V_DIP) 
              ? 1'b1 : 1'b0;
////////////////////////////////
//外部数据请求
assign  lcd_request = (h_cnt >= `H_SYNC + `H_BACK - 1'b1 && h_cnt < `H_SYNC + `H_BACK + `H_DIP - 1'b1) &&
                      (v_cnt >= `V_SYNC + `V_BACK && v_cnt < `V_SYNC + `V_BACK + `V_DIP) 
                       ? 1'b1 : 1'b0;
//lcd xpos & ypos
assign  lcd_xpos    =   lcd_request ? (h_cnt - (`H_SYNC + `H_BACK - 1'b1)) : 11'd0;////////????
assign  lcd_ypos    =   lcd_request ? (v_cnt - (`V_SYNC + `V_BACK)) : 11'd0;///////????/???????


endmodule

3. Display part (the board VGA565)

1> For the display of static pictures, convert a picture into 8bit data through img2lcd software, store it in ip rom/ram, and call the data by inputting the address.

2> For the reception of dynamic data, it can be input through the serial port, stored in a ram/rom and then called. (The clk for writing data is driven by the rising edge of the serial port input data completion flag, and the clk for reading data directly uses the VGA scan clock)


`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
module displayimg(
input clk,
input clkin,//ram写入时钟
input start_flag,
input reset,
input lcd_en,
input[10:0] lcd_xpos,
input[10:0] lcd_ypos,
output reg[15:0] lcd_data,
input[7:0]     data_out
 );
reg[4:0] rgb_r;
reg[5:0] rgb_g;
reg[4:0] rgb_b;
reg[15:0] counter_in;
reg[15:0]


















    











always@(posedge clk or negedge reset)
begin
if(!reset) begin
rgb_r <= 'd0;
rgb_g <= 'd0;
rgb_b <= 'd0;
end
else begin
rgb_r[4:0] <= data_get[7:3];
rgb_g[5:0] <= data_get[7:2];
rgb_b[4:0] <= data_get[7:3];
end
end


always@(posedge clk or negedge reset)
begin
if(!reset)
counter_out <= 'd0;
else if(lcd_ypos > 'd160)
counter_out <= 'd0;
else if(displyarea == 1'b1)
counter_out <= counter_out + 1'b1;
end

always@(posedge clk or negedge reset)
begin
if(!reset)
lcd_data <= 'd0;
else if(displyarea == 1'b1)
lcd_data <= {rgb_r,rgb_g,rgb_b};
else lcd_data<='d0;
end


endmodule

4.top




Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324663988&siteId=291194637