TIMING CLOSURE: Further Sub-Split FIND_NEXT_INSTANCE in dds_reader
The FIND_NEXT_INSTANCE stage of the dds_reader was doing a 128-bit comparison (Key Hash) in 1 clock cycle. The comparison was split among 4 clock cycles.
This commit is contained in:
parent
4841d0a6bb
commit
965e7fbb4a
@ -1183,7 +1183,7 @@ begin
|
|||||||
cur_sample_next <= oldest_sample;
|
cur_sample_next <= oldest_sample;
|
||||||
key_hash_next <= instance_handle_dds;
|
key_hash_next <= instance_handle_dds;
|
||||||
stage_next <= FIND_NEXT_INSTANCE;
|
stage_next <= FIND_NEXT_INSTANCE;
|
||||||
cnt_next <= 0;
|
cnt_next <= 0; -- GET FIRST INSTANCE
|
||||||
end if;
|
end if;
|
||||||
else
|
else
|
||||||
stage_next <= RETURN_DDS;
|
stage_next <= RETURN_DDS;
|
||||||
@ -1204,7 +1204,7 @@ begin
|
|||||||
cur_sample_next <= oldest_sample;
|
cur_sample_next <= oldest_sample;
|
||||||
key_hash_next <= instance_handle_dds;
|
key_hash_next <= instance_handle_dds;
|
||||||
stage_next <= FIND_NEXT_INSTANCE;
|
stage_next <= FIND_NEXT_INSTANCE;
|
||||||
cnt_next <= 0;
|
cnt_next <= 0; -- GET FIRST INSTANCE
|
||||||
end if;
|
end if;
|
||||||
else
|
else
|
||||||
stage_next <= RETURN_DDS;
|
stage_next <= RETURN_DDS;
|
||||||
@ -3726,7 +3726,7 @@ begin
|
|||||||
-- NOTE: We selected a compatible instance, but the instance has no compatible samples.
|
-- NOTE: We selected a compatible instance, but the instance has no compatible samples.
|
||||||
-- Find next compatible instance.
|
-- Find next compatible instance.
|
||||||
stage_next <= FIND_NEXT_INSTANCE;
|
stage_next <= FIND_NEXT_INSTANCE;
|
||||||
cnt_next <= 1;
|
cnt_next <= 1; -- GET NEXT INSTANCE
|
||||||
else
|
else
|
||||||
done_dds <= '1';
|
done_dds <= '1';
|
||||||
return_code_dds <= RETCODE_NO_DATA;
|
return_code_dds <= RETCODE_NO_DATA;
|
||||||
@ -4308,92 +4308,139 @@ begin
|
|||||||
-- Wait for Instance Data
|
-- Wait for Instance Data
|
||||||
if (inst_op_done = '1') then
|
if (inst_op_done = '1') then
|
||||||
case (cnt) is
|
case (cnt) is
|
||||||
|
-- GET FIRST INSTANCE
|
||||||
when 0 =>
|
when 0 =>
|
||||||
-- NOTE: The Generation Counters are not used directly in this state, but will be needed by the FINALIZE_SAMPLE_INFO state.
|
-- NOTE: The Generation Counters are not used directly in this state, but will be needed by the FINALIZE_SAMPLE_INFO state.
|
||||||
inst_op_start <= '1';
|
inst_op_start <= '1';
|
||||||
inst_opcode <= GET_FIRST_INSTANCE;
|
inst_opcode <= GET_FIRST_INSTANCE;
|
||||||
inst_mem_fields <= IMF_STATUS_FLAG or IMF_KEY_HASH_FLAG;
|
inst_mem_fields <= IMF_STATUS_FLAG or IMF_KEY_HASH_FLAG;
|
||||||
cnt_next <= 2;
|
cnt_next <= 2;
|
||||||
|
-- GET NEXT INSTANCE
|
||||||
when 1 =>
|
when 1 =>
|
||||||
-- NOTE: The Generation Counters are not used directly in this state, but will be needed by the FINALIZE_SAMPLE_INFO state.
|
-- NOTE: The Generation Counters are not used directly in this state, but will be needed by the FINALIZE_SAMPLE_INFO state.
|
||||||
inst_op_start <= '1';
|
inst_op_start <= '1';
|
||||||
inst_opcode <= GET_NEXT_INSTANCE;
|
inst_opcode <= GET_NEXT_INSTANCE;
|
||||||
inst_mem_fields <= IMF_STATUS_FLAG or IMF_KEY_HASH_FLAG;
|
inst_mem_fields <= IMF_STATUS_FLAG or IMF_KEY_HASH_FLAG;
|
||||||
cnt_next <= 2;
|
cnt_next <= 2;
|
||||||
|
-- EXIT CONDITION
|
||||||
when 2 =>
|
when 2 =>
|
||||||
assert check_mask(current_imf, IMF_STATUS_FLAG) severity FAILURE;
|
-- No More Instances
|
||||||
|
if (inst_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then
|
||||||
-- Instance Found
|
|
||||||
if (inst_addr_base /= INSTANCE_MEMORY_MAX_ADDRESS) then
|
|
||||||
-- DEFAULT
|
|
||||||
tmp_bool := TRUE;
|
|
||||||
|
|
||||||
-- Check Instance Handle (Key Hash)
|
|
||||||
-- XXX: Posible Worst Case Path (128-bit Comparison)
|
|
||||||
if (to_unsigned(inst_data.key_hash) <= to_unsigned(key_hash)) then
|
|
||||||
tmp_bool := FALSE;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Check Instance State
|
|
||||||
case (instance_state) is
|
|
||||||
when ALIVE_INSTANCE_STATE =>
|
|
||||||
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '1' or inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
|
|
||||||
tmp_bool := FALSE;
|
|
||||||
end if;
|
|
||||||
when NOT_ALIVE_DISPOSED_INSTANCE_STATE =>
|
|
||||||
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0') then
|
|
||||||
tmp_bool := FALSE;
|
|
||||||
end if;
|
|
||||||
when NOT_ALIVE_NO_WRITERS_INSTANCE_STATE =>
|
|
||||||
if (inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
|
|
||||||
tmp_bool := FALSE;
|
|
||||||
end if;
|
|
||||||
when NOT_ALIVE_INSTANCE_STATE =>
|
|
||||||
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0' and inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
|
|
||||||
tmp_bool := FALSE;
|
|
||||||
end if;
|
|
||||||
when ANY_INSTANCE_STATE =>
|
|
||||||
null;
|
|
||||||
when others =>
|
|
||||||
tmp_bool := FALSE;
|
|
||||||
end case;
|
|
||||||
|
|
||||||
-- Check View State
|
|
||||||
case (view_state) is
|
|
||||||
when NEW_VIEW_STATE =>
|
|
||||||
if (inst_data.status_info(ISI_VIEW_FLAG) = '1') then
|
|
||||||
tmp_bool := FALSE;
|
|
||||||
end if;
|
|
||||||
when NOT_NEW_VIEW_STATE =>
|
|
||||||
if (inst_data.status_info(ISI_VIEW_FLAG) = '0') then
|
|
||||||
tmp_bool := FALSE;
|
|
||||||
end if;
|
|
||||||
when ANY_VIEW_STATE =>
|
|
||||||
null;
|
|
||||||
when others =>
|
|
||||||
tmp_bool := FALSE;
|
|
||||||
end case;
|
|
||||||
|
|
||||||
-- Instance Passes Checks
|
|
||||||
if (tmp_bool) then
|
|
||||||
cur_inst_next <= inst_addr_base;
|
|
||||||
stage_next <= GET_NEXT_SAMPLE;
|
|
||||||
cnt_next <= 0;
|
|
||||||
-- Reset
|
|
||||||
sel_sample_next <= SAMPLE_MEMORY_MAX_ADDRESS;
|
|
||||||
sample_p1_next <= SAMPLE_MEMORY_MAX_ADDRESS;
|
|
||||||
sample_p2_next <= SAMPLE_MEMORY_MAX_ADDRESS;
|
|
||||||
else
|
|
||||||
-- NOTE: The Generation Counters are not used directly in this state, but will be needed by the FINALIZE_SAMPLE_INFO state.
|
|
||||||
inst_op_start <= '1';
|
|
||||||
inst_opcode <= GET_NEXT_INSTANCE;
|
|
||||||
inst_mem_fields <= IMF_STATUS_FLAG or IMF_KEY_HASH_FLAG;
|
|
||||||
end if;
|
|
||||||
else
|
|
||||||
-- DONE
|
-- DONE
|
||||||
done_dds <= '1';
|
done_dds <= '1';
|
||||||
return_code_dds <= RETCODE_NO_DATA;
|
return_code_dds <= RETCODE_NO_DATA;
|
||||||
stage_next <= IDLE;
|
stage_next <= IDLE;
|
||||||
|
else
|
||||||
|
-- Check Instance
|
||||||
|
cnt_next <= cnt + 1;
|
||||||
|
end if;
|
||||||
|
-- KEY HASH 1/4
|
||||||
|
when 3 =>
|
||||||
|
assert (inst_addr_base /= INSTANCE_MEMORY_MAX_ADDRESS) severity FAILURE;
|
||||||
|
assert check_mask(current_imf, IMF_KEY_HASH_FLAG) severity FAILURE;
|
||||||
|
|
||||||
|
if (unsigned(inst_data.key_hash(0)) > unsigned(key_hash(0))) then
|
||||||
|
cnt_next <= 7; -- INSTANCE STATUS CHECK
|
||||||
|
elsif (unsigned(inst_data.key_hash(0)) = unsigned(key_hash(0))) then
|
||||||
|
-- Continue Check
|
||||||
|
cnt_next <= cnt + 1;
|
||||||
|
else -- LESS THAN
|
||||||
|
cnt_next <= 1; -- GET NEXT INSTANCE
|
||||||
|
end if;
|
||||||
|
-- KEY HASH 2/4
|
||||||
|
when 4 =>
|
||||||
|
assert (inst_addr_base /= INSTANCE_MEMORY_MAX_ADDRESS) severity FAILURE;
|
||||||
|
assert check_mask(current_imf, IMF_KEY_HASH_FLAG) severity FAILURE;
|
||||||
|
|
||||||
|
if (unsigned(inst_data.key_hash(1)) > unsigned(key_hash(1))) then
|
||||||
|
cnt_next <= 7; -- INSTANCE STATUS CHECK
|
||||||
|
elsif (unsigned(inst_data.key_hash(1)) = unsigned(key_hash(1))) then
|
||||||
|
-- Continue Check
|
||||||
|
cnt_next <= cnt + 1;
|
||||||
|
else -- LESS THAN
|
||||||
|
cnt_next <= 1; -- GET NEXT INSTANCE
|
||||||
|
end if;
|
||||||
|
-- KEY HASH 3/4
|
||||||
|
when 5 =>
|
||||||
|
assert (inst_addr_base /= INSTANCE_MEMORY_MAX_ADDRESS) severity FAILURE;
|
||||||
|
assert check_mask(current_imf, IMF_KEY_HASH_FLAG) severity FAILURE;
|
||||||
|
|
||||||
|
if (unsigned(inst_data.key_hash(2)) > unsigned(key_hash(2))) then
|
||||||
|
cnt_next <= 7; -- INSTANCE STATUS CHECK
|
||||||
|
elsif (unsigned(inst_data.key_hash(2)) = unsigned(key_hash(2))) then
|
||||||
|
-- Continue Check
|
||||||
|
cnt_next <= cnt + 1;
|
||||||
|
else -- LESS THAN
|
||||||
|
cnt_next <= 1; -- GET NEXT INSTANCE
|
||||||
|
end if;
|
||||||
|
-- KEY HASH 4/4
|
||||||
|
when 6 =>
|
||||||
|
assert check_mask(current_imf, IMF_KEY_HASH_FLAG) severity FAILURE;
|
||||||
|
|
||||||
|
if (unsigned(inst_data.key_hash(3)) > unsigned(key_hash(3))) then
|
||||||
|
cnt_next <= 7; -- INSTANCE STATUS CHECK
|
||||||
|
else -- LESS THAN EQUAL
|
||||||
|
cnt_next <= 1; -- GET NEXT INSTANCE
|
||||||
|
end if;
|
||||||
|
-- INSTANCE STATUS CHECK
|
||||||
|
when 7 =>
|
||||||
|
assert (inst_addr_base /= INSTANCE_MEMORY_MAX_ADDRESS) severity FAILURE;
|
||||||
|
assert check_mask(current_imf, IMF_STATUS_FLAG) severity FAILURE;
|
||||||
|
|
||||||
|
-- DEFAULT
|
||||||
|
tmp_bool := TRUE;
|
||||||
|
|
||||||
|
-- Check Instance State
|
||||||
|
case (instance_state) is
|
||||||
|
when ALIVE_INSTANCE_STATE =>
|
||||||
|
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '1' or inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
|
||||||
|
tmp_bool := FALSE;
|
||||||
|
end if;
|
||||||
|
when NOT_ALIVE_DISPOSED_INSTANCE_STATE =>
|
||||||
|
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0') then
|
||||||
|
tmp_bool := FALSE;
|
||||||
|
end if;
|
||||||
|
when NOT_ALIVE_NO_WRITERS_INSTANCE_STATE =>
|
||||||
|
if (inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
|
||||||
|
tmp_bool := FALSE;
|
||||||
|
end if;
|
||||||
|
when NOT_ALIVE_INSTANCE_STATE =>
|
||||||
|
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0' and inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
|
||||||
|
tmp_bool := FALSE;
|
||||||
|
end if;
|
||||||
|
when ANY_INSTANCE_STATE =>
|
||||||
|
null;
|
||||||
|
when others =>
|
||||||
|
tmp_bool := FALSE;
|
||||||
|
end case;
|
||||||
|
|
||||||
|
-- Check View State
|
||||||
|
case (view_state) is
|
||||||
|
when NEW_VIEW_STATE =>
|
||||||
|
if (inst_data.status_info(ISI_VIEW_FLAG) = '1') then
|
||||||
|
tmp_bool := FALSE;
|
||||||
|
end if;
|
||||||
|
when NOT_NEW_VIEW_STATE =>
|
||||||
|
if (inst_data.status_info(ISI_VIEW_FLAG) = '0') then
|
||||||
|
tmp_bool := FALSE;
|
||||||
|
end if;
|
||||||
|
when ANY_VIEW_STATE =>
|
||||||
|
null;
|
||||||
|
when others =>
|
||||||
|
tmp_bool := FALSE;
|
||||||
|
end case;
|
||||||
|
|
||||||
|
-- Instance Passes Checks
|
||||||
|
if (tmp_bool) then
|
||||||
|
cur_inst_next <= inst_addr_base;
|
||||||
|
stage_next <= GET_NEXT_SAMPLE;
|
||||||
|
cnt_next <= 0;
|
||||||
|
-- Reset
|
||||||
|
sel_sample_next <= SAMPLE_MEMORY_MAX_ADDRESS;
|
||||||
|
sample_p1_next <= SAMPLE_MEMORY_MAX_ADDRESS;
|
||||||
|
sample_p2_next <= SAMPLE_MEMORY_MAX_ADDRESS;
|
||||||
|
else
|
||||||
|
cnt_next <= 1; -- GET NEXT INSTANCE
|
||||||
end if;
|
end if;
|
||||||
when others =>
|
when others =>
|
||||||
null;
|
null;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user