Signal assignment in/out process

Inside_process : process(clk)
begin
if clk='1' and clk'event then
signal1 <= signalin;
signal2 <= signal1;
end if;
Out_signal <= signal1 and (not signal2);
end process Inside_process;

end rtl;


VS

Outside_process : process(clk)
begin
if clk='1' and clk'event then
signal1 <= signalin;
signal2 <= signal1;
end if;

end process Outside_process;
Out_signal <= signal1 and (not signal2);
end rtl;


I see in some codes signal assignments are made inside processes and sometimes just a bit before end rtl; in this case rtl is architecture. Sometimes many signals are assigned outside process sometimes many. In above example I get no synthesis error and the my circuit works with both versions. So I don't understand what is the difference between them also some signals can't be assigned in the process they have to be outside and they make difference! Why can some be assigned in process why some not? Why sometimes it doesn't make difference? Also how frequently are the signals assigned outside the process, every rising clock edge? Every 5th rising clock edge? How is it decided? What is the use of assigning a signal outside the processes? If I'm going to assign a signal outside a process I usually do it before end rtl; (the last line). I noticed it doesn't hurt doing this between 2 processes as well, so doesn't have to be just before the last line, can be in the middle as well.

If I should give an example signal assignment in process which gives an error :

d3 <= r4  when (sn(3)='1') else d2;


Full code of error line

Error msg: parse error, unexpected WHEN, expecting SEMICOLON.

There is a semicolon actually. But when this line is taken out of the process, it works. I don't understand how, if someone can enlighten me I would be glad.

Also in VHDL shall I declare processes uppercase letters, signals lowercase letters, or everything uppercase? Is there a common usage and discipline? For example it isn't encouraged in Java for variables to start with uppercase? If there is a common usage like this for VHDL, can I get a link for that?

• The process is called when there is a change in clk signal so the output will only be updated at one of those intervals if written from within the process. If you update the output outside a process, asynchronously, the update will take place as soon as (+tpd) at least one of the signals on the right hand of the assignment was changed. – user34920 Jun 14 '14 at 20:03
• What is the difference? The sensitivity list. – Brian Drummond Jun 14 '14 at 21:51
• @user34920 tpd: time propagation delay? So if one of the signals in outside assignment line get updated every clock cycle this means, the assigned signal on the left will also be updated every clock cycle? Is this going to be asynchronous? It seems to me that can be synchronous if the signals are being updated according to some specific conditions. – Anarkie Jun 15 '14 at 11:56
• @Anarkie tpd = yes, however for simulation purpose you can say that the outputs of the process are being updated together after all the internal part was evaluated in 0 time. In your example it seems like signal1 and signal2 are being updated only inside the process, so when the process updates them so does the async assignment is performed as the said signals are on it's right hand side. If you have some other place that changes signal1 or signal2 then Out_signal might be updated regardless of the clk signal's rising edge as dictated by the process. – user34920 Jun 15 '14 at 12:01
• clocked processes infer flip flops. See here electronics.stackexchange.com/a/114786/16047 – stanri Jun 15 '14 at 19:34

Only sequential statements are allowed inside a process statement. An architecture statement part is comprised of zero or more concurrent statements. rtl appears to be the name of architecture and a process statement is a concurrent statement.

Notice from your referenced code you are having problems with:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity circularshift is  port (
sn     : in  std_logic_vector(5 downto 1);  -- number of rotate steps
di     : in  std_logic_vector(32 downto 1);  -- data in
encdec : in std_logic ;                  -- enc or dec
do     : out std_logic_vector(32 downto 1)   -- data out
);
end circularshift;

architecture Behavioral of circularshift is
signal d0 : std_logic_vector(32 downto 1);
signal d1 : std_logic_vector(32 downto 1);
signal d2 : std_logic_vector(32 downto 1);
signal d3 : std_logic_vector(32 downto 1);
signal d4 : std_logic_vector(32 downto 1);
signal r1 : std_logic_vector(32 downto 1);
signal r2 : std_logic_vector(32 downto 1);
signal r4 : std_logic_vector(32 downto 1);
signal r8 : std_logic_vector(32 downto 1);
signal d5  : std_logic_vector(32 downto 1);
signal r16 : std_logic_vector(32 downto 1);
begin
p1 : process (encdec)
begin

