diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd index f8e161c253214a65523b5deab17d8e29dc63a72c..02708a7acb4f9dd1f7021786114d15b9d5e73557 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd @@ -100,7 +100,6 @@ ARCHITECTURE str OF ddrctrl IS SIGNAL stop : STD_LOGIC; SIGNAL rd_fifo_usedw: STD_LOGIC_VECTOR(ceil_log2(c_rd_fifo_depth*(func_tech_ddr_ctlr_data_w(g_tech_ddr)/c_io_ddr_data_w) )-1 DOWNTO 0); SIGNAL rd_ready : STD_LOGIC; - SIGNAL inp_ds : NATURAL; SIGNAL inp_bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); SIGNAL inp_bsn_adr : NATURAL; diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd index fbada42302024decd5e2f0c597de9f6ba67489c7..2da04e15bcee33174de1ef7a49fcfa75d3858e6b 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd @@ -88,10 +88,6 @@ ARCHITECTURE rtl OF ddrctrl_controller IS CONSTANT c_rest : NATURAL := c_rd_data_w-(g_wr_data_w mod c_rd_data_w); -- 96 CONSTANT c_max_read_cnt : NATURAL := (c_max_adr+1)/c_burstsize; -- 256 - -- not needed hopefully - --CONSTANT c_gcd : NATURAL := GCD(c_rd_data_w, g_wr_data_w); -- 24 - --CONSTANT c_ofset_repeat : NATURAL := c_rd_data_wc/c_gcd; -- 7 - -- type for statemachine TYPE t_state IS (RESET, WRITING, SET_STOP, STOP_WRITING, START_READING, READING, STOP_READING, IDLE); @@ -153,7 +149,9 @@ BEGIN WHEN WRITING => - IF TO_UVEC(inp_adr, c_adr_w)(c_bitshift_adr-1 DOWNTO 0) = c_zeros THEN -- if adr mod c_burstsize = 0 + -- if adr mod c_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(c_max_adr-c_burstsize, dvr_mosi.address'length); @@ -193,7 +191,9 @@ BEGIN v.stop_adr(c_bitshift_adr-1 DOWNTO 0) := c_zeros; -- still a write cyle - IF TO_UVEC(inp_adr, c_adr_w)(c_bitshift_adr-1 DOWNTO 0) = c_zeros THEN -- adr mod 64 = 0 + -- if adr mod c_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(c_max_adr-c_burstsize, dvr_mosi.address'length); @@ -225,7 +225,8 @@ BEGIN WHEN STOP_WRITING => v.dvr_mosi.burstbegin := '0'; - IF dvr_miso.done = '1' AND q_reg.dvr_mosi.burstbegin = '0' THEN -- wait until the write burst is finished + -- wait until the write burst is finished + IF dvr_miso.done = '1' AND q_reg.dvr_mosi.burstbegin = '0' THEN v.stopped := '1'; v.wr_sosi.valid := '0'; v.dvr_mosi.flush := '1'; @@ -254,7 +255,7 @@ BEGIN END IF; END LOOP; - v.outp_bsn := TO_UVEC(TO_UINT(inp_bsn)-((inp_bsn_adr+(c_max_adr-TO_UINT(q_reg.stop_adr)))*g_wr_data_w+v.outp_ds-inp_ds)/c_rd_data_w, c_dp_stream_bsn_w); -- maths WRONG, wil be fixed after L2SDP-705, 706, 707 and 708 + v.outp_bsn := TO_UVEC(TO_UINT(inp_bsn)-((inp_bsn_adr+(c_max_adr-TO_UINT(q_reg.stop_adr)))*g_wr_data_w+v.outp_ds-inp_ds)/c_rd_data_w, c_dp_stream_bsn_w); -- WRONG, wil be fixed after L2SDP-705, 706, 707 and 708 IF rst = '1' THEN @@ -265,14 +266,12 @@ BEGIN WHEN READING => - - IF TO_UINT(rd_fifo_usedw) <= 10 AND dvr_miso.done = '1' AND q_reg.rd_burst_en = '1' AND dvr_miso.done = '1' THEN -- rd_fifo needs a refil after rd_fifo_usedw <= 10 because of delays, if you wait until rd_fifo_usedw = 0 then you get an empty fifo for to long + -- rd_fifo needs a refil after rd_fifo_usedw <= 10 because of delays, if you wait until rd_fifo_usedw = 0 then you get an empty fifo which results in your outputs sosi.valid not being constatly valid. + IF TO_UINT(rd_fifo_usedw) <= 10 AND dvr_miso.done = '1' AND q_reg.rd_burst_en = '1' AND dvr_miso.done = '1' THEN IF TO_UINT(q_reg.stop_adr(c_adr_w-1 DOWNTO 0))+c_burstsize*q_reg.read_cnt >= c_max_adr THEN v.dvr_mosi.address(c_adr_w-1 DOWNTO 0) := TO_UVEC((TO_UINT(q_reg.stop_adr(c_adr_w-1 DOWNTO 0))+c_burstsize*q_reg.read_cnt)-c_max_adr-1, c_adr_w); - --assert false report "1. address: " & natural'image((TO_UINT(q_reg.stop_adr(c_adr_w-1 DOWNTO 0))+c_burstsize*q_reg.read_cnt)-c_max_adr) severity note; ELSE v.dvr_mosi.address(c_adr_w-1 DOWNTO 0) := TO_UVEC(TO_UINT(q_reg.stop_adr(c_adr_w-1 DOWNTO 0))+c_burstsize*q_reg.read_cnt, c_adr_w); - --assert false report "2. address: " & natural'image((TO_UINT(q_reg.stop_adr(c_adr_w-1 DOWNTO 0))+c_burstsize*q_reg.read_cnt)) severity note; END IF; v.dvr_mosi.burstbegin := '1'; v.read_cnt := v.read_cnt+1; @@ -281,7 +280,8 @@ BEGIN v.dvr_mosi.burstbegin := '0'; END IF; - IF TO_UINT(rd_fifo_usedw) = 11 THEN -- make sure the fifo is filled before asking for another rd request. to prevent 4 rd burst to happend directly after one another. + -- makes sure the fifo is filled before asking for another rd request. to prevent 4 rd burst to happend directly after one another. + IF TO_UINT(rd_fifo_usedw) = 11 THEN v.rd_burst_en := '1'; END IF; @@ -294,10 +294,9 @@ BEGIN END IF; - WHEN IDLE => - - + WHEN IDLE => + -- the statemachine goes to Idle when its finished or when its waiting on other components. IF rst = '1' THEN v.state := RESET; ELSIF stop_in = '1' THEN diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd index cc934f3a06924d02e1b166d4a0a84e4f1558c84e..b535fa56b3a62b1589ec20a2a9c184fe530e8226 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd @@ -22,15 +22,12 @@ -- stored in a DDR RAM-stick. -- -- Description: --- First the data from the sosi array gets collected into one data vector. --- After that this data vector gets resized to the right size data vector in --- order to make it storable in a DDR RAM-stick. --- After that a address gets assigned to the data so the data can be found back. +-- First the data from the ddr memory gets resized into its original size +-- after that the data gets assigned a bsn. -- -- Remark: -- Use VHDL coding template from: -- https://support.astron.nl/confluence/display/SBe/VHDL+design+patterns+for+RTL+coding --- The maximum value of the address is determend by g_tech_ddr. LIBRARY IEEE, technology_lib, tech_ddr_lib, common_lib, dp_lib; USE IEEE.std_logic_1164.ALL; @@ -44,19 +41,19 @@ USE dp_lib.dp_stream_pkg.ALL; ENTITY ddrctrl_output IS GENERIC ( - g_tech_ddr : t_c_tech_ddr; -- type of memory - g_sim_model : BOOLEAN := TRUE; -- determens if this is a simulation - 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_tech_ddr : t_c_tech_ddr; -- type of memory + g_sim_model : BOOLEAN := TRUE; -- determens if this is a simulation + 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 ); PORT ( - clk : IN STD_LOGIC := '0'; + clk : IN STD_LOGIC := '0'; rst : IN STD_LOGIC; - in_sosi : IN t_dp_sosi := c_dp_sosi_init; -- input data - in_ds : IN NATURAL; -- amount of internal overflow this output - in_bsn : IN STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); -- bsn corresponding to the data at in_data[in_of] - out_sosi_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_init); -- output data + in_sosi : IN t_dp_sosi := c_dp_sosi_init; -- input data + in_ds : IN NATURAL; -- amount of internal overflow this output + in_bsn : IN STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); -- bsn corresponding to the data at in_data[in_of] + out_sosi_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_init); -- output data out_ready : OUT STD_LOGIC ); END ddrctrl_output; @@ -65,7 +62,7 @@ END ddrctrl_output; ARCHITECTURE str OF ddrctrl_output IS -- constant for readability - CONSTANT c_out_data_w : NATURAL := g_nof_streams*g_data_w; -- the input data with for ddrctrl_repack 168 + CONSTANT c_out_data_w : NATURAL := g_nof_streams*g_data_w; -- the input data width for ddrctrl_repack 168 -- signals for connecting the components SIGNAL sosi : t_dp_sosi := c_dp_sosi_init; @@ -82,10 +79,10 @@ BEGIN PORT MAP( clk => clk, rst => rst, - in_sosi => in_sosi, -- input data + in_sosi => in_sosi, -- input data in_ds => in_ds, in_bsn => in_bsn, - out_sosi => sosi, -- output data + out_sosi => sosi, -- output data out_ready => out_ready ); diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_repack.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_repack.vhd index c566a4cbf00338419ae8f5107862b7c61c532f87..39a88abe29e997b52c3fffb60d60ab47cf459f76 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_repack.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_repack.vhd @@ -40,7 +40,7 @@ ENTITY ddrctrl_output_repack IS g_data_w : NATURAL := 14 ); PORT ( - in_sosi : IN t_dp_sosi := c_dp_sosi_init; + in_sosi : IN t_dp_sosi := c_dp_sosi_init; out_sosi_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_init) ); END ddrctrl_output_repack; 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 8a65a220bad5831e832961dee72f482c9b2515b9..8fb5b17d7f0d6779cc208b43779651e4a35ae3ba 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_unpack.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_unpack.vhd @@ -93,8 +93,9 @@ BEGIN CASE q_reg.state IS WHEN READING => + -- generating output from the data already present in c_v v.out_ready := '0'; - 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); + 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.out_sosi.bsn(c_dp_stream_bsn_w-1 DOWNTO 0) := INCR_UVEC(q_reg.out_sosi.bsn, 1); v.op_data_cnt := q_reg.op_data_cnt+1; @@ -118,8 +119,9 @@ BEGIN 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) := 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); + 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.out_sosi.bsn(c_dp_stream_bsn_w-1 DOWNTO 0) := INCR_UVEC(q_reg.out_sosi.bsn, 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); @@ -147,7 +149,8 @@ BEGIN WHEN FIRST_READ => - v.out_ready := '1'; + -- fills the first half of c_v and generates a output from it. + v.out_ready := '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.a_of := in_ds+2-((12-5)*14); -- will be fixed after in_ds is fixed in ddrctrl_controller. @@ -170,7 +173,8 @@ BEGIN END IF; WHEN SECOND_READ => - v.out_ready := '1'; + -- 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); @@ -212,6 +216,7 @@ BEGIN END IF; WHEN IDLE => + -- the statemachine goes to Idle when its finished or when its waiting on other components. v.out_ready := '1'; v.out_sosi.valid := '0'; @@ -234,6 +239,7 @@ BEGIN WHEN OFF => + -- 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); diff --git a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd index 574fe9cd79b4ca4a2825cfce20ee51c1227db9c9..afba9df90a4352757a0717bb7c94f52a4a2c820d 100644 --- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd +++ b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd @@ -175,11 +175,10 @@ BEGIN ASSERT FALSE REPORT "Test: OK" SEVERITY FAILURE; END PROCESS; - p_checking_output_data : PROCESS -- first do tickets L2SDP-708 and L2SDP-707 before finsishing this is worth my time + p_checking_output_data : PROCESS -- first do tickets L2SDP-708 and L2SDP-707 before finsishing this is worth time BEGIN WAIT UNTIL rising_edge(clk); IF out_sosi_arr(0).valid = '1' THEN - --assert false report "checking" severity note; FOR I IN 0 TO g_nof_streams-1 LOOP IF c_output_stop_adr+output_data_cnt <= c_max_adr THEN --ASSERT out_sosi_arr(I).data(c_in_data_w-1 DOWNTO 0) = c_total_vector(g_data_w*(I+1)+(c_output_stop_adr+output_data_cnt)*c_ctrl_data_w-1 DOWNTO g_data_w*I+(c_output_stop_adr+output_data_cnt)*c_ctrl_data_w) REPORT "wrong output data at: " & NATURAL'image(c_output_stop_adr+output_data_cnt) SEVERITY ERROR;