From 7c27e64cb28f8266de404971b028b28b253750b8 Mon Sep 17 00:00:00 2001
From: JobvanWee <wee@astron.nl>
Date: Fri, 4 Mar 2022 11:06:27 +0100
Subject: [PATCH] Ready for review.

---
 .../src/vhdl/ddrctrl_address_counter.vhd      |  39 +++---
 .../tb/vhdl/tb_ddrctrl_address_counter.vhd    | 130 ++++++++++--------
 2 files changed, 89 insertions(+), 80 deletions(-)

diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_address_counter.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_address_counter.vhd
index f0cf079b5a..f8d6c54ed0 100644
--- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_address_counter.vhd
+++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_address_counter.vhd
@@ -18,7 +18,7 @@
 --
 -------------------------------------------------------------------------------
 -- Author: Job van Wee
--- Purpose: Create address by counting input valids
+-- Purpose: Creates address by counting input valids
 --
 -- Description:
 --  The counter starts on the first valid = '1' clockcylce, the counter stops 
@@ -41,43 +41,44 @@ USE dp_lib.dp_stream_pkg.ALL;
 
 ENTITY ddrctrl_address_counter IS
   GENERIC (
-    g_tech_ddr        : t_c_tech_ddr;
-    g_sim_model       : BOOLEAN := TRUE
+    g_tech_ddr        : t_c_tech_ddr;                                                                                             -- type of memory
+    g_sim_model       : BOOLEAN                           := TRUE                                                                 -- determens if this is a simulation
   );
   PORT (
-    clk               : IN  STD_LOGIC;
     rst               : IN  STD_LOGIC;
-    in_sosi           : IN  t_dp_sosi;
-    out_mosi          : OUT t_mem_ctlr_mosi := c_mem_ctlr_mosi_rst
+    in_sosi           : IN  t_dp_sosi;                                                                                            -- input data
+    out_mosi          : OUT t_mem_ctlr_mosi               := c_mem_ctlr_mosi_rst                                                  -- output data
   );
 END ddrctrl_address_counter;
 
 
 ARCHITECTURE rtl OF ddrctrl_address_counter IS
 
-  CONSTANT c_data_w   : NATURAL := func_tech_ddr_ctlr_data_w( g_tech_ddr ); --576
-  CONSTANT c_adr_w    : NATURAL := sel_a_b(g_sim_model, 4, func_tech_ddr_ctlr_address_w( g_tech_ddr )); --27;
-  CONSTANT c_max_adr  : NATURAL := 2**(c_adr_w) - 1;
+  -- constants for readability
+  CONSTANT c_data_w   : NATURAL                           := func_tech_ddr_ctlr_data_w( g_tech_ddr );                             -- the with of the input data and output data, 576
+  CONSTANT c_adr_w    : NATURAL                           := sel_a_b(g_sim_model, 4, func_tech_ddr_ctlr_address_w( g_tech_ddr )); -- the lengt of the address vector, for simulation this is smaller, otherwise the simulation would take to long, 27
+  CONSTANT c_max_adr  : NATURAL                           := 2**(c_adr_w) - 1;                                                    -- the maximal address that is possible within the vector length of the address
 
-  SIGNAL   s_adr      : NATURAL range 0 to 2**(c_adr_w)-1 := 0;
+  -- signal for storing address
+  SIGNAL   s_adr      : NATURAL range 0 to 2**(c_adr_w)-1 := 0;                                                                   -- a signal that contains the address
 
 BEGIN
 
+  -- The data is directly put through.
   out_mosi.wrdata(c_data_w - 1 DOWNTO 0) <= in_sosi.data(c_data_w - 1 DOWNTO 0);
   out_mosi.wr                            <= in_sosi.valid;
   out_mosi.address(c_adr_w -1 DOWNTO 0)  <= TO_UVEC(s_adr, c_adr_w);
 
-  p_clk : PROCESS(clk)
+  -- Increments the address each time in_sosi.valid = '1', if address = c_max_adr the address is reset to 0.
+  p_adr : PROCESS(rst, in_sosi.valid)
   BEGIN
