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:
Greek 2021-12-08 20:58:33 +01:00 committed by Greek64
parent 4841d0a6bb
commit 965e7fbb4a

View File

@ -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,32 +4308,88 @@ 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 =>
-- 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;
-- 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 =>
@ -4384,16 +4440,7 @@ begin
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_dds <= '1';
return_code_dds <= RETCODE_NO_DATA;
stage_next <= IDLE;
cnt_next <= 1; -- GET NEXT INSTANCE
end if;
when others =>
null;