我正在 vhdl 中实现 Mealy 型 FSM。我目前正在使用双进程,虽然我刚刚读过单进程可能会更整洁。考虑一下你的答案的一个参数。
问题的简短版本是:我可以有一个状态,其中另一个组件的输入被更改,然后,在相同的状态下,使用该组件的输出?这会是安全的还是会是一场激烈的竞赛,我应该使用组件的输出来创建另一个状态?
长版:我有一个内存模块。这是一个先进先出存储器,激活它的复位信号需要一个名为 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;
受第一条评论启发的更多细节:
内存可以在启用启用的同一周期读取数据,如下所示:
注意“1”,启用启用时的值,实际上是如何写入内存的。
不幸的是,这段代码处于异步过程中!尽管我非常强烈地考虑转向单一进程描述。
与我迄今为止设计的所有电路相比,我很难通过仿真对其进行测试。这是我大学的一个项目,我们将 vhdl 程序下载到 xilinx spartan 3 FPGA。这一次,我们得到了一个在 Matlab 和 FPGA 的 SRAM 之间传输数据的单元(我不知道它的功能)。因此,我必须使用这个单元在 SRAM 和我的内存模块之间传输数据。这意味着,为了模拟,我的测试台文件必须模拟给定的单元!这很难……假设我必须尝试一下……