FPGA设计——vga显示图片


前言

数字逻辑大作业,此篇为一部分,略作记录。


一、硬件及软件信息

1.NEXYS A7 100T
2.vivado
3.BMP2Mif

二、使用到的模块

1.顶层模块

top.v

`timescale 1ns / 1ps
module top(
input clock,
input rst,
input [3:0] yidong,
output hsync,
output vsync,
output [3:0] red,
output [3:0] green,
output [3:0] blue
    );
    wire [3:0]red; 
   wire [3:0]blue;
    wire vga_clk;
    clk_25m clk_25m(
    .clock(clock),
    .rst(rst),
    .vga_clk(vga_clk)
    );
   
    
    wire hsync;
    wire vsync;
    vga vga(
    .clock(vga_clk),
    .rst(rst),
    .yidong(yidong),
    .red(red),
    .green(green),
    .blue(blue),
    .hsync(hsync),
    .vsync(vsync)   );

    endmodule

2.VGA显示模块

使用25M时钟;
设置分辨率为640*480,帧数60;
RGB12位深度;
vga.v


`timescale 1ns / 1ps
module vga(
input clock, //系统时钟 100MHZ
input rst, //时钟复位端
output reg [3:0] red, // VGA 数据输出
output reg [3:0] green,
output reg [3:0] blue,
output reg hsync, // VGA 行同步信号
output reg vsync, // VGA 场同步信
input [3:0]yidong
);
wire clock, rst;
wire [3:0] yidong;
reg[9:0] hcount = 0; // 行扫描计数器
reg[9:0] vcount = 0; // 场扫描计数器
wire hcount_ov; //行扫描结束标志位
wire vcount_ov; //帧扫描结束标志位
wire data_act; //显示阶段 data 有效
//VGA 行、场扫描时序参数表
parameter hsync_end = 10'd95, //行同步信号(低电平)结束
hdata_begin = 10'd143, //行显示开始
hdata_end = 10'd783, //行显示结束
hpixel_end = 10'd799, //行显示前延结束
vsync_end = 10'd1, vdata_begin = 10'd34, vdata_end = 10'd514, vline_end =10'd524;
//VGA 驱动程序
//行扫描
always@(posedge clock)
begin
if(hcount_ov) //若行扫描标志位为 1,换行
hcount<=10'd0; //行扫描计数器置 0
else
hcount<= hcount +1; //行扫描计数器+1
end
assign hcount_ov = (hcount == hpixel_end); //行计数器=799,扫描一行结束,
//场扫描
always@(posedge clock)
begin
if(hcount_ov) //行扫描标志位有效
begin
if(vcount_ov) //帧扫描标志位有效,场扫描计数器置零,重新计数
vcount<=10'd0;
else
vcount<= vcount +10'd1; //场扫描计数器加 1
end
end
assign vcount_ov = (vcount == vline_end); //场计数器=524,一帧显示结束,给
//数据、同步信号输出
assign data_act = ((hcount>=hdata_begin-2) &&
(hcount<hdata_end))&&((vcount>=vdata_begin-2)&& (vcount<vdata_end)); //显示阶

always@(posedge clock)
begin
 hsync <= (hcount > hsync_end);//行计数器大于 95,行同步信号置 1
 vsync <= (vcount > vsync_end); //场计数器大于 1,场同步信号置 1
end
reg [3:0] datar;reg [3:0] datag;reg [3:0] datab;

always@(posedge clock)
begin
 red[3:0] <= (data_act) ? datar : 4'b0000;//显示阶段,输出数据,否则输8
 green[3:0] <= (data_act) ? datag : 4'b0000;//显示阶段,输出数据,否则输8
 blue [3:0]<= (data_act) ? datab : 4'b0000;//显示阶段,输出数据,否则输8
