I am studying VHDL and I found one thing particularly difficult to understand, since VHDL is a HDL, in my humble opinion, everything it describe should be able to be converted into a circuit. But how could this happen to variable and process? Is there any circuit that can realize variable and process? Can you give me an example of this? Thanks
Processes containing variables certainly can be converted into circuits.
Here are a couple of simple examples.
Process(clk)
Variable Q : std_logic_vector(7 downto 0);
begin
if rising_edge(clk) then
if En = '0' then
Q := D;
end if;
end if;
Output <= Q;
end process;
In every clock cycle, if the En (Enable) input is low, the input data D is stored in the variable Q; otherwise nothing happens (and the variable keeps its old value). This is a very specific circuit; an 8-bit register with enable; look up the 74LS377 in an old data book to see the same circuit in TTL.
Notice that the clock "if" statement is kept separate from the En statement, and surrounds it. Synthesis tools look for specific patterns that they know how to translate, and this is one of them. If you have any software experience you might be tempted to combine them : if rising_edge(Clk) and En = '0' then ...
- and in simulation you would get exactly the same behaviour.
However some synthesis tools may not recognise this pattern, and may report errors instead of generating hardware. (Synthesis tools are continually improving, so you might be lucky nowadays). The tool's documentation (e.g. Xilinx "synthesis and simulation design guide") ought to describe what is and isn't possible. [edit:] unfortunately it is stuck around 1995 practices and contains some truly horrible examples of VHDL.
Process(clk)
Variable Count : Integer range 0 .. 255 := 0; -- set to 0 when process first starts
begin
if rising_edge(clk) then
Count := Count + 1 mod 256;
end if;
Output := Count;
end process;
Notice that variables, like signals, do not need to be logic types; integers, arrays and records (with some restrictions) are synthesisable; floats usually are not (though this is changing as tools improve). Notice that I limited the range of the integer, to get an 8-bit counter.
With integers, you also need to explicitly specify what happens when they overflow (as I did here) - otherwise you will get errors in simulation. However, specifying the obvious behaviour (as here) should not cost any additional hardware. And using other numeric types like numeric_std.unsigned, the tools are not so fussy.
I have simplified a little; usually there is a Reset clause in a typical process to let you control startup behaviour, but these examples are real and ought to work.