From 3ac2e4aa99c65b7c20ff0b36424e28b6ac26a3c3 Mon Sep 17 00:00:00 2001 From: JobvanWee <wee@astron.nl> Date: Tue, 5 Apr 2022 13:25:19 +0200 Subject: [PATCH] save --- .../ddrctrl/src/vhdl/ddrctrl_input.vhd | 31 +++-- .../ddrctrl/src/vhdl/ddrctrl_input_pack.vhd | 6 +- .../ddrctrl/src/vhdl/ddrctrl_input_repack.vhd | 108 ++++++++++++++---- .../libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd | 14 ++- 4 files changed, 122 insertions(+), 37 deletions(-) diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input.vhd index 0125aa60e0..9cfa736431 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input.vhd @@ -55,7 +55,9 @@ ENTITY ddrctrl_input IS in_sosi_arr : IN t_dp_sosi_arr; -- input data out_of : OUT NATURAL; -- amount of internal overflow this output out_sosi : OUT t_dp_sosi; -- output data - out_adr : OUT NATURAL + out_adr : OUT NATURAL; + out_bsn_ds : OUT NATURAL; + out_bsn : OUT STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0) ); END ddrctrl_input; @@ -69,27 +71,28 @@ ARCHITECTURE str OF ddrctrl_input 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; + SIGNAL a_of : NATURAL := 0; + SIGNAL bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); + SIGNAL adr : NATURAL := 0; BEGIN + out_adr <= adr; + -- makes one data vector out of all the data from the t_dp_sosi_arr - u_pack : ENTITY work.ddrctrl_input_pack + u_ddrctrl_input_pack : ENTITY work.ddrctrl_input_pack GENERIC MAP( - g_nof_streams => g_nof_streams, -- number of input streams g_data_w => g_data_w -- data with of input data vectors - ) PORT MAP( - in_sosi_arr => in_sosi_arr, -- input data - out_data => data -- output data - + out_data => data, -- output data + out_bsn => bsn -- output bsn ); -- resizes the input data vector so that the output data vector can be stored into the ddr memory - u_repack : ENTITY work.ddrctrl_input_repack + u_ddrctrl_input_repack : ENTITY work.ddrctrl_input_repack GENERIC MAP( g_tech_ddr => g_tech_ddr, -- type of memory g_in_data_w => c_out_data_w -- the input data with @@ -98,12 +101,16 @@ BEGIN clk => clk, rst => rst, in_data => data, -- input data + in_bsn => bsn, + adr => adr, out_of => a_of, -- amount of internal overflow - out_sosi => sosi -- output data + out_sosi => sosi, -- output data + out_bsn_ds => out_bsn_ds, -- amount of bits between adr [0] and sosi_arr[0][0] where bsn is assigned to + out_bsn => out_bsn ); -- creates address by counting input valids - u_address_counter : ENTITY work.ddrctrl_input_address_counter + u_ddrctrl_input_address_counter : ENTITY work.ddrctrl_input_address_counter GENERIC MAP( g_tech_ddr => g_tech_ddr, -- type of memory g_sim_model => g_sim_model -- determens if this is a simulation @@ -115,7 +122,7 @@ BEGIN in_of => a_of, out_sosi => out_sosi, -- output data out_of => out_of, - out_adr => out_adr + out_adr => adr ); END str; diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input_pack.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input_pack.vhd index a7f32826e5..083e230501 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input_pack.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input_pack.vhd @@ -40,8 +40,9 @@ ENTITY ddrctrl_input_pack IS ); PORT ( - in_sosi_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); -- input data - out_data : OUT STD_LOGIC_VECTOR((g_nof_streams*g_data_w)-1 DOWNTO 0) -- output data + in_sosi_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); -- input data + out_data : OUT STD_LOGIC_VECTOR((g_nof_streams*g_data_w)-1 DOWNTO 0); -- output data + out_bsn : OUT STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0) -- output bsn ); END ddrctrl_input_pack; @@ -54,5 +55,6 @@ BEGIN gen_extract_and_pack_data : FOR I IN 0 TO g_nof_streams-1 GENERATE out_data(g_data_w*(I+1)-1 DOWNTO g_data_w*I) <= in_sosi_arr(I).data(g_data_w-1 DOWNTO 0); END GENERATE; + out_bsn <= in_sosi_arr(0).bsn(c_dp_stream_bsn_w-1 DOWNTO 0); END rtl; 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 ede68f09a7..850a360b69 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input_repack.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input_repack.vhd @@ -43,8 +43,12 @@ ENTITY ddrctrl_input_repack IS clk : IN STD_LOGIC; rst : IN STD_LOGIC; in_data : IN STD_LOGIC_VECTOR(g_in_data_w-1 DOWNTO 0); -- input data + in_bsn : IN STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); -- input bsn + adr : IN NATURAL; out_of : OUT NATURAL := 0; -- amount of internal overflow this output - out_sosi : OUT t_dp_sosi := c_dp_sosi_init -- output data + out_sosi : OUT t_dp_sosi := c_dp_sosi_init; -- output data + out_bsn_ds : OUT NATURAL := 0; + out_bsn : OUT STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0) ); END ddrctrl_input_repack; @@ -56,20 +60,22 @@ ARCHITECTURE rtl OF ddrctrl_input_repack IS 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); + TYPE t_state IS (BSN_INPUT, 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 + bsn_written : STD_LOGIC; out_of : NATURAL; out_sosi : t_dp_sosi; + out_bsn_ds : NATURAL; + out_bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); 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, (OTHERS => '0'), 0, 0, '0', 0, c_dp_sosi_init, 0, (OTHERS => '0')); -- signals for readability @@ -91,48 +97,106 @@ BEGIN 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(g_in_data_w*(q_reg.c_v_count+1)+q_reg.out_of-1 DOWNTO g_in_data_w*q_reg.c_v_count+q_reg.out_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 + IF rst = '1' THEN + v.state := RESET; + ELSIF ((g_in_data_w*(v.c_v_count+1))+v.out_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.out_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*(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 + v.c_v(g_in_data_w*(q_reg.c_v_count+1)+q_reg.out_of-1 DOWNTO g_in_data_w*q_reg.c_v_count+q_reg.out_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 + + IF rst = '1' THEN + v.state := RESET; + ELSIF ((g_in_data_w*(v.c_v_count+1))+v.out_of >= c_out_data_w*(v.out_data_count+1)) AND (v.out_data_count = 1) THEN + v.state := OVERFLOW_OUTPUT; + ELSIF adr = 0 AND v.bsn_written = '0' THEN -- because of delays in address counter the bsn number will be written in ddr address 1 or 2 dependend on . + v.state := BSN_INPUT; + 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 := 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_of := q_reg.out_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 out_of + v.c_v(k_c_v_w-1 DOWNTO k_c_v_w-(g_in_data_w-v.out_of)) := in_data(g_in_data_w-v.out_of-1 DOWNTO 0); -- fill the rest of c_v untill the end + v.c_v(v.out_of-1 DOWNTO 0) := in_data(g_in_data_w-1 DOWNTO g_in_data_w-v.out_of); -- fill the start of c_v untill the out_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.c_v_count := 0; -- reset counter v.out_data_count := 0; -- reset counter - WHEN RESET => - v := c_t_reg_init; + IF rst = '1' THEN + v.state := RESET; + ELSIF ((g_in_data_w*(v.c_v_count+1))+v.out_of >= c_out_data_w*(v.out_data_count+1)) AND (v.out_data_count = 0) THEN + v.state := FIRST_OUTPUT; + ELSIF adr = 0 AND v.bsn_written = '0' THEN -- because of delays in address counter the bsn number will be written in ddr address 1 or 2 dependend on . + v.state := BSN_INPUT; + ELSE + v.state := FILL_VECTOR; + END IF; - END CASE; + WHEN BSN_INPUT => + -- BSN_INPUT + v.out_bsn := in_bsn; + v.out_bsn_ds := g_in_data_w*q_reg.c_v_count+q_reg.out_of; + v.bsn_written := '1'; + + -- FILL_VECTOR + v.c_v(g_in_data_w*(q_reg.c_v_count+1)+v.out_of-1 DOWNTO g_in_data_w*q_reg.c_v_count+v.out_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 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 + ELSIF ((g_in_data_w*(v.c_v_count+1))+v.out_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 + ELSIF ((g_in_data_w*(v.c_v_count+1))+v.out_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; + ELSIF adr = 0 AND v.bsn_written = '0' THEN -- because of delays in address counter the bsn number will be written in ddr address 1 or 2 dependend on . + v.state := BSN_INPUT; + ELSE + v.state := FILL_VECTOR; + END IF; + + + END CASE; + + IF NOT (adr=0) THEN + v.bsn_written := '0'; + END IF; + d_reg <= v; END PROCESS; -- fill outputs - out_of <= q_reg.out_of; - out_sosi <= q_reg.out_sosi; + out_of <= q_reg.out_of; + out_sosi <= q_reg.out_sosi; + out_bsn_ds <= q_reg.out_bsn_ds; + out_bsn <= q_reg.out_bsn; 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 df1980ae0a..6aef30ec40 100644 --- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd +++ b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd @@ -82,6 +82,10 @@ ARCHITECTURE tb OF tb_ddrctrl IS -- constant for running the test CONSTANT c_total_vector : STD_LOGIC_VECTOR(c_in_data_w*c_sim_length-1 DOWNTO 0) := c_total_vector_init; -- vector which contains all input data vectors to make it easy to fill ctr_vector + CONSTANT c_check : NATURAL := 32; + CONSTANT c_check_bottom : NATURAL := 5; + CONSTANT c_ones : STD_LOGIC_VECTOR(c_check-c_check_bottom-1 DOWNTO 0) := (OTHERS => '1'); + -- input signals for ddrctrl.vhd SIGNAL clk : STD_LOGIC := '1'; @@ -91,7 +95,7 @@ ARCHITECTURE tb OF tb_ddrctrl IS 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 wr_not_rd : STD_LOGIC; SIGNAL stop_in : STD_LOGIC := '0'; - + SIGNAL bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0) := (OTHERS => '0'); -- testbench signal SIGNAL tb_end : STD_LOGIC := '0'; -- signal to turn the testbench off @@ -116,6 +120,8 @@ BEGIN p_test : PROCESS BEGIN + bsn(c_check-1 DOWNTO c_check_bottom) <= c_ones(c_check-c_check_bottom-1 DOWNTO 0); + -- start the test tb_end <= '0'; WAIT UNTIL rising_edge(clk); -- align to rising edge @@ -136,6 +142,8 @@ BEGIN fill_in_sosi_arr_0 : 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; + in_sosi_arr(0).bsn(c_dp_stream_bsn_w-1 DOWNTO 0) <= bsn(c_dp_stream_bsn_w-1 DOWNTO 0); + bsn <= ADD_UVEC(bsn, "0001", c_dp_stream_bsn_w); WAIT FOR c_clk_period*1; END LOOP; @@ -148,6 +156,8 @@ BEGIN fill_in_sosi_arr_1 : 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; + in_sosi_arr(0).bsn(c_dp_stream_bsn_w-1 DOWNTO 0) <= bsn(c_dp_stream_bsn_w-1 DOWNTO 0); + bsn <= ADD_UVEC(bsn, "0001", c_dp_stream_bsn_w); WAIT FOR c_clk_period*1; stop_in <= '0'; END LOOP; @@ -156,6 +166,8 @@ BEGIN fill_in_sosi_arr_2 : 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; + in_sosi_arr(0).bsn(c_dp_stream_bsn_w-1 DOWNTO 0) <= bsn(c_dp_stream_bsn_w-1 DOWNTO 0); + bsn <= ADD_UVEC(bsn, "0001", c_dp_stream_bsn_w); WAIT FOR c_clk_period*1; END LOOP; test_running <= '0'; -- GitLab