From 9fed08ae4bbccf80a4201de9b0d68acfbc62fad7 Mon Sep 17 00:00:00 2001
From: Erik Kooistra <kooistra@astron.nl>
Date: Tue, 20 Jan 2015 14:55:08 +0000
Subject: [PATCH] Improved stimuli using generics and functions to define the
 write and read block accesses. Distinghuis between tests for DDR3 and DDR4,
 because DDR4 model simulates about 20x slower.

---
 libraries/io/ddr/tb/vhdl/tb_tb_io_ddr.vhd | 65 +++++++++++++++++------
 1 file changed, 48 insertions(+), 17 deletions(-)

diff --git a/libraries/io/ddr/tb/vhdl/tb_tb_io_ddr.vhd b/libraries/io/ddr/tb/vhdl/tb_tb_io_ddr.vhd
index 4fc74d94b5..e783fb7ed9 100644
--- a/libraries/io/ddr/tb/vhdl/tb_tb_io_ddr.vhd
+++ b/libraries/io/ddr/tb/vhdl/tb_tb_io_ddr.vhd
@@ -39,28 +39,59 @@ END tb_tb_io_ddr;
 ARCHITECTURE tb OF tb_tb_io_ddr IS
 
   CONSTANT c_technology     : NATURAL      := c_tech_select_default;
-  CONSTANT c_tech_ddr       : t_c_tech_ddr := c_tech_ddr3_4g_800m_master;
+  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_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
   
 BEGIN
 
-  -- g_technology           : NATURAL := c_tech_select_default;
-  -- g_tech_ddr             : t_c_tech_ddr := c_tech_ddr3_4g_800m_master;
-  -- g_sim                  : BOOLEAN := TRUE;  -- when TRUE use the internal DDR memory model, else use the DDR model in this tb.
-  -- g_ctlr_ref_clk_period  : TIME := 5 ns;     -- 200 MHz
-  -- g_dvr_clk_period       : TIME := 20 ns;    -- 50 ns
-  -- g_dp_clk_period        : TIME := 5000 ps;  -- 200 MHz
-  -- g_dp_data_w            : NATURAL := 32;    -- 32 for mixed width and 256 for equal width FIFO
-  -- g_nof_repeat           : NATURAL := 2;
-  -- g_wr_flush_mode        : STRING := "SYN"  -- "VAL", "SOP", "SYN"
+  -- 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_sim                   : BOOLEAN := TRUE;   -- when TRUE use the internal DDR memory model, else use the DDR model in this tb.
+  -- g_cross_domain_dvr_ctlr : BOOLEAN := FALSE;  -- when TRUE insert clock cross domain logic
+  -- g_ctlr_ref_clk_period   : TIME := 5 ns;      -- 200 MHz
+  -- g_dvr_clk_period        : TIME := 5 ns;      -- 50 ns
+  -- g_dp_clk_period         : TIME := 5000 ps;   -- 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_fill_wrfifo_on_next_valid     : ENTITY work.tb_io_ddr GENERIC MAP (c_technology, c_tech_ddr, FALSE, 5 ns,  5 ns, 5 ns, 256, 2, "VAL");
-  u_fill_wrfifo_on_next_sop       : ENTITY work.tb_io_ddr GENERIC MAP (c_technology, c_tech_ddr, FALSE, 5 ns,  5 ns, 5 ns, 256, 2, "SOP");
-  u_fill_wrfifo_on_next_sync      : ENTITY work.tb_io_ddr GENERIC MAP (c_technology, c_tech_ddr, FALSE, 5 ns,  5 ns, 5 ns, 256, 2, "SYN");
+  gen_ddr3 : IF c_tech_ddr.name="DDR3" GENERATE
+    u_fill_wrfifo_on_next_valid     : ENTITY work.tb_io_ddr GENERIC MAP (c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, FALSE, 5 ns,  5 ns, 5 ns,  1, 1000, 2, 1, 4,  2, "VAL") PORT MAP (tb_end_vec(0));
+    u_fill_wrfifo_on_next_sop       : ENTITY work.tb_io_ddr GENERIC MAP (c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, FALSE, 5 ns,  5 ns, 5 ns,  1, 1000, 2, 3, 4,  2, "SOP") PORT MAP (tb_end_vec(1));
+    u_fill_wrfifo_on_next_sync      : ENTITY work.tb_io_ddr GENERIC MAP (c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, FALSE, 5 ns,  5 ns, 5 ns,  1, 1000, 2, 4, 1,  2, "SYN") PORT MAP (tb_end_vec(2));
+                                                                                                                                                                                     
+    u_ext_memory_model              : ENTITY work.tb_io_ddr GENERIC MAP (c_technology, c_tech_ddr3, c_tech_ddr4, FALSE,  TRUE, FALSE, 5 ns,  5 ns, 5 ns,  1, 1000, 1, 2, 3,  1, "VAL") PORT MAP (tb_end_vec(3));
+    u_mixed_width                   : ENTITY work.tb_io_ddr GENERIC MAP (c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, FALSE, 5 ns,  5 ns, 5 ns,  8, 1000, 1, 3, 2,  1, "VAL") PORT MAP (tb_end_vec(4));
+                                                                                                                                                                                     
+    u_wr_burst_size_0               : ENTITY work.tb_io_ddr GENERIC MAP (c_technology, c_tech_ddr3, c_tech_ddr4, FALSE,  TRUE, FALSE, 5 ns,  5 ns, 5 ns,  4,    5, 1, 6, 5,  1, "VAL") PORT MAP (tb_end_vec(5));
+    
+    u_cross_dvr_to_faster_ctlr      : ENTITY work.tb_io_ddr GENERIC MAP (c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, FALSE, 5 ns, 20 ns, 5 ns,  1, 1000, 1, 1, 4,  1, "VAL") PORT MAP (tb_end_vec(6));
+    u_cross_dvr_to_slower_ctlr      : ENTITY work.tb_io_ddr GENERIC MAP (c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, FALSE, 5 ns,  1 ns, 5 ns,  1, 1000, 1, 1, 4,  1, "VAL") PORT MAP (tb_end_vec(7));
+                                                                                                                                                                                     
+    u_sequencer_1_16                : ENTITY work.tb_io_ddr GENERIC MAP (c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, FALSE, 5 ns,  5 ns, 5 ns,  4,   64, 9, 1,16,  1, "VAL") PORT MAP (tb_end_vec(8));
+    u_sequencer_16_1                : ENTITY work.tb_io_ddr GENERIC MAP (c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, FALSE, 5 ns,  5 ns, 5 ns,  4,   64, 9,16, 1,  1, "VAL") PORT MAP (tb_end_vec(9));
+  END GENERATE;
   
