16-03-2017, 09:18 AM
I'll tackle conditional statements today. In my own work I use IF all the time, CASE when it's appropraite, WHEN from time to time and WITH almost never.
IF looks pretty obvious. Here's a simple example of a counter which would be in a clocked process:
if COUNT = 14 then COUNT <= 0;
elsif RESET then COUNT <= 0;
else COUNT <= COUNT + 1;
end if;
A couple of wrinkles. The conditions are evaluated in order. Much of the time this doesn't matter but sometimes you can simplify or get caught out. The other is that if there's no ELSE clause and the other conditions aren't met there's an implied hold. For example:
if J = '1' then Q <= '1';
elseif K = "1" then Q <= '0';
end if
This is a JK flipflop. Since there is no ELSE, if both J and K are zero, Q holds its previous state. J also takes precedence because it's first int he list. So if both J and K are 1 then Q will be set to 1. I sometimes write "else Q <= Q;" explicitly to show the hold but it's not needed.
We've already seen the use of IF to do clocking and clock enable. For clock enable the implicit hold is the important bit. If the flipflop doesn't have a physical CE input it will synthesise logic to do the hold.
If you you use IF outside a process the tools will complain though they will usually give the right answer. If you want to use IF to make purely combinatorial logic (as against clocked) then you should put it in a process with a sensitivity list. If you omit the ELSE clause you will generate a transparent latch, soemthing you may not have intended.
So outside a process you can use WHEN.
X <= A when TEST = '1' else B;
No process needed. It's ugly but it works. You must have an ELSE.
CASE, like iF, normally lives in a clocked process. Same rules as IF when you use it elsewere. My example is from an actual design and shows a CASE within an IF. This is allowed but don't take it too far. It's hard to read and can synthesise badly.
The OTHERS clause is essential. If the condition signal is an integer (XSTD is here) you can put multiple values on one line.
when S1080_50i | S1080_25p | S1080_50p => HREF_PAT <= 2640 - 1920 - HREF_PATFIX;
There is no precedence due to order of statements. All possible values of the condition signal must be evaluated. If not in the individual lines, then by the catch-all ELSE.
As with IF, there's a similar construct for use outside a process. Again it's ugly. It's called WITH and I've only rarely used it. Here's a very truncated example from a real design. It mutliplexes all the various signals that can be read back by a microprocessor. The full version has over 100 inputs and must use rather a lot of logic. Note that I've expressed the readback addresses in hex. That 16#hhh# is how you express hex integers in VHDL. As against using hex to express a std_logic_vector X"hhh". Yuk.
IF looks pretty obvious. Here's a simple example of a counter which would be in a clocked process:
if COUNT = 14 then COUNT <= 0;
elsif RESET then COUNT <= 0;
else COUNT <= COUNT + 1;
end if;
A couple of wrinkles. The conditions are evaluated in order. Much of the time this doesn't matter but sometimes you can simplify or get caught out. The other is that if there's no ELSE clause and the other conditions aren't met there's an implied hold. For example:
if J = '1' then Q <= '1';
elseif K = "1" then Q <= '0';
end if
This is a JK flipflop. Since there is no ELSE, if both J and K are zero, Q holds its previous state. J also takes precedence because it's first int he list. So if both J and K are 1 then Q will be set to 1. I sometimes write "else Q <= Q;" explicitly to show the hold but it's not needed.
We've already seen the use of IF to do clocking and clock enable. For clock enable the implicit hold is the important bit. If the flipflop doesn't have a physical CE input it will synthesise logic to do the hold.
If you you use IF outside a process the tools will complain though they will usually give the right answer. If you want to use IF to make purely combinatorial logic (as against clocked) then you should put it in a process with a sensitivity list. If you omit the ELSE clause you will generate a transparent latch, soemthing you may not have intended.
So outside a process you can use WHEN.
X <= A when TEST = '1' else B;
No process needed. It's ugly but it works. You must have an ELSE.
CASE, like iF, normally lives in a clocked process. Same rules as IF when you use it elsewere. My example is from an actual design and shows a CASE within an IF. This is allowed but don't take it too far. It's hard to read and can synthesise badly.
Code:
if H_LOCK_RATE_IS_MANUAL then H_LOCK_RATE <= H_LOCK_RATE_MANUAL;
else
case XSTD is
when S1080_60i => H_LOCK_RATE <= 4;
when S1080_50i => H_LOCK_RATE <= 6;
when S1035_60i => H_LOCK_RATE <= 4;
when S1080_24sF => H_LOCK_RATE <= 6;
when S1080_30p => H_LOCK_RATE <= 4;
when S1080_25p => H_LOCK_RATE <= 6;
when S1080_24p => H_LOCK_RATE <= 8;
when S720_60p => H_LOCK_RATE <= 2;
when S720_50p => H_LOCK_RATE <= 2;
when S1080_60p => H_LOCK_RATE <= 2;
when S1080_50p => H_LOCK_RATE <= 4;
when S720_30p => H_LOCK_RATE <= 8;
when S720_25p => H_LOCK_RATE <= 10;
when S720_24p => H_LOCK_RATE <= 12;
when S525_60i => H_LOCK_RATE <= 2;
when S625_50i => H_LOCK_RATE <= 2;
when others => H_LOCK_RATE <= 2; -- Catch all other cases
end case;
end if;The OTHERS clause is essential. If the condition signal is an integer (XSTD is here) you can put multiple values on one line.
when S1080_50i | S1080_25p | S1080_50p => HREF_PAT <= 2640 - 1920 - HREF_PATFIX;
There is no precedence due to order of statements. All possible values of the condition signal must be evaluated. If not in the individual lines, then by the catch-all ELSE.
As with IF, there's a similar construct for use outside a process. Again it's ugly. It's called WITH and I've only rarely used it. Here's a very truncated example from a real design. It mutliplexes all the various signals that can be read back by a microprocessor. The full version has over 100 inputs and must use rather a lot of logic. Note that I've expressed the readback addresses in hex. That 16#hhh# is how you express hex integers in VHDL. As against using hex to express a std_logic_vector X"hhh". Yuk.
Code:
with conv_integer(READBACK_ADDRESS) select READBACK_DATA <=
"000000000" & SDI_INPUT_STANDARD1 when 16#3FC#,
"000000000" & SDI_INPUT_STANDARD2 when 16#3FD#,
DE_EMBED_STATUS when 16#97F#,
SQUAWK_READBACK_DATA(15 downto 0) when 16#980# to 16#987#, SQUAWK_READBACK_DATA(31 downto 16) when 16#988# to 16#98F#,
SQUAWK_READBACK_DATA(47 downto 32) when 16#990# to 16#997#, SQUAWK_READBACK_DATA(63 downto 48) when 16#998# to 16#99F#,
CAPTURED_SDRAM_DATA(79 downto 64) when 16#F74#, CAPTURED_SDRAM_DATA(95 downto 80) when 16#F75#,
-- All other addresses read zero
X"0000" when others;
www.borinsky.co.uk Jeffrey Borinsky www.becg.tv








