集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 1032|回复: 2

FPGA的VGA显示

[复制链接]
梅净缘 发表于 2013-3-26 16:51:42 | 显示全部楼层 |阅读模式
各位大神,我想写一个乒乓RAM来实现VGA显示,可是现在画面一直在下降,即感觉每一帧出现的位置在下降,不知道是什么原因,求指导!!
我采用的输入是720*576,输出是800*600.。
这是我的乒乓代码:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;

entity address_800600_control is
generic(
         const800: unsigned(9 downto 0) :="1100100000";--800
        const600: unsigned(9 downto 0) :="1001011000";--600
         const78: std_logic_vector(19 downto 0) :="00000000000001001110";--78
         const800_576: std_logic_vector(19 downto 0) :="01110000011111111111";--800*576-1
         const721: std_logic_vector(19 downto 0) :="00000000001011010001";--721
         const800_575: std_logic_vector(19 downto 0) :="01110000010011011111";--575*800-1=459999
         const878: std_logic_vector(19 downto 0) :="00000000001101101110";--878
         const879: std_logic_vector(19 downto 0) :="00000000001101101111";--879
         const0: std_logic_vector(19 downto 0) :="00000000000000000000"--0
         );
port(
     din : in std_logic_vector(15 downto 0);--输入的RGB16位数据
     rst : in std_logic;
     clk_write : in std_logic;  --27M
     clk_read : in std_logic;   --49M
     sel : in std_logic;     --编一个计数器控制sel
     en_write : in std_logic;
     en_read : in std_logic;
     n_ce1 : out std_logic;
     n_ce2 : out std_logic;
     n_wr1 : out std_logic;
     n_wr2 : out std_logic;
     n_rd1 : out std_logic;
     n_rd2 : out std_logic;
     add1 : out std_logic_vector(19 downto 0);--SRAM1的地址线
     add2 : out std_logic_vector(19 downto 0);--SRAM2的地址线
     dqa : inout std_logic_vector(15 downto 0);--与SRAM1的接口
     dqb : inout std_logic_vector(15 downto 0);--与SRAM1的接口
     dout : out std_logic_vector(15 downto 0);--输出将来给ADV7123的数据
     hcont :  in std_logic_vector(10 downto 0);
     vcont :  in std_logic_vector(10 downto 0)
     );
end entity;

architecture one of address_800600_control is

signal add_temp1 : std_logic_vector(19 downto 0);--写地址信号
signal add_temp2 : std_logic_vector(20 downto 0);--读地址信号
signal add_temp : std_logic_vector(19 downto 0);--偏移量控制信号
signal dqa_reg : std_logic_vector(15 downto 0);
signal dqb_reg : std_logic_vector(15 downto 0);
signal hcnt : unsigned(10 downto 0);
signal vcnt : unsigned(10 downto 0);
begin
hcnt <= unsigned (hcont(10 downto 0));
vcnt <= unsigned(vcont(10 downto 0));
process(en_read,sel,clk_read,add_temp1,add_temp2)--乒乓存储模块 read
begin
if en_read='1' then
        if sel='1' then  
--read 存储器2
                n_rd1 <= '1';
                n_rd2 <= clk_read;
                add1 <= add_temp1;               
                add2 <= add_temp2(19 downto 0);
        else
--read 存储器1
                n_rd2 <= '1';
                n_rd1 <= clk_read;
                add1 <= add_temp2(19 downto 0);
                add2 <= add_temp1;
        end if;
else
        n_rd1 <= 'Z';
        n_rd2 <= 'Z';
        add1 <= "ZZZZZZZZZZZZZZZZZZZZ";
        add2 <= "ZZZZZZZZZZZZZZZZZZZZ";
end if;
end process;

process(en_write,sel,clk_write)--乒乓存储模块
begin
if en_write='1' then
        if sel='1' then  
--写存储器1
                n_wr1 <= clk_write;
                n_wr2 <= '1';
        else
--写存储器2
                n_wr2 <= clk_write;
                n_wr1 <= '1';
        end if;
else
        n_wr1 <= 'Z';
        n_wr2 <= 'Z';
end if;
end process;

process(clk_read)--乒乓存储模块之读
begin
if clk_read'event and clk_read = '1' then
        if en_read='1' then
                if sel='1' then
                        dout <= dqb;
                else
                        dout <= dqa;
                end if;
        else
                dout <= "ZZZZZZZZZZZZZZZZ";
        end if;
end if;
end process;

process(clk_write)
begin
if clk_write'event and clk_write = '1' then
        if en_write='1' then
                if sel='1' then
                        dqa_reg <= din;
                else
                        dqa_reg <= (others=>'0') ;
                end if;
        end if;
end if;
end process;

process(clk_write)
begin
if clk_write'event and clk_write = '1' then
        if en_write='1' then
                if sel='0' then
                        dqb_reg <= din;
                else
                        dqb_reg <= (others=>'0') ;
                end if;
        end if;
end if;
end process;

process(clk_write,rst)--写地址模块
begin
if(rst='0')then
        add_temp <= const0;
        add_temp1 <= const78;--应该从78开始,78=800-720-2(2 = SAV 4 BYTES)