-  u_ext_memory_model              : ENTITY work.tb_io_ddr GENERIC MAP (c_technology, c_tech_ddr,  TRUE, 5 ns,  5 ns, 5 ns, 256, 1, "VAL");
-  u_mixed_width                   : ENTITY work.tb_io_ddr GENERIC MAP (c_technology, c_tech_ddr, FALSE, 5 ns,  5 ns, 5 ns,  32, 1, "VAL");
+  -- Distinghuis between tests for DDR3 and DDR4, because DDR4 model simulates about 20x slower
+  gen_ddr4 : IF c_tech_ddr.name="DDR4" GENERATE
+    u_sequencer_1_16                : ENTITY work.tb_io_ddr GENERIC MAP (c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, FALSE, 5 ns,  5 ns, 5 ns,  4,   64, 9, 1,16,  1, "VAL") PORT MAP (tb_end_vec(0));
+  END GENERATE;
   
-  u_cross_dvr_to_faster_ctlr      : ENTITY work.tb_io_ddr GENERIC MAP (c_technology, c_tech_ddr, FALSE, 5 ns, 20 ns, 5 ns, 256, 1, "VAL");
-  u_cross_dvr_to_slower_ctlr      : ENTITY work.tb_io_ddr GENERIC MAP (c_technology, c_tech_ddr, FALSE, 5 ns,  1 ns, 5 ns, 256, 1, "VAL");
+  p_tb_end : PROCESS
+  BEGIN
+    WAIT UNTIL tb_end_vec=c_tb_end_vec;
+    REPORT "Multi tb simulation finished." SEVERITY FAILURE;
+    WAIT;
+  END PROCESS;
   
 END tb;
-- 
GitLab