cuter

[Zedboard测评] 使用PL实现简单的VGA测试

0
阅读(9000)

硬件平台:Zedboard

开发工具:ISE 14.2(Project Navigator)

 

用Windows Live Writer写的,感觉方便了很多,不知道效果咋样~

 

之所以先用PL做VGA显示测试,是为接下来设计VGA显示控制IP核打基础,首先设计一个没有问题的时序模块出来。

 

Step1:打开Project Navigator,新建工程。

new project

 

Step2:选择存储位置、确定工程名。

工程地址_名称

 

 

Step3:下一步:选择开发板,所用的HDL语言等,开发板里面没有Zedboard或者Zynq,所以不用管它,Family选择Zynq,Device选择Zc7020,Package选择,Speed选-1。HDL看情况,这里我选的VHDL,因为XPS的IP核向导生成的文件用HDL实现,都用HDL,看起来、改起来比较顺。

 111

 

Step4:选择下一步,弹出信息汇总的消息框,直接Finish一个空工程就建立完毕了。信息汇总

 

 

 

 

Step5:点击下图红框内的按钮新建源文件。

新建源文件

 

Step6:弹出源文件新建向导,选择VHDL,命名为vga_test。

新建源文件向导

 

Step7:然后点击下一步。

生成模板的参数

 

Step8:这个界面可以指定的顶层实体名,结构体名称,还可以指明输入输出端口,为了生成模板用的,我没有做设置,后面在代码里改就可以了。Next来到信息汇总页面。

源文件信息汇总

 

Step9:Finish,编辑器自动打开IDE所生成的vga_test.vhd文件:

生成的模板代码

Step10:现在可以添加自己的逻辑代码了,完整代码贴在文章最后吧。

 

Step11:设计引脚约束文件。

11.1:点击下图红框内的按钮新建源文件。

新建源文件

11.2:弹出文件类型选择对话框,选择文件类型,为ucf文件命名,效果如下:

11-新建ucf文件

11.3:下一步,弹出ucf文件信息摘要:

11-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:编程下载,效果图如下:

IMG_20121209_202718

代码如下:

----------------------------------------------------------------------------------
-- 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;