エンティティ キャッシュから他のエンティティ メモリにデータ ブロック (16 バイト、4 ワード) を書き込もうとしています。
メモリはバイト アドレス指定可能であるため、一度に 1 バイトしか書き込むことができません。バイトが書き込まれると、メモリはmem_doneを 1 に更新します。
ブロックを作成するには、次のことを行う必要があります。
1バイト書き込み、
mem_doneが設定されるのを待ちます (メモリ エンティティによって)。
mem_address (メモリに与える次のアドレス) とbyte_countをインクリメントし、4 バイトごとにword_offset (キャッシュ内のワードのオフセット) をインクリメントします。
すべての単語が書き込まれるまでループします ( word_offset = words_per_block-1 )。
ザイリンクスでの合成で、wait_loop に対して「Non-static loop limit exceeded」というエラー メッセージが表示されます。
ループ内でwait untilステートメントを使用できません(エラー: 複数の wait ステートメントは使用できません)。
状態の遷移によって 1 クロック サイクルが無駄になるため、FSM を使用できません (また、タイミングの制約もあります)。
ループ制限を破ることなく、どうすればそれを行うことができますか?
-- block dirty in memory, write cache block back to memory
mem_enable <= '1'; -- out to memory, enable memory transfer
mem_rw <= '1'; -- out to memory. read/write bit
mem_addr_tmp <= cpu_addr; -- internal, address to write to
word_offset <= 0; -- internal, offset in cache
byte_count <= 31;
burst_loop: loop
-- Transfer 1 byte of data
mem_data <= CACHE(index).data(word_offset)(byte_count downto byte_count-7);
mem_addr <= mem_addr_tmp;
wait_loop: loop
if mem_done = '1' then -- mem_done comes from memory entity
exit wait_loop;
end if;
end loop wait_loop;
-- Update address, word offset, byte count
mem_addr_tmp <= std_logic_vector(to_unsigned(to_integer(unsigned(mem_addr_tmp)) + 1, mem_addr_tmp'length));
if (byte_count mod 4 = 0) then -- a word has been transfered, increment word_offset
word_offset <= word_offset + 1;
byte_count <= 31;
else -- a byte of a word has been transfered
byte_count <= byte_count - 7;
end if;
exit burst_loop when (mem_done = '1' and word_offset = words_per_block-1);
end loop burst_loop;
mem_enable <= '0';