diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd index 496b7015d76622ccdb3da51d21d39f2a3ef36ef7..5bef72ca9a0e9e7b3b8dd846180b5c16ae109aa0 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd @@ -97,7 +97,7 @@ BEGIN clk => clk, rst => rst, in_data => data, -- input data - out_of => a_of, -- amount of internal overflow + out_of => a_of, -- amount of internal overflow out_sosi => sosi -- output data ); 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 313f594ff138593c1a1fad09567fea3104952b33..ef295d5d3aac265cccd1b0d364e101c51180ba13 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_address_counter.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_address_counter.vhd @@ -41,13 +41,13 @@ USE dp_lib.dp_stream_pkg.ALL; ENTITY ddrctrl_address_counter IS GENERIC ( - g_tech_ddr : t_c_tech_ddr; -- type of memory + 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 + 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 @@ -60,7 +60,7 @@ 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 : 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 + 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 -- type for statemachine TYPE t_state IS (RESET, COUNTING, MAX, IDLE); @@ -70,9 +70,12 @@ ARCHITECTURE rtl OF ddrctrl_address_counter IS state : t_state; out_mosi : t_mem_ctlr_mosi; out_of : NATURAL; + s_in_sosi : t_dp_sosi; + s_in_of : NATURAL; END RECORD; - CONSTANT c_t_reg_init : t_reg := (RESET, c_mem_ctlr_mosi_rst, 0); + CONSTANT c_t_reg_init : t_reg := (RESET, c_mem_ctlr_mosi_rst, 0, c_dp_sosi_init, 0); + -- signals for readability SIGNAL d_reg : t_reg := c_t_reg_init; @@ -89,16 +92,19 @@ BEGIN BEGIN v := q_reg; - 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; + v.out_mosi.wrdata(c_data_w-1 DOWNTO 0) := v.s_in_sosi.data(c_data_w - 1 DOWNTO 0); + v.out_mosi.wr := v.s_in_sosi.valid; + v.out_of := v.s_in_of; + v.s_in_sosi := in_sosi; + v.s_in_of := in_of; + - CASE v.state IS + CASE q_reg.state IS WHEN RESET => v.out_mosi.address(c_adr_w-1 DOWNTO 0) := (OTHERS => '0'); 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)); + v.out_mosi.address(c_adr_w-1 DOWNTO 0) := STD_LOGIC_VECTOR(TO_UVEC(TO_UINT(q_reg.out_mosi.address)+1, c_adr_w)); WHEN MAX => v.out_mosi.address(c_adr_w-1 DOWNTO 0) := (OTHERS => '0'); @@ -109,7 +115,7 @@ BEGIN 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 + ELSIF q_reg.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; diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_repack.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_repack.vhd index 92b6fc53a92a5ffd585fe6b648397de94a27b918..57f3afd205c0645ecb9a6b1ad09adb4d61b865c9 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_repack.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_repack.vhd @@ -36,15 +36,15 @@ USE tech_ddr_lib.tech_ddr_pkg.ALL; ENTITY ddrctrl_repack IS GENERIC ( - g_tech_ddr : t_c_tech_ddr; -- type of memory - g_in_data_w : NATURAL := 168 -- the input data with + g_tech_ddr : t_c_tech_ddr; -- type of memory + g_in_data_w : NATURAL := 168 -- the input data with ); PORT ( clk : IN STD_LOGIC; rst : IN STD_LOGIC; - in_data : IN STD_LOGIC_VECTOR(g_in_data_w-1 DOWNTO 0); -- input data - out_of : OUT NATURAL := 0; -- amount of internal overflow this output - out_sosi : OUT t_dp_sosi := c_dp_sosi_init -- output data + in_data : IN STD_LOGIC_VECTOR(g_in_data_w-1 DOWNTO 0); -- input data + out_of : OUT NATURAL := 0; -- amount of internal overflow this output + out_sosi : OUT t_dp_sosi := c_dp_sosi_init -- output data ); END ddrctrl_repack; @@ -52,28 +52,28 @@ END ddrctrl_repack; ARCHITECTURE rtl OF ddrctrl_repack IS -- 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 + 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 + 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); + 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; + SIGNAL d_reg : t_reg := c_t_reg_init; + SIGNAL q_reg : t_reg := c_t_reg_init; BEGIN @@ -82,73 +82,52 @@ BEGIN -- put the input data into c_v and fill the output vector from c_v p_state : PROCESS(q_reg, rst) - VARIABLE v : t_reg := c_t_reg_init; + VARIABLE v : t_reg; BEGIN - 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; + v := q_reg; + + CASE q_reg.state IS + WHEN FILL_VECTOR => -- if the input data doesn't exceeds the output data vector width + v.c_v(g_in_data_w*(q_reg.c_v_count+1)+q_reg.a_of-1 DOWNTO g_in_data_w*q_reg.c_v_count+q_reg.a_of) := in_data(g_in_data_w-1 DOWNTO 0); -- fill c_v + v.c_v_count := q_reg.c_v_count+1; -- increase the counter of c_v with 1 + v.out_sosi.valid := '0'; -- out_sosi.valid 0 + + 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*(q_reg.c_v_count+1)+q_reg.a_of-1 DOWNTO g_in_data_w*q_reg.c_v_count+q_reg.a_of) := in_data(g_in_data_w-1 DOWNTO 0); -- fill c_v + v.c_v_count := q_reg.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 := q_reg.out_data_count+1; -- increase the counter of out_sosi.data with 1 + + WHEN OVERFLOW_OUTPUT => -- if the input data exceeds the output data vector width and the c_v width + v.a_of := q_reg.a_of + (g_in_data_w*(q_reg.c_v_count+1)) - (c_out_data_w*(q_reg.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; - ELSE - v.state := FILL_VECTOR; - END IF; + WHEN RESET => + v := c_t_reg_init; END CASE; - d_reg <= v; + + + 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; + + d_reg <= v; END PROCESS; -- fill outputs diff --git a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd index 19af844a04f26fbd20423da04e074d949e0a0935..8b56c9ddcf22d7455e0099fbc19f4179ba6e526c 100644 --- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd +++ b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd @@ -73,6 +73,8 @@ ARCHITECTURE tb OF tb_ddrctrl IS -- input signals for ddrctrl.vhd SIGNAL clk : STD_LOGIC := '1'; SIGNAL rst : STD_LOGIC := '0'; + SIGNAL q_rst : STD_LOGIC := '0'; + SIGNAL q_q_rst : STD_LOGIC := '0'; SIGNAL in_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_init); -- input data signal for ddrctrl_pack.vhd -- output singals from ddrctrl.vhd @@ -84,10 +86,13 @@ ARCHITECTURE tb OF tb_ddrctrl IS -- signals for running test SIGNAL in_data_cnt : NATURAL := 0; -- signal which contains the amount of times there has been input data for ddrctrl_repack.vhd + SIGNAL q_in_data_cnt : NATURAL := 0; -- signal which contains the amount of times there has been input data for ddrctrl_repack.vhd with a delay of 1 clockcycle + SIGNAL q_q_in_data_cnt : NATURAL := 0; -- signal which contains the amount of times there has been input data for ddrctrl_repack.vhd with a delay of 2 clockcycles SIGNAL test_running : STD_LOGIC := '0'; -- signal to tell wheter the testing has started + SIGNAL q_test_running : STD_LOGIC := '0'; -- signal to tell wheter the testing has started with a delay of 1 clockcycle + SIGNAL q_q_test_running : STD_LOGIC := '0'; -- signal to tell wheter the testing has started with a delay of 2 clockcycles SIGNAL lag_due_reset : NATURAL := 0; -- signal to hold the address lag after a rest - SIGNAL q_lag_due_reset : NATURAL := 0; - SIGNAL q_rst : STD_LOGIC := '0'; + SIGNAL q_lag_due_reset : NATURAL := 0; -- signal to hold the address lag after a rest with a delay of 1 clockcycle BEGIN @@ -99,26 +104,21 @@ BEGIN BEGIN -- start the test - tb_end <= '0'; + tb_end <= '0'; WAIT UNTIL rising_edge(clk); -- align to rising edge - WAIT FOR c_clk_period*5; + WAIT FOR c_clk_period*4; rst <= '1'; WAIT FOR c_clk_period*1; rst <= '0'; - 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; + test_running <= '1'; -- filling the input data vectors with the corresponding numbers - 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 0 TO g_sim_length-1 LOOP + in_data_cnt <= in_data_cnt+1; 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; WAIT FOR c_clk_period*1; - in_data_cnt <= in_data_cnt+1; END LOOP; test_running <= '0'; @@ -127,19 +127,14 @@ BEGIN rst <= '1'; WAIT FOR c_clk_period*1; rst <= '0'; - 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_out_data_w/c_in_data_w)+1)*c_adr_size)+4); END LOOP; -- stopping the testbench - WAIT FOR c_clk_period*5; + WAIT FOR c_clk_period*4; tb_end <= '1'; - ASSERT FALSE REPORT "Test: OK" SEVERITY FAILURE; + ASSERT FALSE REPORT "Test: OK" SEVERITY FAILURE; END PROCESS; -- generating compare data for out_mosi @@ -147,8 +142,16 @@ BEGIN BEGIN WAIT UNTIL rising_edge(clk); if rising_edge(clk) THEN - q_lag_due_reset <= lag_due_reset; - q_rst <= rst; + q_q_rst <= q_rst; + q_lag_due_reset <= lag_due_reset; + q_rst <= rst; + END IF; + IF q_rst = '1' THEN + 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; END IF; END PROCESS; @@ -156,14 +159,14 @@ BEGIN p_verify_address : PROCESS BEGIN FOR I IN 0 TO c_adr_size-1 LOOP - WAIT UNTIL out_mosi.wr = '1'; - IF q_rst = '1' THEN - WAIT UNTIL out_mosi.wr = '1'; - END IF; IF I >= q_lag_due_reset THEN - ASSERT I-q_lag_due_reset = TO_UINT(out_mosi.address) REPORT "Wrong address, 1, I = " & NATURAL'image(I-q_lag_due_reset) & ", address = " & NATURAL'image(TO_UINT(out_mosi.address)) SEVERITY ERROR; + ASSERT I-q_lag_due_reset = TO_UINT(out_mosi.address) REPORT "Wrong address, 1, I = " & NATURAL'image(I-q_lag_due_reset) & ", address = " & NATURAL'image(TO_UINT(out_mosi.address)) SEVERITY ERROR; ELSE - ASSERT (I-q_lag_due_reset)+c_adr_size = TO_UINT(out_mosi.address) REPORT "Wrong address, 2, I = " & NATURAL'image((I-q_lag_due_reset)+c_adr_size) & ", address = " & NATURAL'image(TO_UINT(out_mosi.address)) SEVERITY ERROR; + ASSERT (I-q_lag_due_reset)+c_adr_size = TO_UINT(out_mosi.address) REPORT "Wrong address, 2, I = " & NATURAL'image((I-q_lag_due_reset)+c_adr_size) & ", address = " & NATURAL'image(TO_UINT(out_mosi.address)) SEVERITY ERROR; + END IF; + WAIT UNTIL out_mosi.wr = '1'; + IF q_q_rst = '1' THEN + WAIT UNTIL out_mosi.wr = '1'; END IF; END LOOP; END PROCESS; @@ -176,13 +179,13 @@ BEGIN BEGIN WAIT UNTIL rising_edge(clk); - IF test_running = '1' AND out_mosi.wr = '1' THEN + IF q_q_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-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; + ctr_of := c_in_data_w*(q_q_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; 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 29778c5d5804a8f80e837026c30930676437b743..a17f098b594c673887acdc59f982a8dd87d515f2 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 @@ -56,22 +56,26 @@ ARCHITECTURE tb OF tb_ddrctrl_address_counter IS SIGNAL clk : STD_LOGIC := '1'; SIGNAL rst : STD_LOGIC := '0'; SIGNAL q_rst : STD_LOGIC := '0'; + SIGNAL q_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; + SIGNAL in_of : NATURAL := 0; -- signal which contains the amount of overflow -- 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; + SIGNAL out_of : NATURAL := 0; -- signal which is the output from ddrctrl_address_counter.vhd -- 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) := (OTHERS => '0'); -- signal which contains the data that is set as input SIGNAL q_in_data : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0) := (OTHERS => '0'); -- signal which contains the data that is set as input with a delay of 1 clockcycle + SIGNAL q_q_in_data : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0) := (OTHERS => '0'); -- signal which contains the data that is set as input with a delay of 2 clockcycles SIGNAL in_data_enable : STD_LOGIC := '0'; -- signal to determen if in_data is ready for reading 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 q_q_in_data_enable: STD_LOGIC := '0'; -- signal to determen if in_data is ready for reading with a delay of 2 clockcycles + SIGNAL q_in_of : NATURAL := 0; -- signal which contains the amount of overflow with a delay of 1 clockcycle + SIGNAL q_q_in_of : NATURAL := 0; -- signal which contains the amount of overflow with a delay of 2 clockcycles 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 @@ -105,7 +109,7 @@ BEGIN -- stopping the test WAIT FOR c_clk_period*4; tb_end <= '1'; - ASSERT FALSE REPORT "Test: OK" SEVERITY FAILURE; + ASSERT FALSE REPORT "Test: OK" SEVERITY FAILURE; END PROCESS; -- generating compare data for out_mosi @@ -113,11 +117,22 @@ BEGIN BEGIN WAIT UNTIL rising_edge(clk); if rising_edge(clk) THEN - q_in_data_enable <= in_data_enable; - q_in_data <= in_data; - q_lag_due_reset <= lag_due_reset; - q_rst <= rst; - q_in_of <= in_of; + q_q_in_data_enable <= q_in_data_enable; + q_q_in_data <= q_in_data; + q_q_in_of <= q_in_of; + q_q_rst <= q_rst; + q_in_data_enable <= in_data_enable; + q_in_data <= in_data; + q_in_of <= in_of; + q_lag_due_reset <= lag_due_reset; + q_rst <= rst; + END IF; + IF q_rst = '1' THEN + 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; END IF; END PROCESS; @@ -127,9 +142,9 @@ BEGIN BEGIN WAIT UNTIL rising_edge(clk); 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; + ASSERT q_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_q_in_data_enable = out_mosi.wr REPORT "in_sosi.valid does not match out_mosi.wr" SEVERITY ERROR; + ASSERT q_q_in_of = out_of REPORT "in_of does not match out_of" SEVERITY ERROR; END IF; END PROCESS; @@ -137,11 +152,6 @@ BEGIN p_test_reset : PROCESS BEGIN rst <= '0'; - 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*4)+3); rst <= '1'; WAIT FOR c_clk_period*1; @@ -151,14 +161,14 @@ BEGIN p_verify_address : PROCESS BEGIN FOR I IN 0 TO c_adr_size-1 LOOP - WAIT UNTIL out_mosi.wr = '1'; - IF q_rst = '1' THEN - WAIT UNTIL out_mosi.wr = '1'; - END IF; IF I >= q_lag_due_reset THEN - ASSERT I-q_lag_due_reset = TO_UINT(out_mosi.address) REPORT "Wrong address, 1, I = " & NATURAL'image(I-q_lag_due_reset) & ", address = " & NATURAL'image(TO_UINT(out_mosi.address)) SEVERITY ERROR; + ASSERT I-q_lag_due_reset = TO_UINT(out_mosi.address) REPORT "Wrong address, 1, I = " & NATURAL'image(I-q_lag_due_reset) & ", address = " & NATURAL'image(TO_UINT(out_mosi.address)) SEVERITY ERROR; ELSE - ASSERT (I-q_lag_due_reset)+c_adr_size = TO_UINT(out_mosi.address) REPORT "Wrong address, 2, I = " & NATURAL'image((I-q_lag_due_reset)+c_adr_size) & ", address = " & NATURAL'image(TO_UINT(out_mosi.address)) SEVERITY ERROR; + ASSERT (I-q_lag_due_reset)+c_adr_size = TO_UINT(out_mosi.address) REPORT "Wrong address, 2, I = " & NATURAL'image((I-q_lag_due_reset)+c_adr_size) & ", address = " & NATURAL'image(TO_UINT(out_mosi.address)) SEVERITY ERROR; + END IF; + WAIT UNTIL out_mosi.wr = '1'; + IF q_q_rst = '1' THEN + WAIT UNTIL out_mosi.wr = '1'; END IF; END LOOP; END PROCESS; 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 9deac26df49b4450b9dedd6db388dbc819bec720..b458fc3ca7396cf705c96f06a050ab6b657be576 100644 --- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_repack.vhd +++ b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_repack.vhd @@ -111,7 +111,7 @@ BEGIN -- stopping the testbench WAIT FOR c_clk_period*5; tb_end <= '1'; - ASSERT FALSE REPORT "Test: OK" SEVERITY FAILURE; + ASSERT FALSE REPORT "Test: OK" SEVERITY FAILURE; END PROCESS; -- verification by checking if the input vectors are correctly put into the output vector and the amount of overflow is as expected