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_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;