if  encdec <= '1' then

r1  <= d0(32-1  downto 1) & d0(32);
r2  <= d1(32-2  downto 1) & d1(32 downto 32-1);
r4  <= d2(32-4  downto 1) & d2(32 downto 32-3);
r8  <= d3(32-8  downto 1) & d3(32 downto 32-7);
r16 <= d4(32-16 downto 1) & d4(32 downto 32-15);
d0 <= di;
d1 <= r1  when (sn(1)='1') else d0;
d2 <= r2  when (sn(2)='1') else d1;
d3 <= r4  when (sn(3)='1') else d2;
d4 <= r8  when (sn(4)='1') else d3;
d5 <= r16 when (sn(5)='1') else d4;
do <= d5;
else
r1  <= d0(1) & d0(32 downto 2 );
r2  <= d1(2  downto 1) & d1(32 downto 3);
r4  <= d2(4  downto 1) & d2(32 downto 5);
r8  <= d3(8  downto 1) & d3(32 downto 9);
r16 <= d4(16 downto 1) & d4(32 downto 17);
d0 <= di;
d1 <= r1  when (sn(1)='1') else d0;
d2 <= r2  when (sn(2)='1') else d1;
d3 <= r4  when (sn(3)='1') else d2;
d4 <= r8  when (sn(4)='1') else d3;
d5 <= r16 when (sn(5)='1') else d4;
do <= d5;

end if;

end process;
end Behavioral;

-- I'm getting the following Error messages for my code posted below. (I'm using the xilinx 8.1.03i and modelsim )
-- When I run check syntax, the following is displayed:
-- Compiling vhdl file "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" in Library work.
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 38. parse error, unexpected WHEN, expecting SEMICOLON
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 39. parse error, unexpected WHEN, expecting SEMICOLON
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 40. parse error, unexpected WHEN, expecting SEMICOLON
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 41. parse error, unexpected WHEN, expecting SEMICOLON
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 42. parse error, unexpected WHEN, expecting SEMICOLON
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 49. parse error, unexpected WHEN, expecting SEMICOLON
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 50. parse error, unexpected WHEN, expecting SEMICOLON
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 51. parse error, unexpected WHEN, expecting SEMICOLON
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 52. parse error, unexpected WHEN, expecting SEMICOLON
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 53. parse error, unexpected WHEN, expecting SEMICOLON


        d3 <= r4  when (sn(3)='1') else d2;


And that this a concurrent signal assignment and yet it is showing up in a process statement (the domain of sequential statements).

The form of this is a 'conditional signal assignment', which happens to have been added to sequential signal assignments by IEEE Std 1076-2008 (10.5.3 Conditional signal assignments, § 10 is entitled Sequential statements).

And from this we can infer that while Modelsim supports the 2008 VHDL standard, your XST doesn't (error messages of the form 'ERROR:HDLParsers:' are XST messages).

If and when Xilinx would support synthesis of conditional signal assignment statements within a process (as sequential signal assignment) is a matter of versions and/or policy. There's no particular difference in difficulty of synthesis to support it, while representing significant change in the parser.

VHDL is case insensitive except in extended identifiers and character literals.

From IEEE Std 1076-2008 15.2 Character set:

The only characters allowed in the text of a VHDL description (except within comments—see 15.9, and within text treated specially due to the effect of tool directives—see 15.11) are the graphic characters and format effectors. Each graphic character corresponds to a unique code of the ISO eight-bit coded character set (ISO/IEC 8859-1:1998) and is represented (visually) by a graphical symbol.

basic_graphic_character ::=
upper_case_letter | digit | special_character | space_character

