diff --git a/applications/lofar2/libraries/ddrctrl/hdllib.cfg b/applications/lofar2/libraries/ddrctrl/hdllib.cfg index 53fe5f5958c0cf866e1870d4ed11367b023c7df5..dc978140eaaafe0b299a2849864c5465a1fba09a 100644 --- a/applications/lofar2/libraries/ddrctrl/hdllib.cfg +++ b/applications/lofar2/libraries/ddrctrl/hdllib.cfg @@ -13,10 +13,6 @@ synth_files = src/vhdl/ddrctrl.vhd test_bench_files = - tb/vhdl/tb_ddrctrl_input_address_counter.vhd - tb/vhdl/tb_ddrctrl_input_pack.vhd - tb/vhdl/tb_ddrctrl_input_repack.vhd - tb/vhdl/tb_ddrctrl_input.vhd tb/vhdl/tb_ddrctrl.vhd regression_test_vhdl = diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd index 16aedd40d1b09382c4958070343051fead1af495..8c751dcb3925ac03f4ed0bdf0110c3a66c36865d 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd @@ -95,6 +95,7 @@ ARCHITECTURE str OF ddrctrl IS SIGNAL dvr_mosi : t_mem_ctlr_mosi := c_mem_ctlr_mosi_rst; SIGNAL wr_sosi : t_dp_sosi := c_dp_sosi_init; SIGNAL rd_siso : t_dp_siso := c_dp_siso_rst; + SIGNAL stop : STD_LOGIC; BEGIN @@ -112,6 +113,7 @@ BEGIN clk => clk, rst => rst, in_sosi_arr => in_sosi_arr, + in_stop => stop, out_of => out_of, out_sosi => out_sosi, out_adr => out_adr @@ -209,7 +211,8 @@ BEGIN wr_sosi => wr_sosi, rd_siso => rd_siso, - stop_in => stop_in + stop_in => stop_in, + stop_out => stop ); END str; diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd index d11931ba0ee0126455334f2661ebd8bca1634257..67a471ccf8bf7afed700c5788704fad3a61cfcc7 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd @@ -56,7 +56,8 @@ ENTITY ddrctrl_controller IS rd_siso : OUT t_dp_siso; -- ddrctrl - stop_in : IN STD_LOGIC + stop_in : IN STD_LOGIC; + stop_out : OUT STD_LOGIC ); END ddrctrl_controller; @@ -193,5 +194,6 @@ BEGIN dvr_mosi <= q_reg.dvr_mosi; wr_sosi <= q_reg.wr_sosi; rd_siso <= q_reg.rd_siso; + stop_out <= q_reg.stopped; END rtl; diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input.vhd index 0125aa60e02ab526c1befe95d110db62f2e224da..88b7e492bf4950c0fbef9e5bad964b4373e9475d 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input.vhd @@ -53,9 +53,13 @@ ENTITY ddrctrl_input IS clk : IN STD_LOGIC := '0'; rst : IN STD_LOGIC; in_sosi_arr : IN t_dp_sosi_arr; -- input data + in_stop : IN STD_LOGIC; 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); + out_bsn_adr : OUT NATURAL ); END ddrctrl_input; @@ -69,27 +73,29 @@ 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; + SIGNAL bsn_wr : STD_LOGIC := '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 +104,18 @@ BEGIN clk => clk, rst => rst, in_data => data, -- input data + in_bsn => bsn, + in_stop => in_stop, + in_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, + out_bsn_wr => bsn_wr ); -- 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 @@ -113,9 +125,11 @@ BEGIN rst => rst, in_sosi => sosi, -- input data in_of => a_of, + in_bsn_wr => bsn_wr, out_sosi => out_sosi, -- output data out_of => out_of, - out_adr => out_adr + out_adr => adr, + out_bsn_adr => out_bsn_adr ); END str; diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input_address_counter.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input_address_counter.vhd index 1d95748b0f99bcaf94ff7d14b022724efca7e494..8965e03a921531a664ee9aee8e1d5394a47e397e 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input_address_counter.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_input_address_counter.vhd @@ -49,9 +49,11 @@ ENTITY ddrctrl_input_address_counter IS rst : IN STD_LOGIC; in_sosi : IN t_dp_sosi; -- input data in_of : IN NATURAL; + in_bsn_wr : IN STD_LOGIC; out_sosi : OUT t_dp_sosi := c_dp_sosi_init; -- output data out_of : OUT NATURAL; - out_adr : OUT NATURAL + out_adr : OUT NATURAL; + out_bsn_adr : OUT NATURAL ); END ddrctrl_input_address_counter; @@ -71,12 +73,14 @@ ARCHITECTURE rtl OF ddrctrl_input_address_counter IS state : t_state; out_sosi : t_dp_sosi; out_of : NATURAL; + out_bsn_adr : NATURAL; s_in_sosi : t_dp_sosi; s_in_of : NATURAL; s_adr : NATURAL; + s_bsn_wr : STD_LOGIC; END RECORD; - CONSTANT c_t_reg_init : t_reg := (RESET, c_dp_sosi_init, 0, c_dp_sosi_init, 0, 0); + CONSTANT c_t_reg_init : t_reg := (RESET, c_dp_sosi_init, 0, 0, c_dp_sosi_init, 0, 0, '0'); -- signals for readability @@ -99,18 +103,39 @@ BEGIN v.out_of := q_reg.s_in_of; v.s_in_sosi := in_sosi; v.s_in_of := in_of; + IF in_bsn_wr = '0' THEN + v.s_bsn_wr := '1'; + END IF; CASE q_reg.state IS WHEN RESET => v.s_adr := c_max_adr-1; -- when there is a reset the fifo in io_ddr always needs the first out_sosi.valid to stop flushing the data so the first data word always gets lost. if s_adr is set to 0 after a restart the word from s_adr 1 will be put at address 0 in memory. + IF in_bsn_wr = '1' AND v.s_bsn_wr = '1' THEN + v.out_bsn_adr := v.s_adr; + v.s_bsn_wr := '0'; + END IF; + + WHEN COUNTING => v.s_adr := q_reg.s_adr+1; + IF in_bsn_wr = '1' AND v.s_bsn_wr = '1' THEN + v.out_bsn_adr := v.s_adr; + v.s_bsn_wr := '0'; + END IF; + + WHEN MAX => v.s_adr := 0; + IF in_bsn_wr = '1' AND v.s_bsn_wr = '1' THEN + v.out_bsn_adr := v.s_adr; + v.s_bsn_wr := '0'; + END IF; + + WHEN IDLE => END CASE; @@ -129,8 +154,9 @@ BEGIN END PROCESS; -- fill outputs - out_sosi <= q_reg.out_sosi; - out_of <= q_reg.out_of; - out_adr <= q_reg.s_adr; + out_sosi <= q_reg.out_sosi; + out_of <= q_reg.out_of; + out_adr <= q_reg.s_adr; + out_bsn_adr <= q_reg.out_bsn_adr; END rtl; 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 a7f32826e5a101ad17282b27b292e6c15e2b98c3..083e23050173e9e2474ba70eddcb4fcae215c287 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 ede68f09a7bbb58774e4991fae3bed24e1a8b221..1816f41494c2e4058037c02eb47b921c18cb6547 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,14 @@ 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 + in_stop : IN STD_LOGIC := '0'; + in_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); + out_bsn_wr : OUT STD_LOGIC := '0' ); END ddrctrl_input_repack; @@ -56,20 +62,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 (OVERFLOW_OUTPUT, FILL_VECTOR, FIRST_OUTPUT, RESET, STOP); -- 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; + out_bsn_written : STD_LOGIC; -- this signal gets high ones the out_bsn signal is updated, this is so in ddrctrl_input_address_counter the right address can be linked with the out_bsn signal + out_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) + out_sosi : t_dp_sosi; -- this is the sosi stream that contains the data + out_bsn_ds : NATURAL; -- this is the amount of bits that the data corresponding to out_bsn is shifted from the first bit in that data word + out_bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); -- this is the bsn corresponding to the data in memory 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 +99,135 @@ 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 + -- BSN_INPUT + IF in_adr = 0 AND q_reg.out_bsn_written = '0' THEN + v.out_bsn := in_bsn; -- a bsn number is saved when adr ~ 0 + IF g_in_data_w*q_reg.c_v_count+q_reg.out_of >= c_out_data_w THEN + v.out_bsn_ds := g_in_data_w*q_reg.c_v_count+q_reg.out_of-c_out_data_w; -- the amount of bits between word[0] and data[0] where data is the data with the bsn + ELSE + v.out_bsn_ds := g_in_data_w*q_reg.c_v_count+q_reg.out_of; -- the amount of bits between word[0] and data[0] where data is the data with the bsn + END IF; + v.out_bsn_written := '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) + END IF; + + IF rst = '1' THEN + v.state := RESET; + ELSIF in_stop = '1' THEN + v.state := STOP; + 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 + + -- BSN_INPUT + IF in_adr = 0 AND q_reg.out_bsn_written = '0' THEN + v.out_bsn := in_bsn; -- a bsn number is saved when adr ~ 0 + IF g_in_data_w*q_reg.c_v_count+q_reg.out_of >= c_out_data_w THEN + v.out_bsn_ds := g_in_data_w*q_reg.c_v_count+q_reg.out_of-c_out_data_w; -- the amount of bits between word[0] and data[0] where data is the data with the bsn + ELSE + v.out_bsn_ds := g_in_data_w*q_reg.c_v_count+q_reg.out_of; -- the amount of bits between word[0] and data[0] where data is the data with the bsn + END IF; + v.out_bsn_written := '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) + END IF; + + IF rst = '1' THEN + v.state := RESET; + ELSIF in_stop = '1' THEN + v.state := STOP; + 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 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 + -- BSN_INPUT + IF in_adr = 0 AND q_reg.out_bsn_written = '0' THEN + v.out_bsn := in_bsn; -- a bsn number is saved when adr ~ 0 + IF g_in_data_w*q_reg.c_v_count+q_reg.out_of >= c_out_data_w THEN + v.out_bsn_ds := g_in_data_w*q_reg.c_v_count+q_reg.out_of-c_out_data_w; -- the amount of bits between word[0] and data[0] where data is the data with the bsn + ELSE + v.out_bsn_ds := g_in_data_w*q_reg.c_v_count+q_reg.out_of; -- the amount of bits between word[0] and data[0] where data is the data with the bsn + END IF; + v.out_bsn_written := '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) + END IF; + + IF rst = '1' THEN + v.state := RESET; + ELSIF in_stop = '1' THEN + v.state := STOP; + 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; + ELSE + v.state := FILL_VECTOR; + END IF; + WHEN RESET => v := c_t_reg_init; - END CASE; + IF rst = '1' THEN + v.state := RESET; + ELSIF in_stop = '1' THEN + v.state := STOP; + ELSE + v.state := FILL_VECTOR; + END IF; - 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; + WHEN STOP => + IF rst = '1' THEN + v.state := RESET; + ELSIF in_stop = '1' THEN + v.state := STOP; + 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; + + + + + END CASE; + + IF NOT (in_adr=0) THEN + v.out_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; + out_bsn_wr <= q_reg.out_bsn_written; 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 f38fb0f836208aaffcf1b0f292a0c747e61f2563..f6f7b8fb92b150df8038e553c9210d64143b2f83 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 @@ -137,9 +143,11 @@ 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 <= INCR_UVEC(bsn, 1); WAIT FOR c_clk_period*1; END LOOP; - IF k = 2 THEN + IF k = 1 THEN stop_in <= '1'; ELSE stop_in <= '0'; diff --git a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_input.vhd b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_input.vhd deleted file mode 100644 index 1df9277d93977ed10fdb5f7170add3169a8a3e43..0000000000000000000000000000000000000000 --- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_input.vhd +++ /dev/null @@ -1,222 +0,0 @@ -------------------------------------------------------------------------------- --- --- Copyright 2022 --- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> --- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands --- --- Licensed under the Apache License, Version 2.0 (the "License"); --- you may not use this file except in compliance with the License. --- You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, software --- distributed under the License is distributed on an "AS IS" BASIS, --- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --- See the License for the specific language governing permissions and --- limitations under the License. --- -------------------------------------------------------------------------------- --- Author: Job van Wee --- Purpose: Self checking and self-stopping tb for ddrctrl_input.vhd --- Usage: --- > run -a - -LIBRARY IEEE, common_lib, technology_lib, tech_ddr_lib, dp_lib; -USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.NUMERIC_STD.ALL; -USE IEEE.MATH_REAL.ALL; -USE technology_lib.technology_pkg.ALL; -USE tech_ddr_lib.tech_ddr_pkg.ALL; -USE dp_lib.dp_stream_pkg.ALL; -USE common_lib.common_mem_pkg.ALL; -USE common_lib.common_pkg.ALL; - -ENTITY tb_ddrctrl_input IS - GENERIC ( - - g_tech_ddr : t_c_tech_ddr := c_tech_ddr4_8g_1600m; -- type of memory - g_nof_streams : POSITIVE := 12; -- number of input streams - g_data_w : NATURAL := 14; -- data with of input data vectors - g_sim_length : NATURAL := 52 - - ); -END tb_ddrctrl_input; - -ARCHITECTURE tb OF tb_ddrctrl_input IS - - -- constants for testbench - CONSTANT c_sim_model : BOOLEAN := TRUE; -- determens if this is a simulation - CONSTANT c_clk_freq : NATURAL := 200; -- clock frequency in MHz - CONSTANT c_clk_period : TIME := (10**6 / c_clk_freq) * 1 ps; -- clock priod, 5 ns - - -- constants for readability - CONSTANT c_in_data_w : NATURAL := g_nof_streams * g_data_w; -- output data with, 168 - CONSTANT c_out_data_w : NATURAL := func_tech_ddr_ctlr_data_w( g_tech_ddr ); -- output data vector with, 576 - CONSTANT c_adr_w : NATURAL := func_tech_ddr_ctlr_address_w( g_tech_ddr ) ; -- address with in simulation - CONSTANT c_adr_size : NATURAL := 2**c_adr_w; -- address size in simulation - - -- function for making total data vector - FUNCTION c_total_vector_init RETURN STD_LOGIC_VECTOR IS - VARIABLE v_total_vector : STD_LOGIC_VECTOR(c_in_data_w*g_sim_length-1 DOWNTO 0); - BEGIN - FOR I IN 0 TO g_sim_length*g_nof_streams-1 LOOP - v_total_vector(g_data_w*(I+1)-1 DOWNTO g_data_w*I) := TO_UVEC(I, g_data_w); - END LOOP; - RETURN v_total_vector; - END FUNCTION c_total_vector_init; - - -- constant for running the test - CONSTANT c_total_vector : STD_LOGIC_VECTOR(c_in_data_w*g_sim_length-1 DOWNTO 0) := c_total_vector_init; -- vector which contains all input data vectors to make it easy to fill ctr_vector - - - -- input signals for ddrctrl_input.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_input.vhd - SIGNAL out_of : NATURAL := 0; -- output signal from ddrctrl_repack to determen how high the overflow is - SIGNAL out_sosi : t_dp_sosi := c_dp_sosi_init; -- output signal from ddrctrl_pack.vhd - SIGNAL out_adr : NATURAL := 0; - - -- testbench signal - SIGNAL tb_end : STD_LOGIC := '0'; -- signal to turn the testbench off - - -- 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 to hold the address lag after a rest with a delay of 1 clockcycle - -BEGIN - - -- generating clock - clk <= NOT clk OR tb_end AFTER c_clk_period/2; - - -- excecuting test - p_test : PROCESS - BEGIN - - -- start the test - tb_end <= '0'; - WAIT UNTIL rising_edge(clk); -- align to rising edge - WAIT FOR c_clk_period*4; - rst <= '1'; - WAIT FOR c_clk_period*1; - rst <= '0'; - test_running <= '1'; - - -- filling the input data vectors with the corresponding numbers - 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; - END LOOP; - test_running <= '0'; - - -- testing reset - --FOR I IN 0 TO g_sim_length-1 LOOP - --rst <= '1'; - --WAIT FOR c_clk_period*1; - --rst <= '0'; - --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*4; - tb_end <= '1'; - ASSERT FALSE REPORT "Test: OK" SEVERITY FAILURE; - END PROCESS; - - -- generating compare data for out_sosi - p_out_sosi : PROCESS - BEGIN - WAIT UNTIL rising_edge(clk); - if rising_edge(clk) THEN - 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+out_adr+2 >= c_adr_size THEN - lag_due_reset <= lag_due_reset+out_adr+2-c_adr_size; - ELSE - lag_due_reset <= lag_due_reset+out_adr+2; - END IF; - END IF; - END PROCESS; - - -- verifying if the address is correct by keeping track of the address - p_verify_address : PROCESS - - VARIABLE v_adr : NATURAL range 0 to c_adr_size-1 := c_adr_size-2; - - BEGIN - WAIT UNTIL rst = '1'; - WAIT UNTIL rst = '0'; - FOR I IN 0 TO g_sim_length-1 LOOP - IF v_adr >= q_lag_due_reset THEN - ASSERT v_adr-q_lag_due_reset = out_adr REPORT "Wrong address, 1, v_adr = " & NATURAL'image(v_adr-q_lag_due_reset) & ", address = " & NATURAL'image(out_adr) SEVERITY ERROR; - ELSE - ASSERT (v_adr-q_lag_due_reset)+c_adr_size = out_adr REPORT "Wrong address, 2, v_adr = " & NATURAL'image((v_adr-q_lag_due_reset)+c_adr_size) & ", address = " & NATURAL'image(out_adr) SEVERITY ERROR; - END IF; - WAIT UNTIL out_sosi.valid = '1'; - IF q_q_rst = '1' THEN - WAIT UNTIL out_sosi.valid = '1'; - END IF; - IF v_adr = c_adr_size-1 THEN - v_adr := 0; - ELSE - v_adr := v_adr+1; - END IF; - END LOOP; - WAIT; - END PROCESS; - - -- 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; - - BEGIN - WAIT UNTIL rising_edge(clk); - IF q_q_test_running = '1' AND out_sosi.valid = '1' THEN - out_data_cnt := out_data_cnt+1; - IF out_data_cnt mod 2 = 0 THEN - 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_sosi.data(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; - - - -- DUT - u_ddrctrl_input : ENTITY work.ddrctrl_input - GENERIC MAP ( - g_tech_ddr => g_tech_ddr, - g_sim_model => c_sim_model, - g_nof_streams => g_nof_streams, - g_data_w => g_data_w - ) - PORT MAP ( - clk => clk, - rst => rst, - in_sosi_arr => in_sosi_arr, - out_of => out_of, - out_sosi => out_sosi, - out_adr => out_adr - ); - -END tb; diff --git a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_input_address_counter.vhd b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_input_address_counter.vhd deleted file mode 100644 index 843e6b0e8e0061eb6b84efa52efca0bd7ec37068..0000000000000000000000000000000000000000 --- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_input_address_counter.vhd +++ /dev/null @@ -1,208 +0,0 @@ -------------------------------------------------------------------------------- --- --- Copyright 2022 --- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> --- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands --- --- Licensed under the Apache License, Version 2.0 (the "License"); --- you may not use this file except in compliance with the License. --- You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, software --- distributed under the License is distributed on an "AS IS" BASIS, --- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --- See the License for the specific language governing permissions and --- limitations under the License. --- -------------------------------------------------------------------------------- --- Author: Job van Wee --- Purpose: Self checking and self-stopping tb for ddrctrl_input_address_counter.vhd --- Usage: --- > run -a - -LIBRARY IEEE, common_lib, technology_lib, tech_ddr_lib, dp_lib; -USE IEEE.STD_LOGIC_1164.ALL; -USE technology_lib.technology_pkg.ALL; -USE tech_ddr_lib.tech_ddr_pkg.ALL; -USE dp_lib.dp_stream_pkg.ALL; -USE common_lib.common_mem_pkg.ALL; -USE common_lib.common_pkg.ALL; - -ENTITY tb_ddrctrl_input_address_counter IS - GENERIC ( - - 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_input_address_counter; - -ARCHITECTURE tb OF tb_ddrctrl_input_address_counter IS - - -- 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 - - -- 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 := func_tech_ddr_ctlr_address_w( g_tech_ddr ); -- address with in simulation - CONSTANT c_adr_size : NATURAL := 2**c_adr_w; -- address size in simulation - - -- input signals for ddrctrl_address_counter.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 : t_dp_sosi := c_dp_sosi_init; -- signal which is the input for ddrctrl_address_counter.vhd - SIGNAL in_of : NATURAL := 0; -- signal which contains the amount of overflow - - -- output signal from ddrctrl_address_counter.vhd - SIGNAL out_sosi : t_dp_sosi := c_dp_sosi_init; -- signal which is the output from ddrctrl_address_counter.vhd - SIGNAL out_adr : 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 - -BEGIN - - -- 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; - - -- excecuting the test - p_test : PROCESS - BEGIN - - -- initialize inputs - tb_end <= '0'; - in_data <= (OTHERS => '0'); - in_data_enable <= '0'; - WAIT UNTIL rising_edge(clk); - WAIT FOR c_clk_period*4; - rst <= '1'; - WAIT FOR c_clk_period*1; - rst <= '0'; - - -- 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; - in_of <= in_of + 1; - WAIT FOR c_clk_period*1; - in_data_enable <= '0'; - WAIT FOR c_clk_period*2; - END LOOP; - - -- stopping the test - WAIT FOR c_clk_period*4; - tb_end <= '1'; - ASSERT FALSE REPORT "Test: OK" SEVERITY FAILURE; - END PROCESS; - - -- generating compare data for out_sosi - p_out_sosi : PROCESS - BEGIN - WAIT UNTIL rising_edge(clk); - if rising_edge(clk) THEN - 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 + out_adr >= c_adr_size THEN - lag_due_reset <= lag_due_reset+out_adr-c_adr_size; - ELSE - lag_due_reset <= lag_due_reset+out_adr; - END IF; - END IF; - END 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 q_q_in_data(c_data_w-1 DOWNTO 0) = out_sosi.data(c_data_w-1 DOWNTO 0) REPORT "in_sosi.data does not match out_sosi.data" SEVERITY ERROR; - ASSERT q_q_in_data_enable = out_sosi.valid REPORT "in_sosi.valid does not match out_sosi.valid" SEVERITY ERROR; - ASSERT q_q_in_of = out_of REPORT "in_of does not match out_of" 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*4)+3); - rst <= '1'; - WAIT FOR c_clk_period*1; - END PROCESS; - - -- verifying if the address is correct by keeping track of the address - p_verify_address : PROCESS - - VARIABLE v_adr : NATURAL range 0 to c_adr_size-1 := c_adr_size-1; - - BEGIN - WAIT UNTIL rst = '1'; - WAIT UNTIL rst = '0'; - FOR I IN 0 TO g_sim_length-1 LOOP - IF v_adr >= q_lag_due_reset THEN - ASSERT v_adr-q_lag_due_reset = out_adr REPORT "Wrong address, 1, v_adr = " & NATURAL'image(v_adr-q_lag_due_reset) & ", address = " & NATURAL'image(out_adr) SEVERITY ERROR; - ELSE - ASSERT (v_adr-q_lag_due_reset)+c_adr_size = out_adr REPORT "Wrong address, 2, v_adr = " & NATURAL'image((v_adr-q_lag_due_reset)+c_adr_size) & ", address = " & NATURAL'image(out_adr) SEVERITY ERROR; - END IF; - WAIT UNTIL out_sosi.valid = '1'; - IF q_q_rst = '1' THEN - WAIT UNTIL out_sosi.valid = '1'; - END IF; - IF v_adr = c_adr_size-1 THEN - v_adr := 0; - ELSE - v_adr := v_adr+1; - END IF; - END LOOP; - END PROCESS; - - - -- DUT - u_ddrctrl_input_address_counter : ENTITY work.ddrctrl_input_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, - in_of => in_of, - - out_sosi => out_sosi, - out_of => out_of, - out_adr => out_adr - ); - -END tb; diff --git a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_input_pack.vhd b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_input_pack.vhd deleted file mode 100644 index 7570ed4ee919b73037a8f163ad8a447a39c6a052..0000000000000000000000000000000000000000 --- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_input_pack.vhd +++ /dev/null @@ -1,142 +0,0 @@ -------------------------------------------------------------------------------- --- --- Copyright 2022 --- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> --- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands --- --- Licensed under the Apache License, Version 2.0 (the "License"); --- you may not use this file except in compliance with the License. --- You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, software --- distributed under the License is distributed on an "AS IS" BASIS, --- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --- See the License for the specific language governing permissions and --- limitations under the License. --- -------------------------------------------------------------------------------- --- Author: Job van Wee --- Purpose: Self checking and self-stopping tb for ddrctrl_input_pack.vhd --- Usage: --- > run -a - -LIBRARY IEEE, common_lib, technology_lib, tech_ddr_lib, dp_lib; -USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.NUMERIC_STD.ALL; -USE IEEE.MATH_REAL.ALL; -USE technology_lib.technology_pkg.ALL; -USE tech_ddr_lib.tech_ddr_pkg.ALL; -USE dp_lib.dp_stream_pkg.ALL; -USE common_lib.common_mem_pkg.ALL; -USE common_lib.common_pkg.ALL; - -ENTITY tb_ddrctrl_input_pack IS - GENERIC ( - - g_nof_streams : POSITIVE := 12; -- number of input streams - g_data_w : NATURAL := 14; -- data with of input data vectors - g_sim_length : NATURAL := 52 -- determens the lengt of the duration of the test - - ); -END tb_ddrctrl_input_pack; - -ARCHITECTURE tb OF tb_ddrctrl_input_pack IS - - -- 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 priod, 5 ns - - -- constant for readability - CONSTANT c_out_data_w : NATURAL := g_nof_streams*g_data_w; -- output data with, 168 - - -- function for making test vector - FUNCTION c_testv_init RETURN STD_LOGIC_VECTOR IS - VARIABLE temp : STD_LOGIC_VECTOR(c_out_data_w-1 DOWNTO 0); - BEGIN - FOR I IN 0 TO g_nof_streams-1 LOOP - temp(g_data_w*(I+1)-1 DOWNTO g_data_w*I) := TO_UVEC(I, g_data_w); - END LOOP; - RETURN temp; - END FUNCTION c_testv_init; - - -- constants for running the test - CONSTANT c_testv : STD_LOGIC_VECTOR(c_out_data_w-1 DOWNTO 0) := c_testv_init; -- testvector which contains a number for each stream, so the data of stream 6 will look like ...00110 - - - -- input signals for ddrctrl_pack.vhd - SIGNAL clk : STD_LOGIC := '1'; -- clock signal - SIGNAL in_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_init); -- input signal for ddrctrl_pack.vhd - - -- output singal from ddrctrl_pack.vhd - SIGNAL out_data : STD_LOGIC_VECTOR(c_out_data_w-1 DOWNTO 0); -- output signal from ddrctrl_pack.vhd - - -- testbench signal - SIGNAL tb_end : STD_LOGIC := '0'; -- signal to turn the testbench off - -BEGIN - - -- generating clock - clk <= NOT clk OR tb_end AFTER c_clk_period/2; - - -- excecuting the test - p_test : PROCESS - BEGIN - - -- starting the test - tb_end <= '0'; - WAIT UNTIL rising_edge(clk); - WAIT FOR c_clk_period*2; - - - -- the input data vectors get filled with the corresponding number - 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_testv(g_data_w * (I + 1) - 1 DOWNTO g_data_w * I); - END LOOP; - - - -- the numbers get cycled trough the input vectors - change_in_sosi_arr : FOR J IN 0 TO g_sim_length-1 LOOP - WAIT FOR c_clk_period*1; - in_sosi_arr(0).data(g_data_w - 1 DOWNTO 0) <= in_sosi_arr(g_nof_streams-1).data(g_data_w - 1 DOWNTO 0); - loop_switch_data : FOR I IN 1 TO g_nof_streams-1 LOOP - in_sosi_arr(I).data(g_data_w - 1 DOWNTO 0) <= in_sosi_arr(I-1).data(g_data_w - 1 DOWNTO 0); - END LOOP; - END LOOP; - - -- stopping the testbench - WAIT FOR c_clk_period*4; - tb_end <= '1'; - ASSERT FALSE REPORT "Test: OK" SEVERITY FAILURE; - END PROCESS; - - -- verification by checking if the input vectors equel the corresponding index of the output vector - p_verify : PROCESS - BEGIN - WAIT UNTIL rising_edge(clk); - IF rising_edge(clk) THEN - check_data : FOR I IN 0 TO g_nof_streams - 1 LOOP - ASSERT out_data(g_data_w * (I + 1) - 1 DOWNTO g_data_w * I) = in_sosi_arr(I).data(g_data_w-1 DOWNTO 0) REPORT "Data does not match, I = " & NATURAL'image(I) SEVERITY ERROR; - END LOOP; - END IF; - END PROCESS; - - -- DUT - u_ddrctrl_input_pack : ENTITY work.ddrctrl_input_pack - GENERIC MAP ( - g_nof_streams => g_nof_streams, - g_data_w => g_data_w - ) - PORT MAP ( - in_sosi_arr => in_sosi_arr, - - out_data => out_data - ); - -END tb; - - - - - diff --git a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_input_repack.vhd b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_input_repack.vhd deleted file mode 100644 index 2458c6bcf29245d074a584ae6ad5da8e9fe49731..0000000000000000000000000000000000000000 --- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_input_repack.vhd +++ /dev/null @@ -1,152 +0,0 @@ -------------------------------------------------------------------------------- --- --- Copyright 2022 --- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> --- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands --- --- Licensed under the Apache License, Version 2.0 (the "License"); --- you may not use this file except in compliance with the License. --- You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, software --- distributed under the License is distributed on an "AS IS" BASIS, --- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --- See the License for the specific language governing permissions and --- limitations under the License. --- -------------------------------------------------------------------------------- --- Author: Job van Wee --- Purpose: Self checking and self-stopping tb for ddrctrl_input_repack.vhd --- Usage: --- > run -a - -LIBRARY IEEE, common_lib, technology_lib, tech_ddr_lib, dp_lib; -USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.NUMERIC_STD.ALL; -USE IEEE.MATH_REAL.ALL; -USE technology_lib.technology_pkg.ALL; -USE tech_ddr_lib.tech_ddr_pkg.ALL; -USE dp_lib.dp_stream_pkg.ALL; -USE common_lib.common_mem_pkg.ALL; -USE common_lib.common_pkg.ALL; - -ENTITY tb_ddrctrl_input_repack IS - GENERIC ( - - g_tech_ddr : t_c_tech_ddr := c_tech_ddr4_8g_1600m; -- type of memory - g_in_data_w : NATURAL := 168; -- input data vector with - g_sim_lengt : NATURAL := 52 -- amount of times there wil be input data for ddrctrl_repack in this testbench - - ); -END tb_ddrctrl_input_repack; - -ARCHITECTURE tb OF tb_ddrctrl_input_repack IS - - -- constants for running testbench - CONSTANT c_clk_freq : NATURAL := 200; -- clock freqency in MHz - CONSTANT c_clk_period : TIME := (10**6 / c_clk_freq) * 1 ps; -- clock period, 5 ns - - -- constant for readability - CONSTANT c_out_data_w : NATURAL := func_tech_ddr_ctlr_data_w( g_tech_ddr ); -- output data vector with, 576 - - -- function for making total data vector - FUNCTION c_total_vector_init RETURN STD_LOGIC_VECTOR IS - VARIABLE temp : STD_LOGIC_VECTOR(g_in_data_w*g_sim_lengt-1 DOWNTO 0); - BEGIN - FOR I IN 0 TO g_sim_lengt-1 LOOP - temp(g_in_data_w*(I+1)-1 DOWNTO g_in_data_w*I) := TO_UVEC(I, g_in_data_w); - END LOOP; - RETURN temp; - END FUNCTION c_total_vector_init; - - -- constant for running the test - CONSTANT c_total_vector : STD_LOGIC_VECTOR(g_in_data_w*g_sim_lengt-1 DOWNTO 0) := c_total_vector_init; -- vector which contains all input data vectors to make it easy to fill ctr_vector - - - -- input signals for ddrctrl_repack.vhd - SIGNAL clk : STD_LOGIC := '1'; -- clock signal - SIGNAL rst : STD_LOGIC := '0'; -- reset signal - SIGNAL in_data : STD_LOGIC_VECTOR(g_in_data_w-1 DOWNTO 0) := (OTHERS => '0'); -- input data signal for ddrctrl_repack - - -- output signals from ddrctrl_repack.vhd - SIGNAL out_of : NATURAL := 0; -- output signal from ddrctrl_repack to determen how high the overflow is - SIGNAL out_sosi : t_dp_sosi := c_dp_sosi_init; -- output data signal form ddrctrl_repack - - -- testbench signal - SIGNAL tb_end : STD_LOGIC := '0'; -- signal to turn the testbench off - - -- singals for running the test - SIGNAL in_data_cnt : NATURAL := 0; -- signal which contains the amount of times there has been input data for ddrctrl_repack.vhd - SIGNAL test_running : STD_LOGIC := '0'; -- signal to tell wheter the testing has started - -BEGIN - - -- Generating clock - clk <= NOT clk OR tb_end AFTER c_clk_period/2; - - -- Excecuting the test - p_test : PROCESS - BEGIN - - -- start the test - tb_end <= '0'; - WAIT UNTIL rising_edge(clk); -- align to rising edge - WAIT FOR c_clk_period*5; - rst <= '1'; - WAIT FOR c_clk_period*1; - rst <= '0'; - WAIT FOR c_clk_period*1; - test_running <= '1'; -- start of test - - -- filling the input vector g_sim_lengt amount of times - 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; - END LOOP; - test_running <= '0'; - - -- stopping the testbench - WAIT FOR c_clk_period*5; - tb_end <= '1'; - 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 - p_verify : PROCESS - - VARIABLE ctr_of : NATURAL := 0; - VARIABLE out_data_cnt : NATURAL := 0; - - BEGIN - WAIT UNTIL rising_edge(clk); - IF test_running = '1' AND out_sosi.valid = '1' THEN - out_data_cnt := out_data_cnt+1; - IF out_data_cnt mod 2 = 0 THEN - ctr_of := g_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; - END IF; - ASSERT out_sosi.data(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; - - - -- DUT - u_ddrctrl_input_repack : ENTITY work.ddrctrl_input_repack - GENERIC MAP ( - g_tech_ddr => g_tech_ddr, - g_in_data_w => g_in_data_w - ) - PORT MAP ( - clk => clk, - rst => rst, - in_data => in_data, - - out_of => out_of, - out_sosi => out_sosi - ); - -END tb; -