Skip to content
Snippets Groups Projects
Commit 95cc27d9 authored by Pepping's avatar Pepping
Browse files

copy + added ddr_ref_clk en ddr_gen_clk

parent ab437259
No related branches found
No related tags found
No related merge requests found
--------------------------------------------------------------------------------
--
-- Copyright (C) 2011
-- 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, common_lib, dp_lib, ss_lib;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE work.ddr3_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
ENTITY ddr3_transpose IS
GENERIC(
g_sim : BOOLEAN := FALSE;
g_nof_streams : NATURAL := 4;
g_in_dat_w : NATURAL := 8;
g_frame_size_in : NATURAL := 256;
g_frame_size_out : NATURAL := 256;
g_nof_blk_per_sync : NATURAL := 16;
g_use_complex : BOOLEAN := TRUE;
g_ena_pre_transp : BOOLEAN := TRUE;
g_phy : NATURAL := 1; -- 0: ALTMEMPHY 1: UNIPHY_MASTER 2: UNIPHY_SLAVE
g_mts : NATURAL := 800; -- Megatransfers per second
g_ddr3_seq : t_ddr3_seq := c_ddr3_seq;
g_select_file : STRING := "UNUSED"
);
PORT (
mm_rst : IN STD_LOGIC; -- reset synchronous with mm_clk
mm_clk : IN STD_LOGIC; -- memory-mapped bus clock
dp_ref_clk : IN STD_LOGIC;
dp_ref_rst : IN STD_LOGIC;
dp_clk : IN STD_LOGIC;
dp_rst : IN STD_LOGIC;
dp_out_clk : OUT STD_LOGIC;
dp_out_rst : OUT STD_LOGIC;
-- ST sinks
snk_out_arr : OUT t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
snk_in_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
-- ST source
src_in_arr : IN t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
src_out_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
-- Memory Mapped
ram_ss_ss_transp_mosi : IN t_mem_mosi; -- channel select control
ram_ss_ss_transp_miso : OUT t_mem_miso;
ser_term_ctrl_out : OUT STD_LOGIC_VECTOR(13 DOWNTO 0);
par_term_ctrl_out : OUT STD_LOGIC_VECTOR(13 DOWNTO 0);
ser_term_ctrl_in : IN STD_LOGIC_VECTOR(13 DOWNTO 0) := (OTHERS => '0');
par_term_ctrl_in : IN STD_LOGIC_VECTOR(13 DOWNTO 0) := (OTHERS => '0');
phy_in : IN t_ddr3_phy_in;
phy_io : INOUT t_ddr3_phy_io;
phy_ou : OUT t_ddr3_phy_ou
);
END ddr3_transpose;
ARCHITECTURE str OF ddr3_transpose IS
CONSTANT c_min_fifo_size : POSITIVE := 256;
CONSTANT c_blocksize : POSITIVE := g_ddr3_seq.wr_nof_chunks * g_ddr3_seq.wr_chunksize;
CONSTANT c_wr_fifo_depth : NATURAL := sel_a_b(c_blocksize > c_min_fifo_size, c_blocksize, c_min_fifo_size);--c_blocksize * 2;
CONSTANT c_rd_fifo_depth : NATURAL := sel_a_b(c_blocksize > c_min_fifo_size, c_blocksize, c_min_fifo_size);--c_blocksize * 2;
CONSTANT c_total_data_w : NATURAL := g_nof_streams*g_in_dat_w;
CONSTANT c_complex_data_w : NATURAL := c_total_data_w*c_nof_complex;
CONSTANT c_data_w : NATURAL := sel_a_b(g_use_complex, c_complex_data_w, c_total_data_w);
CONSTANT c_nof_ch_in : NATURAL := g_frame_size_in*g_ddr3_seq.rd_chunksize;
CONSTANT c_nof_ch_sel : NATURAL := c_nof_ch_in;
CONSTANT c_cnt_sop_w : NATURAL := ceil_log2(g_nof_blk_per_sync)+1;
SIGNAL ss_in_sosi : t_dp_sosi;
SIGNAL ss_in_siso : t_dp_siso;
-- ctrl & status DDR3 driver
SIGNAL dvr_start_addr : t_ddr3_addr;
SIGNAL dvr_end_addr : t_ddr3_addr;
SIGNAL dvr_en : STD_LOGIC;
SIGNAL dvr_wr_not_rd : STD_LOGIC;
SIGNAL dvr_done : STD_LOGIC;
SIGNAL flush_ena : STD_LOGIC;
-- DDR3 controller status
SIGNAL ctlr_init_done : STD_LOGIC;
SIGNAL ctlr_rdy : STD_LOGIC;
SIGNAL init_done_data_start : STD_LOGIC;
SIGNAL transpose_in_sosi : t_dp_sosi;
SIGNAL transpose_in_siso : t_dp_siso;
SIGNAL transpose_out_sosi : t_dp_sosi;
SIGNAL block_gen_out_sosi : t_dp_sosi;
SIGNAL pipeline_out_sosi : t_dp_sosi;
SIGNAL sync_bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0);
SIGNAL wr_req : STD_LOGIC;
SIGNAL rd_req_i : STD_LOGIC;
SIGNAL rd_dat_i : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0);
SIGNAL rd_val_i : STD_LOGIC;
SIGNAL cnt_sop : STD_LOGIC_VECTOR(c_cnt_sop_w-1 DOWNTO 0);
SIGNAL nof_sop : STD_LOGIC_VECTOR(c_cnt_sop_w-1 DOWNTO 0);
SIGNAL i_mon_nof_sop : STD_LOGIC_VECTOR(c_cnt_sop_w-1 DOWNTO 0);
SIGNAL nxt_mon_nof_sop : STD_LOGIC_VECTOR(c_cnt_sop_w-1 DOWNTO 0);
SIGNAL sync_ok_in : STD_LOGIC;
SIGNAL sync_ok_out : STD_LOGIC;
BEGIN
g_merge_in_complex : IF g_use_complex = TRUE GENERATE
PROCESS(snk_in_arr)
BEGIN
ss_in_sosi <= snk_in_arr(0);
FOR i IN 0 TO g_nof_streams-1 LOOP
ss_in_sosi.data((2*i+1)*g_in_dat_w-1 DOWNTO 2*i*g_in_dat_w) <= snk_in_arr(i).re(g_in_dat_w-1 DOWNTO 0);
ss_in_sosi.data((2*i+2)*g_in_dat_w-1 DOWNTO (2*i+1)*g_in_dat_w) <= snk_in_arr(i).im(g_in_dat_w-1 DOWNTO 0);
END LOOP;
END PROCESS;
END GENERATE;
-- g_merge_in_data : IF g_use_complex = FALSE GENERATE
-- merge_input : PROCESS(snk_in_arr)
-- BEGIN
-- transpose_in_sosi <= snk_in_arr(0);
-- FOR i IN 0 TO g_nof_streams-1 LOOP
-- transpose_in_sosi.data((i+1)*g_in_dat_w-1 DOWNTO i*g_in_dat_w) <= snk_in_arr(i).data(g_in_dat_w-1 DOWNTO 0);
-- END LOOP;
-- END PROCESS;
-- END GENERATE;
gen_pre_transpose : IF g_ena_pre_transp = TRUE GENERATE
u_single_ss : ENTITY ss_lib.ss
GENERIC MAP (
g_dsp_data_w => c_total_data_w,
g_nof_ch_in => c_nof_ch_in,
g_nof_ch_sel => c_nof_ch_sel,
g_select_file_name => g_select_file,
g_use_complex => FALSE
)
PORT MAP (
mm_rst => mm_rst,
mm_clk => mm_clk,
dp_rst => dp_rst,
dp_clk => dp_clk,
-- Memory Mapped
ram_ss_ss_mosi => ram_ss_ss_transp_mosi,
ram_ss_ss_miso => ram_ss_ss_transp_miso,
-- Streaming
input_sosi => ss_in_sosi,
input_siso => ss_in_siso,
output_sosi => transpose_in_sosi,
output_siso => transpose_in_siso
);
END GENERATE;
gen_not_pre_transpose : IF g_ena_pre_transp = FALSE GENERATE
transpose_in_sosi <= ss_in_sosi;
ss_in_siso <= transpose_in_siso;
END GENERATE;
g_siso : FOR J IN 0 TO g_nof_streams-1 GENERATE
snk_out_arr(J) <= ss_in_siso;
END GENERATE;
u_ddr3: ENTITY work.ddr3
GENERIC MAP(
g_ddr => c_ddr3_phy_4g,
g_phy => g_phy,
g_mts => g_mts,
g_wr_data_w => c_data_w,
g_wr_use_ctrl => TRUE,
g_wr_fifo_depth => c_wr_fifo_depth,
g_rd_fifo_depth => c_rd_fifo_depth,
g_rd_data_w => c_data_w,
g_flush_wr_fifo => TRUE,
g_flush_ext_ena => TRUE,
g_flush_sop => TRUE,
g_flush_sop_sync => TRUE,
g_flush_sop_channel => FALSE,
g_flush_sop_start_channel => 0,
g_flush_nof_channels => 0
)
PORT MAP (
ctlr_ref_clk => dp_ref_clk,
ctlr_rst => dp_ref_rst,
phy_in => phy_in,
phy_io => phy_io,
phy_ou => phy_ou,
ctlr_gen_clk => dp_out_clk,
ctlr_gen_rst => dp_out_rst,
ctlr_init_done => ctlr_init_done,
ctlr_rdy => ctlr_rdy,
dvr_start_addr => dvr_start_addr,
dvr_end_addr => dvr_end_addr,
dvr_done => dvr_done,
dvr_wr_not_rd => dvr_wr_not_rd,
dvr_en => dvr_en,
wr_clk => dp_clk,
wr_rst => dp_rst,
wr_sosi => transpose_in_sosi,
wr_siso => transpose_in_siso,
flush_ena => flush_ena,
rd_sosi => transpose_out_sosi,
rd_siso => src_in_arr(0),
rd_clk => dp_clk,
rd_rst => dp_rst,
ser_term_ctrl_out => ser_term_ctrl_out,
par_term_ctrl_out => par_term_ctrl_out,
ser_term_ctrl_in => ser_term_ctrl_in,
par_term_ctrl_in => par_term_ctrl_in,
rd_fifo_usedw => OPEN
);
flush_ena <= NOT(ctlr_init_done) OR NOT(sync_ok_out);
init_done_data_start <= ctlr_init_done AND transpose_in_sosi.sync;
u_ddr3_sequencer: ENTITY work.ddr3_seq
GENERIC MAP(
g_ddr => c_ddr3_phy_4g,
g_ddr3_seq => g_ddr3_seq
)
PORT MAP (
dp_rst => dp_rst,
dp_clk => dp_clk,
en_evt => dvr_en,
wr_not_rd => dvr_wr_not_rd,
start_addr => dvr_start_addr,
end_addr => dvr_end_addr,
done => dvr_done,
init_done => init_done_data_start,
ctlr_rdy => ctlr_rdy,
sync_ok_in => sync_ok_in,
sync_ok_out => sync_ok_out
);
u_cnt_sop : ENTITY common_lib.common_counter
GENERIC MAP (
g_width => c_cnt_sop_w
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
cnt_clr => transpose_in_sosi.sync,
cnt_en => transpose_in_sosi.sop,
count => cnt_sop
);
nof_sop <= INCR_UVEC(cnt_sop, 1); -- +1 because the sop at the sync also counts
nxt_mon_nof_sop <= nof_sop WHEN transpose_in_sosi.sync='1' ELSE i_mon_nof_sop;
sync_ok_in <= '1' WHEN TO_UINT(i_mon_nof_sop) = g_nof_blk_per_sync AND TO_UINT(nof_sop) <= g_nof_blk_per_sync ELSE '0';
p_clk : PROCESS(dp_rst, dp_clk)
BEGIN
IF dp_rst = '1' THEN
i_mon_nof_sop <= (OTHERS=>'0');
ELSIF rising_edge(dp_clk) THEN
i_mon_nof_sop <= nxt_mon_nof_sop;
END IF;
END PROCESS;
---------------------------------------------------------------
-- FIFO FOR SYNC-BSN
---------------------------------------------------------------
wr_req <= snk_in_arr(0).sync AND ctlr_init_done;
u_sync_bsn_fifo : ENTITY common_lib.common_fifo_sc
GENERIC MAP (
g_use_lut => TRUE, -- Make this FIFO in logic, since it's only 2 words deep.
g_reset => FALSE,
g_init => FALSE,
g_dat_w => c_dp_stream_bsn_w,
g_nof_words => 16
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
wr_dat => snk_in_arr(0).bsn,
wr_req => wr_req,
wr_ful => OPEN ,
rd_dat => rd_dat_i,
rd_req => rd_req_i,
rd_emp => open,
rd_val => rd_val_i,
usedw => OPEN
);
---------------------------------------------------------------
-- CREATE READ-AHEAD FIFO INTERFACE FOR SYNC-BSN
---------------------------------------------------------------
u_fifo_adapter : ENTITY common_lib.common_fifo_rd
GENERIC MAP (
g_dat_w => c_dp_stream_bsn_w
)
PORT MAP(
rst => dp_rst,
clk => dp_clk,
-- ST sink: RL = 1
fifo_req => rd_req_i,
fifo_dat => rd_dat_i,
fifo_val => rd_val_i,
-- ST source: RL = 0
rd_req => block_gen_out_sosi.sync,
rd_dat => sync_bsn,
rd_val => OPEN
);
-----------------------
-- Pipeline
-----------------------
u_dp_pipeline : ENTITY dp_lib.dp_pipeline
GENERIC MAP(
g_pipeline => 1
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
-- ST sink
snk_out => OPEN,
snk_in => transpose_out_sosi,
-- ST source
src_in => OPEN,
src_out => pipeline_out_sosi
);
--------------------
-- DP BLOCK GEN (providing sop/eop)
--------------------
u_dp_block_gen : ENTITY dp_lib.dp_block_gen
GENERIC MAP(
g_use_src_in => FALSE,
g_nof_data => g_frame_size_out,
g_nof_blk_per_sync => g_nof_blk_per_sync,
g_empty => 0,
g_channel => 0,
g_error => 0
)
PORT MAP(
rst => dp_rst,
clk => dp_clk,
snk_in => transpose_out_sosi,
-- Use incoming data to generate more data
src_in => c_dp_siso_rdy,
src_out => block_gen_out_sosi,
en => '1'
);
g_merge_out_complex : IF g_use_complex = TRUE GENERATE
gen_merge_out : PROCESS(block_gen_out_sosi, pipeline_out_sosi)
BEGIN
FOR i IN 0 TO g_nof_streams-1 LOOP
src_out_arr(i) <= block_gen_out_sosi;
src_out_arr(i).valid <= pipeline_out_sosi.valid;
src_out_arr(i).re <= RESIZE_DP_DSP_DATA(pipeline_out_sosi.data((2*i+1)*g_in_dat_w-1 DOWNTO 2*i*g_in_dat_w));
src_out_arr(i).im <= RESIZE_DP_DSP_DATA(pipeline_out_sosi.data((2*i+2)*g_in_dat_w-1 DOWNTO (2*i+1)*g_in_dat_w));
IF (block_gen_out_sosi.sync = '1') THEN
src_out_arr(i).bsn <= sync_bsn;
END IF;
END LOOP;
END PROCESS;
END GENERATE;
g_merge_out_data : IF g_use_complex = FALSE GENERATE
gen_merge_out : PROCESS(block_gen_out_sosi, pipeline_out_sosi)
BEGIN
FOR i IN 0 TO g_nof_streams-1 LOOP
src_out_arr(i) <= block_gen_out_sosi;
src_out_arr(i).valid <= pipeline_out_sosi.valid;
src_out_arr(i).data <= RESIZE_DP_DATA(pipeline_out_sosi.data((i+1)*g_in_dat_w-1 DOWNTO i*g_in_dat_w));
IF (block_gen_out_sosi.sync = '1') THEN
src_out_arr(i).bsn <= sync_bsn;
END IF;
END LOOP;
END PROCESS;
END GENERATE;
END str;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment