某三本的数字逻辑课程已经进入了期末大作业阶段,所以这里为大家讲解一下如何在FPGA板上实现VGA的操控。
按照历史的发展, 屏幕显示分为了两种模式。较为简单的是文本模式,也就是平时命令行界面的样子,这种模式只能在屏幕上显示阵列字符,也就是横竖都是对齐的固定大小的字符。另一种,也是微软发家之路,就是图形模式。这种模式的显示单元为像素,每个像素都可以是不同的颜色。对于非程序猿来说,肯定是图形模式更加友好一些。不过,显而易见地,图形模式的实现要更复杂一些。
按照惯例,先上代码。
VGA(char mode).v
module VGA (
input clk, //Clock cycle must be 25mhz.
input rst, //VGA reset at positive edge of rst.
input [31:0] d_in, //Values rrrr_gggg_bbbb_ascii, the color and ascii of the current character.
output reg [3:0] r, //The VGA red channel.
output reg [3:0] g, //The VGA green channel.
output reg [3:0] b, //The VGA blue channel.
output reg hs, //The VGA HSYNC bit.
output reg vs, //The VGA VSYNC bit.
output [12:0] addr //Current pixel position (x = addr[12:6], y = addr[5:0])
);
wire [9:0] row, col;
wire [7:0] font_ascii;
wire [3:0] font_line;
wire [7:0] font_out;
reg rdn;
reg [9:0] h_count; // VGA horizontal counter (0-799): pixels
reg [9:0] v_count; // VGA vertical counter (0-524): lines
FONT FT(.ascii(font_ascii), .line(font_line), .out(font_out));
always @ (posedge clk) begin
if (rst) begin
h_count <= 10'h0;
end else if (h_count == 10'd799) begin
h_count <= 10'h0;
end else begin
h_count <= h_count + 10'h1;
end
end
always @ (posedge clk or posedge rst) begin
if (rst) begin
v_count <= 10'h0;
end else if (h_count == 10'd799) begin
if (v_count == 10'd524) begin
v_count <= 10'h0;
end else begin
v_count <= v_count + 10'h1;
end
end
end
assign row = v_count - 10'd35; //pixel ram row addr
assign col = h_count - 10'd143; //pixel ram col addr
wire h_sync = (h_count > 10'd95); //96 -> 799
wire v_sync = (v_count > 10'd1); //2 -> 524
wire read = (h_count > 10'd142) &&
(h_count < 10'd783) &&
(v_count > 10'd34) &&
(v_count < 10'd515);
assign addr = rdn ? 13'h0 : {col[9:3], row[8:3]};
assign font_ascii = rdn ? 8'b0 : d_in[7:0];
assign font_line = {5'b0, row[2:0]};
reg show_bit;
always @ (posedge clk) begin
rdn <= ~read;
h