diff --git a/src/dds_endpoint.vhd b/src/dds_endpoint.vhd index 11e1edc..9500f5e 100644 --- a/src/dds_endpoint.vhd +++ b/src/dds_endpoint.vhd @@ -277,6 +277,8 @@ architecture arch of history_cache is signal dynamic_next_instance, dynamic_next_instance_next : std_logic := '0'; signal inst_data_variant : INSTANCE_DATA_VARIANT_TYPE := VAR_1; signal abort_khg : std_logic := '0'; + signal lifespan_time, lifespan_time_next : TIME_TYPE := TIME_ZERO; + signal is_lifespan_check, is_lifespan_check_next : std_logic := '0'; signal status_sig, status_sig_next : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := (others => '0'); signal sample_rej_cnt, sample_rej_cnt_next : unsigned(SAMPLE_REJECTED_STATUS_COUNT_WIDTH-1 downto 0) := (others => '0'); @@ -463,6 +465,8 @@ begin deadline_miss_cnt_next <= deadline_miss_cnt; deadline_miss_cnt_change_next <= deadline_miss_cnt_change; deadline_miss_last_inst_next <= deadline_miss_last_inst; + lifespan_time_next <= lifespan_time; + is_lifespan_check_next <= is_lifespan_check; ack_dds <= '0'; inst_data_variant <= VAR_1; done_dds <= '0'; @@ -483,12 +487,24 @@ begin -- DEADLINE QoS - if (DEADLINE_QOS /= DURATION_INFINITE and deadline_time < time) then + if (DEADLINE_QOS /= DURATION_INFINITE and deadline_time <= time) then -- Reset Timeout deadline_time_next <= deadline_time + DEADLINE_QOS; stage_next <= CHECK_DEADLINE; cnt_next <= 0; + -- LIFESPAN QoS + elsif (lifespan_time <= time) then + -- Reset Timeout + lifespan_time_next <= time + TODO; + + -- Samples Available + if (oldest_sample /= SAMPLE_MEMORY_MAX_ADDRESS) then + cur_sample <= oldest_sample; + sample_addr_next <= oldest_sample + SMF_NEXT_ADDR_OFFSET; + stage_next <= CHECK_LIFESPAN; + cnt_next <= 0; + end if; elsif (start_rtps = '1') then case (opcode_rtps) is when ADD_CHANGE => @@ -1575,6 +1591,18 @@ begin -- Continue Processing stage_next <= GET_NEXT_SAMPLE; cnt_next <= 0; + elsif (is_lifespan_check = '1') then + -- Reached End of Samples + if (next_sample = SAMPLE_MEMORY_MAX_ADDRESS) then + -- DONE + stage_next <= IDLE; + else + -- Continue Search + cur_sample_next <= next_sample; + sample_addr_next <= next_sample + SMF_NEXT_ADDR_OFFSET; + stage_next <= CHECK_LIFESPAN; + cnt_next <= 0; + end if; else -- DONE stage_next <= IDLE; @@ -2520,6 +2548,51 @@ begin null; end case; end if; + when CHECK_LIFESPAN => + -- Precondition: cur_sample set, sample_addr (Next Pointer of cur_sample) + + case (cnt) is + -- Preload + when 0 => + sample_addr_next <= cur_sample + SMF_LIFESPAN_DEADLINE_OFFSET; + sample_ren <= '1'; + -- Next Pointer + when 1 => + sample_addr_next <= sample_addr + 1; -- Lifespan 2/2 + sample_ren <= '1'; + + -- Latch Next Sample + next_sample_next <= sample_read_data; + -- Lifespan 1/2 + when 2 => + sample_ren <= '1'; + + long_latch_next <= sample_read_data; + -- Lifespan 2/2 + when 3 => + tmp_dw := (0 => unsigned(long_latch), 1 => unsigned(sample_read_data)); + + -- Sample Lifespan Expired + if (tmp_dw /= TIME_INVALID and time >= tmp_dw) then + -- Remove Sample + sample_addr_next <= cur_sample + SMF_PREV_ADDR_OFFSET; + stage_next <= REMOVE_SAMPLE; + cnt_next <= 0; + else + -- Reached End of Samples + if (next_sample = SAMPLE_MEMORY_MAX_ADDRESS) then + -- DONE + stage_next <= IDLE; + else + -- Continue Search + cur_sample_next <= next_sample; + sample_addr_next <= next_sample + SMF_NEXT_ADDR_OFFSET; + cnt_next <= 0; + end if; + end if; + when others => + null; + end case; when GET_SAMPLE_REJECTED_STATUS => if (ready_out_dds = '1') then cnt_next <= cnt + 1;