0

我正在 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 和我的内存模块之间传输数据。这意味着,为了模拟,我的测试台文件必须模拟给定的单元!这很难……假设我必须尝试一下……

4

1 回答 1

2

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

只有在下一个时钟上升沿之后,您的启用信号才会对您的内存代码产生影响。因此,与实际内存状态相关的完成信号将在更新使能后一个时钟周期可用。我猜(希望!但它在您发布的代码中不可见),您的 FSM 的current_state<=next_state部分是同步的!因此,当完成更新时,您的状态机将处于 SRAM_wait_read 状态!

顺便说一句:使用模拟器!这将有助于检查功能!


感谢您添加模拟视图!奇怪的是,您在 neg 上完成了信号更新。时钟边缘......在我的模拟中,它在 pos 上更新。边缘; 顺便说一句,应该如此! 在此处输入图像描述

为了使情况更清楚,我建议您移动done <= done_buf; “rising_edge-if”内的行(在使用同步进程时无论如何都应该这样做!)。

于 2013-04-28T05:59:47.530 回答