-    IF rising_edge(clk) THEN
-      IF rst = '1' THEN
+    IF rst = '1' THEN
+      s_adr <= 0;
+    ELSIF rising_edge(in_sosi.valid) THEN
+      IF s_adr = c_max_adr THEN
         s_adr <= 0;
-      ELSIF in_sosi.valid = '1' THEN
-        IF (s_adr = c_max_adr) THEN
-          s_adr <= 0;
-        ELSE
-          s_adr <= s_adr + 1;
-        END IF;
+      ELSE
+        s_adr <= s_adr + 1;
       END IF;
     END IF;
   END PROCESS;
diff --git a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_address_counter.vhd b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_address_counter.vhd
index 3a00080067..0f3e4d414a 100644
--- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_address_counter.vhd
+++ b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_address_counter.vhd
@@ -33,75 +33,60 @@ USE common_lib.common_pkg.ALL;
 ENTITY tb_ddrctrl_address_counter IS
   GENERIC (
     
-    g_tech_ddr                : t_c_tech_ddr    := c_tech_ddr4_8g_1600m;
-    g_sim_model               : BOOLEAN         := TRUE
+    g_tech_ddr                : t_c_tech_ddr    := c_tech_ddr4_8g_1600m;                    -- type of memory
+    g_sim_model               : BOOLEAN         := TRUE;                                    -- determens if this is a simulation
+    g_sim_length              : NATURAL         := 52                                       -- determens the length of the duration of the test
 
   );
 END tb_ddrctrl_address_counter;
 
 ARCHITECTURE tb OF tb_ddrctrl_address_counter IS
 
-  CONSTANT  c_clk_freq        : NATURAL         := 200;     -- MHz
-  CONSTANT  c_clk_period      : TIME            := (10**6 / c_clk_freq) * 1 ps;
+  -- constants for running the testbench
+  CONSTANT  c_clk_freq        : NATURAL         := 200;                                     -- clock frequency in MHz
+  CONSTANT  c_clk_period      : TIME            := (10**6/c_clk_freq)*1 ps;                 -- clock period, 5 ns
 
-  CONSTANT  c_data_w          : NATURAL         := func_tech_ddr_ctlr_data_w( g_tech_ddr ); -- 576
-  CONSTANT  c_adr_w           : NATURAL         := 4;
-  CONSTANT  c_max_adr         : NATURAL         := 2**c_adr_w;
+  -- constants for running the test
+  CONSTANT  c_data_w          : NATURAL         := func_tech_ddr_ctlr_data_w( g_tech_ddr ); -- in and output data vector with, 576
+  CONSTANT  c_adr_w           : NATURAL         := 4;                                       -- address with in simulation
+  CONSTANT  c_adr_size        : NATURAL         := 2**c_adr_w;                              -- address size in simulation
 
-  SIGNAL    tb_end            : STD_LOGIC       := '0';
 
+  -- input signals for ddrctrl_address_counter.vhd
   SIGNAL    clk               : STD_LOGIC       := '1';
-  SIGNAL    rst               : STD_LOGIC;
+  SIGNAL    rst               : STD_LOGIC       := '0';
+  SIGNAL    in_sosi           : t_dp_sosi       := c_dp_sosi_init;                          -- signal which is the input for ddrctrl_address_counter.vhd
 
-  SIGNAL    in_data           : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0);
-  SIGNAL    in_data_enable    : STD_LOGIC;
-  SIGNAL    in_sosi           : t_dp_sosi       := c_dp_sosi_init;
+  -- output signal from ddrctrl_address_counter.vhd
+  SIGNAL    out_mosi          : t_mem_ctlr_mosi := c_mem_ctlr_mosi_rst;                     -- signal which is the output from ddrctrl_address_counter.vhd
 
