diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd index 6a102999a4b198ff37643cf257c9fe066758d4d1..bca85556f7dd80bdab56cab9a2727a1b1936009a 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd @@ -63,6 +63,7 @@ ENTITY ddrctrl IS stop_in : IN STD_LOGIC := '0'; out_sosi_arr : OUT t_dp_sosi_arr; + out_siso : IN t_dp_siso := c_dp_siso_rst; term_ctrl_out : OUT t_tech_ddr3_phy_terminationcontrol; term_ctrl_in : IN t_tech_ddr3_phy_terminationcontrol := c_tech_ddr3_phy_terminationcontrol_rst; @@ -250,6 +251,7 @@ BEGIN in_bsn => bsn_co, out_sosi_arr => out_sosi_arr, + out_siso => out_siso, out_ready => rd_ready ); diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd index 2e48f3e4d7861b920a159cc8343f0283e10ef3ea..829126807ac2a515209a5934341a7b26bb6f67e5 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd @@ -54,6 +54,7 @@ ENTITY ddrctrl_output IS rst : IN STD_LOGIC; in_sosi : IN t_dp_sosi := c_dp_sosi_init; -- input data in_bsn : IN STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); + out_siso : IN t_dp_siso; 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 ); @@ -84,6 +85,7 @@ BEGIN rst => rst, in_sosi => in_sosi, -- input data in_bsn => in_bsn, + out_siso => out_siso, out_sosi => sosi, -- output data out_ready => out_ready ); 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 5f92f62557d7b530caf860856400fba7bef66338..5e0700011d131d88169168535d6d3eb3f62d428e 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_unpack.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_unpack.vhd @@ -50,6 +50,7 @@ ENTITY ddrctrl_output_unpack IS rst : IN STD_LOGIC; in_sosi : IN t_dp_sosi := c_dp_sosi_init; in_bsn : IN STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); + out_siso : IN t_dp_siso; out_sosi : OUT t_dp_sosi := c_dp_sosi_init; out_ready : OUT STD_LOGIC := '0' ); @@ -88,7 +89,7 @@ BEGIN q_reg <= d_reg WHEN rising_edge(clk); -- put the input data into c_v and fill the output vector from c_v - p_state : PROCESS(q_reg, rst, in_sosi) + p_state : PROCESS(q_reg, rst, in_sosi, out_siso) VARIABLE v : t_reg; @@ -117,12 +118,14 @@ BEGIN 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' OR v.valid_data = '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') AND out_siso.ready = '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' AND v.valid_data = '0' THEN v.state := IDLE; - ELSE + ELSIF out_siso.ready = '1' THEN v.state := READING; + ELSE + v.state := IDLE; END IF; @@ -135,9 +138,11 @@ BEGIN v.out_sosi.sop := '0'; END IF; - IF q_reg.bsn_cnt = g_block_size-3 THEN + IF q_reg.bsn_cnt = g_block_size-3 AND out_siso.ready = '1' THEN v.state := BSN; v.out_ready := '1'; + ELSIF q_reg.bsn_cnt = g_block_size-3 THEN + v.state := IDLE; END IF; @@ -193,51 +198,52 @@ BEGIN v.dd_fresh := '1'; END IF; - 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 + 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') AND out_siso.ready = '1' THEN v.state := OVER_HALF; ELSIF q_reg.dd_fresh = '0' AND q_reg.valid_data = '0' THEN v.state := IDLE; - ELSE + ELSIF out_siso.ready = '1' THEN v.state := READING; + ELSE + v.state := IDLE; 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 + IF q_reg.bsn_cnt = g_block_size-3 AND out_siso.ready = '1' THEN v.state := BSN; v.dd_fresh := '1'; + ELSIF q_reg.bsn_cnt = g_block_size-3 THEN + v.state := IDLE; END IF; WHEN FIRST_READ => -- fills the first half of c_v and generates output from it. - v.out_ready := '0'; + v.out_ready := '1'; 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.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 := '0'; + v.out_sosi.valid := '1'; 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'; END IF; - - v.state := READING; + IF out_siso.ready = '1' THEN + v.state := READING; + ELSE + v.state := IDLE; + END IF; WHEN BSN => -- generating output data from c_v but past the halfway point of c_v so there needs to be new data added also increases the bsn output @@ -300,8 +306,10 @@ BEGIN IF g_bim+TO_UINT(in_bsn)-1 = TO_UINT(v.out_sosi.bsn) THEN v.state := OFF; - ELSE + ELSIF out_siso.ready = '1' THEN v.state := READING; + ELSE + v.state := IDLE; END IF; WHEN RESET => @@ -316,7 +324,11 @@ BEGIN WHEN IDLE => -- the statemachine goes to Idle when its finished or when its waiting on other components. - v.out_ready := '1'; + IF q_reg.dd_fresh = '0' THEN + v.out_ready := '1'; + ELSE + v.out_ready := '0'; + END IF; v.out_sosi.valid := '0'; IF q_reg.dd_fresh = '1' AND q_reg.valid_data = '0' THEN @@ -331,8 +343,14 @@ BEGIN 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 q_reg.bsn_cnt = g_block_size-3 AND out_siso.ready = '0' THEN + v.state := IDLE; + ELSIF q_reg.bsn_cnt = g_block_size-3 THEN + v.state := BSN; + ELSIF (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of >= g_in_data_w AND v.dd_fresh = '1' AND out_siso.ready = '1' AND out_siso.ready = '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 out_siso.ready = '1' THEN + v.state := READING; ELSE v.state := IDLE; END IF; @@ -341,20 +359,24 @@ 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); v.out_sosi := c_dp_sosi_init; - IF in_sosi.valid = '1' THEN - v.state := FIRST_READ; + IF in_sosi.valid = '1' AND q_reg.dd_fresh = '0' 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.out_ready := '0'; + v.state := FIRST_READ; + ELSIF q_reg.dd_fresh = '1' THEN + v.out_ready := '0'; + v.state := OFF; + ELSIF out_siso.ready = '1' THEN + v.out_ready := '1'; + v.state := OFF; ELSE - v.state := OFF; + v.state := OFF; 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 906aacc14b2b26474621265a62b1cca5ad144c19..87cf0163325778e6fa7650ec10f411e74f674420 100644 --- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd +++ b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd @@ -130,6 +130,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 stop_in : STD_LOGIC := '0'; SIGNAL out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_init); + SIGNAL out_siso : t_dp_siso; -- testbench signal SIGNAL tb_end : STD_LOGIC := '0'; -- signal to turn the testbench off @@ -155,6 +156,8 @@ BEGIN -- generating clock clk <= NOT clk OR tb_end AFTER c_clk_period/2; mm_clk <= NOT mm_clk OR tb_end AFTER c_mm_clk_period/2; + out_siso.ready <= '1'; + out_siso.xon <= '1'; -- excecuting test p_test : PROCESS @@ -259,6 +262,7 @@ BEGIN in_sosi_arr => in_sosi_arr, stop_in => stop_in, out_sosi_arr => out_sosi_arr, + out_siso => out_siso, --PHY phy3_io => phy3_io,