diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd index ef794a959189c434e132772f00fd16c772b5f3c9..dae488683ff8ad66a51d73e59559993dac21dbc8 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd @@ -239,7 +239,8 @@ BEGIN g_in_data_w => c_io_ddr_data_w, g_nof_streams => g_nof_streams, g_data_w => g_data_w, - g_block_size => g_block_size + g_block_size => g_block_size, + g_bim => c_bim ) PORT MAP( clk => clk, diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd index 6bb5a508908316af7538db8337fb7635f5522069..6819e8b424efd4aef9b6f59ebfd7595f2c439578 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd @@ -161,6 +161,7 @@ BEGIN WHEN WAIT_FOR_SOP => + v.dvr_mosi.burstbegin := '0'; v.rst_ddrctrl_input := '0'; IF q_reg.started = '0' AND inp_sosi.eop = '1' THEN v.wr_sosi.valid := '1'; diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input_repack.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input_repack.vhd index 402f27165fff715b993311c756b8a338b95ab917..f85f1b201e9f30497302d8b684c47f73647325c9 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input_repack.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input_repack.vhd @@ -68,7 +68,6 @@ ARCHITECTURE rtl OF ddrctrl_input_repack IS state : t_state; -- the state the process is currently in; 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 - a_of : NATURAL; -- this is the amount of bits that the first data word(168) is shifted from the first bit in the data word(576) q_bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); q_sop : STD_LOGIC; s_input_cnt : NATURAL; @@ -78,7 +77,7 @@ ARCHITECTURE rtl OF ddrctrl_input_repack IS out_data_stopped : STD_LOGIC; -- this signal is '1' when there is no more data comming form ddrctrl_input_pack END RECORD; - CONSTANT c_t_reg_init : t_reg := (RESET, (OTHERS => '0'), 0, 0, (OTHERS => '0'), '0', 0, 0, '0', c_dp_sosi_init, '0'); + CONSTANT c_t_reg_init : t_reg := (RESET, (OTHERS => '0'), 0, (OTHERS => '0'), '0', 0, 0, '0', c_dp_sosi_init, '0'); -- signals for readability @@ -122,7 +121,7 @@ BEGIN v.state := FILL_VECTOR; END IF; - IF in_sosi.sop = '1' THEN + IF in_sosi.eop = '1' THEN v.s_input_cnt := 0; v.state := BSN; END IF; @@ -151,7 +150,7 @@ BEGIN v.state := FILL_VECTOR; END IF; - IF in_sosi.sop = '1' THEN + IF in_sosi.eop = '1' THEN v.s_input_cnt := 0; v.state := BSN; END IF; @@ -182,7 +181,7 @@ BEGIN v.state := FILL_VECTOR; END IF; - IF in_sosi.sop = '1' THEN + IF in_sosi.eop = '1' THEN v.s_input_cnt := 0; v.state := BSN; END IF; @@ -191,18 +190,18 @@ BEGIN WHEN BSN => v.c_v(k_c_v_w-1 DOWNTO ((g_in_data_w*q_reg.c_v_count)+q_reg.out_of)) := (OTHERS =>'0'); + v.out_of := 0; IF ((g_in_data_w*q_reg.c_v_count)+q_reg.out_of < c_out_data_w*1) THEN 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_sosi.valid := '1'; -- out_sosi.valid 1 ELSE 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.out_sosi.valid := '1'; -- out_sosi.valid 1 END IF; -- BSN_INPUT v.q_bsn := in_sosi.bsn; -- a bsn number is saved when the bsn changes v.q_sop := '1'; -- a signal which indicates that a bsn is written in this word(576) so the address counter can save the corresponinding address. (there are delay in address counter so in_adr is not the same as the address of the word the data from the bsn is written to) - v.a_of := 0; v.c_v(g_in_data_w-1 DOWNTO 0) := in_sosi.data(g_in_data_w-1 DOWNTO 0); -- fill c_v v.c_v_count := 1; -- increase the counter of c_v with 1 v.out_data_count := '0'; diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd index 5bef382784b11c0051abe598b9f594191e3fbab2..2e48f3e4d7861b920a159cc8343f0283e10ef3ea 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd @@ -46,7 +46,8 @@ ENTITY ddrctrl_output IS g_in_data_w : NATURAL := 576; g_nof_streams : NATURAL := 12; -- number of input streams g_data_w : NATURAL := 14; -- data with of input data vectors - g_block_size : NATURAL := 1024 + g_block_size : NATURAL := 1024; + g_bim : NATURAL := 54 ); PORT ( clk : IN STD_LOGIC := '0'; @@ -75,7 +76,8 @@ BEGIN g_tech_ddr => g_tech_ddr, g_in_data_w => g_in_data_w, g_out_data_w => c_out_data_w, - g_block_size => g_block_size + g_block_size => g_block_size, + g_bim => g_bim ) PORT MAP( clk => clk, diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_unpack.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_unpack.vhd index 64d6caf13618fb20bde78e16fbb0157b899eec0a..e412655b39d3e7ca9f2244de9eaa83c7394b0673 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_unpack.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_unpack.vhd @@ -42,7 +42,8 @@ ENTITY ddrctrl_output_unpack IS g_tech_ddr : t_c_tech_ddr; g_in_data_w : NATURAL; g_out_data_w : NATURAL; - g_block_size : NATURAL + g_block_size : NATURAL; + g_bim : NATURAL ); PORT ( clk : IN STD_LOGIC; @@ -57,8 +58,10 @@ END ddrctrl_output_unpack; ARCHITECTURE rtl OF ddrctrl_output_unpack IS + CONSTANT c_v_w : NATURAL := g_in_data_w*2; + -- type for statemachine - TYPE t_state IS ( READING, FIRST_READ, SECOND_READ, OVER_HALF, RESET, IDLE, OFF); + TYPE t_state IS ( READING, FIRST_READ, OVER_HALF, BSN, RESET, IDLE, OFF); -- record for readability TYPE t_reg IS RECORD @@ -67,15 +70,14 @@ ARCHITECTURE rtl OF ddrctrl_output_unpack IS op_data_cnt : NATURAL; delay_data : STD_LOGIC_VECTOR(g_in_data_w-1 DOWNTO 0); dd_fresh : STD_LOGIC; - c_v : STD_LOGIC_VECTOR(g_in_data_w*2-1 DOWNTO 0); - sr_done : STD_LOGIC; + valid_data : STD_LOGIC; + c_v : STD_LOGIC_VECTOR(c_v_w-1 DOWNTO 0); bsn_cnt : NATURAL; out_sosi : t_dp_sosi; out_ready : STD_LOGIC; END RECORD; - CONSTANT c_t_reg_init : t_reg := (RESET, 0, 0, (OTHERS => '0'), '0', (OTHERS => '0'), '0', 0, c_dp_sosi_init, '0'); - + CONSTANT c_t_reg_init : t_reg := (RESET, 0, 0, (OTHERS => '0'), '0', '0', (OTHERS => '0'), 0, c_dp_sosi_init, '0'); -- signals for readability SIGNAL d_reg : t_reg := c_t_reg_init; @@ -103,107 +105,205 @@ BEGIN v.bsn_cnt := q_reg.bsn_cnt+1; v.op_data_cnt := q_reg.op_data_cnt+1; - IF q_reg.bsn_cnt = g_block_size-1 THEN - v.out_sosi.bsn(c_dp_stream_bsn_w-1 DOWNTO 0) := INCR_UVEC(q_reg.out_sosi.bsn, 1); - v.bsn_cnt := 0; + IF q_reg.dd_fresh = '1' AND q_reg.valid_data = '0' THEN + -- put the delay data into the second half of c_v beceause these are now zeros + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); + v.dd_fresh := '0'; + v.valid_data := '1'; END IF; - IF in_sosi.valid = '1' THEN v.delay_data(g_in_data_w-1 DOWNTO 0) := in_sosi.data(g_in_data_w-1 DOWNTO 0); v.dd_fresh := '1'; END IF; - IF (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of >= g_in_data_w AND v.dd_fresh = '1' THEN + IF (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of >= g_in_data_w AND (v.dd_fresh = '1' OR v.valid_data = '1')THEN v.state := OVER_HALF; - ELSIF (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of >= g_in_data_w AND v.dd_fresh = '0' THEN + ELSIF (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of >= g_in_data_w AND v.dd_fresh = '0' AND v.valid_data = '0' THEN v.state := IDLE; ELSE v.state := READING; END IF; + IF q_reg.out_sosi.eop = '1' THEN + v.out_sosi.bsn(c_dp_stream_bsn_w-1 DOWNTO 0) := INCR_UVEC(q_reg.out_sosi.bsn, 1); + v.out_sosi.eop := '0'; + v.out_sosi.sop := '1'; + v.bsn_cnt := 0; + ELSIF q_reg.out_sosi.sop = '1' THEN + v.out_sosi.sop := '0'; + END IF; + + IF q_reg.bsn_cnt = g_block_size-3 THEN + v.state := BSN; + v.out_ready := '1'; + END IF; + + WHEN OVER_HALF => -- generating output data from c_v but past the halfway point of c_v so there needs to be new data added - v.out_ready := '1'; - v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := q_reg.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); - v.out_sosi.valid := '1'; - v.bsn_cnt := q_reg.bsn_cnt+1; - v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(g_in_data_w*2-1 DOWNTO g_in_data_w); - v.c_v(g_in_data_w*2-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); - v.dd_fresh := '0'; - v.a_of := (g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-g_in_data_w; - v.op_data_cnt := 0; - - IF q_reg.bsn_cnt = g_block_size-1 THEN - v.out_sosi.bsn(c_dp_stream_bsn_w-1 DOWNTO 0) := INCR_UVEC(q_reg.out_sosi.bsn, 1); - v.bsn_cnt := 0; + IF q_reg.dd_fresh = '1' AND q_reg.valid_data = '1' THEN + v.out_ready := '1'; + -- generate output from the middle of c_v + v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := q_reg.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); + v.out_sosi.valid := '1'; + v.bsn_cnt := q_reg.bsn_cnt+1; + -- put the second half of c_v into the first half of c_v + v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(c_v_w-1 DOWNTO g_in_data_w); + -- put the delay data into the first half of c_v + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); + v.dd_fresh := '0'; + v.a_of := ((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of)-g_in_data_w; + v.op_data_cnt := 0; + ELSIF q_reg.dd_fresh = '0' AND q_reg.valid_data = '1' THEN + v.out_ready := '1'; + -- generate output from the middle of c_v + v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := q_reg.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); + v.out_sosi.valid := '1'; + v.bsn_cnt := q_reg.bsn_cnt+1; + -- put the second half of c_v into the first half of c_v + v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(c_v_w-1 DOWNTO g_in_data_w); + -- put zeros into the second half of c_v beceause dd_fresh is '0' + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := (OTHERS => '0'); + v.a_of := ((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of)-g_in_data_w; + v.op_data_cnt := 0; + v.valid_data := '0'; + ELSIF q_reg.dd_fresh = '1' AND q_reg.valid_data = '0' THEN + v.out_ready := '1'; + -- put the delay data into the second half of c_v beceause these are now zeros + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); + -- generate output from the middle of c_v + v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := v.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); + -- put the second half of c_v into the first half of c_v + v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(c_v_w-1 DOWNTO g_in_data_w); + v.out_sosi.valid := '1'; + v.bsn_cnt := q_reg.bsn_cnt+1; + v.dd_fresh := '0'; + v.a_of := ((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of)-g_in_data_w; + v.op_data_cnt := 0; END IF; + + + IF in_sosi.valid = '1' THEN v.delay_data(g_in_data_w-1 DOWNTO 0) := in_sosi.data(g_in_data_w-1 DOWNTO 0); - v.dd_fresh := '1'; + v.dd_fresh := '1'; END IF; - - IF (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of >= g_in_data_w AND v.dd_fresh = '1' THEN - v.state := OVER_HALF; - ELSIF (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of >= g_in_data_w AND v.dd_fresh = '0' THEN - v.state := IDLE; + IF (g_out_data_w*(v.op_data_cnt+1))+v.a_of >= g_in_data_w AND (v.dd_fresh = '1' OR v.valid_data = '1') THEN + v.state := OVER_HALF; + ELSIF q_reg.dd_fresh = '0' AND q_reg.valid_data = '0' THEN + v.state := IDLE; ELSE - v.state := READING; + v.state := READING; END IF; + IF q_reg.out_sosi.sop = '1' THEN + v.out_sosi.sop := '0'; + END IF; + + IF q_reg.bsn_cnt = g_block_size-3 THEN + v.state := BSN; + v.dd_fresh := '1'; + END IF; WHEN FIRST_READ => -- fills the first half of c_v and generates a output from it. - v.out_ready := '0'; + v.out_ready := '0'; + v.c_v(c_v_w-1 DOWNTO 0) := (OTHERS => '0'); v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); - v.dd_fresh := '0'; + v.dd_fresh := '0'; v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := v.c_v(g_out_data_w+v.a_of-1 DOWNTO v.a_of); - v.out_sosi.valid := '1'; + v.out_sosi.valid := '0'; v.out_sosi.bsn(c_dp_stream_bsn_w-1 DOWNTO 0) := in_bsn(c_dp_stream_bsn_w-1 DOWNTO 0); - + v.out_sosi.sop := '1'; + v.out_sosi.eop := '0'; + v.bsn_cnt := 0; + v.op_data_cnt := q_reg.op_data_cnt+1; + + IF v.dd_fresh = '1' AND v.valid_data = '0' THEN + -- put the delay data into the second half of c_v beceause these are now zeros + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); + v.dd_fresh := '0'; + v.valid_data := '1'; + END IF; IF in_sosi.valid = '1' THEN v.delay_data(g_in_data_w-1 DOWNTO 0) := in_sosi.data(g_in_data_w-1 DOWNTO 0); - v.dd_fresh := '1'; + v.dd_fresh := '1'; END IF; - IF v.dd_fresh = '1' THEN - v.state := SECOND_READ; - ELSE - v.state := IDLE; + v.state := READING; + + WHEN BSN => + v.out_sosi.valid := '0'; + -- generating output data from c_v but past the halfway point of c_v so there needs to be new data added + IF q_reg.dd_fresh = '1' AND q_reg.valid_data = '1' THEN + -- generate output from the middle of c_v + v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := q_reg.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); + v.out_sosi.valid := '1'; + v.bsn_cnt := q_reg.bsn_cnt+1; + -- put the second half of c_v into the first half of c_v + v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(c_v_w-1 DOWNTO g_in_data_w); + -- put the delay data into the first half of c_v + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); + v.dd_fresh := '0'; + v.op_data_cnt := 0; + ELSIF q_reg.dd_fresh = '0' AND q_reg.valid_data = '1' THEN + -- generate output from the middle of c_v + v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := q_reg.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); + v.out_sosi.valid := '1'; + v.bsn_cnt := q_reg.bsn_cnt+1; + -- put the second half of c_v into the first half of c_v + v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(c_v_w-1 DOWNTO g_in_data_w); + -- put zeros into the second half of c_v beceause dd_fresh is '0' + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := (OTHERS => '0'); + v.op_data_cnt := 0; + v.valid_data := '0'; + ELSIF q_reg.dd_fresh = '1' AND q_reg.valid_data = '0' THEN + -- put the delay data into the second half of c_v beceause these are now zeros + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); + -- generate output from the middle of c_v + v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := v.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); + -- put the second half of c_v into the first half of c_v + v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(c_v_w-1 DOWNTO g_in_data_w); + v.out_sosi.valid := '1'; + v.bsn_cnt := q_reg.bsn_cnt+1; + v.dd_fresh := '0'; + v.op_data_cnt := 0; + ELSIF q_reg.dd_fresh = '0' AND q_reg.valid_data = '0' AND (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of < g_in_data_w THEN + -- generate output from the middle of c_v + v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := q_reg.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); + v.out_sosi.valid := '1'; + v.bsn_cnt := q_reg.bsn_cnt+1; END IF; - WHEN SECOND_READ => - -- fills the second half of c_v and generates a output from it. - v.out_ready := '0'; - v.c_v(g_in_data_w*2-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); - v.dd_fresh := '0'; - v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := v.c_v(g_out_data_w*2+q_reg.a_of-1 DOWNTO g_out_data_w+q_reg.a_of); - v.out_sosi.valid := '1'; - v.bsn_cnt := 1; - v.op_data_cnt := 2; - v.sr_done := '1'; + v.out_ready := '0'; + v.out_sosi.eop := '1'; + v.a_of := 0; + v.bsn_cnt := q_reg.bsn_cnt+1; + IF v.dd_fresh = '1' AND v.valid_data = '0' THEN + -- put the delay data into the second half of c_v beceause these are now zeros + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); + v.dd_fresh := '0'; + v.valid_data := '1'; + END IF; IF in_sosi.valid = '1' THEN v.delay_data(g_in_data_w-1 DOWNTO 0) := in_sosi.data(g_in_data_w-1 DOWNTO 0); - v.dd_fresh := '1'; + v.dd_fresh := '1'; END IF; - - IF (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of >= g_in_data_w AND v.dd_fresh = '1' THEN - v.state := OVER_HALF; - ELSIF (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of >= g_in_data_w AND v.dd_fresh = '0' THEN - v.state := IDLE; + IF g_bim+TO_UINT(in_bsn)-1 = TO_UINT(v.out_sosi.bsn) THEN + v.state := OFF; ELSE - v.state := READING; + v.state := READING; END IF; - WHEN RESET => v := c_t_reg_init; @@ -219,16 +319,20 @@ BEGIN v.out_ready := '1'; v.out_sosi.valid := '0'; + IF q_reg.dd_fresh = '1' AND q_reg.valid_data = '0' THEN + -- put the delay data into the second half of c_v beceause these are now zeros + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); + v.dd_fresh := '0'; + v.valid_data := '1'; + END IF; IF in_sosi.valid = '1' THEN v.delay_data(g_in_data_w-1 DOWNTO 0) := in_sosi.data(g_in_data_w-1 DOWNTO 0); v.dd_fresh := '1'; END IF; - IF (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of >= g_in_data_w AND v.dd_fresh = '1' AND q_reg.sr_done = '1' THEN + IF (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of >= g_in_data_w AND v.dd_fresh = '1'THEN v.state := OVER_HALF; - ELSIF (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of >= g_in_data_w AND v.dd_fresh = '1' AND q_reg.sr_done = '0' THEN - v.state := SECOND_READ; ELSE v.state := IDLE; END IF; @@ -239,7 +343,7 @@ BEGIN -- the stamachine has a state off so it knows when to go to first read, it can't go to first read from IDLE v.out_ready := '1'; v.delay_data(g_in_data_w-1 DOWNTO 0) := in_sosi.data(g_in_data_w-1 DOWNTO 0); - + v.out_sosi := c_dp_sosi_init; IF in_sosi.valid = '1' THEN v.state := FIRST_READ; diff --git a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd index 130720661eb7da7403696fe2eeb2bb5e3bfa62c7..0222a38227e4d365719d46471d94692524c91ed4 100644 --- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd +++ b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd @@ -1,3 +1,4 @@ + ------------------------------------------------------------------------------- -- -- Copyright 2022 @@ -128,7 +129,6 @@ ARCHITECTURE tb OF tb_ddrctrl IS SIGNAL mm_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 SIGNAL stop_in : STD_LOGIC := '0'; - SIGNAL bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0) := (OTHERS => '0'); SIGNAL out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_init); -- testbench signal @@ -158,6 +158,9 @@ BEGIN -- excecuting test p_test : PROCESS + + + BEGIN -- start the test @@ -180,27 +183,24 @@ BEGIN make_data : FOR J IN 0 TO c_bim*g_block_size-1 LOOP in_data_cnt <= in_data_cnt+1; 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)+J*c_in_data_w-1 DOWNTO g_data_w*I+J*c_in_data_w); - in_sosi_arr(I).valid <= '1'; - in_sosi_arr(I).bsn(c_dp_stream_bsn_w-1 DOWNTO 0) <= bsn(c_dp_stream_bsn_w-1 DOWNTO 0); IF bsn_cnt = g_block_size-1 THEN - bsn_cnt <= 0; - FOR I IN 0 TO g_nof_streams-1 LOOP - in_sosi_arr(I).sop <= '1'; - in_sosi_arr(I).eop <= '0'; - END LOOP; - bsn <= INCR_UVEC(bsn, 1); + IF I = 0 THEN + bsn_cnt <= 0; + END IF; + in_sosi_arr(I).sop <= '1'; + in_sosi_arr(I).eop <= '0'; + in_sosi_arr(I).bsn <= INCR_UVEC(in_sosi_arr(I).bsn, 1); ELSE - bsn_cnt <= bsn_cnt + 1; - FOR I IN 0 TO g_nof_streams-1 LOOP - in_sosi_arr(I).sop <= '0'; - END LOOP; + IF I = 0 THEN + bsn_cnt <= bsn_cnt + 1; + END IF; + in_sosi_arr(I).sop <= '0'; END IF; IF bsn_cnt = g_block_size-2 THEN - FOR I IN 0 TO g_nof_streams-1 LOOP - in_sosi_arr(I).eop <= '1'; - END LOOP; + in_sosi_arr(I).eop <= '1'; END IF; + 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); + in_sosi_arr(I).valid <= '1'; END LOOP; IF K = 0 AND J = c_bim*g_block_size-1 THEN stop_in <= '1';