-  SIGNAL    out_mosi          : t_mem_ctlr_mosi := c_mem_ctlr_mosi_rst;
+  -- testbench signals
+  SIGNAL    tb_end            : STD_LOGIC       := '0';                                     -- signal to turn the testbench off
+  SIGNAL    in_data           : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0);                      -- signal which contains the data that is set as input
+  SIGNAL    in_data_enable    : STD_LOGIC;                                                  -- signal to determen if in_data is ready for reading
+  SIGNAL    lag_due_reset     : NATURAL         := 0;                                       -- signal to hold the address lag after a rest
 
 BEGIN
 
-  -- if these ASSERT's get uncommented u can see that modelsim does take a few itteration before the warning gets asserted. These asserts are also present in p_verify
-
-  --ASSERT in_sosi.data(c_data_w - 1 DOWNTO 0) = out_mosi.wrdata(c_data_w - 1 DOWNTO 0) REPORT "in_sosi.data does not match out_mosi.wrdata"  SEVERITY ERROR;   -- gives error if in_sosi and out_mosi do not match
-  --ASSERT in_sosi.valid                       = out_mosi.wr                            REPORT "in_sosi.valid does not match out_mosi.wr"      SEVERITY ERROR;
-  --ASSERT in_sosi.data(c_data_w - 1 DOWNTO 0) /= out_mosi.wrdata(c_data_w - 1 DOWNTO 0) REPORT "in_sosi.data does match out_mosi.wrdata"  SEVERITY WARNING;    -- gives warning if in_sosi and out_mosi do match
-  --ASSERT in_sosi.valid                       /= out_mosi.wr                            REPORT "in_sosi.valid does match out_mosi.wr"      SEVERITY WARNING;
-
-  in_sosi.data(c_data_w - 1 DOWNTO 0)    <= in_data(c_data_w - 1 DOWNTO 0);
-  in_sosi.valid                          <= in_data_enable;
+  -- wiring the input signals to the inputs of the testbench
+  in_sosi.data(c_data_w-1 DOWNTO 0) <= in_data(c_data_w-1 DOWNTO 0);
+  in_sosi.valid                     <= in_data_enable;
 
+  -- generating clock
   clk <= NOT clk OR tb_end AFTER c_clk_period/2;
 
-  p_mm : PROCESS
+  -- excecuting the test
+  p_test : PROCESS
   BEGIN
 
-    rst               <= '1', '0' AFTER c_clk_period/10;
-
+    -- initialize inputs
     tb_end            <= '0';
     in_data           <= (OTHERS => '0');
     in_data_enable    <= '0';
+    WAIT UNTIL rising_edge(clk);
 
-    WAIT UNTIL rising_edge(clk);  -- align to rising edge
-    WAIT FOR c_clk_period*10;
-
-    FOR I IN 0 TO 6 LOOP
-      in_data_enable  <= '1';
-      in_data         <= NOT in_data;
-      ASSERT I                                 = TO_UINT(out_mosi.address)              REPORT "Wrong address, I = " & NATURAL'image(I) SEVERITY ERROR;
-      WAIT FOR c_clk_period*1;
-      in_data_enable  <= '0';
-      WAIT FOR c_clk_period*2;
-    END LOOP;
-
-    WAIT FOR c_clk_period*1;
-    rst               <= '1';               -- reset
-    WAIT FOR c_clk_period*1;
-    rst               <= '0';
-    WAIT FOR c_clk_period*1;
-
-    FOR I IN 0 TO 20 LOOP
-      ASSERT I = TO_UINT(out_mosi.address)  OR I - c_max_adr = TO_UINT(out_mosi.address)    REPORT "Wrong address, I = " & NATURAL'image(I) SEVERITY ERROR;
+    -- changing inputs to start the address counting
+    FOR I IN 0 TO g_sim_length-1 LOOP
       in_data_enable  <= '1';
       in_data         <= NOT in_data;
       WAIT FOR c_clk_period*1;
@@ -109,41 +94,64 @@ BEGIN
       WAIT FOR c_clk_period*2;
     END LOOP;
 
-    WAIT FOR c_clk_period*20;
-
+    -- stopping the test
+    WAIT FOR c_clk_period*4;
     tb_end            <= '1';
