VHDL FSM устанавливает ввод единицы измерения и использует вывод в том же состоянии

Я реализую FSM типа Мили в vhdl. В настоящее время я использую двойной процесс, хотя я только что прочитал, что одиночный процесс может быть более аккуратным. Считайте это параметром вашего ответа.

Краткая версия вопроса: могу ли я иметь состояние, внутри которого изменяется ввод другого компонента, а затем, в том же состоянии, использовать вывод указанного компонента? Будет ли это безопасно или это будут крысиные бега, и я должен создать другое состояние, используя вывод компонента?

Длинная версия: у меня есть модуль памяти. Это память 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;

Более подробная информация, вдохновленная первым комментарием:

Память может считывать данные при включенном включении цикла, как показано здесь: Route Simulation"> Обратите внимание на то, как "1", значение, когда включена активация, на самом деле записывается в память.

К сожалению, часть кода находится в асинхронном процессе! Хотя ОЧЕНЬ сильно подумываю перейти на однопроцессное описание.

В отличие от всех схем, которые я разработал до сих пор, мне очень сложно протестировать их с помощью моделирования. Это проект в моем университете, где мы загружаем наши vhdl-программы на xilinx spartan 3 FPGA. На этот раз нам дали модуль, который передает данные между Matlab и SRAM FPGA (функционал которого я понятия не имею). Таким образом, я должен использовать это устройство для передачи данных между SRAM и моим модулем памяти. Это означает, что для симуляции мой тестовый файл должен будет симулировать данную единицу измерения! А это сложно... предположим, я все же должен попробовать...


person user1058795    schedule 27.04.2013    source источник


Ответы (1)


прежде всего, вопрос о предпочтениях (или правилах стиля кодирования компании) использовать один процесс или двойной тип нотации FSM. Я считаю, что нотацию с одним процессом легче писать/читать/управлять.

ваш сигнал enable повлияет на ваш код памяти только после следующего нарастающего фронта тактового сигнала. поэтому сигнал done, относящийся к фактическому состоянию памяти, будет доступен через один такт после включения обновления. Я предполагаю (и надеюсь!, но это не видно в вашем опубликованном коде), ваша часть current_state‹=next_state FSM является синхронной! поэтому ваш конечный автомат будет находиться в состоянии SRAM_wait_read к моменту обновления done!

Кстати: используйте симулятор! это поможет проверить работоспособность!


спасибо за добавление вида симуляции! странно, ваш сигнал done обновляется на отрицательный. край часов... в моей симуляции он обновляется на поз. край; как надо, кстати! введите здесь описание изображения

чтобы прояснить ситуацию, я предлагаю переместить строку done ‹= done_buf; внутрь «rising_edge-if» (это нужно делать в любом случае при использовании синхронных процессов!).

person baldyHDL    schedule 28.04.2013