Foundation Express infers registers using the wait and if statements.
A register is a simple, one-bit memory device, either a flip-flop or a latch. A flip-flop is an edge-triggered memory device. A latch is a level-sensitive memory device.
Use the wait statement to imply flip-flops in a synthesized circuit. Foundation Express creates flip-flops for all signals and some variables that are assigned values in a process with a wait statement.
The if statement can be used to imply registers (flip-flops or latches) for signals and variables in the branches of the if statement.
To infer registers, describe latches and flip-flops, and learn to efficiently use registers, familiarize yourself with the following subsections of this chapter.
To infer registers, you describe clocked signals and use wait and if statements. Recommended models for different types of inferred registers and current Express restrictions must also be considered.
Foundation Express can infer asynchronous memory elements from VHDL descriptions written in a natural style.
Use the wait and if statements to test for the rising or falling edge of a signal. The most common uses of the wait and if statement follow.
process
begin
wait until (edge);
...
end process;
...
process (sensitivity_list)
begin
if (edge)
...
end if;
end process;
Another form follows.
process (sensitivity_list)
begin
if (...) then
...
elsif (...)
...
elsif (edge) then
...
end if;
end process;
An edge expression tests for the positive or negative edge of a signal. The syntax of an edge expression follows.
SIGNAL'event and SIGNAL = '1' -- rising edge
NOT SIGNAL'stable and SIGNAL = '1' -- rising edge
SIGNAL'event and SIGNAL = '0' -- falling edge
NOT SIGNAL'stable and SIGNAL = '0' -- falling edge
In a wait statement, edge can also be the following.
signal = '1' -- rising edge
signal = '0' -- falling edge
An edge expression must be the only condition of an if or an elsif statement. You can have only one edge expression in an if statement, and the if statement must not have an else clause. An edge expression cannot be part of another logical expression nor used as an argument.
The following examples show illegal syntax. These lines illustrate three incorrect uses of the edge expression. In the first group, the edge expression is part of a larger Boolean expression. In the second group, the edge expression is used as an argument. In the third group, the edge expression is used as an intermediate condition.
if (edge and RST = '1')
Edge must be the only condition.
Any_function(edge);
Edge cannot be an argument.
if X > 5 then
sequential_statement;
elsif edge then
sequential_statement;
else
; ;sequential_statement;
end if;
Do not use edge as an intermediate expression.
Sometimes you can use the wait and if statements interchangeably. The if statement is usually preferred, because it provides greater control over the inferred register's capabilities, as described in the next section.
IEEE VHDL requires that a process with a wait statement must not have a sensitivity list.
An if edge statement can appear anywhere in a process. The sensitivity list of the process must contain all signals read in the process, including the edge signal. In general, the following guidelines apply.
The register inference capability can support styles of description other than those described here. However, for best results, follow the recommendations below.
LATCH: process(sensitivity_list)
begin
if LATCH_ENABLE then
...
end if;
end process;
LATCH_ASYNC_SET:
...
attribute async_set_reset of SET : signal is "true";
...
process(sensitivity_list)
begin
if SET then
Q <= '1';
elsif LATCH_ENABLE then
...
end if;
end process;
FF: process(CLK)
begin
if edge then
...
end if;
end process;
FF_ASYNC_RESET:
process(RESET, CLK)
begin
if RESET then
Q <= '0';
elsif edge then
Q <= ...;
end if;
end process;
FF_SYNC_RESET:
process(RESET, CLK)
begin
if edge ;then
if RESET then
Q <= '0';
else
Q <= ...;
end if;
end if;
end process;
Examples of these templates are provided in the Describing Latches section and the Describing Flip-flops section in this chapter.
The following restrictions apply to register capabilities.
process(CLK_A, CLK_B)
begin
if(CLK_A'event and CLK_A = '1') then
A <= B;
end if;
if(CLK_B'event and CLK_B = '1') then --Illegal
C <= B;
end if;
end process;
process(CLK)
begin
if(rising_edge) then
SIG <= B;
else
SIG <= C; -- Illegal
end if;
end process;
process(CLK)
variable EDGE_VAR, ANY_VAR: BIT;
begin
if (rising_edge) then
EDGE_SIGNAL <= X;
EDGE_VAR := Y;
ANY_VAR := EDGE_VAR; -- Legal
end if;
ANY_VAR := EDGE_VAR; -- Illegal
end process;
If you use delay specifications with values that may be registered, these values might cause the simulation to behave differently from the logic synthesized by Foundation Express. For example, the description in the example below contains delay information that causes Foundation Express to synthesize a circuit that behaves unexpectedly.
component flip_flop (
D, clock: in BIT;
Q: out BIT;);
end component;
process ( A, C, D, clock );
signal B: BIT;
begin
B <= A after 100ns;
F1: flip_flop port map ( A, C, clock ),
F2: flip_flop port map ( B, D, clock );
end process;
In the example above, fewer than 100 nanoseconds, output D is one or more clock cycles behind output C when the circuit is simulated. However, because Foundation Express ignores the delay information, A and B change values at the same time and so do C and D. This behavior is not the same as in the simulated circuit.
When you use delay information in your designs, make sure the delays do not affect registered values. In general, you can safely include delay information in your description if it does not change the value that gets clocked into a flip-flop.
Foundation Express infers latches from incompletely specified conditional expressions. In the following example, the if statement infers a latch because there is no else clause. The inferred latch uses CLK as its clock and DATA as its data input, as shown in the figure following the example.
process(GATE, DATA)
begin
if (GATE = '1') then
Q <= DATA;
end if;
end process;
Figure 8.1 Circuit for Latch Inference |
A signal or variable that is not driven under all conditions becomes a latched value. As shown in the example below, TEMP becomes a latched value because it is assigned only when PHI is 1. The resulting circuit follows the example.
if(PHI = '1') then
TEMP <= A;
end if;
Figure 8.2 Circuit for Automatically Inferred Latch |
To avoid inferred latches, assign a value to the signal under all conditions, as shown in the following example. The resulting circuit follows the example.
if (PHI = '1') then
TEMP <= A;
else
TEMP <= '0';
end if;
Figure 8.3 Circuit for Fully Specified Signal: No Latch Inference |
You cannot read a conditionally assigned variable after the if statement in which it is assigned. A conditionally assigned variable is assigned a new value under some, but not all, conditions.
Therefore, a variable must always have a value before it is read. The example below shows illegal syntax.
signal X, Y: BIT;
. . .
process
variable VALUE: BIT;
begin
if (condition) then
VALUE := X;
end if;
Y <= VALUE; -- Illegal
end;
In simulation, latch inference occurs because signals and variables can hold state over time. A signal or variable holds its value until that value is reassigned. Foundation Express inserts a latch to duplicate this holding of state in hardware.
Variables declared locally within a subprogram do not hold their value over time. Every time a subprogram is used, its variables are initialized again. Therefore, Foundation Express does not infer latches for variables declared in subprograms. In the following example, no latches are inferred. The resulting circuit is shown in the figure following the example.
function MY_FUNC(DATA, GATE : BIT) return BIT is
variable STATE: BIT;
begin
if GATE then
STATE := DATA;
end if;
return STATE;
end;
. . .
Q <= MY_FUNC(DATA, GATE);
Figure 8.4 Circuit for Function without Inferred Latch |
By using the latch inference capability, you can describe network structures, such as two-phase systems in a technology independent manner. The example below shows a simple two-phase system with clocks PHI_1 and PHI_2. The resulting circuit follows the example.
entity LATCH_VHDL is
port(PHI_1, PHI_2, A : in BIT;
t: out BIT);
end LATCH_VHDL;
architecture EXAMPLE of LATCH_VHDL is
signal TEMP, LOOP_BACK: BIT;
begin
process(PHI_1, A, LOOP_BACK)
begin
if(PHI_1 = '1') then
TEMP <= A and LOOP_BACK;
end if;
end process;
process(PHI_2, TEMP)
begin
if(PHI_2 = '1') then
LOOP_BACK <= not TEMP;
end if;
end process;
t <= LOOP_BACK;
end EXAMPLE;
Figure 8.5 Circuit for Two-Phase Clocks |
Foundation Express does not automatically infer dual-phase latches (devices with master and slave clocks). To use these devices, you must instantiate them as components, as described in the Describing Designs chapter.
The example below shows how an edge construct creates a flip-flop. The resulting circuit follows the example.
process(CLK, DATA)
begin
if (rising_edge) then
Q <= DATA;
end if;
end process;
Figure 8.6 Circuit for Inferred Flip-flop |
The example below shows how to specify a flip-flop with an asynchronous reset. The resulting circuit follows the example.
process(RESET_LOW, CLK, SYNC_DATA)
begin
if RESET_LOW = `0' then
Q <= '0';
elsif (rising_edge) then
Q <= SYNC_DATA;
end if;
end process;
Figure 8.7 Circuit for Inferred Flip-flop with Asynchronous Reset |
The following notes show how the flip-flop in the previous example is wired.
The example below shows an inferred flip-flop with an asynchronous reset, where the reset condition is not computable. The resulting circuit follows the example.
process (CLK, ANY_SIGNAL, ASYNC_DATA, SYNC_DATA)
begin
if (ANY_SIGNAL) then
Q <= ASYNC_DATA;
elsif (rising_edge) then
Q <= SYNC_DATA;
end if;
end process;
Figure 8.8 Circuit for Inferred Flip-flop with Asynchronous Set or Clear |
The following example shows a synchronous finite state machine with asynchronous reset. The resulting circuit follows the example.
package MY_TYPES is
type STATE_TYPE is (S0, S1, S2, S3);
end MY_TYPES;
use WORK.MY_TYPES.ALL;
entity STATE_MACHINE is
port(CLK, INC, A, B: in BIT; RESET: in Boolean;
t: out BIT);
end STATE_MACHINE;
architecture EXAMPLE of STATE_MACHINE is
signal CURRENT_STATE, NEXT_STATE: STATE_TYPE;
begin
SYNC: process(CLK, RESET)
begin
if (RESET) then
CURRENT_STATE <= S0;
elsif (rising_edge) then
CURRENT_STATE <= NEXT_STATE;
end if;
end process SYNC;
FSM: process(CURRENT_STATE, A, B)
begin
t <= A; -- Default assignment
NEXT_STATE <= S0; -- Default assignment
if (INC = '1') then
case CURRENT_STATE is
when S0 =>
NEXT_STATE <= S1;
when S1 =>
NEXT_STATE <= S2;
t <= B;
when S2 =>
NEXT_STATE <= S3;
when S3 =>
null;
end case;
end if;
end process FSM;
end EXAMPLE;
Figure 8.9 Circuit for a Synchronous Finite State Machine with Asynchronous Reset |
New attributes used to assist register inference are discussed in this section. The attributes are defined in a VHDL library called Synopsys ATTRIBUTES package.
attribute async_set_reset : string;
attribute sync_set_reset : string;
attribute async_set_reset_local : string;
attribute sync_set_reset_local : string;
attribute async_set_reset_local_all : string;
attribute sync_set_reset_local_all : string;
attribute one_hot : string;
attribute one_cold : string;
The examples below that use reset and set are only valid for 9k designs.
The async_set_reset attribute is attached to single-bit signals using the attribute construct. Foundation Express checks signals with the async_set_reset attribute set to TRUE to determine whether these signals asynchronously set or reset a latch in the entire design.
The syntax of async_set_reset follows.
attribute async_set_reset of signal_name,. : signal is "true";
The asynchronous clear signal for a latch is inferred by driving the Q pin of your latch to 0. The asynchronous set signal for a latch is inferred by driving the Q pin of your latch to 1. Although Foundation Express does not require that the clear (set) be the first condition in your conditional branch, it is best to write your VHDL in this manner.
The example below shows how to specify a latch with an asynchronous clear input. To specify a latch with an asynchronous set, change the logic as indicated by the comments. The resulting circuit follows the example.
attribute async_set_reset of clear : signal is "true";
process(clear, gate, a)
begin
if (clear = `1') then
q <= `0';
elsif (gate = '1') then
q <= a;
end if;
end process;
Figure 8.10 Circuit for Inferred Latch with Asynchronous Clear |
The sync_set_reset attribute is attached to single-bit signals with the attribute constructs. Foundation Express checks signals with the sync_set_reset attribute set to TRUE to determine whether these signals synchronously set or reset a flip-flop in the entire design.
The syntax of sync_set_reset follows.
attribute sync_set_reset of signal_name,... : signal is "true";
The example below shows how to specify a flip-flop with a synchronous reset. The resulting circuit follows the example.
attribute sync_set_reset of RESET, SET : signal is "true";
process(RESET, CLK)
begin
if (rising_edge) then
if RESET = `1' then
Q <= '0';
else
Q <= DATA_A;
end if;
end if;
end process;
process (SET, CLK)
begin
if (rising_edge) then
if SET = `1' then
T <= '1';
else
T <= DATA_B;
end if;
end if;
end process;
Figure 8.11 Circuit for an Inferred Flip-flop with Synchronous Reset Input |
The async_set_reset_local attribute is attached to the label of a process with a value of a double-quoted list of single-bit signals. Every signal in the list is treated as though it has the async_set_reset attribute attached in the specified process.
The syntax of async_set_reset_local follows.
attribute async_set_reset_local of process_label : label is
"signal_name,...";
The example shows an asynchronous set/reset on a single block. The resulting circuit follows the example.
library IEEE;
library synopsys;
use IEEE.std_logic_1164.all;
use synopsys.attributes.all;
entity e_async_set_reset_local is
port(reset, set, gate: in std_logic; y, t: out std_logic);
end e_async_set_reset_local;
architecture rtl of e_async_set_reset_local is
attribute async_set_reset_local of direct_set_reset : label
is "reset, set";
begin
direct_set_reset: process (reset, set)
begin
if (reset = '1') then
y <= '0'; -- asynchronous reset
elsif (set = '1') then
y <= '1'; -- asynchronous set
end if;
end process direct_set_reset;
gated_data: process (gate, reset, set)
begin
if (gate = '1') then
if (reset = '1') then
t <= '0'; -- gated data
elsif (set = '1') then
t <= '1'; -- gated data
end if;
end if;
end process gated_set_reset;
end rtl;
Figure 8.12 Circuit for an Asynchronous Set/Reset on a Single Block |
The sync_set_reset_local attribute is attached to the label of a process with a value of a double-quoted list of single-bit signals. Every signal in the list is treated as though it has the sync_set_reset attribute attached in the specified process.
The syntax of sync_set_reset_local follows.
attribute sync_set_reset_local of process_label : label is "signal_name,..."
The following example shows synchronous set/reset on a single block. The resulting circuit follows the example.
library IEEE;
library synopsys;
use IEEE.std_logic_1164.all;
use synopsys.attributes.all;
entity e_sync_set_reset_local is
port(clk, reset, set, gate : in std_logic; y, t: out std_logic);
end e_sync_set_reset_local;
architecture rtl of e_sync_set_reset_local is
attribute sync_set_reset_local of clocked_set_reset : label is "reset, set";
begin
clocked_reset: process (clk, reset, set)
begin
if (rising_edge) then
if (reset = '1') then
y <= '0'; -- synchronous reset
else
y <= '1'; -- synchronous set
end if;
end if;
end process clocked_set_reset;
gated_data: process (clk, gate, reset, set)
begin
if (rising_edge) then
if (gate = '1') then
if (reset = '1') then
t <= '0'; -- gated data
elsif (set = '1') then
t <= '1'; -- gated data
end if;
end if;
end if;
end process gated_set_reset;
end rtl;
Figure 8.13 Circuit for a Synchronous Set/Reset on a Single Block |
The async_set_reset_local_all attribute is attached to a process label. The attribute async_set_reset_local_all specifies that all the signals in the process are used to detect an asynchronous set or reset condition for inferred latches or flip-flops.
The syntax of async_set_reset_local_all follows.
attribute async_set_reset_local_all of process_label,... : label is "true";
The following example shows an asynchronous set/reset on part of a design. The resulting circuit follows the example.
library IEEE;
library synopsys;
use IEEE.std_logic_1164.all;
use synopsys.attributes.all;
entity e_async_set_reset_local_all is
port(reset, set, gate, gate2: in std_logic; y, t, w: out std_logic);
end e_async_set_reset_local_all;
architecture rtl of e_async_set_reset_local_all is
attribute async_set_reset_local_all of
direct_set_reset, direct_set_reset_too: label is "true";
begin
direct_set_reset: process (reset, set)
begin
if (reset = '1') then
y <= '0'; -- asynchronous reset
elsif (set = '1') then
y <= '1'; -- asynchronous set
end if;
end process direct_set_reset;
direct_set_reset_too: process (gate, reset, set)
begin
if (gate = '1') then
if (reset = '1') then
t <= '0'; -- asynchronous reset
elsif (set = '1') then
t <= '1'; -- asynchronous set
end if;
end if;
end process direct_set_reset_too;
gated_data: process (gate2, reset, set)
begin
if (gate = '1') then
if (reset = '1') then
w <= '0'; -- gated data
elsif (set = '1') then
w <= '1'; -- gated data
end if;
end if;
end process gated_set_reset;
end rtl;
Figure 8.14 Circuit for an Asynchronous Set/Reset on Part of a Design |
The sync_set_reset_local_all attribute is attached to a process label. The attribute sync_set_reset_local_all specifies that all the signals in the process are used to detect a synchronous set or reset condition for inferred latches or flip-flops.
The syntax of sync_set_reset_local_all follows.
attribute sync_set_reset_local_all of process_label,... : label is "true";
The following example shows a synchronous set/reset on a part of a design. The resulting circuit follows the example.
library IEEE;
library synopsys;
use IEEE.std_logic_1164.all;
use synopsys.attributes.all;
entity e_sync_set_reset_local_all is
port(clk, reset, set, gate, gate2: in std_logic; y, t, w: out std_logic);
end e_sync_set_reset_local_all;
architecture rtl of e_sync_set_reset_local_all is
attribute sync_set_reset_local_all of
clocked_set_reset, clocked_set_reset_too: label is "true";
begin
clocked_set_reset: process (clk, reset, set)
begin
if (rising_edge) then
if (reset = '1') then
y <= '0'; -- synchronous reset
elsif (set = '1') then
y <= '1'; -- synchronous set
end if;
end if;
end process clocked_set_reset;
clocked_set_reset_too: process (clk, gate, reset, set)
begin
if (rising_edge) then
if (gate = '1') then
if (reset = '1') then
t <= '0'; -- synchronous reset
elsif (set = '1') then
t <= '1'; -- synchronous set
end if;
end if;
end if;
end process clocked_set_reset_too;
gated_data: process (clk, gate2, reset, set)
begin
if (rising_edge) then
if (gate = '1') then
if (reset = '1') then
w <= '0'; -- gated data
elsif (set = '1') then
w <= '1'; -- gated data
end if;
end if;
end if;
end process gated_set_reset;
end rtl;
Figure 8.15 Circuit for a Synchronous Set/Reset on a Part of a Design |
Use the one_hot and one_cold directives to implement D-type flip-flops with asynchronous set and reset signals. These two attributes tell Foundation Express that only one of the objects in the list are active at a time. If you are defining active high signals, use one_hot. For active low, use one_cold. Each attribute has two objects specified.
The one_hot directive takes one argument of a double-quoted list of signals separated by commas. This attribute indicates that the group of signals are one_hot (at any time, no more than one signal can have a Logic 1 value). Check that the group of signals are really one_hot, because Foundation Express does not produce any logic to check this assertion.
The syntax of one_hot follows.
attribute one_hot signal_name,... : label is "true";
The following example shows how to use one_hot for set and reset. The resulting circuit follows the example.
library IEEE;
library synopsys;
use IEEE.std_logic_1164.all;
use synopsys.attributes.all;
entity e_one_hot is
port(reset, set, reset2, set2: in std_logic; y, t: out std_logic);
attribute async_set_reset of reset, set : signal is "true";
attribute async_set_reset of reset2, set2 : signal is "true";
attribute one_hot of reset, set : signal is "true";
end e_one_hot;
architecture rtl of e_one_hot is
begin
direct_set_reset: process (reset, set )
begin
if (reset = '1') then
y <= '0'; -- asynchronous reset by "reset"
elsif (set = '1') then
y <= '1'; -- asynchronous set by "set"
end if;
end process direct_set_reset;
direct_set_reset_too: process (reset2, set2 )
begin
if (reset2 = '1') then
t <= '0'; -- asynchronous reset by "reset2"
elsif (set2 = '1') then
t <= '1'; -- asynchronous set by "~reset2 set2"
end if;
end process direct_set_reset_too;
-- synopsys synthesis_off
process (reset, set)
begin
assert not (reset='1' and set='1')
report "One-hot violation"
severity Error;
end process;
-- synopsys synthesis_on
end rtl;
Figure 8.16 Circuit for one_hot for Set and Reset |
The one_cold directive is similar to the one_hot directive. one_cold indicates that no more than one signal in the group can have a Logic 0 value at any time.
The syntax of one_cold follows.
attribute one_cold signal_name,... : label is "true";
The following example shows how to use one_cold for set and reset. The resulting circuit follows the example.
library IEEE;
library synopsys;
use IEEE.std_logic_1164.all;
use synopsys.attributes.all;
entity e_one_cold is
port(reset, set, reset2, set2: in std_logic; y, t: out std_logic);
attribute async_set_reset of reset, set : signal is "true";
attribute async_set_reset of reset2, set2 : signal is "true";
attribute one_cold of reset, set : signal is "true";
end e_one_cold;
architecture rtl of e_one_cold is
begin
direct_set_reset: process (reset, set )
begin
if (reset = '0') then
y <= '0'; -- asynchronous reset by "not reset"
elsif (set = '0') then
y <= '1'; -- asynchronous set by "not set"
end if;
end process direct_set_reset;
direct_set_reset_too: process (reset2, set2 )
begin
if (reset2 = '0') then
t <= '0'; -- asynchronous reset by "not reset2"
elsif (set2 = '0') then
t <= '1'; -- asynchronous set by "(not reset2) (not set2)"
end if;
end process direct_set_reset_too;
-- synopsys synthesis_off
process (reset, set)
begin
assert not (reset='0' and set='0')
report "One-cold violation"
severity Error;
end process;
-- synopsys synthesis_on
end rtl;
Figure 8.17 Circuit for one_cold for Set and Reset |
Foundation Express infers latches and flip-flops as follows.
Foundation Express generates a brief report on inferred latches, flip-flops, or three-state devices.
Organize your HDL description so that you build only as many flip-flops as the design requires. The following example shows a description where too many flip-flops are implied. The resulting circuit follows the example.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity ex8_13 is
port ( clk , reset : in std_logic;
and_bits , or_bits , xor_bits : out std_logic
);
end ex8_13;
architecture rtl of ex8_13 is
begin
process
variable count : std_logic_vector (2 downto 0);
begin
wait until rising_edge;
if (reset = '1') then
count := "000";
else count := count + 1;
end if;
and_bits <= count(2) and count(1) and count(0);
or_bits <= count(2) or count(1) or count(0);
xor_bits <= count(2) xor count(1) xor count(0);
end process;
end rtl;
Figure 8.18 Circuit with Six Implied Registers |
In the example of the circuit with six implied registers, the outputs AND_BITS, OR_BITS, and XOR_BITS depend solely on the value of COUNT. Because COUNT is registered, the three outputs do not need to be registered. To avoid implying extra registers, assign the outputs from within a process that does not have a wait statement. The following example shows a description with two processes, one with a wait statement and one without. The resulting circuit follows the example.
This description style lets you choose the signals that are registered and those that are not. This technique of separating combinatorial logic from registered or sequential logic is useful when describing finite state machines.
use work.ARITHMETIC.all;
entity COUNT is
port(CLOCK, RESET: in BIT;
AND_BITS, OR_BITS, XOR_BITS : out BIT);
end COUNT;
architecture RTL of COUNT is
signal COUNT : UNSIGNED (2 downto 0);
begin
REG: process -- Registered logic
begin
wait until rising_edge;
if (RESET = '1') then
COUNT <= "000";
else
COUNT <= COUNT + 1;
end if;
end process;
COMBIN: process(COUNT) -- Combinational logic
begin
AND_BITS <= COUNT(2) and COUNT(1) and COUNT(0);
OR_BITS <= COUNT(2) or COUNT(1) or COUNT(0);
XOR_BITS <= COUNT(2) xor COUNT(1) xor COUNT(0);
end process;
end RTL;
Figure 8.19 Circuit with Three Implied Registers |
If you want to keep some of the values computed by a process in flip-flops while allowing other values to change between clock edges, split your algorithm between two processes, one with a wait statement and one without. Put the registered (synchronous) assignments into the wait process. Put the other (asynchronous) assignments into the other process. Use signals to communicate between the two processes.
For example, suppose you want to build a design with the following characteristics.
The implementation of this design requires two processes. The process with a wait statement synchronizes the CONTROL value. The other process multiplexes the output, based on the synchronized control. The signal SYNC_CONTROL communicates between the two processes.
The example below shows the code and a schematic of one possible implementation.
entity SYNC_ASYNC is
port (CLOCK: in BIT;
CONTROL: in INTEGER range 0 to 3;
A: in BIT_VECTOR(0 to 3);
t: out BIT);
end SYNC_ASYNC;
architecture EXAMPLE of SYNC_ASYNC is
signal SYNC_CONTROL: INTEGER range 0 to 3;
begin
process
begin
wait until rising_edge;
SYNC_CONTROL <= CONTROL;
end process;
process (A, SYNC_CONTROL)
begin
t <= A(SYNC_CONTROL);
end process;
end EXAMPLE;
Figure 8.20 Circuit for Two Processes: One Synchronous, One Asynchronous |