I'm a software engineer (JAVA/C++) and not an electrical engineer so you can imagine that VHDL is thoroughly confusing to me because I have little idea what the synthesizer is trying to do behind the scenes. And it's telling me it can't synthesize what I believe to be a very simple architecture. (in fact it's doing it for several entities I have so I suspect I am misunderstanding some fundamental concept and repeating the architectural mistake in multiple places.)
Why does this not synthesize... (ERROR - controller.vhd(63): statement is not synthesizable since it does not hold its value under NOT(clock-edge) condition. VHDL-1242 Done: error code 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;
(Yes, I am fully aware that the "logic" of the process could be replaced by ack <= data_request; but my vhdl source is actually much more complex than this but I have distilled it down to the simplest subset that throws the error. please, don't suggest replacing the process with a different structure/concurrent statement.)
Basically, when the data_request line transitions to high the ack output should be driven high; on the falling edge it should be changed to driven low. (and In each case I want a whole bunch of other stuff to change as well, hence I need the process instead of a concurrent statement, the ack change it just to signal a top-level entity that a request has been completed.)
What is "not holding its value"? What "clock" is it talking about when it says "NOT(clock-edge)"?
I would love an explanation of how to fix this (without changing the structure) and an explanation of what I trying to ask the synthesizer to do and why the synthesizer can't accomplish the goal.
The problem is your signal ack
is set on rising edge and falling edge only. The synthesis will try to make your component working in the real world, with physics constraints. In other word you must manage the case there is no events.
In your case you just have to add a else
statement in your if
, like the following way :
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;
This way your signal is always mapped to a value. If you try to draw the schematics you will get the point. Also you must use a signal
because you can't to the ack <= ack;
when ack
is an output.
As a tip I recommend you to always have an else
statement every time you do a if
block because on a circuit in the real world you always need a default behavior.