You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.8 KiB
Verilog

module vga_ctrl(
input wire clk_25 ,
input wire vga_rst_n ,
input wire [15: 0] rgb_data ,
output wire hsync ,
output wire vsync ,
output wire [9: 0] pixel_x ,
output wire [9: 0] pixel_y ,
output wire [15: 0] vga_data
);
//行
parameter H_SYNC = 10'd96 ,
H_BACK = 10'd40 ,
H_LEFT = 10'd8 ,
H_AREA = 10'd640 ,
H_RIGHT = 10'd8 ,
H_FRONT = 10'd8 ,
H_TOTAL = 10'd800 ;
//列
parameter V_SYNC = 10'd2 ,
V_BACK = 10'd25 ,
V_TOP = 10'd8 ,
V_AREA = 10'd480,
V_BUTTON = 10'd8 ,
V_FRONT = 10'd2 ,
V_TOTAL = 10'd525;
//像素计数
reg [9: 0] cnt_pixel;
wire add_cnt_pixel;
wire end_cnt_pixel;
//行计数
reg [9: 0] cnt_row;
wire add_cnt_row;
wire end_cnt_row;
wire area_vld;
wire vld_req ;
always @(posedge clk_25 or negedge vga_rst_n) begin
if(!vga_rst_n)begin
cnt_pixel <= 10'd0;
end
else if(add_cnt_pixel)begin
if(end_cnt_pixel)begin
cnt_pixel <= 10'd0;
end
else begin
cnt_pixel <= cnt_pixel + 1'd1;
end
end
else begin
cnt_pixel <= cnt_pixel;
end
end
assign add_cnt_pixel = 1'b1;
assign end_cnt_pixel = add_cnt_pixel && cnt_pixel == (H_TOTAL - 1'd1);
always @(posedge clk_25 or negedge vga_rst_n)begin
if(!vga_rst_n)begin
cnt_row <= 10'd0;
end
else if(add_cnt_row)begin
if(end_cnt_row)begin
cnt_row <= 10'd0;
end
else begin
cnt_row <= cnt_row + 1'd1;
end
end
else begin
cnt_row <= cnt_row;
end
end
assign add_cnt_row = end_cnt_pixel;
assign end_cnt_row = add_cnt_row && cnt_row == V_TOTAL - 1'd1;
assign hsync = (cnt_pixel <= H_SYNC - 1'd1) ? 1'b1: 1'b0;
assign vsync = (cnt_row <= V_SYNC - 1'd1) ? 1'b1: 1'b0;
assign area_vld = (cnt_pixel >= (H_SYNC + H_BACK + H_LEFT)) &&
(cnt_pixel < (H_SYNC + H_BACK + H_LEFT + H_AREA)) &&
(cnt_row >= (V_SYNC + V_BACK + V_TOP)) &&
(cnt_row < (V_SYNC + V_BACK + V_TOP + V_AREA));
assign vld_req = (cnt_pixel >= (H_SYNC + H_BACK + H_LEFT - 1'd1)) &&
(cnt_pixel < (H_SYNC + H_BACK + H_LEFT + H_AREA - 1'd1)) &&
(cnt_row >= (V_SYNC + V_BACK + V_TOP)) &&
(cnt_row < (V_SYNC + V_BACK + V_TOP + V_AREA));
//超前一个时钟周期,目的是为了时序对齐
assign pixel_x = (vld_req == 1'b1) ? (cnt_pixel - (H_SYNC + H_BACK + H_LEFT - 1'b1)): 10'h3ff;
assign pixel_y = (vld_req == 1'b1) ? (cnt_row - (V_SYNC + V_BACK + V_TOP)): 10'h3ff;
assign vga_data = (area_vld == 1'b1) ? rgb_data: 16'h0000;
endmodule