From 82db8eff20d5089570426322ecc6843cfadd280d Mon Sep 17 00:00:00 2001 From: JobvanWee <wee@astron.nl> Date: Tue, 19 Apr 2022 10:47:06 +0200 Subject: [PATCH] Ready for review. --- .../libraries/ddrctrl/src/vhdl/ddrctrl.vhd | 16 +++---- .../ddrctrl/src/vhdl/ddrctrl_controller.vhd | 42 +++++++++++-------- .../vhdl/ddrctrl_input_address_counter.vhd | 4 +- .../libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd | 36 ++++++++-------- 4 files changed, 53 insertions(+), 45 deletions(-) diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd index e265a81e25..e802791e80 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd @@ -113,14 +113,14 @@ ARCHITECTURE str OF ddrctrl IS SIGNAL ctrl_clk : STD_LOGIC; SIGNAL ctrl_rst : STD_LOGIC; SIGNAL rst_ddrctrl_input : STD_LOGIC; - SIGNAL out_of : NATURAL := 0; - SIGNAL out_sosi : t_dp_sosi := c_dp_sosi_init; - SIGNAL out_adr : NATURAL := 0; - SIGNAL dvr_mosi : t_mem_ctlr_mosi := c_mem_ctlr_mosi_rst; - SIGNAL dvr_miso : t_mem_ctlr_miso := c_mem_ctlr_miso_rst; - SIGNAL wr_sosi : t_dp_sosi := c_dp_sosi_init; - SIGNAL rd_siso : t_dp_siso := c_dp_siso_rst; - SIGNAL rd_sosi : t_dp_sosi := c_dp_sosi_init; + SIGNAL out_of : NATURAL := 0; + SIGNAL out_sosi : t_dp_sosi := c_dp_sosi_init; + SIGNAL out_adr : NATURAL := 0; + SIGNAL dvr_mosi : t_mem_ctlr_mosi := c_mem_ctlr_mosi_rst; + SIGNAL dvr_miso : t_mem_ctlr_miso := c_mem_ctlr_miso_rst; + SIGNAL wr_sosi : t_dp_sosi := c_dp_sosi_init; + SIGNAL rd_siso : t_dp_siso := c_dp_siso_rst; + SIGNAL rd_sosi : t_dp_sosi := c_dp_sosi_init; SIGNAL stop : STD_LOGIC; SIGNAL rd_fifo_usedw : STD_LOGIC_VECTOR(c_rd_fifo_uw_w-1 DOWNTO 0); SIGNAL rd_ready : STD_LOGIC; diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd index 1bace4b441..df90236414 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd @@ -48,8 +48,8 @@ ENTITY ddrctrl_controller IS g_block_size : NATURAL; g_rd_fifo_uw_w : NATURAL; g_max_adr : NATURAL; - g_burstsize : NATURAL; - g_last_burstsize : NATURAL + g_burstsize : NATURAL; + g_last_burstsize : NATURAL ); PORT ( clk : IN STD_LOGIC; @@ -144,9 +144,9 @@ BEGIN CASE q_reg.state IS WHEN RESET => v := c_t_reg_init; - v.dvr_mosi.burstbegin := '1'; + v.dvr_mosi.burstbegin := '1'; v.dvr_mosi.burstsize(dvr_mosi.burstsize'length-1 DOWNTO 0) := (OTHERS => '0'); - v.dvr_mosi.wr := '1'; + v.dvr_mosi.wr := '1'; @@ -164,7 +164,7 @@ BEGIN v.dvr_mosi.burstsize := TO_UVEC(g_last_burstsize, dvr_mosi.burstsize'length); ELSE v.dvr_mosi.address := TO_UVEC(inp_adr-g_burstsize, dvr_mosi.address'length); - v.dvr_mosi.address(c_bitshift_adr-1 DOWNTO 0) := c_zeros(c_bitshift_adr-1 DOWNTO 0); + v.dvr_mosi.address(c_bitshift_adr-1 DOWNTO 0) := c_zeros(c_bitshift_adr-1 DOWNTO 0); -- makes sure that a burst is only started on a multiple of g_burstsize v.dvr_mosi.burstsize := TO_UVEC(g_burstsize, dvr_mosi.burstsize'length); END IF; ELSE @@ -188,20 +188,26 @@ BEGIN -- still a write cyle -- if adr mod g_burstsize = 0 -- this makes sure that only ones every 64 writes a writeburst is started. - IF TO_UVEC(inp_adr, c_adr_w)(c_bitshift_adr-1 DOWNTO 0) = c_zeros THEN - v.dvr_mosi.burstbegin := '1'; - IF inp_adr = 0 THEN - v.dvr_mosi.address := TO_UVEC(g_max_adr-g_burstsize, dvr_mosi.address'length); + IF TO_UVEC(inp_adr, c_adr_w)(c_bitshift_adr-1 DOWNTO 0) = c_zeros AND q_reg.dvr_mosi.burstbegin = '0'THEN + v.need_burst := '1'; + END IF; + IF dvr_miso.done = '1' AND q_reg.need_burst = '1' THEN + v.dvr_mosi.burstbegin := '1'; + v.need_burst := '0'; + IF inp_adr < g_burstsize-1 THEN + v.dvr_mosi.address := TO_UVEC(g_max_adr-g_last_burstsize, dvr_mosi.address'length); + v.dvr_mosi.burstsize := TO_UVEC(g_last_burstsize, dvr_mosi.burstsize'length); ELSE - v.dvr_mosi.address := TO_UVEC(inp_adr-g_burstsize, dvr_mosi.address'length); + v.dvr_mosi.address := TO_UVEC(inp_adr-g_burstsize, dvr_mosi.address'length); + v.dvr_mosi.address(c_bitshift_adr-1 DOWNTO 0) := c_zeros(c_bitshift_adr-1 DOWNTO 0); -- makes sure that a burst is only started on a multiple of g_burstsize + v.dvr_mosi.burstsize := TO_UVEC(g_burstsize, dvr_mosi.burstsize'length); END IF; ELSE - v.dvr_mosi.burstbegin := '0'; + v.dvr_mosi.burstbegin := '0'; END IF; - v.dvr_mosi.burstsize := TO_UVEC(g_burstsize, dvr_mosi.burstsize'length); - v.dvr_mosi.wr := '1'; - v.dvr_mosi.rd := '0'; - v.wr_sosi := inp_sosi; + v.dvr_mosi.wr := '1'; + v.dvr_mosi.rd := '0'; + v.wr_sosi := inp_sosi; WHEN STOP_WRITING => @@ -232,7 +238,7 @@ BEGIN v.dvr_mosi.burstsize := TO_UVEC(g_last_burstsize, dvr_mosi.burstsize'length); ELSE v.dvr_mosi.address := TO_UVEC(inp_adr-g_burstsize, dvr_mosi.address'length); - v.dvr_mosi.address(c_bitshift_adr-1 DOWNTO 0) := c_zeros(c_bitshift_adr-1 DOWNTO 0); + v.dvr_mosi.address(c_bitshift_adr-1 DOWNTO 0) := c_zeros(c_bitshift_adr-1 DOWNTO 0); -- makes sure that a burst is only started on a multiple of g_burstsize v.dvr_mosi.burstsize := TO_UVEC(g_burstsize, dvr_mosi.burstsize'length); END IF; ELSE @@ -249,14 +255,14 @@ BEGIN v.dvr_mosi.rd := '1'; v.outp_ds := inp_ds; - FOR I IN 0 TO inp_bsn_adr+(g_max_adr-TO_UINT(q_reg.stop_adr)) LOOP -- takes a while WRONG, wil be fixed after L2SDP-705, 706, 707 and 708 + FOR I IN 0 TO inp_bsn_adr+(g_max_adr-TO_UINT(q_reg.stop_adr)) LOOP -- takes a while WRONG, wil be fixed after L2SDP-705, 706 and 70 IF v.outp_ds-c_rest <= 0 THEN v.outp_ds := v.outp_ds+c_rd_data_w-c_rest; ELSE v.outp_ds := v.outp_ds-c_rest; END IF; END LOOP; - v.outp_bsn := TO_UVEC(TO_UINT(inp_sosi.bsn), c_dp_stream_bsn_w); -- WRONG, wil be fixed after L2SDP-705, 706, 707 and 708 + v.outp_bsn := TO_UVEC(TO_UINT(inp_sosi.bsn), c_dp_stream_bsn_w); -- WRONG, wil be fixed after L2SDP-705, 706 and 707 v.state := READING; 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 ca11efff43..43cb85d273 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 @@ -105,7 +105,7 @@ BEGIN CASE q_reg.state IS WHEN RESET => - v.s_adr := 0; -- 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. + v.s_adr := 0; IF q_reg.s_in_sosi.sop = '1' THEN v.out_bsn_adr := v.s_adr; @@ -129,10 +129,12 @@ BEGIN WHEN IDLE => + -- after a reset skip the first data block so the ddr memory can calm down. IF NOT(q_reg.s_in_sosi.bsn(c_dp_stream_bsn_w-1 DOWNTO 0) = in_sosi.bsn(c_dp_stream_bsn_w-1 DOWNTO 0)) THEN v.bsn_passed := '1'; END IF; + END CASE; IF rst = '1' THEN diff --git a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd index 440df0677c..fb535d7ad9 100644 --- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd +++ b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd @@ -37,15 +37,15 @@ USE technology_lib.technology_select_pkg.ALL; ENTITY tb_ddrctrl 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 := 16500; -- close to the amount of word that gets put into the memory - g_technology : NATURAL := c_tech_select_default; - g_tech_ddr3 : t_c_tech_ddr := c_tech_ddr3_4g_800m_master; - g_tech_ddr4 : t_c_tech_ddr := c_tech_ddr4_4g_1600m; - g_stop_percentage : NATURAL := 80; -- percentage there needs to be already written in the ddr memory when a stop gets triggered - g_block_size : NATURAL := 1023 -- amount of samples that goes into one bsn + 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 := 16500; -- close to the amount of word that gets put into the memory + g_technology : NATURAL := c_tech_select_default; + g_tech_ddr3 : t_c_tech_ddr := c_tech_ddr3_4g_800m_master; + g_tech_ddr4 : t_c_tech_ddr := c_tech_ddr4_4g_1600m; + g_stop_percentage : NATURAL := 80; -- percentage there needs to be already written in the ddr memory when a stop gets triggered + g_block_size : NATURAL := 1024 -- amount of samples that goes into one bsn ); END tb_ddrctrl; @@ -59,7 +59,7 @@ ARCHITECTURE tb OF tb_ddrctrl IS CONSTANT c_tech_ddr : t_c_tech_ddr := func_tech_sel_ddr(c_sim_model, c_sim_ddr, c_mem_ddr); -- constants for readability - CONSTANT c_ctrl_data_w : NATURAL := func_tech_ddr_ctlr_data_w(c_tech_ddr); -- 576 + CONSTANT c_ctrl_data_w : NATURAL := func_tech_ddr_ctlr_data_w(c_tech_ddr); -- 576 CONSTANT c_in_data_w : NATURAL := g_nof_streams * g_data_w; -- output data with, 168 -- constants for testbench @@ -70,12 +70,12 @@ ARCHITECTURE tb OF tb_ddrctrl IS CONSTANT c_sim_length : NATURAL := (g_sim_length*c_ctrl_data_w)/c_in_data_w; -- amount of input words that get put into the DUT -- constant for checking output data - CONSTANT c_adr_w : NATURAL := func_tech_ddr_ctlr_address_w(c_tech_ddr); -- the lengt of the address vector, for simulation this is smaller, otherwise the simulation would take to long, 27 - CONSTANT c_max_adr : NATURAL := 2**(c_adr_w)-1; -- the maximal address that is possible within the vector length of the address + CONSTANT c_adr_w : NATURAL := func_tech_ddr_ctlr_address_w(c_tech_ddr); -- the lengt of the address vector, for simulation this is smaller, otherwise the simulation would take to long, 27 + CONSTANT c_max_adr : NATURAL := 2**(c_adr_w)-1; -- the maximal address that is possible within the vector length of the address CONSTANT c_output_stop_adr : NATURAL := (c_max_adr+1)-((((c_max_adr+1)/64)*g_stop_percentage/100)*64); CONSTANT c_output_ds : NATURAL := 144; CONSTANT c_bim : NATURAL := (c_max_adr*c_ctrl_data_w)/(g_block_size*g_nof_streams*g_data_w); -- the amount of whole blocks that fit in memory. - CONSTANT c_adr_per_b : NATURAL := ((g_block_size*g_nof_streams*g_data_w)/c_ctrl_data_w)+1; -- rounding error removes the amount of extra addresses. + CONSTANT c_adr_per_b : NATURAL := ((g_block_size*g_nof_streams*g_data_w)/c_ctrl_data_w)+1; -- rounding error removes the amount of extra addresses. -- the amount of addresses used CONSTANT c_nof_adr : NATURAL := (c_bim*g_block_size*g_nof_streams*g_data_w)/c_ctrl_data_w; -- rounding error removes the amount of extra addresses. @@ -96,7 +96,7 @@ ARCHITECTURE tb OF tb_ddrctrl IS RETURN temp; END FUNCTION c_of_after_nof_adr_init; - -- the amount of overflow into the address: c_nof_adr + -- the amount of overflow into the address: c_nof_adr NOT YET USED DELETE AFTER L2SDP-706 CONSTANT c_of_after_nof_adr : NATURAL := c_of_after_nof_adr_init; -- function for making total data vector @@ -116,9 +116,9 @@ ARCHITECTURE tb OF tb_ddrctrl IS -- constant for running the test CONSTANT c_total_vector : STD_LOGIC_VECTOR(g_data_w*g_nof_streams*c_bim*g_block_size-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'); + 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 @@ -217,7 +217,7 @@ BEGIN -- stopping the testbench - WAIT FOR c_clk_period*1024; + WAIT FOR c_clk_period*g_block_size; tb_end <= '1'; ASSERT FALSE REPORT "Test: OK" SEVERITY FAILURE; END PROCESS; -- GitLab