号的电压为 0~0.7V。本次要实现的分辨率是640*480,帧率是60Hz,所需要的时钟是25Mhz.话不多说,直接上图:
VGA 时序图
需要注意的是,VGA的时序图和参数表可以看出,每帧需要525个vsync脉冲,在每个vsync的周期中,即Tvsync,又包含着800个hsync脉冲,而图像RGB的有效时间在hsync的640个显示脉冲之中。 二、逻辑实现[plain] view plain copy
-
//vga_sync.v VGA同步控制逻辑
[plain] view plain copy
- module vga_sync(
- input wire clk,
- input wire rst_n,
- output wire video_en, //数据有效
- output reg hsync, //场同步信号
- output reg vsync, //行同步信号
- output wire [9:0] pixel_x, //待显示待像素的x坐标
- output wire [9:0] pixel_y //待显示待像素的y坐标
- );
- reg [9:0] pixel_cnt;
- reg [9:0] line_cnt;
- reg v_video_en;
- reg h_video_en;
- always @(posedge clk or negedge rst_n)
- if(!rst_n)
- begin
- pixel_cnt <= 10'b0;
- end
- else
- begin
- pixel_cnt <= pixel_cnt + 1'b1;
- if(pixel_cnt == 10'd799)
- begin
- pixel_cnt <= 10'b0;
- end
- end
- always @(posedge clk or negedge rst_n)
- if(!rst_n)
- begin
- h_video_en <= 1'b1;
- hsync <= 1'b1;
- end
- else
- begin
- case (pixel_cnt)
- 10'd0:
- begin
- h_video_en <= 1'b1;
- end
- 10'd639:
- begin
- h_video_en <= 1'b0;
- end
- 10'd655:
- begin
- hsync <= 1'b0;
- end
- 10'd751:
- begin
- hsync <= 1'b1;
- end
- endcase
- end
- always @(posedge clk or negedge rst_n)
- if(!rst_n)
- begin
- line_cnt <= 10'b0;
- end
- else
- begin
- if(pixel_cnt == 10'd799)
- begin
- line_cnt <= line_cnt + 1'b1;
- end
- if(line_cnt == 10'd524)
- begin
- line_cnt <= 10'b0;
- end
- end
- always @(posedge clk or negedge rst_n)
- if(!rst_n)
- begin
- v_video_en <= 1'b1;
- vsync <= 1'b1;
- end
- else
- begin
- case(line_cnt)
- 10'd0:
- begin
- v_video_en <= 1'b1;
- end
- 10'd479:
- begin
- v_video_en <= 1'b0;
- end
- 10'd489:
- begin
- vsync <= 1'b0;
- end
- 10'd491:
- begin
- vsync <= 1'b1;
- end
- endcase
- end
- assign pixel_x = pixel_cnt;
- assign pixel_y = line_cnt;
- assign video_en = ((h_video_en == 1'b1) && (v_video_en == 1'b1));
-
endmodule
[plain] view plain copy
-
//由于开发板上的PL部分时钟是100Mh的,所以需要用PLL把VGA的基准时钟时钟分频到25Mhz
[plain] view plain copy
-
//test_vga.v文件 利用上面的代码显示彩色图像
[plain] view plain copy
- module vga_test(
- input wire sys_clk,
- input wire sys_rst_n,
- output wire hsync,
- output wire vsync,
- output wire [11:0] rgb,
- output reg led
- );
- //红_绿_蓝
- parameter BLACK = 12'b0000_0000_0000;
- parameter BLUE = 12'b0000_0000_1111;
- parameter GREEN = 12'b0000_1111_0000;
- parameter DIAN = 12'b0000_1111_1111;
- parameter RED = 12'b1111_0000_0000;
- parameter PURPLE = 12'b1111_0000_1111;
- parameter YELLOW = 12'b1111_1111_0000;
- parameter WHITE = 12'b1111_1111_1111;
- wire [9:0] pixel_x;
- wire [9:0] pixel_y;
- wire clk_25mhz;
- reg [11:0] rgb_reg;
- //显示静态图像640*480
- reg [23:0] cnt;
- always @(posedge clk_25mhz or negedge sys_rst_n)
- if(!sys_rst_n)
- begin
- cnt <= 0;
- led <= 0;
- end
- else
- begin
- cnt <= cnt + 1'b1;
- if(cnt == 24'd12500000)
- begin
- cnt <= 24'b0;
- led <= ~led;
- end
- end
- always @ (posedge clk_25mhz or negedge sys_rst_n)
- if(!sys_rst_n)
- begin
- rgb_reg <= 12'b0;
- end
- else
- begin //显示图像
- //rgb_reg <= q_sig;
- rgb_reg[3:0] <= q_sig[7:4];
- rgb_reg[7:4] <= q_sig[3:0];
- rgb_reg[11:8] <= q_sig[11:8];
- end
- always @ (posedge clk_25mhz or negedge sys_rst_n)
- if(!sys_rst_n)
- begin
- address_sig <= 19'b0;
- end
- else
- begin
- if(pixel_x>=0 && pixel_x<= 639 && pixel_y>=0 && pixel_y<=479)
- address_sig = (pixel_x + 640*pixel_y);
- end
- //////////////////////////////////////////////////////////////
- assign rgb = (video_en == 1'b1) ? rgb_reg:12'b0;
- vga_sync vga_syn_inst(
- .clk (clk_25mhz),
- .rst_n (sys_rst_n),
- .video_en (video_en),
- .hsync (hsync),
- .vsync (vsync),
- .pixel_x (pixel_x),
- .pixel_y (pixel_y)
- );
- reg [18:0] address_sig;
- wire [11:0] q_sig;
- rom_pic rom_pic_inst (
- .clka(clk_25mhz), // input wire clka
- .addra(address_sig), // input wire [18 : 0] addra
- .douta(q_sig) // output wire [11 : 0] douta
- );
- clk_wiz_0 clk_wiz_0_inst
- (
- // Clock in ports
- .clk_in1(sys_clk),
- // Clock out ports
- .clk_out1(clk_25mhz)
- );
-
endmodule
三、生成coe文件1.准备软件BmpToMif和Image2Lcd 下载 2.准备好640*480的彩色图片 3.打开Image2Lcd ,并且打开待显示的图片,并且按照下图配置参数:
4.配置完毕后,点击保存 5.打开BmpToMif,选择数据文件,打开刚才生成的bin文件,字长改为12,点击生成Mif文件(弹出的窗口可以选择否)。
6.用excel 打开生成的mif文件,选中这一列
7.然后在菜单栏中选择 数据->分列
8.选择分隔符号,下一步
9.选择其他,输入冒号(注意是英文的冒号),下一步 10.然后,按Ctrl+H,把分号换成逗号,(最后一组数据是分号)。
11.到此为止,图片的数据就准备好了,下面把数据添加到vivado,的coe文件里面。打开vivado,点击 IP Catalog ,搜索rom,双击 Block memory Cenerator
12.Memor type 选择Signal Poart ROM,Port A Opation按照如图所示配置
13.然后选择 Other Options(也可以先做好coe文件在此选择) 点击Edit,选择YES,输入文件名
14.radix 必须是2,vector可以先随便输,save,close 15.打开刚才新建的coe文件,按照如图所示的格式把生成的图像数据复制进来,注意最后一行数据以分号结束
16.至此,coe文件已经生成好了,ROM初始化的时候,会加载,供我们读取,显示在VGA上。
四、下面写好代码,生成bit文件后,就可以把代码烧到ZYNQ测试了
测试效果如图所示: