[Zedboard测评] 使用PL实现简单的VGA测试
0赞硬件平台:Zedboard
开发工具:ISE 14.2(Project Navigator)
用Windows Live Writer写的,感觉方便了很多,不知道效果咋样~
之所以先用PL做VGA显示测试,是为接下来设计VGA显示控制IP核打基础,首先设计一个没有问题的时序模块出来。
Step1:打开Project Navigator,新建工程。
Step2:选择存储位置、确定工程名。
Step3:下一步:选择开发板,所用的HDL语言等,开发板里面没有Zedboard或者Zynq,所以不用管它,Family选择Zynq,Device选择Zc7020,Package选择,Speed选-1。HDL看情况,这里我选的VHDL,因为XPS的IP核向导生成的文件用HDL实现,都用HDL,看起来、改起来比较顺。
Step4:选择下一步,弹出信息汇总的消息框,直接Finish一个空工程就建立完毕了。
Step5:点击下图红框内的按钮新建源文件。
Step6:弹出源文件新建向导,选择VHDL,命名为vga_test。
Step7:然后点击下一步。
Step8:这个界面可以指定的顶层实体名,结构体名称,还可以指明输入输出端口,为了生成模板用的,我没有做设置,后面在代码里改就可以了。Next来到信息汇总页面。
Step9:Finish,编辑器自动打开IDE所生成的vga_test.vhd文件:
Step10:现在可以添加自己的逻辑代码了,完整代码贴在文章最后吧。
Step11:设计引脚约束文件。
11.1:点击下图红框内的按钮新建源文件。
11.2:弹出文件类型选择对话框,选择文件类型,为ucf文件命名,效果如下:
11.3:下一步,弹出ucf文件信息摘要:
11.4:点击Finish,编辑ucf文件如下:(参考官方ucf文件更改得到)
NET clk100MHz LOC = Y9 | IOSTANDARD=LVCMOS33; # "GCLK"
NET blue[0] LOC = Y21 | IOSTANDARD=LVCMOS33; # "VGA-B1"
NET blue[1] LOC = Y20 | IOSTANDARD=LVCMOS33; # "VGA-B2"
NET blue[2] LOC = AB20 | IOSTANDARD=LVCMOS33; # "VGA-B3"
NET blue[3] LOC = AB19 | IOSTANDARD=LVCMOS33; # "VGA-B4"
NET green[0] LOC = AB22 | IOSTANDARD=LVCMOS33; # "VGA-G1"
NET green[1] LOC = AA22 | IOSTANDARD=LVCMOS33; # "VGA-G2"
NET green[2] LOC = AB21 | IOSTANDARD=LVCMOS33; # "VGA-G3"
NET green[3] LOC = AA21 | IOSTANDARD=LVCMOS33; # "VGA-G4"
NET hsync LOC = AA19 | IOSTANDARD=LVCMOS33; # "VGA-HS"
NET red[0] LOC = V20 | IOSTANDARD=LVCMOS33; # "VGA-R1"
NET red[1] LOC = U20 | IOSTANDARD=LVCMOS33; # "VGA-R2"
NET red[2] LOC = V19 | IOSTANDARD=LVCMOS33; # "VGA-R3"
NET red[3] LOC = V18 | IOSTANDARD=LVCMOS33; # "VGA-R4"
NET vsync LOC = Y19 | IOSTANDARD=LVCMOS33; # "VGA-VS"
Step12:综合、配置、除错。点击下图红框中的“Implement Top Module”按钮开始,有错误的话自己更改测试。
Step13:编程下载,效果图如下:
代码如下:
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 18:47:55 12/09/2012
-- Design Name:
-- Module Name: vga_test - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity vga_test is
port(
clk100MHz : in std_logic;
hsync,vsync : out std_logic;
red,green,blue : out std_logic_vector(3 downto 0)
);
end vga_test;
architecture Behavioral of vga_test is
signal clk50MHz, clk25MHz : std_logic;
signal hcount, vcount : std_logic_vector(11 downto 0);
signal hcount_ov, vcount_ov : std_logic;
signal data_oe : std_logic;
begin
------------时钟产生进程-----------------
vga_clk_gen_proc1: process(clk100MHz) begin
if(clk100MHz'event and clk100MHz='1') then
clk50MHz <= not clk50MHz;
end if;
end process vga_clk_gen_proc1;
vga_clk_gen_proc2: process(clk50MHz) begin
if(clk50MHz'event and clk50MHz='1') then
clk25MHz <= not clk25MHz;
end if;
end process vga_clk_gen_proc2;
------------时钟产生完毕----------------
----------------vga时序产生部分--------------------
--
----------------行扫描进程---------------------
hcnt_ov_flag_gen: process(hcount) begin
if(hcount = 799) then
hcount_ov <= '1';
else
hcount_ov <= '0';
end if;
end process hcnt_ov_flag_gen;
pixel_count_proc: process(clk25MHz) begin
if(clk25MHz'event and clk25MHz='1') then
if(hcount_ov = '1') then
hcount <= (others => '0');
else
hcount <= hcount + 1;
end if;
end if;
end process pixel_count_proc;
----------------行扫描结束---------------------
----------------场扫描进程---------------------
vcnt_ov_flag_gen: process(hcount) begin
if(vcount = 524) then
vcount_ov <= '1';
else
vcount_ov <= '0';
end if;
end process vcnt_ov_flag_gen;
line_count_proc: process(clk25MHz) begin
if(clk25MHz'event and clk25MHz='1') then
if(hcount_ov = '1') then
if(vcount_ov = '1') then
vcount <= (others => '0');
else
vcount <= vcount + 1;
end if;
end if;
end if;
end process line_count_proc;
----------------场扫描结束---------------------
----------------行同步头产生-------------------
hsync_gen_proc: process(hcount) begin
if(hcount > 95) then
hsync <= '1';
else
hsync <= '0';
end if;
end process hsync_gen_proc;
----------------行同步头结束-------------------
----------------场同步头产生-------------------
vsync_gen_proc: process(hcount) begin
if(vcount > 1) then
vsync <= '1';
else
vsync <= '0';
end if;
end process vsync_gen_proc;
----------------场同步头结束-------------------
----------------vga时序产生结束---------------------
-----------------输出数据部分-------------------
--------------数据输出使能信号产生---------------------
-- 分辨率:640*480
data_oe_proc: process(hcount, vcount) begin
if(( hcount>=143 and hcount<783 )and(vcount >= 34 and vcount<524)) then
data_oe <= '1';
else
data_oe <= '0';
end if;
end process data_oe_proc;
---------------使能信号产生进程完毕------------------------
----------------简单的测试画面产生进程-----------------------
-- 随意产生了一个测试画面,屏幕左红右绿,但不平分
data_output_proc: process(hcount, vcount) begin
if(data_oe = '1') then
if(hcount<463) then --左半屏为红
red <= "1111";
green <= "0000";
blue <= "0000";
else --右半屏为绿
red <= "0000";
green <= "1111";
blue <= "0000";
end if;
else
red <= "0000";
green <= "0000";
blue <= "0000";
end if;
end process data_output_proc;
------------------画面产生进程结束--------------------------
--------------------vga数据输出部分结束----------------
end Behavioral;