基于FPGA的VGA协议实现
–
一、屏幕上显示彩色条纹
1.创建工程
通过python脚本创建好工程文件夹,然后进行代码编写
2.代码编写
我这里使用了vscode来进行代码编写
在这里插入图片描述
上图verilog文件定义了会使用的一些变量
在vga_ctrl中则是控制vga显示的逻辑
代码:
`define vga_800_600
`include "vga_param.v"
module vga_ctrl (
input clk ,
input rst_n ,
input [23:0] data_dis ,
output reg [10:0] h_addr , //数据有效显示区域行地址
output reg [10:0] v_addr , //数据有效显示区域场地址
output reg hsync ,
output reg vsync ,
output reg [7:0] vga_r ,
output reg [7:0] vga_g ,
output reg [7:0] vga_b ,
output reg vga_blk , //VGA消隐信号
output reg vga_clk
);
//参数定义
parameter H_SYNC_STA = 1 ,
H_SYNC_STO = `H_Sync_Time ,
H_DATA_STA = `H_Sync_Time + `H_Back_Porch + `H_Left_Border ,
H_DATA_STO = `H_Sync_Time + `H_Back_Porch + `H_Left_Border + `H_Data_Time ,
V_SYNC_STA = 1 ,
V_SYNC_STO = `V_Sync_Time ,
V_DATA_STA = `V_Sync_Time + `V_Back_Porch + `V_Top_Border ,
V_DATA_STO = `V_Sync_Time + `V_Back_Porch + `V_Top_Border + `V_Data_Time;
//信号定义
reg [11:0] cnt_h_addr ; //行地址计数器
wire add_cnt_h_addr ;
wire end_cnt_h_addr ;
reg [11:0] cnt_v_addr ; //场地址计数器
wire add_cnt_v_addr ;
wire end_cnt_v_addr ;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
cnt_h_addr <= 1'd0;
end
else if(add_cnt_h_addr)begin
if(end_cnt_h_addr)begin
cnt_h_addr <= 1'd0;
end
else begin
cnt_h_addr <= cnt_h_addr + 1'd1 ;
end
end
end
assign add_cnt_h_addr = 1'd1 ;
assign end_cnt_h_addr = add_cnt_h_addr && cnt_h_addr == `H_Total_Time - 1 ;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
cnt_v_addr <= 1'd0;
end
else if(add_cnt_v_addr)begin
if(end_cnt_v_addr)begin
cnt_v_addr <= 1'd0;
end
else begin
cnt_v_addr <= cnt_v_addr + 1'd1;
end
end
end
assign add_cnt_v_addr = end_cnt_h_addr;
assign end_cnt_v_addr = add_cnt_v_addr && cnt_v_addr == `V_Total_Time - 1 ;
//行场同步信号
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
hsync <= 1'b1;
end
else if(cnt_h_addr == H_SYNC_STA - 1)begin
hsync <= 1'b0;
end
else if(cnt_h_addr == H_SYNC_STO - 1)begin
hsync <= 1'b1;
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
vsync <= 1'b1;
end
else if(cnt_v_addr == V_SYNC_STA - 1)begin
vsync <= 1'b0;
end
else if(cnt_v_addr == V_SYNC_STO - 1)begin
vsync <= 1'b1;
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
vga_clk <= 1'b1;
end
else begin
vga_clk <= ~vga_clk;
end
end
//assign vga_clk = ~clk ;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
h_addr <= 11'b0;
end
else if((cnt_h_addr >= H_DATA_STA - 1) &&(cnt_h_addr <= H_DATA_STO - 1))begin
h_addr <= cnt_h_addr - H_DATA_STA;
end
else begin
h_addr <= 11'd0;
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
v_addr <= 11'b0;
end
else if((cnt_v_addr >= V_DATA_STA - 1) && (cnt_v_addr <= V_DATA_STO - 1))begin
v_addr <= cnt_v_addr - V_DATA_STA;
end
else begin
v_addr <= 11'd0;
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
vga_r <= 8'd0;
vga_g <= 8'd0;
vga_b <= 8'd0;
vga_blk <= 1'b0;
end
else if((cnt_h_addr >= H_DATA_STA - 1) && (cnt_h_addr <= H_DATA_STO - 1)
&& (cnt_v_addr >= V_DATA_STA - 1) && (cnt_v_addr <= V_DATA_STO - 1)) begin
vga_r <= data_dis[23:16];
vga_g <= data_dis[15:8] ;
vga_b <= data_dis[7:0] ;
vga_blk <= 1'b1 ;
end
else begin
vga_r <= 8'd0;
vga_g <= 8'd0;
vga_b <= 8'd0;
vga_blk <= 1'b0;
end
end
endmodule
data_gen则是vga显示的数据生成文件
代码:
module data_gen (
input clk ,
input rst_n ,
input [10:0] h_addr , //数据有效显示区域行地址
input [10:0] v_addr , //数据有效显示区域场地址
output reg [23:0] data_dis
);
//参数定义
parameter BLACK =