vhdl で Mealy タイプの FSM を実装しています。私は現在二重プロセスを使用していますが、単一プロセスの方がきれいかもしれないと読んだばかりです。それをあなたの答えのパラメータと考えてください。
質問の短いバージョンは次のとおりです。別のコンポーネントの入力が変更された状態があり、その後、同じ状態で、そのコンポーネントの出力を使用できますか? それは安全でしょうか、それともラット レースでしょうか?コンポーネントの出力を使用して別の状態を作成する必要がありますか?
長いバージョン: 私はメモリ モジュールを持っています。これは fifo メモリであり、そのリセット信号をアクティブにすると、queue_pointer という名前の変数が最初の要素に移動します。メモリへの書き込み後、ポインタは増加し、範囲外になると、最初の要素にリセットされ、出力信号doneがアクティブになります。ちなみに、私はこのコンポーネントを FIMEM と呼んでいます。
私の FSM は最初に FIMEM 全体を書き、それから他の問題に移ります。最後の書き込みは次の状態から行われます。
when SRAM_read =>
READ_ACK <= '1';
FIMEM_enable <= '1';
FIMEM_write_readNEG <= '0';
if(FIMEM_done = '1') then --is that too fast? if so, we're gonna have to add another state
FIMEM_reset <= '1'; --this is even faster, will need check
data_pipe_to_FOMEM := DELAYS_FIMEM_TO_FOMEM;
next_state <= processing_phase1;
else
SRAM_address := SRAM_address + 1;
next_state <= SRAM_wait_read;
end if;
この状態で、イネーブルと書き込みがアクティブになっているということは、データが FIMEM に書き込まれることを意味します。それがメモリ上の最後のデータ空間であった場合、FIMEM_done がアクティブになり、if 内のコードのナイス チャンクが将来の処理を行います。しかし、十分な時間はありますか?そうでない場合、次の状態が SRAM_wait_read に移行し、FIMEM_done がアクティブになると、問題が発生します。FIMEM が完全に同期的であるという事実 (私のコードのこの部分が非同期プロセスにある間) は、さらに混乱を招きますか?
念のため、ここに私のメモリコードがあります:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity memory is
generic (size: positive := 20);
Port ( clk,
reset,
enable,
write_readNEG: in std_logic;
done: out std_logic;
data_in: in STD_LOGIC_VECTOR(7 downto 0);
data_out: out STD_LOGIC_VECTOR(7 downto 0) );
end memory;
architecture Behavioral of memory is
subtype word is STD_LOGIC_VECTOR(7 downto 0);
type fifo_memory_t is array (0 to size-1) of word;
signal fifo_memory : fifo_memory_t :=((others=> (others=>'0')));
--Functionality instructions:
--Resetting sets the queue pointer to the first element, and done to 0
--Each cycle with enable active, a datum from the pointer position is
--written/read according to write_readNEG, and the pointer is incremented.
--If the operation was at the last element, the pointer returns to the first place
--and done is set to 1. When done is 1, enable is ignored.
Begin
process(clk,reset)
variable done_buf : std_logic;
variable queue_pointer: natural range 0 to size-1;
begin
if(reset = '1') then
queue_pointer := 0;
done_buf := '0';
elsif(rising_edge(clk)) then
if(done_buf = '0' and enable = '1') then
case write_readNEG is
when '0' =>
data_out <= fifo_memory(queue_pointer);
when '1' =>
fifo_memory(queue_pointer) <= data_in;
when others => null;
end case;
if(queue_pointer = size-1) then
done_buf := '1';
queue_pointer := 0;--check
else
queue_pointer := queue_pointer + 1;
end if;
end if; --enable x not done if
end if; --reset/rising edge end if
done <= done_buf;
end process;
End Behavioral;
最初のコメントに触発された詳細:
次に示すように、メモリは、イネーブルがアクティブになるのと同じサイクルでデータを読み取ることができ ます。
残念ながら、コードの一部は非同期プロセスにあります! 私は単一プロセスの記述に移行することを非常に強く考えていますが.
これまでに設計したすべての回路とは対照的に、シミュレーションでテストするのは非常に困難です。これは私の大学のプロジェクトで、vhdl プログラムを xilinx spartan 3 FPGA にダウンロードします。今回は、Matlab と FPGA の SRAM の間でデータを転送するユニットが与えられました (その機能はわかりません)。したがって、このユニットを使用して、SRAM とメモリ モジュールの間でデータを転送する必要があります。つまり、シミュレートするには、テストベンチ ファイルで特定のユニットをシミュレートする必要があります。そして、これは難しい..私はそれを試してみなければならないと思う.