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;
|
||||
key_hash_next <= instance_handle_dds;
|
||||
stage_next <= FIND_NEXT_INSTANCE;
|
||||
cnt_next <= 0;
|
||||
cnt_next <= 0; -- GET FIRST INSTANCE
|
||||
end if;
|
||||
else
|
||||
stage_next <= RETURN_DDS;
|
||||
@ -1204,7 +1204,7 @@ begin
|
||||
cur_sample_next <= oldest_sample;
|
||||
key_hash_next <= instance_handle_dds;
|
||||
stage_next <= FIND_NEXT_INSTANCE;
|
||||
cnt_next <= 0;
|
||||
cnt_next <= 0; -- GET FIRST INSTANCE
|
||||
end if;
|
||||
else
|
||||
stage_next <= RETURN_DDS;
|
||||
@ -3726,7 +3726,7 @@ begin
|
||||
-- NOTE: We selected a compatible instance, but the instance has no compatible samples.
|
||||
-- Find next compatible instance.
|
||||
stage_next <= FIND_NEXT_INSTANCE;
|
||||
cnt_next <= 1;
|
||||
cnt_next <= 1; -- GET NEXT INSTANCE
|
||||
else
|
||||
done_dds <= '1';
|
||||
return_code_dds <= RETCODE_NO_DATA;
|
||||
@ -4308,92 +4308,139 @@ begin
|
||||
-- Wait for Instance Data
|
||||
if (inst_op_done = '1') then
|
||||
case (cnt) is
|
||||
-- GET FIRST INSTANCE
|
||||
when 0 =>
|
||||
-- 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_FIRST_INSTANCE;
|
||||
inst_mem_fields <= IMF_STATUS_FLAG or IMF_KEY_HASH_FLAG;
|
||||
cnt_next <= 2;
|
||||
-- GET NEXT INSTANCE
|
||||
when 1 =>
|
||||
-- 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;
|
||||
cnt_next <= 2;
|
||||
-- EXIT CONDITION
|
||||
when 2 =>
|
||||
assert check_mask(current_imf, IMF_STATUS_FLAG) severity FAILURE;
|
||||
|
||||
-- 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
|
||||
-- No More Instances
|
||||
if (inst_addr_base = INSTANCE_MEMORY_MAX_ADDRESS) then
|
||||
-- DONE
|
||||
done_dds <= '1';
|
||||
return_code_dds <= RETCODE_NO_DATA;
|
||||
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;
|
||||
when others =>
|
||||
null;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user