------------------------------------------------------------------------------- -- -- Copyright (C) 2014 -- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.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: Multi testbench for io_ddr. -- Description: -- Usage: -- > as 5 -- > run -all -- # Takes about 10m for DDR3 -- # Takes about 1u10m for DDR4 LIBRARY IEEE, technology_lib, tech_ddr_lib, common_lib; USE IEEE.std_logic_1164.ALL; USE technology_lib.technology_pkg.ALL; USE technology_lib.technology_select_pkg.ALL; USE tech_ddr_lib.tech_ddr_pkg.ALL; USE common_lib.tb_common_pkg.ALL; ENTITY tb_tb_io_ddr IS END tb_tb_io_ddr; ARCHITECTURE tb OF tb_tb_io_ddr IS CONSTANT c_technology : NATURAL := c_tech_select_default; CONSTANT c_tech_ddr3 : t_c_tech_ddr := c_tech_ddr3_4g_800m_master; --CONSTANT c_tech_ddr4 : t_c_tech_ddr := c_tech_ddr4_4g_1600m; CONSTANT c_tech_ddr4 : t_c_tech_ddr := func_tech_sel_ddr(c_technology = c_tech_arria10_e1sg, c_tech_ddr4_4g_1600m, c_tech_ddr4_8g_1600m); -- use 4GB for unb2b, 8GB for unb2c CONSTANT c_tech_ddr : t_c_tech_ddr := func_tech_sel_ddr(c_technology, c_tech_ddr3, c_tech_ddr4); -- Select DDR3 or DDR4 dependent on the technology CONSTANT c_tb_end_vec : STD_LOGIC_VECTOR(15 DOWNTO 0) := (OTHERS=>'1'); SIGNAL tb_end_vec : STD_LOGIC_VECTOR(15 DOWNTO 0) := c_tb_end_vec; -- sufficiently long to fit all tb instances SIGNAL tb_end : STD_LOGIC := '0'; BEGIN -- g_sim_model : BOOLEAN := FALSE; -- g_technology : NATURAL := c_tech_select_default; -- g_tech_ddr3 : t_c_tech_ddr := c_tech_ddr3_4g_800m_master; -- g_tech_ddr4 : t_c_tech_ddr := c_tech_ddr4_4g_1600m; -- g_tb_end : BOOLEAN := TRUE; -- when TRUE then tb_end ends this simulation, else a higher multi-testbench will end the simulation -- g_cross_domain_dvr_ctlr : BOOLEAN := FALSE; -- when TRUE insert clock cross domain logic and also insert clock cross domain logic when g_dvr_clk_period/=c_ctlr_clk_period -- g_dvr_clk_period : TIME := 5 ns; -- 200 MHz -- g_dp_factor : NATURAL := 1; -- 1 or power of 2, c_dp_data_w = c_ctlr_data_w / g_dp_factor -- g_block_len : NATURAL := 64; -- block length for a DDR write access and read back access in number of c_ctlr_data_w words -- g_nof_block : NATURAL := 12; -- number of blocks that will be written to DDR and readback from DDR -- g_nof_wr_per_block : NATURAL := 1; -- number of write accesses per block -- g_nof_rd_per_block : NATURAL := 16; -- number of read accesses per block -- g_nof_repeat : NATURAL := 1; -- number of stimuli repeats with write flush after each repeat -- g_wr_flush_mode : STRING := "SYN" -- "VAL", "SOP", "SYN" u_sim_model : ENTITY work.tb_io_ddr GENERIC MAP ( TRUE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 4, 2500, 2, 1, 1, 1, "VAL") PORT MAP (tb_end_vec(0)); gen_ddr3 : IF c_tech_ddr.name="DDR3" GENERATE u_default : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 4, 2500, 2, 1, 1, 1, "VAL") PORT MAP (tb_end_vec(1)); u_fill_wrfifo_on_next_valid : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 1, 1000, 2, 1, 4, 2, "VAL") PORT MAP (tb_end_vec(2)); u_fill_wrfifo_on_next_sop : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 1, 1000, 2, 3, 4, 2, "SOP") PORT MAP (tb_end_vec(3)); u_fill_wrfifo_on_next_sync : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 1, 1000, 2, 4, 1, 2, "SYN") PORT MAP (tb_end_vec(4)); u_cross_domain : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, TRUE, 5 ns, 1, 2500, 1, 2, 3, 1, "VAL") PORT MAP (tb_end_vec(5)); u_mixed_width : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 8, 2500, 1, 3, 2, 1, "VAL") PORT MAP (tb_end_vec(6)); u_wr_burst_size_0 : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 4, 2,10, 3, 3, 2, "VAL") PORT MAP (tb_end_vec(7)); u_wr_burst_size_1 : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 4, 1,10, 1, 1, 2, "VAL") PORT MAP (tb_end_vec(8)); u_cross_dvr_to_faster_ctlr : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 20 ns, 1, 2500, 1, 1, 4, 1, "VAL") PORT MAP (tb_end_vec(9)); u_cross_dvr_to_slower_ctlr : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 1 ns, 1, 2500, 1, 1, 4, 1, "VAL") PORT MAP (tb_end_vec(10)); u_sequencer_1_16 : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 4, 64,10, 1,16, 1, "VAL") PORT MAP (tb_end_vec(11)); u_sequencer_16_1 : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 4, 64,10,16, 1, 1, "VAL") PORT MAP (tb_end_vec(12)); END GENERATE; -- Distinghuis between tests for DDR3 and DDR4, because the Quartus 14.1 ip_arria10 DDR4 model simulates about 40x slower than the Quartus 11.1 ip_stratixiv DDR3 uniphy model. gen_ddr4 : IF c_tech_ddr.name="DDR4" GENERATE u_default : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 4, 2500, 2, 1, 1, 1, "VAL") PORT MAP (tb_end_vec(1)); END GENERATE; tb_end <= '1' WHEN tb_end_vec=c_tb_end_vec ELSE '0'; proc_common_timeout_failure(1 ms, tb_end); p_tb_end : PROCESS BEGIN WAIT UNTIL tb_end='1'; WAIT FOR 1 ns; REPORT "Multi tb simulation finished." SEVERITY FAILURE; WAIT; END PROCESS; END tb;