end
reg [15:0] addra = 16'b0;
wire [15:0] douta;
tupian tupian(
    .addra(addra),
    .clka(clock),
    .douta(douta)
    );
    reg [15:0] xiaodou;//移动消抖
    always@(posedge clock)
    begin 
    xiaodou[3:0] <= {xiaodou[2:0],yidong[0]};
    xiaodou[7:4] <= {xiaodou[6:4],yidong[1]};
    xiaodou[11:8] <= {xiaodou[10:8],yidong[2]};
    xiaodou[15:12] <= {xiaodou[14:12],yidong[3]};
    end
    
    wire [3:0] yidongend;
    assign yidongend[0] = (xiaodou[3:0]==4'b1111)?1:0; //shang
     assign yidongend[1] = (xiaodou[7:4]==4'b1111)?1:0; //xia
      assign yidongend[2] = (xiaodou[11:8]==4'b1111)?1:0;//zuo
       assign yidongend[3] = (xiaodou[15:12]==4'b1111)?1:0;//you
       
       reg[8:0] h = 143;reg[8:0] v = 34;  //控制移动和移动速度
       always@(posedge clock )
       begin
       if(vcount == 6&hcount ==6)
       begin
       if(h>=583&&yidongend[3]==1)
       h<=583;
       else if(h==143&&yidongend[2]==1)
       h<=143;
       else if(yidongend[3] == 1&&yidongend[2] ==0)
       h<=h+1;
       else if(yidongend[2] == 1&&yidongend[3] ==0)
       h<=h-1;
       end
       end
       always@(posedge clock)
       begin
       if(vcount ==6 & hcount ==6)
       begin
       if(v==314&&yidongend[1]==1)
       v<=314;
       else if(v==34&&yidongend[0]==1)
       v<=34;
       else if(yidongend[1] == 1&&yidongend[0] ==0)
       v<=v+1;
       else if(yidongend[0] == 1&&yidongend[1] ==0)
       v<=v-1;
       end
      end
always@(posedge clock) 
begin
if(addra == 39999)addra = 0;
 else if(hcount>=(h-2)&&hcount<(h+198)&&vcount>=(v-2)&&vcount<(v+198))
    begin 
      datar =douta[15:12];datag<=douta[10:7];datab[3:0]<=douta[4:1];addra <= addra+1;end
    else 
    begin 
   datar = 4'b1111;datag [3:0] = 4'b1001;datab [3:0] = 4'b0101;
    end
    end
endmodule

3.时钟分频模块

1.verilog代码创建

简单的分频器,100M
clk_25m.v

`timescale 1ns / 1ps
module clk_25m(
input clock,
input rst, output vga_clk
);
reg vga_clk;
reg clk_tmp;
always @(posedge clk_tmp or posedge rst) begin
if (rst)
vga_clk <= 0;
else
vga_clk <= ~vga_clk;
end
always @(posedge clock or posedge rst) begin
if (rst)
clk_tmp <= 0;
else
clk_tmp <= ~clk_tmp;
end
endmodule

2.使用Clocking WizardIP核

此种方式适合复杂频率。

  1. 选择指定模块

选择指定模块

  1. 更改模块名,选择需要的频率
    更改模块名,选择需要的频率

  2. 低电平触发,取消locked

低电平触发,取消locked

  1. 默认生成即可

默认生成即可

4.ROM存储图片

  1. 生成图片的coe文件,可使用MATLAB或BMP2Mif
    提取码:mru2 。

软件使用简单,但没有rgb444的格式,博主生成RGB565,使用时只需要每种颜色的前4位。
在这里插入图片描述

  1. 创建Block Memory GeneratorIP核

选择ip;选择ip
更改模块名,选择Single Port ROM;
更改模块名,选择Single Port ROM
选择生成的coe文件
选择生成的coe文件
根据coe文件的RGB位数和大小选择。
此处为16位——RGB565,图片200*200,故Depth为40000。
使能端始终开启(方便)。
在这里插入图片描述

二、仿真

1.仿真文件

代码如下:

`timescale 1ns / 1ps

module tb;

reg clock;
reg rst;
reg[3:0] yidong;
wire [3:0]red;
wire [3:0]green;
wire [3:0]blue;
wire hsync;
wire vsync;

initial begin
yidong = 0;
end
initial begin
		rst=1;#20;
		rst =0;		
	end
	always begin
		clock =0 ; #1;
		clock =1 ; #1;
   end

top uut(
.clock(clock),
.rst(rst),
.hsync(hsync),
.vsync(vsync),
.yidong(yidong),
.red(red),
.green(green),
.blue(blue)
);

endmodule

2.仿真结果

此处为显示阶段,rgb皆被赋值
在这里插入图片描述

附:代码中还进行了图片移动的设计,消抖设计。与本文无关,请忽略。
又附:文章主要写给自己,若新人有惑,望能解答;若大佬有勘误,先行谢过;若诸位有所得,不胜荣幸。

  • 18
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FPGA中使用VGA时序显示图像的仿真过程可以通过以下步骤实现: 1. 首先,需要使用时钟生成模块(PLL)来生成VGA工作所需的时钟信号。这个时钟信号将用于控制图像的扫描和刷新。 2. 接下来,使用图像生成模块(VGA_P)来确定每个有效图像区域的像素点。这个模块将根据控制模块传入的坐标信号,生成待显示图像的色彩信息。 3. 图像控制模块(VGA_C)负责生成行场同步信号,并确定有效图像区域的位置和零点坐标。这个模块还需要接收RGB信息和行场同步信号。 4. 最后,将生成的图像信号通过VGA端口输出,连接到VGA显示器上进行显示。 通过以上步骤,可以在FPGA中使用VGA时序显示图像的仿真。这样,你就可以在仿真环境中验证图像的显示效果,并进行必要的调试和优化。 #### 引用[.reference_title] - *1* [FPGA学习——VGA显示](https://blog.csdn.net/weixin_56102526/article/details/124964347)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [FPGA——VGA显示协议](https://blog.csdn.net/a17377547725/article/details/129729079)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值