Newer
Older

Eric Kooistra
committed
--------------------------------------------------------------------------------
--
-- Copyright (C) 2014
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
--------------------------------------------------------------------------------
LIBRARY IEEE, technology_lib, tech_ddr_lib, common_lib, dp_lib;
USE IEEE.STD_LOGIC_1164.ALL;
USE common_lib.common_pkg.ALL;
USE technology_lib.technology_select_pkg.ALL;
USE technology_lib.technology_pkg.ALL;
USE tech_ddr_lib.tech_ddr_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
ENTITY io_ddr IS
GENERIC(
g_technology : NATURAL := c_tech_select_default;
g_tech_ddr : t_c_tech_ddr;
g_wr_data_w : NATURAL := 32;
g_wr_use_ctrl : BOOLEAN := FALSE; -- TRUE to allow filling the write FIFO by disabling flush after an EOP
g_wr_fifo_depth : NATURAL := 128; -- >=16 AND >g_tech_ddr.maxburstsize, defined at DDR side of the FIFO.
g_rd_fifo_depth : NATURAL := 256; -- >=16 AND >g_tech_ddr.maxburstsize, defined at DDR side of the FIFO.
g_rd_data_w : NATURAL := 32;

Eric Kooistra
committed
g_flush_mode : STRING := "VAL"; -- "VAL", "SOP", "SYN"
g_flush_use_channel : BOOLEAN := FALSE;
g_flush_start_channel : NATURAL := 0;
g_flush_nof_channels : POSITIVE := 1

Eric Kooistra
committed
);

Eric Kooistra
committed
PORT (
-- DDR reference clock

Eric Kooistra
committed
ctlr_ref_clk : IN STD_LOGIC;
ctlr_ref_rst : IN STD_LOGIC;

Eric Kooistra
committed
-- DDR controller clock domain
ctlr_clk_out : OUT STD_LOGIC;
ctlr_rst_out : OUT STD_LOGIC;
ctlr_clk_in : IN STD_LOGIC; -- connect ctlr_clk_out to ctlr_clk_in at top level to avoid potential delta-cycle differences between the same clock
ctlr_rst_in : IN STD_LOGIC; -- connect ctlr_rst_out to ctlr_rst_in at top level

Eric Kooistra
committed
ctlr_init_done : OUT STD_LOGIC;
ctlr_rdy : OUT STD_LOGIC;
dvr_en : IN STD_LOGIC;
dvr_wr_not_rd : IN STD_LOGIC;
dvr_start_addr : IN t_tech_ddr_addr;
dvr_end_addr : IN t_tech_ddr_addr;

Eric Kooistra
committed
dvr_done : OUT STD_LOGIC;
dvr_flush_en : IN STD_LOGIC := '0';

Eric Kooistra
committed
dvr_wr_fifo_usedw : OUT STD_LOGIC_VECTOR(ceil_log2(g_wr_fifo_depth * (func_tech_ddr_ctlr_data_w(g_tech_ddr)/g_wr_data_w) )-1 DOWNTO 0); -- for monitoring purposes

Eric Kooistra
committed

Eric Kooistra
committed
-- Write FIFO clock domain

Eric Kooistra
committed
wr_clk : IN STD_LOGIC;
wr_rst : IN STD_LOGIC;
wr_sosi : IN t_dp_sosi;
wr_siso : OUT t_dp_siso;

Eric Kooistra
committed
-- Read FIFO clock domain
rd_clk : IN STD_LOGIC;
rd_rst : IN STD_LOGIC;

Eric Kooistra
committed
rd_sosi : OUT t_dp_sosi;
rd_siso : IN t_dp_siso;

Eric Kooistra
committed
rd_fifo_usedw : OUT STD_LOGIC_VECTOR(ceil_log2(g_rd_fifo_depth * (func_tech_ddr_ctlr_data_w(g_tech_ddr)/g_rd_data_w) )-1 DOWNTO 0);

Eric Kooistra
committed

Eric Kooistra
committed
-- DDR PHY external interface

Eric Kooistra
committed
phy_in : IN t_tech_ddr_phy_in;
phy_io : INOUT t_tech_ddr_phy_io;
phy_ou : OUT t_tech_ddr_phy_ou
);
END io_ddr;
ARCHITECTURE str OF io_ddr IS
CONSTANT c_ctlr_data_w : NATURAL := func_tech_ddr_ctlr_data_w(g_tech_ddr);
CONSTANT c_wr_fifo_depth : NATURAL := g_wr_fifo_depth * (c_ctlr_data_w/g_wr_data_w); -- get FIFO depth at write side
CONSTANT c_wr_fifo_af_margin : NATURAL := 4 + 1; -- use +1 to compensate for latency introduced by registering wr_siso.ready due to RL=0
CONSTANT c_rd_fifo_af_margin : NATURAL := 4 + g_tech_ddr.maxburstsize; -- use ctlr_rd_src_in.ready to only start new rd access when there is sufficient space in the read FIFO

