使用双端口ram(FPGA)从不同时钟域传输数据

时间:2018-06-15 17:22:08

标签: vhdl fpga intel-fpga

我想将帧从143 Mhz时钟域传输到49 Mhz时钟域,以通过VGA查看帧。对于测试,我尝试传输垂直和水平白线以通过VGA端口进行查看。但我说得不对。

我的期望是:

(点击放大)

但我得到的是:

(点击放大)

我不知道我做错了什么。我被困在这里。如果有人可以帮助我,那就太好了。

(所有VHD文件都已上传,顶层是“fifo.vhd”。我正在使用的是DE1-SoC)

FIFO:

**library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;


entity fifo is
port(
clk : in std_logic;
HS,VS,VGACLK : out std_logic;
R,G,B : out std_logic_vector(7 downto 0));
end fifo;

architecture main of fifo is 
-----------signals----------------------
signal clk_49,clk_143 : std_logic;
signal datain, dataout : std_logic_vector(7 downto 0);
signal addr2,addr1 : integer range 0 to 2047 := 0;
signal hpos,vpos : integer range 0 to 2047 := 0;
---------------------------------------------------
component pll is
        port (
            clk_clk       : in  std_logic := 'X'; -- clk
            reset_reset_n : in  std_logic := 'X'; -- reset_n
            clk_49_clk    : out std_logic;        -- clk
            clk_143_clk   : out std_logic         -- clk
        );
end component pll;

component simple_dual_port_ram_dual_clock is
    port 
    (
        rclk    : in std_logic;
        wclk    : in std_logic;
        raddr   : in natural range 0 to 2047;
        waddr   : in natural range 0 to 2047;
        data    : in std_logic_vector(7 downto 0);
        we      : in std_logic := '1';
        q       : out std_logic_vector(7 downto 0)
    );
end component simple_dual_port_ram_dual_clock;

component sync is
    port(
        clk : in std_logic;
        data : in std_logic_vector(7 downto 0);
        hsync, vsync: out std_logic;
        R,G,B : out std_logic_vector(7 downto 0)
    );
end component sync;

begin
VGACLK <= clk_49;

u2 : component sync
          port map (clk_49,dataout,HS,VS,R,G,B);

u0 : component pll
        port map (
            clk_clk       => clk,         --     clk.clk
            reset_reset_n => '1',         --   reset.reset_n
            clk_49_clk    => clk_49,      --  clk_49.clk
            clk_143_clk   => clk_143       -- clk_143.clk
        ); 
u1 : component simple_dual_port_ram_dual_clock
        port map (clk_143,clk_49,addr2,addr1,datain,'1',dataout);  


process(clk_143)
begin
if(clk'event and clk='1') then
-------loop-----------------
    if(hpos<1055)then 
    hpos<=hpos+1;
    else
    hpos<=0;
        if(vpos<625)then
            vpos<=vpos+1;
            else
            vpos<=0;
        end if;
    end if;
------------------------------
    if (addr1 = addr2) then
    ------do nothing-------------
    else
        if(hpos = 600 or vpos = 300) then
            datain<= (others=> '1');
        else
            datain<= (others=> '0');
        end if;
        addr1 <= addr1 + 1;
        if(addr1 = 1055)then
            addr1<=0;
        end if;
    end if; 
end if;
end process;

process(clk_49)
begin
if(clk'event and clk='1') then
    addr2 <= addr2 + 1;
    if(addr2 = 1055)then
        addr2<=0;
    end if; 
end if;
end process;

end main;**

RAM:

-- Quartus Prime VHDL Template
-- Simple Dual-Port RAM with different read/write addresses and
-- different read/write clock

library ieee;
use ieee.std_logic_1164.all;

entity simple_dual_port_ram_dual_clock is

    generic 
    (
        DATA_WIDTH : natural := 8;
        ADDR_WIDTH : natural := 11
    );

    port 
    (
        rclk    : in std_logic;
        wclk    : in std_logic;
        raddr   : in natural range 0 to 2**ADDR_WIDTH - 1;
        waddr   : in natural range 0 to 2**ADDR_WIDTH - 1;
        data    : in std_logic_vector((DATA_WIDTH-1) downto 0);
        we      : in std_logic := '1';
        q       : out std_logic_vector((DATA_WIDTH -1) downto 0)
    );

end simple_dual_port_ram_dual_clock;

architecture rtl of simple_dual_port_ram_dual_clock is

    -- Build a 2-D array type for the RAM
    subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0);
    type memory_t is array(2**ADDR_WIDTH-1 downto 0) of word_t;

    -- Declare the RAM signal.  
    signal ram : memory_t;

begin

    process(wclk)
    begin
    if(rising_edge(wclk)) then 
        if(we = '1') then
            ram(waddr) <= data;
        end if;
    end if;
    end process;

    process(rclk)
    begin
    if(rising_edge(rclk)) then 
        q <= ram(raddr);
    end if;
    end process;

end rtl;

同步:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity sync is
port(
clk : in std_logic;
data : in std_logic_vector(7 downto 0);
hsync, vsync: out std_logic;
R,G,B : out std_logic_vector(7 downto 0));
end sync;

architecture main of sync is
signal hpos : integer range 0 to 1055:=0;
signal vpos : integer range 0 to 625:=0;
begin
process(clk)
begin
if(clk'event and clk='1')then
-----------------------------------
--loop-----------------------------
    if(hpos<1055)then 
    hpos<=hpos+1;
    else
    hpos<=0;
        if(vpos<625)then
            vpos<=vpos+1;
            else
            vpos<=0;
        end if;
    end if;
--------------------------------------
--SYNC-----------------------------------
   if(hpos<80)then
        hsync<='0';
        else
        hsync<='1';
    end if;
   if(vpos<3)then
        vsync<='0';
        else
        vsync<='1';
    end if;
--------------------------------------  
   if((hpos<240)or(hpos>1040)or(vpos<24)or(vpos>623))then
    R<=(OTHERS=>'0');
    G<=(OTHERS=>'0');
    B<=(OTHERS=>'0');
    else
    R<=data;
    G<=data;
    B<=data;
    end if;
----------------------------
end if;
end process;
end main;

0 个答案:

没有答案