本帖最后由 超级开发板 于 2017-10-8 09:39 编辑
今天,我们来进行锆石A4 FPGA开发板的VGA输出应用
FPGA能通过硬件描述语言的编程编程您想要的芯片,当然,也能把它变成带有简单显卡功能的芯片,通过编程,至少能进行显示信号的输出,当然,如果您有更高能力的编程,还能将它变成更功能强大的芯片。
有人说德语是个工具,其实Verilog也能算是工具,就像一把锤子,其本身并不包含您的设计思想,您需要在大脑或草稿中构思好您的 电路框架,再用硬件描述语言把这一设计理念实现化,让FPGA读懂您想要的需求,让它变成您需要的样子。
如此一来,我们需要先了解VGA信号的构成,以及VGA显示成像的原理。
经过查阅资料,我们可以了解到:VGA信号]驱动显示器一般用的是扫描的方式,而且一般是逐行扫描。
逐行扫描这个词可能过于术语,顾名思义是一行一行扫下来的,而具体上,它其实是从屏幕左上的第一个像素点向右改变像素的色彩,每行结束会同步一下。
硬件引脚方面:
随便找根不用了的VGA线剥开,发现里面一堆线,其中五根比较重要:
三根粗的RGB:
红色信号 r
绿色信号 g
蓝色信号 b
俩像素信号起始同步:
行同步信号 hs
场同步信号 vs
然后还有根地线也比较重要,屏蔽线初期弄的话可以随便搞搞,等弄的差不多了要追求显示质量了,再去研究它们,这儿先满足最基本的显示需求。
.
然后是代码方面:
实现最基本功能的参考范例:
- module Main(
- CLK,
- VGA_HS,
- VGA_VS,
- VGA_R,
- VGA_G,
- VGA_B
- );
- input CLK;
- output VGA_HS,VGA_VS, VGA_R, VGA_G, VGA_B;
- reg[10:0] x_counter;
- reg[10:0] y_counter;
- reg [3:1] GRBX;
- initial begin
- x_counter = 0;
- y_counter = 0;
- end
- // Always block to drive drawing, {front|back}-doors, and syncs.
- always @(posedge CLK) begin
- if(x_counter == 1055)
- begin
- x_counter = 0;
- if(y_counter == 627)
- y_counter = 0;
- else
- y_counter = y_counter + 1;
- end
- else
- x_counter = x_counter + 1;
- end
- always @(x_counter or y_counter)
- begin
- if (x_counter<100) GRBX<=3'b111;
- else if (x_counter<200) GRBX<=3'b110;
- else if (x_counter<300) GRBX<=3'b101;
- else if (x_counter<400) GRBX<=3'b100;
- else if (x_counter<500) GRBX<=3'b011;
- else if (x_counter<600) GRBX<=3'b010;
- else if (x_counter<700) GRBX<=3'b001;
- else GRBX<=3'b000 ;
- end
- assign VGA_R=GRBX[2];
- assign VGA_G=GRBX[3];
- assign VGA_B=GRBX[1];
- assign VGA_HS = x_counter > 839 && x_counter < 968;
- assign VGA_VS = y_counter > 600 && y_counter < 605;
- endmodule
复制代码
带注释的参考代码:
- //640*480@60HZ,时钟像素:25MHZ
- module a1( nclk,rst_n, hsync,vsync, vga_r,r0,r1,r2,vga_g,g0,g1,g2,vga_b,b0,b1,b2);
- input nclk;
- //内部100M时钟输入
- input rst_n;
- //复位键
- output reg hsync,vsync;
- //场同步,行同步信号
- output vga_r,vga_g,vga_b,r0,r1,r2,g0,g1,g2,b0,b1,b2;
- //颜色信号输出
- reg[10:0] x_cnt;
- //行坐标计数,为后面行的0或者1及具体像素点的位置做准备
- reg[9:0] y_cnt;
- //列坐标计数,为后面列的0或者1及具体像素点的位置做准备
- reg clk;
- //实现4分频后的像素点频率 //100M到25M分频器设计
- reg[2:0]clk_cnt;initial
- //寄存器变量赋初值
- begin clk=1'b0;
- clk_cnt=3'd0;
- end
- //红绿蓝的其他三个端口
- assign r0=1'b0;
- assign r1=1'b0;
- assign r2=1'b0;
- assign g0=1'b0;
- assign g1=1'b0;
- assign g2=1'b0;
- assign b0=1'b0;
- assign b1=1'b0;
- assign b2=1'b0;
- always @(negedge nclk) begin clk_cnt = clk_cnt + 1;
- if(clk_cnt==3'd2) clk =1'b1; else if(clk_cnt==3'd4) begin clk = 1'b0;
- clk_cnt=3'd0;
- end
- end
- //VGA显示的设计
- //像素点的计数
- always@(posedge clk or negedge rst_n) begin if(!rst_n) x_cnt=11'd0;
- else if(x_cnt==11'd800) x_cnt=11'd0; else x_cnt = x_cnt + 1'b1;
- end
- //行的计数
- always@(posedge clk or negedge rst_n) if(!rst_n) y_cnt = 10'd0; else if(y_cnt==10'd525) y_cnt=11'd0;
- else if(x_cnt==11'd800)y_cnt = y_cnt + 1'b1;
- //定义屏幕显示区域
- wire valid = (x_cnt>=11'd144)&&(x_cnt<=11'd784)&&(y_cnt>=10'd35)&&(y_cnt<=10'd515);
- wire [9:0] xpos = x_cnt-11'd144; wire [9:0] ypos = y_cnt-10'd35;
- //行时序的确定
- always@(posedge clk or negedge rst_n) if(!rst_n) hsync =1'b0;
- //复位从0开始
- else if(x_cnt==11'd0) hsync=1'b0; else if(x_cnt==11'd96) hsync=1'b1;
- //帧时序的确定
- always@(posedge clk or negedge rst_n) if(!rst_n) vsync =1'b0;
- //复位从0开始
- else if(y_cnt==10'd0) vsync=1'b0; else if(y_cnt==10'd2) vsync=1'b1;
- //划分不同显示界面
- wire a_dis=((xpos>=200)&&(xpos<=220))&&((ypos>=140)&&(ypos<=460));
- wire b_dis=((xpos>=580)&&(xpos<=600))&&((ypos>=140)&&(ypos<=460));
- wire c_dis=((xpos>=220)&&(xpos<=580))&&((ypos>=140)&&(ypos<=160));
- wire d_dis=((xpos>=220)&&(xpos<=580))&&((ypos>=440)&&(ypos<=460));
- wire e_rdy=((xpos>=385)&&(xpos<=415))&&((ypos>=285)&&(ypos<=315));
- //RGB像素点的赋值
- assign vga_r= valid?e_rdy:1'b0;
- assign vga_g= valid? (a_dis|b_dis|c_dis|d_dis):1'b0;
- assign vga_b= valid? ~(a_dis|b_dis|c_dis|d_dis):1'b0;
- endmodule
复制代码
然后,我们将代码编译,并烧写到锆石A4 FPGA开发板上,
找一根合适的VGA线材接入到锆石A4 FPGA开发板的VGA接口中,
重新上电锆石A4 FPGA开发板,以开始运行VGA刷写显示代码,
我们可以看到上电后先是完全的黑屏,然后从左上角顶部开始向下刷写白色,
由于锆石A4 FPGA开发板的运算速度极快,
即使反应很快的人类也只能看到白色从上到下被载入,
试着放慢过速率,还是快到转瞬刷白,
每行的从左到右如果想观察的话,可以借助高速相机,
或者按照开发者什么都自己做的行事风格,
再买块锆石A4 FPGA开发板,写个高速相机的软件,
用FPGA的速度捕捉FPGA的速度,
大概上电后零点几秒就全白了,效果如下
然后按右侧实体按键的第二个键,全红
然后第三个键,左上角有小字,字库已经用了双点像素,普通屏幕轻松看到,如果是视网膜屏贴近了即可看清
然后是第四个键,从白刷黑的感觉很舒服,感觉整个屏幕的像素都被抚平
|