From f152abc3738d71875299f79ec954b64e469cabfc Mon Sep 17 00:00:00 2001 From: Greek Date: Fri, 22 Jan 2021 12:01:16 +0100 Subject: [PATCH] Remove GENERATION_COUNTERS Option Generation Counters are always needed (e.g. for the calculation of the view_state, since they are dependent on the reading of samples of the last generation). As such, the Generation Counters were "converted" to mandatory fields. --- src/REF.txt | 16 +++- src/dds_endpoint.vhd | 186 +++++++++++++++++++------------------------ 2 files changed, 92 insertions(+), 110 deletions(-) diff --git a/src/REF.txt b/src/REF.txt index 248c94e..180e227 100644 --- a/src/REF.txt +++ b/src/REF.txt @@ -354,9 +354,9 @@ READER +-------------------------------------------------------------+ 06| INSTANCE_ADDRESS | {A} +-------------------------------------------------------------+ -07| DISPOSED_GENERATION_COUNT | {A} [only GENERATION_COUNTERS] +07| DISPOSED_GENERATION_COUNT | {A} +-------------------------------------------------------------+ -08| NO_WRITERS_GENERATION_COUNT | {A} [only GENERATION_COUNTERS] +08| NO_WRITERS_GENERATION_COUNT | {A} +-------------------------------------------------------------+ 09| PREV_ADDRESS | {A} +-------------------------------------------------------------+ @@ -441,9 +441,9 @@ INSTANCE MEMORY +-------------------------------------------------------------+ 06| SAMPLE_COUNT | {A/B} +-------------------------------------------------------------+ -07| DISPOSED_GENERATION_COUNT | {A} [only GENERATION_COUNTERS] +07| DISPOSED_GENERATION_COUNT | {A} +-------------------------------------------------------------+ -08| NO_WRITERS_GENERATION_COUNT | {A} [only GENERATION_COUNTERS] +08| NO_WRITERS_GENERATION_COUNT | {A} +-------------------------------------------------------------+ 09| | + IGNORE_DEADLINE + {A} [only TIME_BASED_FILTER] @@ -600,6 +600,14 @@ Scenario 2: With SHARED ownership and destination order by SOURCE timestamp, re associated with the instance would forget the source timestamp when the deletion occurs and if a different DataWriter where to write the instance with an earlier timestamp the update would be incorrectly accepted. +2.2.2.5.3.8 read (DDS) +Samples that contain no data do not count towards the limits imposed by the RESOURCE_LIMITS QoS policy. + +2.2.2.5.3.8 read (DDS) +The act of reading a sample sets its sample_state to READ. If the sample belongs to the most recent +generation of the instance, it will also set the view_state of the instance to NOT_NEW. It will not +affect the instance_state of the instance. + INVALIDATION ============ diff --git a/src/dds_endpoint.vhd b/src/dds_endpoint.vhd index a2c1515..03c22c0 100644 --- a/src/dds_endpoint.vhd +++ b/src/dds_endpoint.vhd @@ -11,7 +11,6 @@ entity history_cache is MAX_SAMPLES_PER_INSTANCE : natural := DEFAULT_MAX_SAMPLES_PER_INSTANCE; HISTORY_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := DEFAULT_HISTORY_QOS; RELIABILITY_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := DEFAULT_RELIABILTY_QOS; - GENERATION_COUNTERS : boolean := TRUE; ); port ( clk : in std_logic; @@ -30,6 +29,9 @@ entity history_cache is res_b : out HISTORY_CACHE_RESPOSNE_TYPE; data_out_b : out std_logic_vector(WORD_WIDTH-1 downto 0); last_word_out_b : in std_logic; + instance_state : in INSTANCE_STATE_TYPE; + view_state : in VIEW_STATE_TYPE; + sample_state : in SAMPLE_STATE; ); end entity; @@ -82,7 +84,7 @@ architecture arch of history_cache is constant SMF_INSTANCE_ADDR_OFFSET : natural := 6; constant SMF_DISPOSED_GEN_CNT_OFFSET : natural := 7; constant SMF_NO_WRITERS_GEN_CNT_OFFSET : natural := 8; - constant SMF_PREV_ADDR_OFFSET : natural := SMF_NO_WRITERS_GEN_CNT_OFFSET+1 when GENERATION_COUNTERS else SMF_INSTANCE_ADDR_OFFSET+1; + constant SMF_PREV_ADDR_OFFSET : natural := SMF_NO_WRITERS_GEN_CNT_OFFSET+1; constant SMF_NEXT_ADDR_OFFSET : natural := SMF_PREV_ADDR_OFFSET+1; -- *PAYLOAD MEMORY FRAME FORMAT* constant PMF_NEXT_ADDR_OFFSET : natural := 0; @@ -94,11 +96,8 @@ architecture arch of history_cache is constant IMF_SAMPLE_CNT_OFFSET : natural := 6; constant IMF_DISPOSED_GEN_CNT_OFFSET : natural := IMF_SAMPLE_CNT_OFFSET+1 when (MAX_SAMPLES_PER_INSTANCE /= LENGTH_UNLIMITED) else IMF_STATUS_INFO_OFFSET+1; constant IMF_NO_WRITERS_GEN_CNT_OFFSET : natural := IMF_DISPOSED_GEN_CNT_OFFSET+1; - constant IMF_IGNORE_DEADLINE_OFFSET : natural := IMF_NO_WRITERS_GEN_CNT_OFFSET+1 when (GENERATION_COUNTERS) else - IMF_SAMPLE_CNT_OFFSET+1 when (MAX_SAMPLES_PER_INSTANCE /= LENGTH_UNLIMITED) else IMF_STATUS_INFO_OFFSET+1; - constant IMF_WRITER_BITMAP_OFFSET : natural := IMF_IGNORE_DEADLINE_OFFSET+2 when (TIME_BASED_FILTER_QOS /= DURATION_ZERO) else - IMF_NO_WRITERS_GEN_CNT_OFFSET+1 when (GENERATION_COUNTERS) else - IMF_SAMPLE_CNT_OFFSET+1 when (MAX_SAMPLES_PER_INSTANCE /= LENGTH_UNLIMITED) else IMF_STATUS_INFO_OFFSET+1; + constant IMF_IGNORE_DEADLINE_OFFSET : natural := IMF_NO_WRITERS_GEN_CNT_OFFSET+1; + constant IMF_WRITER_BITMAP_OFFSET : natural := IMF_IGNORE_DEADLINE_OFFSET+2 when (TIME_BASED_FILTER_QOS /= DURATION_ZERO) else IMF_NO_WRITERS_GEN_CNT_OFFSET+1; --*****TYPE DECLARATION***** -- FSM states. Explained below in detail @@ -177,7 +176,7 @@ architecture arch of history_cache is signal sample_mem_full, sample_mem_full_next : std_logic := '0'; signal writer_pos, writer_pos_next : natural range TODO := 0; signal writer_bitmap : ENDPOINT_BITMAP_ARRAY_TYPE; - signal instance_state : INSTANCE_STATE_TYPE := ALIVE; + signal instance_state_update : INSTANCE_STATE_TYPE := ALIVE; signal key_hash, key_hash_next : KEY_HASH_TYPE := (others => (others => '0')); signal remove_oldest_sample, remove_oldest_sample_next : std_logic := '0'; signal remove_oldest_inst_sample, remove_oldest_inst_sample_next : std_logic := '0'; @@ -564,7 +563,7 @@ begin -- Wait for Instance Search to finish if (inst_op_done = '1') then - sample_addr_next <= sample_addr + 1; -- Disposed Gen Counter (Prev Address if GENERATION_COUNTERS=FALSE) + sample_addr_next <= sample_addr + 1; -- Disposed Gen Counter -- Instance Found if (inst_addr_base /= INSTANCE_MEMORY_MAX_ADDRESS) then @@ -641,7 +640,7 @@ begin cnt_next <= 0; else stage_next <= PRE_SAMPLE_FINALIZE; - cnt_next <= 0 when GENERATION_COUNTERS else 2; + cnt_next <= 0; end if; else -- Drop Change @@ -664,7 +663,7 @@ begin cnt_next <= 0; else stage_next <= PRE_SAMPLE_FINALIZE; - cnt_next <= 0 when GENERATION_COUNTERS else 2; + cnt_next <= 0; end if; else -- Drop Change @@ -685,7 +684,7 @@ begin if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) /= '1' and inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) /= '1') then -- STATUS INFO tmp_update <= tmp_update or STATUS_FLAG; - instance_state <= NOT_ALIVE_DISPOSED; + instance_state_update <= NOT_ALIVE_DISPOSED; end if; -- WRITER BITMAP -- Convert Writer Bitmap to SLV @@ -710,25 +709,23 @@ begin if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) /= '1' and inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) /= '1' and tmp_bitmap = (tmp_bitmap => '0')) then -- STATUS INFO tmp_update <= tmp_update or STATUS_FLAG; - instance_state <= NOT_ALIVE_NO_WRITERS; + instance_state_update <= NOT_ALIVE_NO_WRITERS; end if; -- Instance ALIVE/FILTERED else -- STATUS INFO tmp_update <= tmp_update or STATUS_FLAG; - instance_state <= ALIVE; + instance_state_update <= ALIVE; -- GENERATION COUNTERS - if (GENERATION_COUNTERS) then - -- NOT_ALIVE_DISPOSED -> ALIVE Transition - if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '1') then - tmp_update := tmp_update or DISPOSED_CNT_FLAG; - gen_cnt <= inst_data.disposed_gen_cnt + 1; - -- NOT_ALIVE_NO_WRITERS -> ALIVE Transition - elsif (inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '1') then - tmp_update := tmp_update or NO_WRITERS_CNT_FLAG; - gen_cnt <= inst_data.no_writers_gen_cnt + 1; - end if; + -- NOT_ALIVE_DISPOSED -> ALIVE Transition + if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '1') then + tmp_update := tmp_update or DISPOSED_CNT_FLAG; + gen_cnt <= inst_data.disposed_gen_cnt + 1; + -- NOT_ALIVE_NO_WRITERS -> ALIVE Transition + elsif (inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '1') then + tmp_update := tmp_update or NO_WRITERS_CNT_FLAG; + gen_cnt <= inst_data.no_writers_gen_cnt + 1; end if; -- WRITER BITMAP @@ -765,7 +762,7 @@ begin cnt_next <= 0; else stage_next <= PRE_SAMPLE_FINALIZE; - cnt_next <= 0 when GENERATION_COUNTERS else 2; + cnt_next <= 0; end if; end if; when FINALIZE_PAYLOAD => @@ -786,7 +783,7 @@ begin payload_wen <= '1'; stage_next <= PRE_SAMPLE_FINALIZE; - cnt_next <= 0 when GENERATION_COUNTERS else 2; + cnt_next <= 0; when others => null; end case; @@ -798,28 +795,24 @@ begin case (cnt) is -- Disposed Generation Counter when 0 => - if (GENERATION_COUNTERS) then - sample_addr_next <= sample_addr + 1; - sample_wen <= '1'; - - -- NOT_ALIVE_DISPOSED -> ALIVE Transition - if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '1' and sample_status_info(NOT_ALIVE_DISPOSED_FLAG) = '0' and sample_status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '0') then - sample_write_data <= gen_cnt + 1; - else - sample_write_data <= gen_cnt; - end if; + sample_addr_next <= sample_addr + 1; + sample_wen <= '1'; + + -- NOT_ALIVE_DISPOSED -> ALIVE Transition + if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '1' and sample_status_info(NOT_ALIVE_DISPOSED_FLAG) = '0' and sample_status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '0') then + sample_write_data <= gen_cnt + 1; + else + sample_write_data <= gen_cnt; end if; -- No Writer Generation Counter when 1 => - if (GENERATION_COUNTERS) then - sample_wen <= '1'; - - -- NOT_ALIVE_NO_WRITERS -> ALIVE Transition - if (inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '1' and sample_status_info(NOT_ALIVE_DISPOSED_FLAG) = '0' and sample_status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '0') then - sample_write_data <= gen_cnt + 1; - else - sample_write_data <= gen_cnt; - end if; + sample_wen <= '1'; + + -- NOT_ALIVE_NO_WRITERS -> ALIVE Transition + if (inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '1' and sample_status_info(NOT_ALIVE_DISPOSED_FLAG) = '0' and sample_status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '0') then + sample_write_data <= gen_cnt + 1; + else + sample_write_data <= gen_cnt; end if; when 2 => -- First Sample @@ -1221,7 +1214,7 @@ begin -- No More Writers for Instance if (tmp_bitmap = (tmp_bitmap'range => '0')) then inst_op_start <= '1'; - instance_state <= NOT_ALIVE_NO_WRITERS; + instance_state_update <= NOT_ALIVE_NO_WRITERS; inst_opcode <= UPDATE_INSTANCE; update_inst_flags <= STATUS_FLAG or WRITER_BITMAP_FLAG; else @@ -1301,7 +1294,7 @@ begin -- Latch Signals needed for Mermory Operation (Use _next signals, because some signals are set in same clk) inst_latch_data_next <= ( key_hash => key_hash_next, - instance_state => instance_state, + instance_state => instance_state_update, sample_cnt => sample_cnt, gen_cnt => gen_cnt, deadline => deadline, @@ -1358,11 +1351,11 @@ begin inst_stage_next <= UPDATE_INSTANCE; inst_addr_next <= inst_addr_update + IMF_SAMPLE_CNT_OFFSET; inst_cnt_next <= 3; - elsif (GENERATION_COUNTERS and (update_inst_flags and DISPOSED_CNT_FLAG) = DISPOSED_CNT_FLAG) then + elsif ((update_inst_flags and DISPOSED_CNT_FLAG) = DISPOSED_CNT_FLAG) then inst_stage_next <= UPDATE_INSTANCE; inst_addr_next <= inst_addr_update + IMF_DISPOSED_GEN_CNT_OFFSET; inst_cnt_next <= 6; - elsif (GENERATION_COUNTERS and (update_inst_flags and NO_WRITERS_CNT_FLAG) = NO_WRITERS_CNT_FLAG) then + elsif ((update_inst_flags and NO_WRITERS_CNT_FLAG) = NO_WRITERS_CNT_FLAG) then inst_stage_next <= UPDATE_INSTANCE; inst_addr_next <= inst_addr_update + IMF_NO_WRITERS_GEN_CNT_OFFSET; inst_cnt_next <= 7; @@ -1619,32 +1612,19 @@ begin -- Sample Count when 7 => inst_write_data <= std_logic_vector(to_unsigned(1, WORD_WIDTH)); + -- Disposed Generation Count + when 8 => + inst_write_data <= (others => '0'); + -- No Writers Generation Count + when 9 => + inst_write_data <= (others => '0'); - if (GENERATION_COUNTERS) then - inst_cnt <= 8; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO) then + if (TIME_BASED_FILTER_QOS /= DURATION_ZERO) then inst_cnt <= 10; else inst_stage_next <= SET_WRITER_BITMAP; inst_cnt_next <= 0; end if; - -- Disposed Generation Count - when 8 => - if (GENERATION_COUNTERS) then - inst_write_data <= (others => '0'); - end if; - -- No Writers Generation Count - when 9 => - if (GENERATION_COUNTERS) then - inst_write_data <= (others => '0'); - - if (TIME_BASED_FILTER_QOS /= DURATION_ZERO) then - inst_cnt <= 10; - else - inst_stage_next <= SET_WRITER_BITMAP; - inst_cnt_next <= 0; - end if; - end if; -- Ignore Deadline 1/2 when 10 => if (TIME_BASED_FILTER_QOS /= DURATION_ZERO) then @@ -1699,10 +1679,10 @@ begin if ((inst_latch_data.update_flags and SAMPLE_CNT_FLAG) = SAMPLE_CNT_FLAG) then inst_addr_next <= inst_addr_base + IMF_SAMPLE_CNT_OFFSET; inst_cnt_next <= 1; - elsif (GENERATION_COUNTERS and (inst_latch_data.update_flags and DISPOSED_CNT_FLAG) = DISPOSED_CNT_FLAG) then + elsif ((inst_latch_data.update_flags and DISPOSED_CNT_FLAG) = DISPOSED_CNT_FLAG) then inst_addr_next <= inst_addr_base + IMF_DISPOSED_GEN_CNT_OFFSET; inst_cnt_next <= 2; - elsif (GENERATION_COUNTERS and (inst_latch_data.update_flags and NO_WRITERS_CNT_FLAG) = NO_WRITERS_CNT_FLAG) then + elsif ((inst_latch_data.update_flags and NO_WRITERS_CNT_FLAG) = NO_WRITERS_CNT_FLAG) then inst_addr_next <= inst_addr_base + IMF_NO_WRITERS_GEN_CNT_OFFSET; inst_cnt_next <= 3; elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and (inst_latch_data.update_flags and IGNORE_DEADLINE_FLAG) = IGNORE_DEADLINE_FLAG) then @@ -1721,10 +1701,10 @@ begin inst_wen <= '1'; inst_write_data <= inst_latch_data.sample_cnt; - if (GENERATION_COUNTERS and (inst_latch_data.update_flags and DISPOSED_CNT_FLAG) = DISPOSED_CNT_FLAG) then + if ((inst_latch_data.update_flags and DISPOSED_CNT_FLAG) = DISPOSED_CNT_FLAG) then inst_addr_next <= inst_addr_base + IMF_DISPOSED_GEN_CNT_OFFSET; inst_cnt_next <= 2; - elsif (GENERATION_COUNTERS and (inst_latch_data.update_flags and NO_WRITERS_CNT_FLAG) = NO_WRITERS_CNT_FLAG) then + elsif ((inst_latch_data.update_flags and NO_WRITERS_CNT_FLAG) = NO_WRITERS_CNT_FLAG) then inst_addr_next <= inst_addr_base + IMF_NO_WRITERS_GEN_CNT_OFFSET; inst_cnt_next <= 3; elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and (inst_latch_data.update_flags and IGNORE_DEADLINE_FLAG) = IGNORE_DEADLINE_FLAG) then @@ -1740,42 +1720,36 @@ begin end if; -- Disposed Generation Count when 2 => - if (GENERATION_COUNTERS) then - inst_wen <= '1'; - inst_write_data <= inst_latch_data.gen_cnt; - - if (GENERATION_COUNTERS and (inst_latch_data.update_flags and NO_WRITERS_CNT_FLAG) = NO_WRITERS_CNT_FLAG) then - inst_addr_next <= inst_addr_base + IMF_NO_WRITERS_GEN_CNT_OFFSET; - inst_cnt_next <= 3; - elsif (TIME_BASED_FILTER_QOS /= DURATION_ZERO and (inst_latch_data.update_flags and IGNORE_DEADLINE_FLAG) = IGNORE_DEADLINE_FLAG) then - inst_addr_next <= inst_addr_base + IMF_IGNORE_DEADLINE_OFFSET; - inst_cnt_next <= 4; - elsif ((inst_latch_data.update_flags and WRITER_BITMAP_FLAG) = WRITER_BITMAP_FLAG) then - inst_addr_next <= inst_addr_base + IMF_WRITER_BITMAP_OFFSET; - inst_stage_next <= SET_WRITER_BITMAP; - inst_cnt_next <= 0; - else - -- DONE - inst_stage_next <= IDLE; - end if; + inst_wen <= '1'; + inst_write_data <= inst_latch_data.gen_cnt; + + -- NOTE: Both Generation Counters cannot be updated on the same update procedure + if (TIME_BASED_FILTER_QOS /= DURATION_ZERO and (inst_latch_data.update_flags and IGNORE_DEADLINE_FLAG) = IGNORE_DEADLINE_FLAG) then + inst_addr_next <= inst_addr_base + IMF_IGNORE_DEADLINE_OFFSET; + inst_cnt_next <= 4; + elsif ((inst_latch_data.update_flags and WRITER_BITMAP_FLAG) = WRITER_BITMAP_FLAG) then + inst_addr_next <= inst_addr_base + IMF_WRITER_BITMAP_OFFSET; + inst_stage_next <= SET_WRITER_BITMAP; + inst_cnt_next <= 0; + else + -- DONE + inst_stage_next <= IDLE; end if; -- No Writers Generation Count when 3 => - if (GENERATION_COUNTERS) then - inst_wen <= '1'; - inst_write_data <= inst_latch_data.gen_cnt; - - if (TIME_BASED_FILTER_QOS /= DURATION_ZERO and (inst_latch_data.update_flags and IGNORE_DEADLINE_FLAG) = IGNORE_DEADLINE_FLAG) then - inst_addr_next <= inst_addr_base + IMF_IGNORE_DEADLINE_OFFSET; - inst_cnt_next <= 4; - elsif ((inst_latch_data.update_flags and WRITER_BITMAP_FLAG) = WRITER_BITMAP_FLAG) then - inst_addr_next <= inst_addr_base + IMF_WRITER_BITMAP_OFFSET; - inst_stage_next <= SET_WRITER_BITMAP; - inst_cnt_next <= 0; - else - -- DONE - inst_stage_next <= IDLE; - end if; + inst_wen <= '1'; + inst_write_data <= inst_latch_data.gen_cnt; + + if (TIME_BASED_FILTER_QOS /= DURATION_ZERO and (inst_latch_data.update_flags and IGNORE_DEADLINE_FLAG) = IGNORE_DEADLINE_FLAG) then + inst_addr_next <= inst_addr_base + IMF_IGNORE_DEADLINE_OFFSET; + inst_cnt_next <= 4; + elsif ((inst_latch_data.update_flags and WRITER_BITMAP_FLAG) = WRITER_BITMAP_FLAG) then + inst_addr_next <= inst_addr_base + IMF_WRITER_BITMAP_OFFSET; + inst_stage_next <= SET_WRITER_BITMAP; + inst_cnt_next <= 0; + else + -- DONE + inst_stage_next <= IDLE; end if; -- Ignore Deadline 1/2 when 4 =>