FPGA 之 VGA的IP核编写

做一个简单的VGA 640*480   超了一天半, 整整七天才搞定,不过也很开心了!  加油努力.....

 

主要分成三个文件: 

VGA.v 主文件, 同时调用FIFO

vga_timing.v VGA时序控制文件

vga_sdram.v 读取SDRAM内存文件

 

 

 

1. VGA.v 

 


module VGA(
input wire clk,
input wire reset,

// 控制寄存器读写
input wire slave_chipselect,
input wire[1:0] slave_address, //
input wire slave_write, //写请求
input wire[31:0] slave_writedata, //写数据
input wire slave_read, //读请求
output wire[31:0] slave_readdata, //读数据
input wire[3:0] slave_byteenable, //数据有效标志


// 读写SDRAM数据
output wire[31:0] master_address, //数据地址
output wire master_read, //主端口读请求
output wire master_byteenable,
input wire master_waitrequest, //迫使主端口等待
input wire master_readdatavalid, //指示已经提供有效数据
input wire[7:0] master_readdata, //读入数据值

// VGA 时序
input wire vga_clk,
output wire vga_line_sync,
output wire vga_field_sync,
output wire [2:0] vga_r,
output wire [2:0] vga_g,
output wire [1:0] vga_b
);


wire vga_pixel_flag;

wire [7:0] fifo_data;
wire [7:0] tmp_data0;
reg [7:0] tmp_data1;

wire vga_frame_o;

 


/
// VGA输出 /
/

assign vga_b = vga_pixel_flag ? fifo_data[1:0]:8'b00000000;
assign vga_g = vga_pixel_flag ? fifo_data[4:2]:8'b00000000;
assign vga_r = vga_pixel_flag ? fifo_data[7:5]:8'b00000000;


/
// VGA 时序 /
/
vga_timing vga_l1(
.clk(vga_clk),
.reset_i(reset),
.pixel_flag(vga_pixel_flag),
.hsync(vga_line_sync),
.vsync(vga_field_sync),
.frame_o(vga_frame_o),
.vga_rgb(tmp_data0)
);

 


/
// VGA 寄存器操作 /
/

//register 操作寄存器
wire vga_go; //VGA 启动标志
wire [31:0] vga_base_address; //vga 数据基地址

vga_register vga_slave(
.clk(clk),
.reset_n(reset),

// 控制寄存器读写
.slave_chipselect(slave_chipselect),
.slave_address(slave_address), //
.slave_write(slave_write), //写请求
.slave_writedata(slave_writedata), //写数据
.slave_read(slave_read), //读请求
.slave_readdata(slave_readdata), //读数据
.slave_byteenable(slave_byteenable), //数据有效标志

.vga_base_address(vga_base_address),
.vga_go(vga_go)
);

 


/
// VGA SDRAM 读取像素 /
/

 

 

 

 


wire [11:0] fifo_count;

vga_sdram vga_sdram_11(
.clk(clk),
.reset_n(reset),

.master_address(master_address), //数据地址
.master_read(master_read), //主端口读请求
.master_byteenable(master_byteenable),
.master_waitrequest(master_waitrequest), //迫使主端口等待
.master_readdatavalid(master_readdatavalid),//指示已经提供有效数据
.master_readdata(master_readdata), //读入数据值

.vga_base_addr(vga_base_address), //VGA基地址
.vga_go(vga_go), //VGA 启动标记
.frame_start_flag(vga_frame_o), //帧开始标记
.fifo_count(fifo_count)
);

 

 

 

/
// VGA FIFO 做数据缓冲 以匹配不同速度的外设//
/

 

vga_fifo fifo_l2(
.aclr(vga_frame_o),
.data(master_readdata),
// .data(8'b00001000),
.rdclk(~vga_clk),
.rdreq(vga_pixel_flag),
.wrclk(clk),
.wrreq(master_readdatavalid),
.q(fifo_data),
.wrusedw(fifo_count)
);

 

 

endmodule

 

2. vga_timing.v 

 

 

//640*480
module vga_timing( clk,reset_i,pixel_flag,
hsync,
vsync,
frame_o,
vga_rgb);



// VGA

input clk;
input reset_i;
output hsync; //VGA行同步信号
output vsync; //VGA场同步信号
output pixel_flag;
output frame_o;
output[7:0] vga_rgb;


reg [10:0] hcount; //VGA行扫描计数器
reg [9:0] vcount; //VGA场扫描计数器
reg [8:0] data; //VGA数据
reg vga_clk;

wire h_end;
wire v_end;

wire dat_act;

 


// VGA

always @(posedge clk)
begin
vga_clk = ~vga_clk;
end
// 竖向....
always @(posedge clk)
begin
if(h_end)
hcount <= 10'd0;
else
hcount <= hcount + 10'd1;
end

