From c3b656c6549dc6e70a7f7dd27d207db9276fa04e Mon Sep 17 00:00:00 2001 From: Greek Date: Fri, 22 Jan 2021 13:24:37 +0100 Subject: [PATCH] Insert Instances in KEY_HASH numerical order in order to support the read_next_instance/take_next_instance operations, the instances have to have a a logical order. Whie the previous implementation did have a logical order for inserted instances (Since they are added in a linked list), we need to support relative ordering also for non-inserted instances (acording to DDS Spec), so we just order them in ascending order. --- src/dds_endpoint.vhd | 223 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 185 insertions(+), 38 deletions(-) diff --git a/src/dds_endpoint.vhd b/src/dds_endpoint.vhd index 03c22c0..4a1cada 100644 --- a/src/dds_endpoint.vhd +++ b/src/dds_endpoint.vhd @@ -196,7 +196,7 @@ architecture arch of history_cache is signal inst_next_addr_base, inst_next_addr_base_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); signal inst_prev_addr_base, inst_prev_addr_base_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); signal inst_empty_head, inst_empty_head_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal inst_occupied_tail, inst_occupied_tail_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); + signal inst_occupied_head, inst_occupied_head_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0'); signal inst_latch_data, inst_latch_data_next : INST_LATCH_DATA_TYPE := ZERO_INST_LATCH_DATA; signal update_inst_flags : std_logic_vector(0 to UPDATE_INSTANCE_FLAG_WIDTH-1) := (others => '0'); signal inst_cnt, inst_cnt_next : natural range TODO := 0; @@ -1337,9 +1337,9 @@ begin -- by the main process that the operation can succeed (Memory is available) assert (inst_empty_head /= INSTANCE_MEMORY_MAX_ADDRESS) report "Instance Insertion while memory Full" severity FAILURE; - inst_addr_next <= inst_empty_head; - inst_addr_base_next <= inst_empty_head; - inst_stage_next <= INSERT_INSTANCE; + inst_addr_next <= inst_occupied_head; + inst_addr_base_next <= inst_occupied_head; + inst_stage_next <= FIND_POS; inst_cnt_next <= 0; when UPDATE_INSTANCE => inst_addr_base_next <= inst_addr_update; @@ -1578,65 +1578,212 @@ begin -- DONE inst_stage_next <= IDLE; end if; - when INSERT_INSTANCE => + when FIND_POS => + inst_cnt_next <= inst_cnt + 1; + inst_addr_next <= inst_addr + 1; + inst_ren <= '1'; - inst_wen <= '1'; + -- NOTE: Instances are inserted in KEY_HASH numerical order. + + case (inst_cnt) is + + -- Preload + when 0 => + null; + -- Next Instance + when 1 => + inst_next_addr_base_next <= inst_read_data; + -- Key Hash 1/4 + when 2 => + -- Found Position + if (inst_latch_data.key_hash(0) < inst_read_data) then + inst_next_addr_base_next <= inst_addr_base; + -- Occupied List Head + if (inst_prev_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then + assert (inst_addr_base = inst_occupied_head) + inst_occupied_head_next <= inst_empty_head; + + inst_addr_base_next <= inst_empty_head; + inst_addr_next <= inst_empty_head + IMF_NEXT_ADDR_OFFSET; + inst_stage_next <= INSERT_INSTANCE; + cnt_next <= 1; -- Skip First Step + else + inst_addr_base_next <= inst_prev_addr_base; + inst_addr_next <= inst_prev_addr_base + IMF_NEXT_ADDR_OFFSET; + inst_stage_next <= INSERT_INSTANCE; + cnt_next <= 0; + end if; + -- BIGGER-THAN + elsif (inst_latch_data.key_hash /= inst_read_data) then + -- Continue + inst_prev_addr_base_next <= inst_addr_base; + inst_addr_next <= inst_next_addr_base; + inst_addr_base_next <= inst_next_addr_base; + cnt_next <= 0; + end if; + -- Key Hash 2/4 + when 3 => + -- Found Position + if (inst_latch_data.key_hash < inst_read_data) then + inst_next_addr_base_next <= inst_addr_base; + -- Occupied List Head + if (inst_prev_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then + assert (inst_addr_base = inst_occupied_head) + inst_occupied_head_next <= inst_empty_head; + + inst_addr_base_next <= inst_empty_head; + inst_addr_next <= inst_empty_head + IMF_NEXT_ADDR_OFFSET; + inst_stage_next <= INSERT_INSTANCE; + cnt_next <= 1; -- Skip First Step + else + inst_addr_base_next <= inst_prev_addr_base; + inst_addr_next <= inst_prev_addr_base + IMF_NEXT_ADDR_OFFSET; + inst_stage_next <= INSERT_INSTANCE; + cnt_next <= 0; + end if; + -- BIGGER-THAN + elsif (inst_latch_data.key_hash(1) /= inst_read_data) then + -- Continue + inst_prev_addr_base_next <= inst_addr_base; + inst_addr_next <= inst_next_addr_base; + inst_addr_base_next <= inst_next_addr_base; + cnt_next <= 0; + end if; + -- Key Hash 3/4 + when 4 => + -- Found Position + if (inst_latch_data.key_hash(2) < inst_read_data) then + inst_next_addr_base_next <= inst_addr_base; + -- Occupied List Head + if (inst_prev_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then + assert (inst_addr_base = inst_occupied_head) + inst_occupied_head_next <= inst_empty_head; + + inst_addr_base_next <= inst_empty_head; + inst_addr_next <= inst_empty_head + IMF_NEXT_ADDR_OFFSET; + inst_stage_next <= INSERT_INSTANCE; + cnt_next <= 1; -- Skip First Step + else + inst_addr_base_next <= inst_prev_addr_base; + inst_addr_next <= inst_prev_addr_base + IMF_NEXT_ADDR_OFFSET; + inst_stage_next <= INSERT_INSTANCE; + cnt_next <= 0; + end if; + -- BIGGER-THAN + elsif (inst_latch_data.key_hash /= inst_read_data) then + -- Continue + inst_prev_addr_base_next <= inst_addr_base; + inst_addr_next <= inst_next_addr_base; + inst_addr_base_next <= inst_next_addr_base; + cnt_next <= 0; + end if; + -- Key Hash 4/4 + when 5 => + -- Found Position + if (inst_latch_data.key_hash(3) < inst_read_data) then + inst_next_addr_base_next <= inst_addr_base; + -- Occupied List Head + if (inst_prev_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then + assert (inst_addr_base = inst_occupied_head) + inst_occupied_head_next <= inst_empty_head; + + inst_addr_base_next <= inst_empty_head; + inst_addr_next <= inst_empty_head + IMF_NEXT_ADDR_OFFSET; + inst_stage_next <= INSERT_INSTANCE; + cnt_next <= 1; -- Skip First Step + else + inst_addr_base_next <= inst_prev_addr_base; + inst_addr_next <= inst_prev_addr_base + IMF_NEXT_ADDR_OFFSET; + inst_stage_next <= INSERT_INSTANCE; + cnt_next <= 0; + end if; + else + assert (inst_latch_data.key_hash(3) /= inst_read_data) report "Doublicate Instance Detected" severity FAILURE; + + -- Continue + inst_prev_addr_base_next <= inst_addr_base; + inst_addr_next <= inst_next_addr_base; + inst_addr_base_next <= inst_next_addr_base; + cnt_next <= 0; + end if; + when others => + null; + end case; + when INSERT_INSTANCE => inst_addr_next <= inst_addr + 1; inst_cnt_next <= inst_cnt + 1; case (inst_cnt) is - -- Preload + -- Next Pointer (Previous Instance) when 0 => - inst_ren <= '1'; - -- Next Instance Address + inst_write_data <= inst_empty_head; + inst_wen <= '1'; + inst_addr_next <= inst_empty_head; + inst_addr_base_next <= inst_empty_head; + -- Preload when 1 => - inst_empty_head_next <= inst_read_data; - -- Make New Occupied Head - inst_write_data <= inst_occupied_head; - inst_occupied_head_next <= inst_empty_head; - -- Key Hash 1/4 + inst_ren <= '1'; + inst_addr_next <= inst_addr; -- Keep Addr + -- Next Pointer (New Instance) when 2 => - inst_write_data <= inst_latch_data.key_hash(0); - -- Key Hash 2/4 + -- Fix Empty List Head + inst_empty_head_next <= inst_read_data; + + inst_write_data <= inst_next_addr_base; + inst_wen <= '1'; + -- Key Hash 1/4 when 3 => - inst_write_data <= inst_latch_data.key_hash(1); - -- Key Hash 3/4 + inst_write_data <= inst_latch_data.key_hash(0); + inst_wen <= '1'; + -- Key Hash 2/4 when 4 => - inst_write_data <= inst_latch_data.key_hash(2); - -- Key Hash 4/4 + inst_write_data <= inst_latch_data.key_hash(1); + inst_wen <= '1'; + -- Key Hash 3/4 when 5 => - inst_write_data <= inst_latch_data.key_hash(3); - -- Status Info + inst_write_data <= inst_latch_data.key_hash(2); + inst_wen <= '1'; + -- Key Hash 4/4 when 6 => - inst_write_data <= inst_latch_data.status_info; - -- Sample Count + inst_write_data <= inst_latch_data.key_hash(3); + inst_wen <= '1'; + -- Status Info when 7 => - inst_write_data <= std_logic_vector(to_unsigned(1, WORD_WIDTH)); - -- Disposed Generation Count + inst_write_data <= inst_latch_data.status_info; + inst_wen <= '1'; + -- Sample Count when 8 => - inst_write_data <= (others => '0'); - -- No Writers Generation Count + inst_write_data <= std_logic_vector(to_unsigned(1, WORD_WIDTH)); + inst_wen <= '1'; + -- Disposed Generation Count when 9 => - inst_write_data <= (others => '0'); + inst_write_data <= (others => '0'); + inst_wen <= '1'; + -- No Writers Generation Count + when 10 => + inst_write_data <= (others => '0'); + inst_wen <= '1'; if (TIME_BASED_FILTER_QOS /= DURATION_ZERO) then - inst_cnt <= 10; + inst_cnt <= 11; else inst_stage_next <= SET_WRITER_BITMAP; inst_cnt_next <= 0; end if; -- Ignore Deadline 1/2 - when 10 => - if (TIME_BASED_FILTER_QOS /= DURATION_ZERO) then - inst_write_data <= inst_latch_data.deadline(0); - end if; - -- Ignore Deadline 1/2 when 11 => if (TIME_BASED_FILTER_QOS /= DURATION_ZERO) then - inst_write_data <= inst_latch_data.deadline(1); + inst_write_data <= inst_latch_data.deadline(0); + inst_wen <= '1'; + end if; + -- Ignore Deadline 1/2 + when 12 => + if (TIME_BASED_FILTER_QOS /= DURATION_ZERO) then + inst_write_data <= inst_latch_data.deadline(1); + inst_wen <= '1'; - inst_stage_next <= SET_WRITER_BITMAP; - inst_cnt_next <= 0; + inst_stage_next <= SET_WRITER_BITMAP; + inst_cnt_next <= 0; end if; when others => null;