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.
This commit is contained in:
Greek 2021-01-22 13:24:37 +01:00
parent f152abc373
commit c3b656c654

View File

@ -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_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_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_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 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 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; 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) -- 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; assert (inst_empty_head /= INSTANCE_MEMORY_MAX_ADDRESS) report "Instance Insertion while memory Full" severity FAILURE;
inst_addr_next <= inst_empty_head; inst_addr_next <= inst_occupied_head;
inst_addr_base_next <= inst_empty_head; inst_addr_base_next <= inst_occupied_head;
inst_stage_next <= INSERT_INSTANCE; inst_stage_next <= FIND_POS;
inst_cnt_next <= 0; inst_cnt_next <= 0;
when UPDATE_INSTANCE => when UPDATE_INSTANCE =>
inst_addr_base_next <= inst_addr_update; inst_addr_base_next <= inst_addr_update;
@ -1578,62 +1578,209 @@ begin
-- DONE -- DONE
inst_stage_next <= IDLE; inst_stage_next <= IDLE;
end if; 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_addr_next <= inst_addr + 1;
inst_cnt_next <= inst_cnt + 1; inst_cnt_next <= inst_cnt + 1;
case (inst_cnt) is case (inst_cnt) is
-- Preload -- Next Pointer (Previous Instance)
when 0 => when 0 =>
inst_ren <= '1'; inst_write_data <= inst_empty_head;
-- Next Instance Address inst_wen <= '1';
inst_addr_next <= inst_empty_head;
inst_addr_base_next <= inst_empty_head;
-- Preload
when 1 => when 1 =>
inst_empty_head_next <= inst_read_data; inst_ren <= '1';
-- Make New Occupied Head inst_addr_next <= inst_addr; -- Keep Addr
inst_write_data <= inst_occupied_head; -- Next Pointer (New Instance)
inst_occupied_head_next <= inst_empty_head;
-- Key Hash 1/4
when 2 => when 2 =>
inst_write_data <= inst_latch_data.key_hash(0); -- Fix Empty List Head
-- Key Hash 2/4 inst_empty_head_next <= inst_read_data;
inst_write_data <= inst_next_addr_base;
inst_wen <= '1';
-- Key Hash 1/4
when 3 => when 3 =>
inst_write_data <= inst_latch_data.key_hash(1); inst_write_data <= inst_latch_data.key_hash(0);
-- Key Hash 3/4 inst_wen <= '1';
-- Key Hash 2/4
when 4 => when 4 =>
inst_write_data <= inst_latch_data.key_hash(2); inst_write_data <= inst_latch_data.key_hash(1);
-- Key Hash 4/4 inst_wen <= '1';
-- Key Hash 3/4
when 5 => when 5 =>
inst_write_data <= inst_latch_data.key_hash(3); inst_write_data <= inst_latch_data.key_hash(2);
-- Status Info inst_wen <= '1';
-- Key Hash 4/4
when 6 => when 6 =>
inst_write_data <= inst_latch_data.status_info; inst_write_data <= inst_latch_data.key_hash(3);
-- Sample Count inst_wen <= '1';
-- Status Info
when 7 => when 7 =>
inst_write_data <= std_logic_vector(to_unsigned(1, WORD_WIDTH)); inst_write_data <= inst_latch_data.status_info;
-- Disposed Generation Count inst_wen <= '1';
-- Sample Count
when 8 => when 8 =>
inst_write_data <= (others => '0'); inst_write_data <= std_logic_vector(to_unsigned(1, WORD_WIDTH));
-- No Writers Generation Count inst_wen <= '1';
-- Disposed Generation Count
when 9 => 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 if (TIME_BASED_FILTER_QOS /= DURATION_ZERO) then
inst_cnt <= 10; inst_cnt <= 11;
else else
inst_stage_next <= SET_WRITER_BITMAP; inst_stage_next <= SET_WRITER_BITMAP;
inst_cnt_next <= 0; inst_cnt_next <= 0;
end if; end if;
-- Ignore Deadline 1/2 -- 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 => when 11 =>
if (TIME_BASED_FILTER_QOS /= DURATION_ZERO) then
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 if (TIME_BASED_FILTER_QOS /= DURATION_ZERO) then
inst_write_data <= inst_latch_data.deadline(1); inst_write_data <= inst_latch_data.deadline(1);
inst_wen <= '1';
inst_stage_next <= SET_WRITER_BITMAP; inst_stage_next <= SET_WRITER_BITMAP;
inst_cnt_next <= 0; inst_cnt_next <= 0;