Events 为什么这不能合成?(不在not(时钟边缘)下保持其值)

Events 为什么这不能合成?(不在not(时钟边缘)下保持其值),events,process,vhdl,clock,synthesis,Events,Process,Vhdl,Clock,Synthesis,我是一名软件工程师(JAVA/C++),而不是电气工程师,所以你可以想象VHDL让我完全困惑,因为我不知道合成器在幕后要做什么。它告诉我它不能综合我认为是非常简单的架构。(事实上,它是为我拥有的几个实体做的,所以我怀疑我误解了一些基本概念,并在多个地方重复了架构错误。) 为什么这不能合成。。。 (错误-controller.vhd(63):语句不可合成,因为它不可合成 在非(时钟边缘)条件下保持其值。VHDL-1242 完成:错误代码2) ieee库; 使用ieee.std_logic_1164

我是一名软件工程师(JAVA/C++),而不是电气工程师,所以你可以想象VHDL让我完全困惑,因为我不知道合成器在幕后要做什么。它告诉我它不能综合我认为是非常简单的架构。(事实上,它是为我拥有的几个实体做的,所以我怀疑我误解了一些基本概念,并在多个地方重复了架构错误。)

为什么这不能合成。。。 (错误-controller.vhd(63):语句不可合成,因为它不可合成 在非(时钟边缘)条件下保持其值。VHDL-1242 完成:错误代码2)

ieee库;
使用ieee.std_logic_1164.all;
实体控制器是
港口(
确认:输出标准逻辑:='0';
数据请求:在标准逻辑中
);
终端控制器;
控制器的结构逻辑是
开始
过程(数据请求)
开始
如果(上升沿(数据请求)),则
--这里将添加其他逻辑

ack与软件编译器相反,硬件合成通常不是逐字进行的。相反,对整个代码块进行分析,以找到诸如有限状态机之类的通用结构。在您的情况下,大多数合成工具将识别一个过程,例如

process (...)
begin
    if rising_edge(clk) then
        -- code here
    end if;
end process;
也就是说,只要一张支票就可以看到上升沿。您的代码可能会出现问题,因为您使用相同的if语句检查上升沿和下降沿

要使代码正常工作,只需使用两条if语句即可。然而,正如所指出的,在两个边缘触发可能不会对所有目标(FPGA)起作用。模拟没有这个限制

您还可以尝试添加一个单独的时钟信号,该信号将在上升沿上触发某段代码。该代码随后检查
数据请求
信号

或者(但这取决于您拥有的其他代码),您可以检查
数据请求的级别,而不是边缘,例如

if data_request = '1' then
    -- rising edge code
else
    -- falling edge code
end if;

VHDL只是一种编程语言,许多结构实际上都是可能的。但是,您希望为设备(FPGA?)编程VHDL。这意味着您必须根据特定规则对其进行编程

为了能够检测边缘,您必须在两个时间点观察一个值:一个在前一个在后。因此,您必须在代码中引入时间的概念。“信号x在t-1处为“0”,在t处为“1”。”

在大多数可编程设备中,时钟时间的概念是未知的。作为程序员,你必须介绍它。在大多数数字电路中,你会使用一个特定频率的振荡器来实现这一点,通常被称为“时钟”

数字逻辑还有一个问题,那就是延迟。通过逻辑,电不会以无限的速度传播。因此,您必须考虑通过不同旅行路径的延迟。这使得设计异步逻辑非常困难。或者,您可以将值存储在特定位置的内存元素中,以解决称为同步逻辑的计时问题。这些元素通常是寄存器

我之所以解释这一点,是为了激发在设计中引入时钟的理由,以满足您的特定需求。您需要记住以前的
数据请求状态
,以便观察更改

    signal data_request_old : std_logic;
begin
    data_request_old <= data_request when rising_edge(clk);
    if data_request = '1' and data_request_old = '0' then
        -- rising edge
    end if;
    if data_request = '0' and data_request_old = '1' then
        -- falling edge
    end if;
信号数据请求旧:标准逻辑;
开始

数据请求旧问题在于您的信号
ack
仅设置在上升沿和下降沿。合成将尝试使您的组件在物理约束下在真实世界中工作。换句话说,您必须管理没有事件的情况。 在本例中,您只需在
if
中添加
else
语句,如下所示:

architecture logic of controller is

signal ack_s : std_logic := '0';

begin
    process(data_request)
    begin
        if (rising_edge(data_request)) then
            -- other logic will be added here
            ack_s <= '1';
        elsif (falling_edge(data_request)) then
            -- other logic will be added here too
            ack_s <= '0';
        else then
            ack_s <= ack_s;
        end if;
    end process;

    ack <= ack_s;    -- You map the output on the internal signal

end architecture logic;
控制器的架构逻辑为
信号确认:标准逻辑:='0';
开始
过程(数据请求)
开始
如果(上升沿(数据请求)),则
--这里将添加其他逻辑

确认我可能已经找到了一些原因。。。阅读后,我认为“X”中的X输出将包含顺序逻辑的HDL指南,显示从IEEE Std 1076.6-2004(撤销)衍生的可接受形式。这里的问题是,您试图将data_请求的两个边缘都用作双数据速率时钟,而DDR如果受支持,则仅适用于iO单元,并且需要特殊调用(并且使用两个触发器)。通常每个进程只支持一个时钟边缘。请考虑硬件描述语言。此修复是否会导致问题?”上升沿码“这就像A=A+1,增量将失去控制?如果您确实有这样的语句,则级别触发代码不适合您。尝试其他两个仍处于边缘触发状态的建议。何时更新数据?你在一个异步系统上。@kingsjester我不明白你的问题。请你重新措辞好吗?我不在任何系统上。组件是异步的,所以何时更新
数据\u请求\u旧的
?我假设它是
数据\u request
的先前值,但在异步系统中,不能在时钟边缘更新它。因此,我假设您在
数据请求
值更改时更新它,这意味着在
数据请求
的下降沿或上升沿上,这正是您试图实现的…@King'sjester首先:我没有尝试实现任何东西。我只是在帮助提出问题的人。其次,不确定询问者想要实现什么:同步还是异步。然后在内容上:询问者报告来自Xilinx合成工具的错误。因此,他正在为FPGA进行合成。FPGA逻辑构建块由查找表(LUT)-寄存器对组成,旨在实现同步设计。在FPGA中设计异步通信非常困难,因为您必须手动设置所有timi
architecture logic of controller is

signal ack_s : std_logic := '0';

begin
    process(data_request)
    begin
        if (rising_edge(data_request)) then
            -- other logic will be added here
            ack_s <= '1';
        elsif (falling_edge(data_request)) then
            -- other logic will be added here too
            ack_s <= '0';
        else then
            ack_s <= ack_s;
        end if;
    end process;

    ack <= ack_s;    -- You map the output on the internal signal

end architecture logic;