我是一名软件工程师(JAVA/C++)而不是电气工程师,所以你可以想象 VHDL 对我来说完全令人困惑,因为我几乎不知道合成器在幕后试图做什么。它告诉我它无法合成我认为非常简单的架构。 (事实上,它正在为我拥有的多个实体执行此操作,因此我怀疑我误解了一些基本概念并在多个地方重复了架构错误。)
为什么这个不合成... (错误 -controller.vhd(63):语句不可合成,因为它不 在 NOT(时钟边沿)条件下保持其值。 VHDL-1242 完成:错误代码 2)
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY controller IS
PORT (
ack: out STD_LOGIC := '0';
data_request: in STD_LOGIC
);
END controller;
ARCHITECTURE logic OF controller IS
BEGIN
PROCESS (data_request)
BEGIN
if (rising_edge(data_request)) then
-- other logic will be added here
ack <= '1';
elsif (falling_edge(data_request)) then
-- other logic will be added here too
ack<='0';
end if;
END PROCESS;
END logic;
(是的,我完全意识到该过程的“逻辑”可以被替换为 ack <= 数据请求;但我的 vhdl 源实际上比这个复杂得多 但我已将其提炼为引发错误的最简单的子集。请不要建议用不同的结构/并发语句替换该进程。)
基本上,当 data_request 线转换为高电平时,ack 输出应该被驱动为高电平;在下降沿,应将其更改为驱动低电平。 (在每种情况下,我也希望更改一大堆其他内容,因此我需要流程而不是并发语句,ack 更改它只是为了向顶级实体发出请求已完成的信号。)
什么是“不保值”?当它说“NOT(clock-edge)”时它在谈论什么“时钟”?
我希望解释如何解决这个问题(不改变结构),并解释我试图要求合成器做什么以及为什么合成器无法实现目标。
最佳答案
问题是你的信号ack
仅在上升沿和下降沿设置。综合将尝试使您的组件在物理约束的现实世界中工作。换句话说,您必须处理没有事件的情况。
在您的情况下,您只需添加 else
您的 if
中的声明,如下所示:
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;
这样您的信号始终会映射到一个值。如果您尝试绘制原理图,您就会明白这一点。您还必须使用 signal
因为你不能到ack <= ack;
当ack
是一个输出。
作为提示,我建议您始终拥有 else
每次执行 if
时的声明阻止,因为在现实世界的电路上,您总是需要默认行为。
关于events - 为什么这个不能合成? (在 NOT(时钟边沿)下不保持其值),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45392405/