# Concurrent assignments

*Combinational logic as equations*

A concurrent signal assignment in VHDL (signal <= boolean expression) describes a piece of combinational logic that is always active, the same standing gate network the expression denotes, and it can be derived directly from a truth table as a sum of products.

Group: HDL
URL: https://digiwleea.wleeaf.dev/learn/vhdl-concurrent/

You now know [std_logic](https://digiwleea.wleeaf.dev/learn/vhdl-signals/) wires and the [entity/architecture](https://digiwleea.wleeaf.dev/learn/vhdl-entity/) split. This lesson covers the workhorse of combinational VHDL: the **concurrent signal assignment**, the `F <= ...` line. Every one is a standing gate network, and because a [truth table](https://digiwleea.wleeaf.dev/learn/truth-tables/) completely specifies a combinational function, you can write the assignment straight from the table.

## Concurrent means always live

A statement like `F <= A and B` is **concurrent**: it is not executed once, it describes a gate that drives `F` continuously from `A` and `B`. Write several such lines in an architecture and they all run at the same time, in parallel, in any order, because each is its own piece of hardware. This is the direct opposite of software statements, and it is exactly how every gate on your canvas behaves: always on, instantly reflecting its inputs.

> **TIP:** Because concurrent statements are parallel hardware, their **order in the file does not matter**. `F <= t and C;` then `t <= A and B;` describes the same circuit as the reverse order: two gates wired together, and wires do not care which line you typed first. If reordering lines could change behavior, you are thinking in software, not hardware.

## From truth table to sum of products

Any combinational output can be written as a **sum of products**: OR together one product (an AND) for each input row where the output is `1`, with each input that is `0` in that row negated. "Sum" is OR, "product" is AND, an old habit from boolean algebra. Take [XOR](https://digiwleea.wleeaf.dev/learn/xor/), whose output is `1` exactly when the inputs differ:

| A | B | F |
| --- | --- | --- |
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |

_XOR's truth table. The output is 1 in two rows: (A=0, B=1) and (A=1, B=0). Each becomes one product term._

Read off the two rows where `F` is `1`. The row `A=0, B=1` gives the product `(not A) and B`. The row `A=1, B=0` gives `A and (not B)`. OR them together and you have the equation, which is also the VHDL, line for line:

```vhdl
library ieee;
use ieee.std_logic_1164.all;

entity xor_gate is
  port (
    A : in std_logic;
    B : in std_logic;
    F : out std_logic
  );
end entity;

architecture rtl of xor_gate is
begin
  F <= (not A and B) or (A and not B);
end architecture;
```

_XOR as a concurrent assignment, read straight off its truth table: the OR (sum) of the two rows where F is 1. digiwleea generated this exact text from an XOR built on the canvas._

That single expression is a complete description of XOR: two AND gates (the products), each fed by an inverter on one input, ORed together. It is the same structure you would draw by hand, just written as one line. The synthesis tool is free to optimise it (perhaps into NANDs), but the behavior is fixed by the equation.

_Circuit diagram: The XOR the equation describes. Open it in the lab and sweep the inputs: F is 1 only when A and B differ, matching (not A and B) or (A and not B)._

> **WARN:** A frequent mistake is forgetting to negate the inputs that are `0` in a row. The row `A=0, B=1` is **not** `A and B`, it is `(not A) and B`, the term must be true for that exact row and no other. Drop the `not` and your equation lights up for the wrong input combination. Always negate every input that reads `0` in the row you are encoding.

> **KEY:** Why this matters: sum of products is the bridge from the truth tables you have been filling in to real HDL. Any combinational block you can describe with a table, a decoder, a comparator, one bit of an adder, you can now write as a concurrent assignment. A [Karnaugh map](https://digiwleea.wleeaf.dev/learn/karnaugh/) then trims that equation to fewer gates. Sequential logic (anything that remembers) needs one more tool, the process, which is next.

**Q (Try it):** Write the concurrent assignment for a two-input function `F` that is `1` only when `A=1` and `B=0` (and `0` for all three other rows). Then say how many product terms it needs.

**A:** Only **one** row has output `1`, so it is a single product term: `F <= A and not B;`. With just one `1` in the table there is nothing to OR together. (This function is sometimes called "A AND NOT B", or "A but not B".) If two rows were `1`, you would OR two products; the count of product terms equals the count of `1` rows.

### FAQ

**Q:** What is a concurrent assignment in VHDL?

**A:** A concurrent signal assignment (signal <= expression) describes a piece of combinational logic that is always active. It is not executed once like a software statement; it is a standing gate network that continuously drives the signal from its inputs. Multiple concurrent statements all run in parallel.

**Q:** Does the order of concurrent statements in VHDL matter?

**A:** No. Concurrent statements describe parallel hardware, so reordering them does not change the circuit. They are wires and gates connected together, and wires do not care which line you wrote first.

**Q:** How do you write a VHDL equation from a truth table?

**A:** Use sum of products: OR together one product (AND) term for each row where the output is 1, negating every input that is 0 in that row. For XOR, the rows (A=0,B=1) and (A=1,B=0) give F <= (not A and B) or (A and not B).

**Q:** What does sum of products mean?

**A:** It is a boolean expression written as an OR (the 'sum') of AND terms (the 'products'). Each product term is true for exactly one input combination, so ORing the terms for every '1' row reproduces the truth table exactly.