Eric Kooistra
committed
SIGNAL i_ctlr_init_done : STD_LOGIC;
SIGNAL i_dvr_done : STD_LOGIC;
SIGNAL ctlr_mosi : t_tech_ddr_mosi := c_tech_ddr_mosi_rst;
SIGNAL ctlr_miso : t_tech_ddr_miso := c_tech_ddr_miso_rst;
SIGNAL wr_flush : STD_LOGIC := '0';

Eric Kooistra
committed

Eric Kooistra
committed
SIGNAL wr_fifo_src_in : t_dp_siso;
SIGNAL wr_fifo_src_out : t_dp_sosi := c_dp_sosi_rst;
SIGNAL ctlr_wr_snk_out : t_dp_siso := c_dp_siso_rdy; -- default xon='1'
SIGNAL ctlr_wr_snk_in : t_dp_sosi := c_dp_sosi_rst;

Eric Kooistra
committed
SIGNAL ctlr_rd_src_in : t_dp_siso;
SIGNAL ctlr_rd_src_out : t_dp_sosi := c_dp_sosi_rst;

Eric Kooistra
committed
SIGNAL wr_fifo_usedw : STD_LOGIC_VECTOR(ceil_log2(g_wr_fifo_depth)-1 DOWNTO 0); -- read side depth of the write FIFO
BEGIN
ctlr_init_done <= i_ctlr_init_done;
ctlr_rdy <= ctlr_miso.waitrequest_n;

Eric Kooistra
committed
dvr_done <= i_dvr_done;

Eric Kooistra
committed
dvr_wr_fifo_usedw <= wr_fifo_usedw;

Eric Kooistra
committed
u_wr_fifo : ENTITY dp_lib.dp_fifo_dc_mixed_widths
GENERIC MAP (
g_wr_data_w => g_wr_data_w,
g_rd_data_w => c_ctlr_data_w,

Eric Kooistra
committed
g_use_ctrl => g_wr_use_ctrl,
g_wr_fifo_size => c_wr_fifo_depth,
g_wr_fifo_af_margin => c_wr_fifo_af_margin,

Eric Kooistra
committed
g_rd_fifo_rl => 0
)
PORT MAP (
wr_rst => wr_rst,
wr_clk => wr_clk,

Eric Kooistra
committed
rd_rst => ctlr_rst_in,
rd_clk => ctlr_clk_in,

Eric Kooistra
committed
snk_out => wr_siso,
snk_in => wr_sosi,
wr_usedw => OPEN,
rd_usedw => wr_fifo_usedw,
rd_emp => OPEN,

Eric Kooistra
committed
src_in => wr_fifo_src_in,
src_out => wr_fifo_src_out

Eric Kooistra
committed
);
u_dp_flush : ENTITY dp_lib.dp_flush

