Skip to content
Snippets Groups Projects
Commit cb537a0e authored by Job van Wee's avatar Job van Wee
Browse files

ddrctrl is able to react to back pressure.

parent 141e5847
No related branches found
No related tags found
1 merge request!250Resolve L2SDP-728
Pipeline #29620 failed
......@@ -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
);
......
......@@ -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
);
......
......@@ -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
......
......@@ -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,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment