各位大神,我想写一个乒乓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; |