Eric Kooistra
committed
GENERIC MAP (
g_ready_latency => 0,
g_framed_xon => g_wr_use_ctrl, -- stop flushing when wr_flush is low and a sop has arrived
g_framed_xoff => FALSE -- immediately start flushing when wr_flush goes high

Eric Kooistra
committed
)
PORT MAP (

Eric Kooistra
committed
rst => ctlr_rst_in,
clk => ctlr_clk_in,

Eric Kooistra
committed

Eric Kooistra
committed
snk_in => wr_fifo_src_out,
snk_out => wr_fifo_src_in,

Eric Kooistra
committed
src_out => ctlr_wr_snk_in,
src_in => ctlr_wr_snk_out,

Eric Kooistra
committed
flush_en => wr_flush

Eric Kooistra
committed
);
u_io_ddr_driver_flush_ctrl : ENTITY work.io_ddr_driver_flush_ctrl
GENERIC MAP (
g_mode => g_flush_mode,
g_use_channel => g_flush_use_channel,
g_start_channel => g_flush_start_channel,
g_nof_channels => g_flush_nof_channels
)
PORT MAP (

Eric Kooistra
committed
rst => ctlr_rst_in,
clk => ctlr_clk_in,
dvr_flush_en => dvr_flush_en,
dvr_en => dvr_en,
dvr_wr_not_rd => dvr_wr_not_rd,
dvr_done => i_dvr_done,

Eric Kooistra
committed
wr_sosi => wr_fifo_src_out,
wr_flush => wr_flush
);

Eric Kooistra
committed
u_rd_fifo : ENTITY dp_lib.dp_fifo_dc_mixed_widths
GENERIC MAP (
g_wr_data_w => c_ctlr_data_w,

Eric Kooistra
committed
g_rd_data_w => g_rd_data_w,
g_use_ctrl => FALSE,
g_wr_fifo_size => g_rd_fifo_depth,
g_wr_fifo_af_margin => c_rd_fifo_af_margin, -- >=4 (required by dp_fifo)

Eric Kooistra
committed
g_rd_fifo_rl => 1
)
PORT MAP (

Eric Kooistra
committed
wr_rst => ctlr_rst_in,
wr_clk => ctlr_clk_in,

Eric Kooistra
committed
rd_rst => rd_rst,
rd_clk => rd_clk,
snk_out => ctlr_rd_src_in,
snk_in => ctlr_rd_src_out,

Eric Kooistra
committed
wr_usedw => OPEN,
rd_usedw => rd_fifo_usedw,
rd_emp => OPEN,
src_in => rd_siso,
src_out => rd_sosi
);
u_io_ddr_driver : ENTITY work.io_ddr_driver
GENERIC MAP (
g_tech_ddr => g_tech_ddr

Eric Kooistra
committed
)
PORT MAP (

Eric Kooistra
committed
rst => ctlr_rst_in,
clk => ctlr_clk_in,

Eric Kooistra
committed
dvr_en => dvr_en,
dvr_wr_not_rd => dvr_wr_not_rd,
dvr_start_addr => dvr_start_addr,
dvr_end_addr => dvr_end_addr,

Eric Kooistra
committed
dvr_done => i_dvr_done,
wr_fifo_usedw => wr_fifo_usedw,
wr_snk_in => ctlr_wr_snk_in,

Eric Kooistra
committed
wr_snk_out => ctlr_wr_snk_out,

Eric Kooistra
committed
rd_src_out => ctlr_rd_src_out,
rd_src_in => ctlr_rd_src_in,

Eric Kooistra
committed
ctlr_init_done => i_ctlr_init_done,
ctlr_miso => ctlr_miso,
ctlr_mosi => ctlr_mosi

Eric Kooistra
committed
);
u_tech_ddr : ENTITY tech_ddr_lib.tech_ddr
GENERIC MAP (
g_technology => g_technology,
g_tech_ddr => g_tech_ddr
)
PORT MAP (
-- PLL reference clock
ctlr_ref_clk => ctlr_ref_clk,
ctlr_ref_rst => ctlr_ref_rst,
-- Controller user interface

Eric Kooistra
committed
ctlr_gen_clk => ctlr_clk_out,
ctlr_gen_rst => ctlr_rst_out,
ctlr_gen_clk_2x => OPEN,
ctlr_gen_rst_2x => OPEN,
ctlr_init_done => i_ctlr_init_done,
ctrl_mosi => ctlr_mosi,
ctrl_miso => ctlr_miso,
-- PHY interface
phy_in => phy_in,
phy_io => phy_io,
phy_ou => phy_ou
);