【问题标题】:FIFO error: can't find control signal - VHDLFIFO 错误:找不到控制信号 - VHDL
【发布时间】:2015-04-27 13:34:09
【问题描述】:

我找到了一个 VHDL FIFO 代码并尝试修改它以使用两个不同的时钟,一个用于写入,一个用于读取。 我已经尝试了代码并且似乎可以在模拟中工作,但是当我尝试合成它时,我得到了这个错误:

“找不到完整的控制信号”

library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;

entity FIFO is
    Generic (
        constant DATA_WIDTH  : positive := 8;
        constant FIFO_DEPTH : positive := 100
    );
    Port ( 
        WCLOCK      : in  STD_LOGIC;
        RCLOCK      : in  STD_LOGIC;
        WriteEn : in  STD_LOGIC;
        DataIn  : in  STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
        ReadEn  : in  STD_LOGIC;
        DataOut : out STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
        Empty   : out STD_LOGIC;
        Full    : out STD_LOGIC;
        ModuleRESET : in STD_LOGIC
    );
end FIFO;

architecture FIFO_archi of FIFO is
    type FIFO_Memory is array (0 to FIFO_DEPTH - 1) of STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
    signal Memory : FIFO_Memory;
    signal Head : natural range 0 to FIFO_DEPTH - 1;
    signal Tail : natural range 0 to FIFO_DEPTH - 1;


    begin
         -- Memory Pointer Process
        process (WCLOCK, RCLOCK, ModuleRESET)
            variable Looped : boolean;
        begin
            if ModuleRESET = '0' then
                Head <= 0;
                Tail <= 0;
                Looped := false;
                Full  <= '0';
                Empty <= '1';
                DataOut <= (others => '0');
            elsif ReadEn = '1' then
                if rising_edge(RCLOCK) then                    
                    if ((Looped = true) or (Head /= Tail)) then
                        -- Update data output
                        DataOut <= Memory(Tail);

                        -- Update Tail pointer as needed
                        if (Tail = FIFO_DEPTH - 1) then
                            Tail <= 0;
                            Looped := false;
                            else
                                Tail <= Tail + 1;
                            end if;
                        end if;
                    end if;
                -- Update Empty and Full flags
                if (Head = Tail) then
                    if Looped then
                        Full <= '1';
                        else
                            Empty <= '1';
                        end if;
                    else
                        Empty   <= '0';
                        Full    <= '0';
                end if;
            elsif WriteEn = '1' then
                if rising_edge(WCLOCK) then   
                        if ((Looped = false) or (Head /= Tail)) then
                            -- Write Data to Memory
                            Memory(Head) <= DataIn;

                            -- Increment Head pointer as needed
                            if (Head = FIFO_DEPTH - 1) then
                                Head <= 0;
                                Looped := true;
                            else
                                Head <= Head + 1;
                            end if;
                        end if;
                -- Update Empty and Full flags
                if (Head = Tail) then
                    if Looped then
                        Full <= '1';
                        else
                            Empty <= '1';
                        end if;
                    else
                        Empty   <= '0';
                        Full    <= '0';
                end if;
                end if;
            end if;
        end process;

end FIFO_archi;

我该如何解决这个错误?

【问题讨论】:

  • 你不能那样做。具有不同 clk 用于读取和写入的 FIFO 与具有一个时钟的简单 FIFO 非常不同。您必须使用灰色计数器逻辑进行指针重新同步,这可能超出您的舒适区。每个综合工具都有用于双时钟 FIFO 的 IP 核,为什么不使用它呢?
  • 确实如此。您不能只修改单个时钟 FIFO 并期望它成为 CDC FIFO。跨时钟域是一种非常不同的野兽。

标签: vhdl fpga fifo


【解决方案1】:

试图将单个时钟 FIFO 修改为跨时钟域的 FIFO 并非易事。他们是两种截然不同的野兽。

我试图绘制一个可能的最简单的跨时钟域 FIFO 设计的框图。请原谅我徒手绘画技巧的粗鲁。我的例子是一个 16 字节的 FIFO,但它可以扩展到任意深度和宽度,只要深度是 2 的幂。

我使用蓝色标记突出显示必须应用供应商特定属性以防止合成优化的所有信号。

没有捷径。如果您想创建自己的跨时钟域 FIFO,那么此框图代表了您必须做的最低限度的工作。

【讨论】:

    【解决方案2】:

    无论工具集如何,使用单个时钟来推断 FIFO 进行读取和写入通常都很简单。根据您的目标硬件和用于综合 HDL 的工具,推断具有单独时钟用于读取和写入的 FIFO 可能很棘手。

    首先查看您的综合工具的手册/用户指南,以确保它支持使用单独的读/写时钟推断 FIFO。如果是这样,它可能会建议一个受支持的 HDL 行为描述,您应该按照该描述对您的代码进行建模。

    一个问题经常是用两个时钟的单个进程来描述 FIFO。通常这样做会推断出一个对两个时钟敏感的寄存器——硬件不支持,因此会导致错误。如果没有关于工具的更具体信息,更具体的答案将是猜测。

    【讨论】:

    • 我有两个模块,一个写 FIFO,另一个,当 FIFO 满时,开始从 FIFO 读取。所以我有两个不同的时钟,当我写入 FIFO 时,我不会读取数据,而当我读取 FIFO 时,我不会在其上写入数据,因此指针或时钟冲突永远不会发生。另一种解决方案是使用具有两个输入时钟和一个输出时钟的模块。但这会产生与时钟冲突相同的问题吗?
    • @Yaro 当您写入或读取 FIFO 时,与 FIFO 使用的时钟无关。这些时钟真的独立吗?他们需要吗?例如,它们是从完全独立的时钟源生成的,它们没有任何关系(即独立的振荡器)?如果您不需要真正独立的时钟,请使用通用时钟。那将描述一个同步 FIFO 而不是异步 FIFO。同步 FIFO 更容易实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-05
    • 1970-01-01
    • 2014-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多