elsif(clk_write'event and clk_write='1')then
        if en_write = '1' then
                if (add_temp1 < const800_576) then--800*576-1
                        if (add_temp < const721) then-- move 721
                                add_temp <= add_temp+1;
                                add_temp1 <= add_temp1+1;
                        elsif (add_temp1 = const800_575) then --奇数场的最后位置:575*800-1=459999
                                add_temp <= const0;
                                add_temp1 <= const878;--go to 878       
                        else
                                add_temp <= const0;
                                add_temp1 <= add_temp1+const879;--偏879个
                        end if;
                else
                        add_temp <= const0;
                        add_temp1 <= const78;--应该从78开始       
                end if;
        end if;
end if;
end process;

--------------读地址模块----------------------

process(clk_read,rst)
begin
if(rst='0')then
        add_temp2 <= "000000000000000000000";
elsif(clk_read'event and clk_read='1')then
        if en_read = '1' then
                if (hcnt<const800 and vcnt<const600) then
                        add_temp2 <= (hcnt + (const800 * vcnt));
                end if;
        end if;       
end if;
end process;
dqb <= dqb_reg when (en_write='1' and sel='0') else (others=>'Z');
dqa <= dqa_reg when (en_write='1' and sel='1') else (others=>'Z');
n_ce1 <= '0';
n_ce2 <= '0';
--add3 <= add_temp;
--add4 <= add_temp1;
end architecture;
时序代码:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;

entity time_800600_control is       

generic(
         const1056: std_logic_vector(10 downto 0) :="10000011111";--1055       
         const625: std_logic_vector(10 downto 0) :="01001110000";--624
         const808: std_logic_vector(10 downto 0) :="01100101000";--808               
         const800: std_logic_vector(9 downto 0) :="1100100000";--800
        const600: std_logic_vector(9 downto 0) :="1001011000";--600
         const78: std_logic_vector(19 downto 0) :="00000000000001001110";--78
         const800_576: std_logic_vector(19 downto 0) :="01110000011111111111";--800*576-1       
         const721: std_logic_vector(19 downto 0) :="00000000001011010001";--721
         const800_575: std_logic_vector(19 downto 0) :="01110000010011011111";--575*800-1=459999
         const878: std_logic_vector(19 downto 0) :="00000000001101101110";--878       
         const879: std_logic_vector(19 downto 0) :="00000000001101101111";--879
         const0: std_logic_vector(19 downto 0) :="00000000000000000000"--0
         );

port(
     clk : in std_logic;--49M
     reset : in std_logic;
         en : in std_logic;
         sel1 : out std_logic;
         sel2 : out std_logic;
         hcont :  out std_logic_vector(10 downto 0);
         vcont :  out std_logic_vector(10 downto 0);
     vga_hs : out std_logic;--给VGA
     vga_vs : out std_logic;--给VGA
     vga_blank : out std_logic;--给ADV7123
     vga_clock : out std_logic--50M,to adv7123
     );
end entity;

architecture one of time_800600_control is
signal hcnt : std_logic_vector(10 downto 0);
signal vcnt : std_logic_vector(10 downto 0);
signal sel_reg : std_logic;
signal temp : std_logic_vector(2 downto 0);
begin

process(clk,reset)
begin
if reset='0' then
        hcnt <= (others => '0');
elsif (rising_edge(clk)) then
        if en='1' then
        if (hcnt < const1056) then
                hcnt <= hcnt + 1;
        else
                hcnt <= (others => '0');
        end if;
        end if;
end if;
end process;

process(clk,reset)
begin
if reset='0' then
        vcnt <= (others => '0');
elsif (rising_edge(clk)) then
        if en='1' then
        if (hcnt = const808 ) then
                if(vcnt < const625) then
                        vcnt <= vcnt + 1;
                else
                        vcnt <= (others => '0');
                end if;
        end if;
        end if;
end if;
end process;

process(clk)
begin
if (rising_edge(clk)) then
        if((hcnt>=816)and (hcnt<896)) then
                vga_hs <= '0';
        else
                vga_hs <= '1';
        end if;
end if;
end process;

process(vcnt) begin
if ((vcnt >= 601) and (vcnt < 604)) then
        vga_vs <= '0';
else
        vga_vs <= '1';
end if;
end process;

process(clk) begin
if (rising_edge(clk)) then
        if en='1' then
        if (hcnt<const800 and vcnt<const600) then
                vga_blank <= '1';
        else
                vga_blank <= '0';
        end if;
        end if;
end if;
end process;

process(reset,clk)
begin
if reset = '0' then
        temp <= "000";
        sel_reg <= '0';
elsif (rising_edge(clk)) then
        if en='1' then
                if (temp < "011") then
                        if (hcnt = 0 and vcnt = 0) then
                                temp <= temp + 1;
                        end if;
                elsif (temp = "011") then
                        if (hcnt = 0 and vcnt = 0) then
                                sel_reg <= not(sel_reg);
                                temp <= "001";
                        end if;
                end if;
        end if;
end if;
end process;

vga_clock <= clk;
hcont <= hcnt;
vcont <= vcnt;
sel1 <= sel_reg;
sel2 <= sel_reg;
end architecture;
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2025-6-27 07:47 , Processed in 0.063065 second(s), 20 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表