From b1bdcf91cc5719606f7cefdca47d60d8cc688d4a Mon Sep 17 00:00:00 2001 From: JobvanWee <wee@astron.nl> Date: Thu, 10 Mar 2022 17:53:57 +0100 Subject: [PATCH] I am confused. --- .../libraries/ddrctrl/src/vhdl/ddrctrl.vhd | 7 +- .../src/vhdl/ddrctrl_address_counter.vhd | 114 +++++++++--- .../ddrctrl/src/vhdl/ddrctrl_repack.vhd | 170 ++++++++++-------- .../libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd | 21 +-- .../tb/vhdl/tb_ddrctrl_address_counter.vhd | 17 +- .../ddrctrl/tb/vhdl/tb_ddrctrl_repack.vhd | 4 +- 6 files changed, 210 insertions(+), 123 deletions(-) diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd index 6f27a4b62d..496b7015d7 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd @@ -68,6 +68,7 @@ ARCHITECTURE str OF ddrctrl IS -- signals for connecting the components SIGNAL data : STD_LOGIC_VECTOR(c_out_data_w-1 DOWNTO 0); SIGNAL sosi : t_dp_sosi := c_dp_sosi_init; + SIGNAL a_of : NATURAL := 0; BEGIN @@ -96,7 +97,7 @@ BEGIN clk => clk, rst => rst, in_data => data, -- input data - out_of => out_of, -- amount of internal overflow + out_of => a_of, -- amount of internal overflow out_sosi => sosi -- output data ); @@ -110,7 +111,9 @@ BEGIN clk => clk, rst => rst, in_sosi => sosi, -- input data - out_mosi => out_mosi -- output data + in_of => a_of, + out_mosi => out_mosi, -- output data + out_of => out_of ); END str; 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 4a7e513d17..4dea33752e 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_address_counter.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_address_counter.vhd @@ -41,14 +41,16 @@ USE dp_lib.dp_stream_pkg.ALL; ENTITY ddrctrl_address_counter IS GENERIC ( - g_tech_ddr : t_c_tech_ddr; -- type of memory - g_sim_model : BOOLEAN := TRUE -- determens if this is a simulation + 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; -- input data - out_mosi : OUT t_mem_ctlr_mosi := c_mem_ctlr_mosi_rst -- output data + clk : IN STD_LOGIC; + rst : IN STD_LOGIC; + in_sosi : IN t_dp_sosi; -- input data + in_of : IN NATURAL; + out_mosi : OUT t_mem_ctlr_mosi := c_mem_ctlr_mosi_rst; -- output data + out_of : OUT NATURAL ); END ddrctrl_address_counter; @@ -56,32 +58,98 @@ END ddrctrl_address_counter; ARCHITECTURE rtl OF ddrctrl_address_counter IS -- 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 + 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 : STD_LOGIC_VECTOR(c_adr_w-1 DOWNTO 0) := STD_LOGIC_VECTOR(TO_UVEC(2**(c_adr_w)-1, c_adr_w)); -- the maximal address that is possible within the vector length of the address - -- signal for storing address - SIGNAL s_adr : NATURAL range 0 to 2**(c_adr_w)-1 := 0; -- a signal that contains the address + -- type for statemachine + TYPE t_state IS (RESET, COUNTING, MAX, IDLE); + + -- record for readability + TYPE t_reg IS RECORD + state : t_state; + out_mosi : t_mem_ctlr_mosi; + out_of : NATURAL; + END RECORD; + + CONSTANT c_t_reg_init : t_reg := (RESET, c_mem_ctlr_mosi_rst, 0); + + -- signals for readability + SIGNAL d_reg : t_reg := c_t_reg_init; + SIGNAL q_reg : t_reg := c_t_reg_init; BEGIN - out_mosi.address(c_adr_w -1 DOWNTO 0) <= TO_UVEC(s_adr, c_adr_w); + q_reg <= d_reg WHEN rising_edge(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, clk) + p_adr : PROCESS(rst, in_sosi) + + VARIABLE v : t_reg := c_t_reg_init; + BEGIN - IF rising_edge(clk) THEN - out_mosi.wrdata(c_data_w - 1 DOWNTO 0) <= in_sosi.data(c_data_w - 1 DOWNTO 0); - out_mosi.wr <= in_sosi.valid; + v.out_mosi.wrdata(c_data_w-1 DOWNTO 0) := in_sosi.data(c_data_w - 1 DOWNTO 0); + v.out_mosi.wr := in_sosi.valid; + v.out_of := in_of; + + CASE v.state IS + WHEN RESET => + v.out_mosi.address(c_adr_w-1 DOWNTO 0) := (OTHERS => '0'); + IF rst = '1' THEN - s_adr <= 0; + v.state := RESET; + ELSIF v.out_mosi.address(c_adr_w-1 DOWNTO 0) = c_max_adr(c_adr_w-1 DOWNTO 0) AND in_sosi.valid = '1' THEN + v.state := MAX; ELSIF in_sosi.valid = '1' THEN - IF s_adr = c_max_adr THEN - s_adr <= 0; - ELSE - s_adr <= s_adr + 1; - END IF; + v.state := COUNTING; + ELSE + v.state := IDLE; END IF; - END IF; + + WHEN COUNTING => + v.out_mosi.address(c_adr_w-1 DOWNTO 0) := STD_LOGIC_VECTOR(TO_UVEC(TO_UINT(v.out_mosi.address)+1, c_adr_w)); + + IF rst = '1' THEN + v.state := RESET; + ELSIF v.out_mosi.address(c_adr_w-1 DOWNTO 0) = c_max_adr(c_adr_w-1 DOWNTO 0) AND in_sosi.valid = '1' THEN + v.state := MAX; + ELSIF in_sosi.valid = '1' THEN + v.state := COUNTING; + ELSE + v.state := IDLE; + END IF; + + WHEN MAX => + v.out_mosi.address(c_adr_w-1 DOWNTO 0) := (OTHERS => '0'); + + IF rst = '1' THEN + v.state := RESET; + ELSIF v.out_mosi.address(c_adr_w-1 DOWNTO 0) = c_max_adr(c_adr_w-1 DOWNTO 0) AND in_sosi.valid = '1' THEN + v.state := MAX; + ELSIF in_sosi.valid = '1' THEN + v.state := COUNTING; + ELSE + v.state := IDLE; + END IF; + + WHEN IDLE => + + IF rst = '1' THEN + v.state := RESET; + ELSIF v.out_mosi.address(c_adr_w-1 DOWNTO 0) = c_max_adr(c_adr_w-1 DOWNTO 0) AND in_sosi.valid = '1' THEN + v.state := MAX; + ELSIF in_sosi.valid = '1' THEN + v.state := COUNTING; + ELSE + v.state := IDLE; + END IF; + + END CASE; + d_reg <= v; END PROCESS; + + -- fill outputs + out_mosi <= q_reg.out_mosi; + out_of <= q_reg.out_of; + END rtl; diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_repack.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_repack.vhd index 8bf4c5c339..92b6fc53a9 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_repack.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_repack.vhd @@ -51,92 +51,108 @@ END ddrctrl_repack; ARCHITECTURE rtl OF ddrctrl_repack IS - TYPE t_state IS (OVER_FLOW, FIRST_HALF, SECOND_HALF, RESET); - -- constant for readability CONSTANT c_out_data_w : NATURAL := func_tech_ddr_ctlr_data_w( g_tech_ddr ); -- the output data with, 576 CONSTANT k_c_v_w : NATURAL := c_out_data_w*2; -- the c_v data with, 2*576=1152 + -- type for statemachine + TYPE t_state IS (OVERFLOW_OUTPUT, FILL_VECTOR, FIRST_OUTPUT, RESET); + + -- record for readability + TYPE t_reg IS RECORD + state : t_state; -- the state the process is currently in; + a_of : NATURAL; -- amount of overflow + c_v : STD_LOGIC_VECTOR(k_c_v_w-1 DOWNTO 0); -- the vector that stores the input data until the data is put into the output data vector + c_v_count : NATURAL; -- the amount of times the c_v vector received data from the input since the last time it was filled completely + out_data_count : NATURAL; -- the amount of times the output data vector has been filled since the last time c_v was filled completely + out_of : NATURAL; + out_sosi : t_dp_sosi; + END RECORD; + + CONSTANT c_t_reg_init : t_reg := (RESET, 0, (OTHERS => '0'), 0, 0, 0, c_dp_sosi_init); + + -- signals for readability + SIGNAL d_reg : t_reg := c_t_reg_init; + SIGNAL q_reg : t_reg := c_t_reg_init; + BEGIN + q_reg <= d_reg WHEN rising_edge(clk); + -- put the input data into c_v and fill the output vector from c_v - p_clk : PROCESS(clk) + p_state : PROCESS(q_reg, rst) - VARIABLE a_of : NATURAL := 0; -- amount of overflow - VARIABLE c_v : STD_LOGIC_VECTOR (k_c_v_w-1 DOWNTO 0) := (OTHERS => '0'); -- the vector that stores the input data until the data is put into the output data vector - VARIABLE c_v_count : NATURAL := 0; -- the amount of times the c_v vector received data from the input since the last time it was filled completely - VARIABLE out_data_count : NATURAL := 0; -- the amount of times the output data vector has been filled since the last time c_v was filled completely - VARIABLE state : t_state := FIRST_HALF; -- the state the process is currently in; + VARIABLE v : t_reg := c_t_reg_init; BEGIN - IF rising_edge(clk) THEN - CASE state IS - WHEN FIRST_HALF => -- if the input data doesn't exceeds the output data vector width - c_v(g_in_data_w * (c_v_count + 1) + a_of - 1 DOWNTO g_in_data_w * c_v_count + a_of) := in_data(g_in_data_w - 1 DOWNTO 0); -- fill c_v - c_v_count := c_v_count + 1; -- increase the counter of c_v with 1 - out_sosi.valid <= '0'; -- out_sosi.valid 0 - - IF rst = '1' THEN - state := RESET; - ELSIF ((g_in_data_w*(c_v_count+1))+a_of >= c_out_data_w*(out_data_count+1)) AND (out_data_count = 0) THEN - state := SECOND_HALF; - ELSIF ((g_in_data_w*(c_v_count+1))+a_of >= c_out_data_w*(out_data_count+1)) AND (out_data_count = 1) THEN - state := OVER_FLOW; - ELSE - state := FIRST_HALF; - END IF; - - WHEN SECOND_HALF => -- if the input data exceeds output data vector width but not the c_v width - c_v(g_in_data_w * (c_v_count + 1) + a_of - 1 DOWNTO g_in_data_w * c_v_count + a_of) := in_data(g_in_data_w - 1 DOWNTO 0); -- fill c_v - c_v_count := c_v_count + 1; -- increase the counter of c_v with 1 - out_sosi.data(c_out_data_w - 1 DOWNTO 0) <= c_v(c_out_data_w - 1 DOWNTO 0); -- fill out_sosi.data with 1st part of c_v - out_sosi.valid <= '1'; -- out_sosi.valid 1 - out_data_count := out_data_count + 1; -- increase the counter of out_sosi.data with 1 - - IF rst = '1' THEN - state := RESET; - ELSIF ((g_in_data_w*(c_v_count+1))+a_of >= c_out_data_w*(out_data_count+1)) AND (out_data_count = 0) THEN - state := SECOND_HALF; - ELSIF ((g_in_data_w*(c_v_count+1))+a_of >= c_out_data_w*(out_data_count+1)) AND (out_data_count = 1) THEN - state := OVER_FLOW; - ELSE - state := FIRST_HALF; - END IF; - - WHEN OVER_FLOW => -- if the input data exceeds the output data vector width and the c_v width - a_of := a_of + (g_in_data_w*(c_v_count+1)) - (c_out_data_w*(out_data_count+1)); -- check how much overflow there is and safe it in a_of - out_of <= a_of; -- set the output overflow to the overflow that maches the out_sosi.data vector - c_v(k_c_v_w - 1 DOWNTO k_c_v_w-(g_in_data_w - a_of)) := in_data(g_in_data_w - a_of - 1 DOWNTO 0); -- fill the rest of c_v untill the end - c_v(a_of - 1 DOWNTO 0) := in_data(g_in_data_w - 1 DOWNTO g_in_data_w - a_of); -- fill the start of c_v untill the a_of - out_sosi.data(c_out_data_w - 1 DOWNTO 0) <= c_v(k_c_v_w - 1 DOWNTO c_out_data_w); -- fill out_sosi.data with 2nd part of c_v - out_sosi.valid <= '1'; -- out_sosi.valid 1 - c_v_count := 0; -- reset counter - out_data_count := 0; -- reset counter - - IF rst = '1' THEN - state := RESET; - ELSIF ((g_in_data_w*(c_v_count+1))+a_of >= c_out_data_w*(out_data_count+1)) AND (out_data_count = 0) THEN - state := SECOND_HALF; - ELSIF ((g_in_data_w*(c_v_count+1))+a_of >= c_out_data_w*(out_data_count+1)) AND (out_data_count = 1) THEN - state := OVER_FLOW; - ELSE - state := FIRST_HALF; - END IF; - - WHEN RESET => - a_of := 0; - c_v := (OTHERS => '0'); - c_v_count := 0; - out_data_count := 0; - out_of <= 0; - out_sosi <= c_dp_sosi_init; - IF rst = '1' THEN - state := RESET; - ELSE - state := FIRST_HALF; - END IF; - - END CASE; - END IF; + CASE v.state IS + WHEN FILL_VECTOR => -- if the input data doesn't exceeds the output data vector width + v.c_v(g_in_data_w*(v.c_v_count+1)+v.a_of-1 DOWNTO g_in_data_w*v.c_v_count+v.a_of) := in_data(g_in_data_w-1 DOWNTO 0); -- fill c_v + v.c_v_count := v.c_v_count+1; -- increase the counter of c_v with 1 + v.out_sosi.valid := '0'; -- out_sosi.valid 0 + + IF rst = '1' THEN + v.state := RESET; + ELSIF ((g_in_data_w*(v.c_v_count+1))+v.a_of >= c_out_data_w*(v.out_data_count+1)) AND (v.out_data_count = 0) THEN + v.state := FIRST_OUTPUT; + ELSIF ((g_in_data_w*(v.c_v_count+1))+v.a_of >= c_out_data_w*(v.out_data_count+1)) AND (v.out_data_count = 1) THEN + v.state := OVERFLOW_OUTPUT; + ELSE + v.state := FILL_VECTOR; + END IF; + + WHEN FIRST_OUTPUT => -- if the input data exceeds output data vector width but not the c_v width + v.c_v(g_in_data_w*(v.c_v_count+1)+v.a_of-1 DOWNTO g_in_data_w*v.c_v_count+v.a_of) := in_data(g_in_data_w-1 DOWNTO 0); -- fill c_v + v.c_v_count := v.c_v_count + 1; -- increase the counter of c_v with 1 + v.out_sosi.data(c_out_data_w - 1 DOWNTO 0) := v.c_v(c_out_data_w - 1 DOWNTO 0); -- fill out_sosi.data with 1st part of c_v + v.out_sosi.valid := '1'; -- out_sosi.valid 1 + v.out_data_count := v.out_data_count+1; -- increase the counter of out_sosi.data with 1 + + IF rst = '1' THEN + v.state := RESET; + ELSIF ((g_in_data_w*(v.c_v_count+1))+v.a_of >= c_out_data_w*(v.out_data_count+1)) AND (v.out_data_count = 0) THEN + v.state := FIRST_OUTPUT; + ELSIF ((g_in_data_w*(v.c_v_count+1))+v.a_of >= c_out_data_w*(v.out_data_count+1)) AND (v.out_data_count = 1) THEN + v.state := OVERFLOW_OUTPUT; + ELSE + v.state := FILL_VECTOR; + END IF; + + WHEN OVERFLOW_OUTPUT => -- if the input data exceeds the output data vector width and the c_v width + v.a_of := v.a_of + (g_in_data_w*(v.c_v_count+1)) - (c_out_data_w*(v.out_data_count+1)); -- check how much overflow there is and safe it in a_of + v.out_of := v.a_of; -- set the output overflow to the overflow that maches the out_sosi.data vector + v.c_v(k_c_v_w-1 DOWNTO k_c_v_w-(g_in_data_w-v.a_of)) := in_data(g_in_data_w-v.a_of-1 DOWNTO 0); -- fill the rest of c_v untill the end + v.c_v(v.a_of-1 DOWNTO 0) := in_data(g_in_data_w-1 DOWNTO g_in_data_w-v.a_of); -- fill the start of c_v untill the a_of + v.out_sosi.data(c_out_data_w-1 DOWNTO 0) := v.c_v(k_c_v_w-1 DOWNTO c_out_data_w); -- fill out_sosi.data with 2nd part of c_v + v.out_sosi.valid := '1'; -- out_sosi.valid 1 + v.c_v_count := 0; -- reset counter + v.out_data_count := 0; -- reset counter + + IF rst = '1' THEN + v.state := RESET; + ELSIF ((g_in_data_w*(v.c_v_count+1))+v.a_of >= c_out_data_w*(v.out_data_count+1)) AND (v.out_data_count = 0) THEN + v.state := FIRST_OUTPUT; + ELSIF ((g_in_data_w*(v.c_v_count+1))+v.a_of >= c_out_data_w*(v.out_data_count+1)) AND (v.out_data_count = 1) THEN + v.state := OVERFLOW_OUTPUT; + ELSE + v.state := FILL_VECTOR; + END IF; + + WHEN RESET => + v := c_t_reg_init; + + IF rst = '1' THEN + v.state := RESET; + ELSE + v.state := FILL_VECTOR; + END IF; + + END CASE; + d_reg <= v; END PROCESS; + + -- fill outputs + out_of <= q_reg.out_of; + out_sosi <= q_reg.out_sosi; + END rtl; diff --git a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd index fa829a0ca0..19af844a04 100644 --- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd +++ b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd @@ -110,15 +110,10 @@ BEGIN ELSE lag_due_reset <= lag_due_reset+TO_UINT(out_mosi.address); END IF; - WAIT FOR c_clk_period*1; -- filling the input data vectors with the corresponding numbers - fill_in_sosi_arr : FOR I IN 0 TO g_nof_streams-1 LOOP - in_sosi_arr(I).data(g_data_w-1 DOWNTO 0) <= c_total_vector(g_data_w*(I+1)-1 DOWNTO g_data_w*I); - END LOOP; - WAIT FOR c_clk_period*1; test_running <= '1'; -- beceause there is al delay in address counter, test running should go up one clockcycle later in order for p_verify to function - make_data : FOR J IN 1 TO g_sim_length-1 LOOP + make_data : FOR J IN 0 TO g_sim_length-1 LOOP fill_in_sosi_arr_rest : FOR I IN 0 TO g_nof_streams-1 LOOP in_sosi_arr(I).data(g_data_w-1 DOWNTO 0) <= c_total_vector(g_data_w*(I+1)+J*c_in_data_w-1 DOWNTO g_data_w*I+J*c_in_data_w); END LOOP; @@ -137,7 +132,7 @@ BEGIN ELSE lag_due_reset <= lag_due_reset+TO_UINT(out_mosi.address); END IF; - WAIT FOR c_clk_period*((((c_out_data_w / c_in_data_w)+1)*c_adr_size)+4); + WAIT FOR c_clk_period*((((c_out_data_w/c_in_data_w)+1)*c_adr_size)+4); END LOOP; @@ -176,18 +171,18 @@ BEGIN -- verification by checking if the input vectors are correctly put into the output vector and the amount of overflow is as expected p_verify : PROCESS - VARIABLE ctr_of : NATURAL := 0; - VARIABLE out_data_cnt : NATURAL := 0; + VARIABLE ctr_of : NATURAL := 0; + VARIABLE out_data_cnt : NATURAL := 0; BEGIN WAIT UNTIL rising_edge(clk); - IF test_running = '1' AND out_mosi.wr = '1'THEN + IF test_running = '1' AND out_mosi.wr = '1' THEN out_data_cnt := out_data_cnt+1; IF out_data_cnt mod 2 = 0 THEN - ctr_of := c_in_data_w*in_data_cnt-c_out_data_w*out_data_cnt; - ASSERT ctr_of = out_of REPORT "The amount of overflow does not match, ctr_of = " & NATURAL'image(ctr_of) & ", out_of = " & NATURAL'image(out_of) SEVERITY ERROR; + ctr_of := c_in_data_w*(in_data_cnt-2)-c_out_data_w*out_data_cnt; + ASSERT ctr_of = out_of REPORT "The amount of overflow does not match, ctr_of = " & NATURAL'image(ctr_of) & ", out_of = " & NATURAL'image(out_of) SEVERITY ERROR; END IF; - ASSERT out_mosi.wrdata(c_out_data_w-1 DOWNTO 0) = c_total_vector(c_out_data_w*out_data_cnt-1 DOWNTO c_out_data_w*(out_data_cnt-1)) REPORT "Data does not match, out_data_cnt = " & NATURAL'image(out_data_cnt) SEVERITY ERROR; + ASSERT out_mosi.wrdata(c_out_data_w-1 DOWNTO 0) = c_total_vector(c_out_data_w*out_data_cnt-1 DOWNTO c_out_data_w*(out_data_cnt-1)) REPORT "Data does not match, out_data_cnt = " & NATURAL'image(out_data_cnt) SEVERITY ERROR; 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 0a5b356e38..519f863121 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 @@ -35,7 +35,7 @@ ENTITY tb_ddrctrl_address_counter IS 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 + g_sim_length : NATURAL := 152 -- determens the length of the duration of the test ); END tb_ddrctrl_address_counter; @@ -57,9 +57,11 @@ ARCHITECTURE tb OF tb_ddrctrl_address_counter IS SIGNAL rst : STD_LOGIC := '0'; SIGNAL q_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_of : NATURAL := 0; -- 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_of : NATURAL := 0; -- testbench signals SIGNAL tb_end : STD_LOGIC := '0'; -- signal to turn the testbench off @@ -69,6 +71,7 @@ ARCHITECTURE tb OF tb_ddrctrl_address_counter IS SIGNAL q_in_data_enable : STD_LOGIC := '0'; -- signal to determen if in_data is ready for reading with a delay of 1 clockcycle SIGNAL lag_due_reset : NATURAL := 0; -- signal to hold the address lag after a reset SIGNAL q_lag_due_reset : NATURAL := 0; -- signal to hold the address lag after a reset with a delay of 1 clockcycle + SIGNAL q_in_of : NATURAL := 0; BEGIN @@ -93,6 +96,7 @@ BEGIN FOR I IN 0 TO g_sim_length-1 LOOP in_data_enable <= '1'; in_data <= NOT in_data; + in_of <= in_of + 1; WAIT FOR c_clk_period*1; in_data_enable <= '0'; WAIT FOR c_clk_period*2; @@ -113,6 +117,7 @@ BEGIN q_in_data <= in_data; q_lag_due_reset <= lag_due_reset; q_rst <= rst; + q_in_of <= in_of; END IF; END PROCESS; @@ -124,6 +129,7 @@ BEGIN IF rising_edge(clk) THEN ASSERT q_in_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 q_in_data_enable = out_mosi.wr REPORT "in_sosi.valid does not match out_mosi.wr" SEVERITY ERROR; + ASSERT q_in_of = out_of REPORT "in_of does not match out_of" SEVERITY ERROR; END IF; END PROCESS; @@ -131,13 +137,12 @@ BEGIN p_test_reset : PROCESS BEGIN rst <= '0'; - --WAIT FOR c_clk_period*1; 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; - WAIT FOR c_clk_period*(c_adr_size+3); + WAIT FOR c_clk_period*((c_adr_size*4)+3); rst <= '1'; WAIT FOR c_clk_period*1; END PROCESS; @@ -146,7 +151,7 @@ BEGIN p_verify_address : PROCESS BEGIN FOR I IN 0 TO c_adr_size-1 LOOP - WAIT UNTIL out_mosi.wr = '1'; + WAIT UNTIL out_mosi.wr = '1'; IF q_rst = '1' THEN WAIT UNTIL out_mosi.wr = '1'; END IF; @@ -169,8 +174,10 @@ BEGIN clk => clk, rst => rst, in_sosi => in_sosi, + in_of => in_of, - out_mosi => out_mosi + out_mosi => out_mosi, + out_of => out_of ); END tb; diff --git a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_repack.vhd b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_repack.vhd index 7044955402..9deac26df4 100644 --- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_repack.vhd +++ b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_repack.vhd @@ -99,11 +99,9 @@ BEGIN rst <= '0'; WAIT FOR c_clk_period*1; test_running <= '1'; -- start of test - in_data_cnt <= in_data_cnt +1; - WAIT FOR c_clk_period*1; -- filling the input vector g_sim_lengt amount of times - make_in_data : FOR I IN 1 TO g_sim_lengt-1 LOOP + make_in_data : FOR I IN 0 TO g_sim_lengt-1 LOOP in_data(g_in_data_w-1 DOWNTO 0) <= TO_UVEC(I, g_in_data_w); WAIT FOR c_clk_period*1; in_data_cnt <= in_data_cnt + 1; -- GitLab