- //640x480
- //像素頻率為25M Hz. Xilinx的zedboard板子時鐘為100M Hz
- //逐行掃描
- //H_Back_Porch=40
- //H_Top_Border=8
- //H_Bottom_Border=8
- //H_Front_Porch=8
- //V_Back_Porch=25
- //V_Top_Border=8
- //V_Bottom_Border=8
- //V_Front_Porch=2
- //H_sync=96
- //V_sync=2
- module VGA(rst,clk,Hsync,Vsync,R,G,B);
- input rst,clk;
- output Hsync;
- output Vsync;
- output reg [3:0] R; //輸出Red
- output reg [3:0] G; //輸出Green
- output reg [3:0] B; //輸出Blue
- reg [9:0] H_cnt; //列計數器
- reg [9:0] V_cnt; //行計數器
- wire clk_25M; //頻率為25M Hz
- wire R0_active;
- wire G0_active;
- wire B0_active;
- wire R1_active;
- wire G1_active;
- wire B1_active;
- reg [2:0] div_cnt; //分頻計數器
- //===========================================================
- // 4分頻.頻率為25M Hz
- //===========================================================
- always@(posedge clk or negedge rst)
- begin
- if(!rst) div_cnt <= 3'd0;
- else if(div_cnt == 3'd3) div_cnt <= 3'd0;
- else div_cnt <= div_cnt + 3'd1;
- end
- assign clk_25M = (div_cnt <= 3'd1) ? 1 : 0;
- //===========================================================
- //行計數器
- //===========================================================
- always@(posedge clk_25M or negedge rst)
- begin
- if(!rst) V_cnt <= 10'd0;
- else if(H_cnt == 10'd799)
- begin
- if(V_cnt == 10'd524 && H_cnt == 10'd799) V_cnt <= 10'd0;
- else V_cnt <= V_cnt + 10'd1;
- end
- else V_cnt <= V_cnt;
- end
- //===========================================================
- //列計數器
- //===========================================================
- always@(posedge clk_25M or negedge rst)
- begin
- if(!rst) H_cnt <= 10'd0;
- else if(H_cnt == 10'd799) H_cnt <= 10'd0;
- else H_cnt <= H_cnt + 10'd1;
- end
- //===========================================================
- //Hsync 和 Vsync
- //===========================================================
- assign Hsync= (H_cnt < 10'd96) ? 1 : 0;
- assign Vsync= (V_cnt < 10'd2) ? 1 : 0;
- //===========================================================
- //有效顯示區內active為1
- //===========================================================
- //有效顯示區內active==1.顯示Red
- assign R0_active = (H_cnt>10'd143 && H_cnt<10'd249 && V_cnt>10'd34 && V_cnt<10'd514) ? 1 : 0;
- //有效顯示區內active==1.顯示Green
- assign G0_active = (H_cnt>10'd250 && H_cnt<10'd356 && V_cnt>10'd34 && V_cnt<10'd514) ? 1 : 0;
- //有效顯示區內active==1.顯示Blue
- assign B0_active = (H_cnt>10'd357 && H_cnt<10'd463 && V_cnt>10'd34 && V_cnt<10'd514) ? 1 : 0;
- //有效顯示區內active==1.顯示Red
- assign R1_active = (H_cnt>10'd464 && H_cnt<10'd570 && V_cnt>10'd34 && V_cnt<10'd514) ? 1 : 0;
- //有效顯示區內active==1.顯示Green
- assign G1_active = (H_cnt>10'd571 && H_cnt<10'd677 && V_cnt>10'd34 && V_cnt<10'd514) ? 1 : 0;
- //有效顯示區內active==1.顯示Blue
- assign B1_active = (H_cnt>10'd678 && H_cnt<10'd783 && V_cnt>10'd34 && V_cnt<10'd514) ? 1 : 0;
- //===========================================================
- //RGB輸出
- //===========================================================
- always@(posedge clk_25M)
- begin
- if(R0_active == 1'b1) //顯示Red
- begin
- R <= 4'b1111;
- G <= 4'b0;
- B <= 4'b0;
- end
- else if(G0_active == 1'b1) //顯示Green
- begin
- R <= 4'b0;
- G <= 4'b1111;
- B <= 4'b0;
- end
- else if(B0_active == 1'b1) //顯示Blue
- begin
- R <= 4'b0;
- G <= 4'b0;
- B <= 4'b1111;
- end
- else if(R1_active == 1'b1) //顯示Red
- begin
- R <= 4'b1111;
- G <= 4'b0;
- B <= 4'b0;
- end
- else if(G1_active == 1'b1) //顯示Green
- begin
- R <= 4'b0;
- G <= 4'b1111;
- B <= 4'b0;
- end
- else if(B1_active == 1'b1) //顯示Blue
- begin
- R <= 4'b0;
- G <= 4'b0;
- B <= 4'b1111;
- end
- else
- begin
- R <= 4'b0;
- G <= 4'b0;
- B <= 4'b0;
- end
- end
- //===========================================================
- endmodule
螢幕輸出依序為Red.Green.Blue.Red.Green.Blue,故實驗完成