hdet/fpga/src/vendor/xilinx/atlys_ddr2/ddr2/example_design/rtl/traffic_gen/read_posted_fifo.vhd

340 lines
12 KiB
VHDL
Executable File

--*****************************************************************************
-- (c) Copyright 2009 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--
--*****************************************************************************
-- ____ ____
-- / /\/ /
-- /___/ \ / Vendor: Xilinx
-- \ \ \/ Version: %version
-- \ \ Application: MIG
-- / / Filename: read_posted_fifo.vhd
-- /___/ /\ Date Last Modified: $Date: 2011/06/02 07:16:40 $
-- \ \ / \ Date Created: Jul 03 2009
-- \___\/\___\
--
-- Device: Spartan6
-- Design Name: DDR/DDR2/DDR3/LPDDR
-- Purpose: This module instantiated by read_data_path module and sits between
-- mcb_flow_control module and read_data_gen module to buffer up the
-- commands that has sent to memory controller.
-- Reference:
-- Revision History:
--*****************************************************************************
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
entity read_posted_fifo is
generic (
TCQ : time := 100 ps;
MEM_BURST_LEN : integer := 4;
FAMILY : string := "SPARTAN6";
ADDR_WIDTH : integer := 32;
BL_WIDTH : integer := 6
);
port (
clk_i : in std_logic;
rst_i : in std_logic;
cmd_rdy_o : out std_logic;
cmd_valid_i : in std_logic;
data_valid_i : in std_logic;
addr_i : in std_logic_vector(ADDR_WIDTH - 1 downto 0);
bl_i : in std_logic_vector(BL_WIDTH - 1 downto 0);
user_bl_cnt_is_1 : in std_logic;
cmd_sent : in std_logic_vector(2 downto 0);
bl_sent : in std_logic_vector(5 downto 0);
cmd_en_i : in std_logic;
gen_rdy_i : in std_logic;
gen_valid_o : out std_logic;
gen_addr_o : out std_logic_vector(ADDR_WIDTH - 1 downto 0);
gen_bl_o : out std_logic_vector(BL_WIDTH - 1 downto 0);
rd_buff_avail_o : out std_logic_vector(6 downto 0);
rd_mdata_fifo_empty : in std_logic;
rd_mdata_en : out std_logic
);
end entity read_posted_fifo;
architecture trans of read_posted_fifo is
component afifo is
generic (
DSIZE : integer := 32;
FIFO_DEPTH : integer := 16;
ASIZE : integer := 4;
SYNC : integer := 1
);
port (
wr_clk : in std_logic;
rst : in std_logic;
wr_en : in std_logic;
wr_data : in std_logic_vector(DSIZE - 1 downto 0);
rd_en : in std_logic;
rd_clk : in std_logic;
rd_data : out std_logic_vector(DSIZE - 1 downto 0);
full : out std_logic;
empty : out std_logic;
almost_full : out std_logic
);
end component;
signal full : std_logic;
signal empty : std_logic;
signal wr_en : std_logic;
signal rd_en : std_logic;
signal data_valid_r : std_logic;
signal user_bl_cnt_not_1 : std_logic;
signal buf_avail_r : std_logic_vector(6 downto 0);
signal rd_data_received_counts : std_logic_vector(6 downto 0);
signal rd_data_counts_asked : std_logic_vector(6 downto 0);
signal dfifo_has_enough_room : std_logic;
signal wait_cnt : std_logic_vector(1 downto 0);
signal wait_done : std_logic;
signal dfifo_has_enough_room_d1 : std_logic;
signal empty_r : std_logic;
signal rd_first_data : std_logic;
-- current count is 1 and data_is_valie, then next cycle is not 1
-- calculate how many buf still available
-- assign buf_avail = 64 - (rd_data_counts_asked - rd_data_received_counts);
-- signal tmp_buf_avil : std_logic_vector(5 downto 0);
-- X-HDL generated signals
signal xhdl3 : std_logic;
signal xhdl4 : std_logic;
signal xhdl5 : std_logic_vector(37 downto 0);
signal xhdl6 : std_logic_vector(37 downto 0);
-- Declare intermediate signals for referenced outputs
signal cmd_rdy_o_xhdl0 : std_logic;
signal gen_addr_o_xhdl1 : std_logic_vector(ADDR_WIDTH - 1 downto 0);
signal gen_bl_o_xhdl2 : std_logic_vector(BL_WIDTH - 1 downto 0);
begin
-- Drive referenced outputs
cmd_rdy_o <= cmd_rdy_o_xhdl0;
-- gen_addr_o <= gen_addr_o_xhdl1;
-- gen_bl_o <= gen_bl_o_xhdl2;
gen_bl_o <= xhdl6(BL_WIDTH+ADDR_WIDTH-1 downto ADDR_WIDTH);
gen_addr_o <= xhdl6(ADDR_WIDTH-1 downto 0);
rd_mdata_en <= rd_en;
rd_buff_avail_o <= buf_avail_r;
process (clk_i)
begin
if (clk_i'event and clk_i = '1') then
cmd_rdy_o_xhdl0 <= not(full) and dfifo_has_enough_room and wait_done;
end if;
end process;
process (clk_i)
begin
if (clk_i'event and clk_i = '1') then
if (rst_i = '1') then
wait_cnt <= "00";
elsif ((cmd_rdy_o_xhdl0 and cmd_valid_i) = '1') then
wait_cnt <= "10";
elsif (wait_cnt > "00") then
wait_cnt <= wait_cnt - "01";
end if;
end if;
end process;
process (clk_i)
begin
if (clk_i'event and clk_i = '1') then
if (rst_i = '1') then
wait_done <= '1';
elsif ((cmd_rdy_o_xhdl0 and cmd_valid_i) = '1') then
wait_done <= '0';
elsif (wait_cnt = "00") then
wait_done <= '1';
else
wait_done <= '0';
end if;
end if;
end process;
xhdl3 <= '1' when (buf_avail_r >= "0111110") else
'0';
process (clk_i)
begin
if (clk_i'event and clk_i = '1') then
dfifo_has_enough_room <= xhdl3;
dfifo_has_enough_room_d1 <= dfifo_has_enough_room;
end if;
end process;
wr_en <= cmd_valid_i and not(full) and dfifo_has_enough_room_d1 and wait_done;
process (clk_i)
begin
if (clk_i'event and clk_i = '1') then
data_valid_r <= data_valid_i;
end if;
end process;
process (clk_i)
begin
if (clk_i'event and clk_i = '1') then
if ((data_valid_i and user_bl_cnt_is_1) = '1') then
user_bl_cnt_not_1 <= '1';
else
user_bl_cnt_not_1 <= '0';
end if;
end if;
end process;
process (clk_i)
begin
if (clk_i'event and clk_i = '1') then
if (rst_i = '1') then
rd_data_counts_asked <= (others => '0');
elsif (cmd_en_i = '1' and cmd_sent(0) = '1') then
rd_data_counts_asked <= rd_data_counts_asked + (bl_sent + "0000001" );
end if;
end if;
end process;
process (clk_i)
begin
if (clk_i'event and clk_i = '1') then
if (rst_i = '1') then
rd_data_received_counts <= "0000000";
elsif (data_valid_i = '1') then
rd_data_received_counts <= rd_data_received_counts + "0000001";
end if;
end if;
end process;
process (clk_i)
begin
if (clk_i'event and clk_i = '1') then
buf_avail_r <= "1000000" - (rd_data_counts_asked - rd_data_received_counts);
end if;
end process;
process (clk_i)
begin
if (clk_i'event and clk_i = '1') then
empty_r <= empty;
end if;
end process;
process (clk_i)
begin
if (clk_i'event and clk_i = '1') then
if (rst_i = '1') then
rd_first_data <= '0';
elsif ( empty = '0' AND empty_r = '1') then
rd_first_data <= '1';
end if;
end if;
end process;
process (gen_rdy_i, empty,empty_r, data_valid_i, data_valid_r, user_bl_cnt_not_1,rd_mdata_fifo_empty,rd_first_data)
begin
if (FAMILY = "SPARTAN6") then
rd_en <= gen_rdy_i and not(empty);
else
IF (MEM_BURST_LEN = 4) then
rd_en <= (not(empty) and empty_r and not(rd_first_data)) or (not(rd_mdata_fifo_empty) and not(empty)) or
(user_bl_cnt_not_1 and data_valid_i);
ELSE
rd_en <= (data_valid_i and not(data_valid_r)) or (user_bl_cnt_not_1 and data_valid_i);
END IF;
end if;
end process;
gen_valid_o <= not(empty);
-- set the SYNC to 1 because rd_clk = wr_clk to reduce latency
-- xhdl4 <= to_integer(to_stdlogic(BL_WIDTH) + to_stdlogic(ADDR_WIDTH));
xhdl5 <= (bl_i & addr_i);
-- (gen_bl_o_xhdl2, gen_addr_o_xhdl1) <= xhdl6;
rd_fifo : afifo
GENERIC MAP (
DSIZE => (BL_WIDTH + ADDR_WIDTH),--xhdl4,
FIFO_DEPTH => 16,
ASIZE => 4,
SYNC => 1
)
port map (
wr_clk => clk_i,
rst => rst_i,
wr_en => wr_en,
wr_data => xhdl5,
rd_en => rd_en,
rd_clk => clk_i,
rd_data => xhdl6,
full => full,
empty => empty,
almost_full => open
);
end architecture trans;