-    WAIT;
-
+    ASSERT FALSE                                                                      REPORT "Test: OK"                                                            SEVERITY FAILURE;
   END PROCESS;
 
-  p_verify : PROCESS
+  -- verifying if the data is correct and if valid is correct
+  p_verify_data_valid : PROCESS
   BEGIN
     WAIT UNTIL rising_edge(clk);
     IF rising_edge(clk) THEN
-      ASSERT in_sosi.data(c_data_w - 1 DOWNTO 0) = out_mosi.wrdata(c_data_w - 1 DOWNTO 0) REPORT "in_sosi.data does not match out_mosi.wrdata"  SEVERITY ERROR;   -- gives error if in_sosi and out_mosi do not match
-      ASSERT in_sosi.valid                       = out_mosi.wr                            REPORT "in_sosi.valid does not match out_mosi.wr"      SEVERITY ERROR;
-      --ASSERT in_sosi.data(c_data_w - 1 DOWNTO 0) /= out_mosi.wrdata(c_data_w - 1 DOWNTO 0) REPORT "in_sosi.data does match out_mosi.wrdata"  SEVERITY WARNING;    -- gives warning if in_sosi and out_mosi do match
-      --ASSERT in_sosi.valid                       /= out_mosi.wr                            REPORT "in_sosi.valid does match out_mosi.wr"      SEVERITY WARNING;
+      ASSERT in_sosi.data(c_data_w-1 DOWNTO 0) = out_mosi.wrdata(c_data_w-1 DOWNTO 0) REPORT "in_sosi.data does not match out_mosi.wrdata"                         SEVERITY ERROR;
+      ASSERT in_sosi.valid                     = out_mosi.wr                          REPORT "in_sosi.valid does not match out_mosi.wr"                            SEVERITY ERROR;
     END IF;
   END PROCESS;
 
+  -- excecuting the reset test
+  p_test_reset : PROCESS
+  BEGIN
+    rst <= '0';
+    WAIT FOR c_clk_period*(c_adr_size+3);
+    IF lag_due_reset + TO_UINT(out_mosi.address) >= c_adr_size THEN
+      lag_due_reset <= lag_due_reset+TO_UINT(out_mosi.address)-c_adr_size;
+    ELSE
+      lag_due_reset <= lag_due_reset+TO_UINT(out_mosi.address);
+    END IF;
+    rst <= '1';
+    WAIT FOR c_clk_period*1;
+  END PROCESS;
+
+  -- verifying if the address is correct by keeping trach of the address
+  p_verify_address : PROCESS
+  BEGIN
+    FOR I IN 0 TO c_adr_size-1 LOOP
+      WAIT UNTIL out_mosi.wr = '1';
+      IF rst = '1' THEN
+        WAIT UNTIL out_mosi.wr = '1';
+      END IF;
+      IF I >= lag_due_reset THEN
+        ASSERT I-lag_due_reset   = TO_UINT(out_mosi.address)                           REPORT "Wrong address, 1, I = " & NATURAL'image(I-lag_due_reset) & ", address = " & NATURAL'image(TO_UINT(out_mosi.address))                SEVERITY ERROR;
+      ELSE
+        ASSERT (I-lag_due_reset)+c_adr_size = TO_UINT(out_mosi.address)                REPORT "Wrong address, 2, I = " & NATURAL'image((I-lag_due_reset)+c_adr_size) & ", address = " & NATURAL'image(TO_UINT(out_mosi.address))   SEVERITY ERROR;
+      END IF;
+    END LOOP;
+  END PROCESS;
+
+
+  -- DUT
   u_ddrctrl_address_counter : ENTITY work.ddrctrl_address_counter
   GENERIC MAP (
     g_tech_ddr        => g_tech_ddr,
     g_sim_model       => g_sim_model
   )
   PORT MAP (
-    clk               => clk,
     rst               => rst,
     in_sosi           => in_sosi,
 
     out_mosi          => out_mosi
-
   );
 
 END tb;
-
-
-
-
-
-- 
GitLab