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