assign h_end = (hcount == 799);

// 横向....
always @(posedge clk)
begin
if(h_end)
begin
if(v_end)
vcount <= 10'd0;
else
vcount <= vcount + 10'd1;
end
end
assign v_end = (vcount == 524);


//使能信号
assign pixel_flag = ((hcount >= 144) && (hcount < 784))&& ((vcount >= 34) && (vcount < 514));

 

assign hsync = (hcount > 95);//水平同步
assign vsync = (vcount > 2);//垂直同步

 

reg frame_o_t;
always @(posedge clk)
begin
if( vcount < 3)
frame_o_t <= 1;
else
frame_o_t <= 0;
end

assign frame_o = frame_o_t;//垂直同步


wire[10:0] x_pos;
wire[10:0] y_pos;
assign x_pos = hcount - 144;//垂直同步
assign y_pos = vcount - 34;//垂直同步


reg[7:0] vga_rgb_t;

always @(posedge clk)
begin

if( x_pos<500 && y_pos > 80)
vga_rgb_t <= 8'b01101111;
else
vga_rgb_t <= 8'b00000000;
end


assign vga_rgb = vga_rgb_t;


endmodule

 

 

3. vga_sdram.v

 

 


module vga_sdram(input wire clk,
input wire reset_n,

output wire[31:0] master_address, //数据地址
output wire master_read, //主端口读请求
output wire master_byteenable,
input wire master_waitrequest, //迫使主端口等待
input wire master_readdatavalid, //指示已经提供有效数据
input wire[7:0] master_readdata, //读入数据值

input wire[31:0] vga_base_addr, //VGA基地址
input wire vga_go, //VGA 启动标记
input wire frame_start_flag, //帧开始标记
input wire[11:0] fifo_count
);

 

reg [19:0] input_data_count;
reg vga_read;

assign master_read = vga_read;
assign master_byteenable = 1'd1; //位使能
assign master_address = vga_base_addr + input_data_count;

//统计FIFO已经读了多少数据
always @ (posedge clk or negedge reset_n)
begin
if (!reset_n)
begin
//vga_read <= 1'b0; //SDRAM 停止读
end

// 一帧数据开始时,清除FIFO
else if (!master_waitrequest ) //地址计数 : // 1. 数据有效
begin

if (frame_start_flag)
begin
vga_read <= 1'b0;
end
else if( (fifo_count < 500) && (input_data_count < 307200) )
begin
vga_read <= 1'b1; // 向FIFO读数据
end
else if(fifo_count > 2000)
begin
vga_read <= 1'b0; // 向FIFO读数据
end


end

end


always @ (posedge clk or negedge reset_n)
begin
if (!reset_n)
begin
//input_data_count <= 0;
end

// 一帧数据开始时,清除FIFO
else if (!master_waitrequest ) //地址计数 : // 1. 数据有效
begin

if (frame_start_flag)
begin
input_data_count <= 0;
end
else if( input_data_count < 307200)
begin
if(vga_read == 1'b1)
input_data_count <= input_data_count + 1;
end

end

end

 

endmodule

 

 

 

 

 

转载于:https://www.cnblogs.com/signal/archive/2012/07/31/2616745.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Contents 1 VGA时序以及如何产生 3 1.1 VGA接口............................. 3 1.2 VGA驱动原理........................... 4 1.3 时序产生以及颜色给定...................... 4 1.3.1 行同步信号以及场同步信号怎么给........... 4 1.3.2 屏幕上的每个像素点是如何给定颜色的......... 6 2 字模提取 9 2.1 使用PCtoLCD2002提取字模................... 9 2.2 mif文件格式............................ 9 2.3 用C代码把从PCtoLCD软件得到的数据转换成mif文件 .... 10 3 VGAIPCore设计 11 3.1 屏幕上的像素以及字符...................... 11 3.2 显示字符的原理.......................... 12 3.3 实现向上卷动显示........................ 14 3.4 遇到换行怎么办.......................... 16 3.4.1 简单的处理办法(不完美)................ 16 3.4.2 更加完美的换行处理................... 17 3.5 如何使用这个VGAIPCore................... 17 4 UART模块 19 4.1 系统时钟、波特率........................ 19 4.2 如何通过UART发送数据..................... 19 4.3 采样时钟的概念以及如何通过UART接受数据......... 20 4.4 如何产生采样时钟........................ 20 4.5 还缺什么 ............................. 22 1 CONTENTS 2 5 未来要做什么 23 5.1 一个完美的VGAIPCore .................... 23 5.2 我的数字设计水平........................ 23 5.3 所以,未来还有很长的路...................... 23 A生成mif文件的C代码 24 B效果图 26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值