Select Git revision
serializers.py
-
Nico Vermaas authored
(and to read serializer, not yet to write serializer)
Nico Vermaas authored(and to read serializer, not yet to write serializer)
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
io_ddr_cross_domain.vhd 4.66 KiB
--------------------------------------------------------------------------------
--
-- 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/>.
--
-------------------------------------------------------------------------------
-- Purpose: Cross clock domain between dvr_clk and ctlr_clk
-- Description:
--
-- Remarks:
-- . If the dvr_clk=ctlr_clk then the clock domain crossing logic defaults
-- to wires. However dvr_clk could also be the dp_clk or the mm_clk and then
-- the clock domain crossing logic is needed.
-- No need to cross dvr_start_address and dvr_nof_data, because these
-- are stable when the dvr_en is stable.
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_cross_domain IS
GENERIC (
g_cross_domain : BOOLEAN := TRUE;
g_delay_len : NATURAL := c_meta_delay_len
);
PORT (
-- Driver clock domain
dvr_clk : IN STD_LOGIC;
dvr_rst : IN STD_LOGIC;
dvr_done : OUT STD_LOGIC;
dvr_en : IN STD_LOGIC;
dvr_wr_not_rd : IN STD_LOGIC;
dvr_start_address : IN STD_LOGIC_VECTOR;
dvr_nof_data : IN STD_LOGIC_VECTOR;
dvr_wr_flush_en : IN STD_LOGIC := '0';
-- DDR controller clock domain
ctlr_clk : IN STD_LOGIC;
ctlr_rst : IN STD_LOGIC;
ctlr_dvr_done : IN STD_LOGIC;
ctlr_dvr_en : OUT STD_LOGIC;
ctlr_dvr_wr_not_rd : OUT STD_LOGIC;
ctlr_dvr_start_address : OUT STD_LOGIC_VECTOR;
ctlr_dvr_nof_data : OUT STD_LOGIC_VECTOR;
ctlr_dvr_wr_flush_en : OUT STD_LOGIC := '0'
);
END io_ddr_cross_domain;
ARCHITECTURE str OF io_ddr_cross_domain IS
SIGNAL dvr_en_busy : STD_LOGIC;
SIGNAL new_dvr_done : STD_LOGIC;
BEGIN
no_cross : IF g_cross_domain=FALSE GENERATE
-- dvr_clk --> ctlr_clk
ctlr_dvr_en <= dvr_en;
ctlr_dvr_wr_not_rd <= dvr_wr_not_rd;
ctlr_dvr_start_address <= dvr_start_address;
ctlr_dvr_nof_data <= dvr_nof_data;
ctlr_dvr_wr_flush_en <= dvr_wr_flush_en;
-- ctlr_clk --> dvr_clk
dvr_done <= ctlr_dvr_done;
END GENERATE;
gen_cross : IF g_cross_domain=TRUE GENERATE
-- dvr_clk --> ctlr_clk
u_common_spulse_ctlr_dvr_en : ENTITY common_lib.common_spulse
GENERIC MAP (
g_delay_len => g_delay_len
)
PORT MAP (
in_rst => dvr_rst,
in_clk => dvr_clk,
in_pulse => dvr_en,
in_busy => dvr_en_busy,
out_rst => ctlr_rst,
out_clk => ctlr_clk,
out_pulse => ctlr_dvr_en
);
-- Only register into the other clock domain
ctlr_dvr_wr_not_rd <= dvr_wr_not_rd WHEN rising_edge(ctlr_clk);
ctlr_dvr_start_address <= dvr_start_address WHEN rising_edge(ctlr_clk);
ctlr_dvr_nof_data <= dvr_nof_data WHEN rising_edge(ctlr_clk);
u_common_spulse_ctlr_dvr_wr_flush_en : ENTITY common_lib.common_spulse
GENERIC MAP (
g_delay_len => g_delay_len
)
PORT MAP (
in_rst => dvr_rst,
in_clk => dvr_clk,
in_pulse => dvr_wr_flush_en,
out_rst => ctlr_rst,
out_clk => ctlr_clk,
out_pulse => ctlr_dvr_wr_flush_en
);
-- ctlr_clk --> dvr_clk
u_common_async_dvr_done : ENTITY common_lib.common_async
GENERIC MAP (
g_rst_level => '0',
g_delay_len => g_delay_len
)
PORT MAP (
rst => dvr_rst,
clk => dvr_clk,
din => ctlr_dvr_done,
dout => new_dvr_done
);
-- Ensure previous dvr_done goes low after new dvr_en
dvr_done <= new_dvr_done AND NOT dvr_en_busy;
END GENERATE;
END str;