graphic_character ::=
basic_graphic_character | lower_case_letter | other_special_character

basic_character ::=
basic_graphic_character | format_effector

The basic character set is sufficient for writing any description, other than a PSL declaration, a PSL directive, or a PSL verification unit.

And 15.4 Identifiers:

All characters of a basic identifier are significant, including any underline character inserted between a letter or digit and an adjacent letter or digit. Basic identifiers differing only in the use of corresponding uppercase and lowercase letters are considered the same.

Thanks a lot for the answer, how about the Inside_process vs Outside_process ? Out_signal <= signal1 and (not signal2); Out_signal is being assigned once inside and once outside, but the result doesn't change, circuit still works, no warnings? So is this a sequential assignment or concurrent? If concurrent, how can it be inside the process, if sequential, how can it be outside the process? – Anarkie 6 hours ago

There's an obvious difference between the two processes. The one with the concurrent signal assignment(Outside_process) will have Out_signal show change immediately upon change update for signals signal1 and signal2 because the concurrent signal assignment will have an equivalent process containing a sequential signal assignment statement and a sensitivity list equivalent containing signal1 and signal2. (Every signal appearing on the right hand side of a signal assignment statement).

The process Inside_process only has clk in the sensitivity list, meaning in simulation Out_signal will be assigned at the next clk'EVENT, an apparent half clock delay because the assignments to your two shift register signals are visible in the next delta cycle.

See this stackoverflow answer The VHDL Simulation Cycle as well as this one - Unexpected delays with register VHDL.

Interestingly enough both will probably synthesize identically because the sensitivity list will either be disregarded or updated (assumed to include signal1 and signal2 in Inside_process). Any assumptions should likely show up in warnings.

Elaboration devolves a design description into block statements (maintaining hierarchy), process statements and function calls. All concurrent statements have a process statement equivalent, potentially within block statements (or nested block statements). In the case of simple signal assignment statements there is little observable difference between signal assignment inside or outside a process (except the sensitivity list which in this case is incomplete for Inside_process).

A design specification will be elaborated before simulation and as a predicate for synthesis as well.

• BTW easy to fix... if you still want everything inside a process you can use 'case' – user34920 Jun 14 '14 at 20:07
• @user34920 Actually the LRM tells us the equivalent process for a concurrent conditional signal assignment is comprised of an if statement structure. The equivalent process for a concurrent selected signal assignment statement is comprised of a case statement. Yes, it's quibbling case statements can also be expressed in if statement structures (with a guaranteed following else), but all models are devolved into processes, function calls and block statements (implying structure/locality) canonically for simulation. – user8352 Jun 14 '14 at 21:13
• @DavidKoontz Thanks a lot for the answer, how about the Inside_process vs Outside_process ? Out_signal <= signal1 and (not signal2); Out_signal is being assigned once inside and once outside, but the result doesn't change, circuit still works, no warnings? So is this a sequential assignment or concurrent? If concurrent, how can it be inside the process, if sequential, how can it be outside the process? – Anarkie Jun 15 '14 at 11:59

The Inside_process and Outside_process versions behave differently. If both designs work, it is mostly out of luck, because in this case Out_signal simply lags half a clock cycle when declared inside the process.

Inside_process

Out_signal is assigned when the process triggers, which in this case occurs on rising and falling edges of clk. At the rising edge, it will grab the previous values of signal1/signal2, but at the falling edge it will catch up. So it is behaving like a dual edge flip flop.

Outside_process

Out_signal is assigned continuously, so as soon as signal1/signal2 are updated in the clocked process, Out_signal will update.

Overall behavior

If the rest of the circuit is fully synchronous to the rising edge of clk, then the overall behavior might 'look' the same, but be aware that they won't produce the same physical implementation, and the Inside_process version will be slower (because it only has half a clock cycle to update Out_signal) and use more/different resources (because of how the dual edge flip flop functionality ends up being implemented).

Simulation

A simple simulation illustrates the 'half clock cycle' delay: