VHDL FSM在相同状态下设置单元输入和使用输出

VHDL FSM在相同状态下设置单元输入和使用输出,vhdl,fsm,Vhdl,Fsm,我正在用vhdl实现一个Mealy类型的FSM。我目前正在使用双进程,尽管我刚刚读到一个进程可能更整洁。考虑一下你的答案的一个参数。< /P> 这个问题的简短版本是:我可以有一个状态,其中另一个组件的输入被改变,然后,在相同的状态下,使用该组件的输出吗?这是安全的还是激烈的竞争,我应该使用组件的输出创建另一个状态 长版本:我有一个内存模块。这是一个fifo内存,激活它的重置信号会将一个名为queue_pointer的变量带到它的第一个元素。写入内存后,指针增加,如果超出范围,指针(然后)重置为第

我正在用vhdl实现一个Mealy类型的FSM。我目前正在使用双进程,尽管我刚刚读到一个进程可能更整洁。考虑一下你的答案的一个参数。< /P> 这个问题的简短版本是:我可以有一个状态,其中另一个组件的输入被改变,然后,在相同的状态下,使用该组件的输出吗?这是安全的还是激烈的竞争,我应该使用组件的输出创建另一个状态

长版本:我有一个内存模块。这是一个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;
当SRAM\u读取=>
阅读确认(其他=>'0');
--功能说明:
--重置将队列指针设置为第一个元素,并将其设置为0
--启用激活后的每个循环,都会从指针位置获取一个基准
--根据write_readNEG写入/读取,指针递增。
--如果操作位于最后一个元素,指针将返回到第一个位置
--“完成”设置为1。当“完成”为1时,将忽略启用。
开始
过程(时钟、复位)
变量done_buf:std_逻辑;
变量队列_指针:自然范围0到大小-1;
开始
如果(重置='1'),则
队列_指针:=0;
完成时间:='0';
elsif(上升沿(clk))然后
如果(done_buf='0'和enable='1'),则
案例写入_readNEG为
当“0”=>
数据输出
fifo_内存(队列_指针)为空;
终例;
如果(队列指针=size-1),则
完成时间:='1';
队列_指针:=0--检查
其他的
队列指针:=队列指针+1;
如果结束;
如果结束--启用x未完成,如果
如果结束--复位/上升沿结束,如果

完成首先,是使用单进程还是双进程类型的FSM符号是首选(或公司编码风格规则)。我发现单进程表示法更容易写/读/管理

只有在下一个上升时钟边缘之后,启用信号才会对内存代码产生影响。因此,与实际内存状态相关的done信号将在更新启用后的一个时钟周期内可用。我猜(希望如此!但在你发布的代码中看不到),你的当前状态
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;