4. Мультиплексоры и демультиплексоры

Мультиплексирование (multiplexing) — важный дизайн-петтерн, идея которого заключается в объединении аналоговых или цифровых сигналов в один канал. На принимающей же стороне эти сигналы разделяются, это называется демультиплексирование (demultiplexing). В цифровой логике же этот дизайн паттерн реализуется через комбинационные схемы особого вида мультиплексоры (MUX) и демультиплексоры (DEMUX) соответственно и используются, например.

  1. Для реализации логических функций и, связанное с этим, реализации LUT-ов.

  2. Для маршрутизации данных.

  3. Для декодирования адресов.

Мультиплексор

Мультиплексор — это устройство, которое выбирает один из нескольких входных сигналов и передаёт его на выход в зависимости от значения управляющих сигналов (селекторов). Простейший пример — 2:1 MUX, который имеет два входа, один выход и один управляющий сигнал.

В простейшем случае это просто тернарный оператор.

src/04-mux-demux/mux_2to1.sv
module mux_2to1 (
    input  logic in0, in1,
    input  logic sel,
    output logic out
);
  assign out = sel ? in1 : in0;
endmodule

Схема такого мультиплексора выглядит довольно просто.

mux 2to1
Рисунок 1. Схема мультиплексора 2:1

И она тоже реализуется при помощи привычных логических операторов.

mux 2to1 logic
Рисунок 2. Схема мультиплексора 2:1 через логические элементы

Мультиплексоры больших порядков можно реализовать как через логические операторы, так и через мультиплексоры меньшей разрядности. Например, 4:1 MUX выглядит так.

src/04-mux-demux/mux_4to1.sv
module mux_4to1 (
  input logic[3:0] in,
  input logic [1:0] sel,
  output logic out
);
  logic [1:0] temp_i; (1)

  mux_2to1 mux1 (
    .in0(in[0]),
    .in1(in[1]),
    .sel(sel[0]), (2)
    .out(temp_i[0]) (3)
  );

  mux_2to1 mux2 (
      .in0(in[2]),
      .in1(in[3]),
      .sel(sel[0]),
      .out(temp_i[1])
  );

  mux_2to1 mux3 (
    .in0(temp_i[0]),
    .in1(temp_i[1]),
    .sel(sel[1]), (4)
    .out(out)
  );
endmodule
1 Промежуточные провода.
2 Выбор по старшему биту.
3 Передача промежуточных выборов.
4 Выбор по младшему биту.

Со следующей схемой.

mux 4to1
Рисунок 3. Схема мультиплексора 4:1 через мультиплексоры 2:1

Демультиплексор

Демультиплексор выполняет обратную функцию: он направляет один входной сигнал на один из нескольких выходов в зависимости от управляющих сигналов. Простейший пример — 1:2 демультиплексор.

demux 1to2
Рисунок 4. Схема демультиплексора 1:2

В сочетании с мультиплексором, позволяет использовать один ресурс нескольким сигналам.

Связь с LUT

LUT (Look-Up Table) — это таблица истинности, которая хранит результат для всех возможных комбинаций входных сигналов. В ПЛИС LUT реализуются с помощью мультиплексоров и является одним из важнейший её ресурсов: большая части логики работает именно на LUT-ах[1]. Например, LUT с двумя входами может быть представлен как 4:1 MUX: два бита селекторов отвечает за вход, а входы мультиплексора будут значениями на соответствующем входе.

Реализуем для примера импликацию через LUT.

src/04-mux-demux/lut_imply.sv
module lut_imply (
  input logic a, b,
  output logic c
);
  mux_4to1 lut(
    .in({1'b1, 1'b1, 1'b0, 1'b0}),
    .sel({a, b}),
    .out(c)
  );

endmodule

По сути мы просто записали таблицу истинности для импликации.

a (sel[0]) b (sel[1]) c (out)

0

0

1 (in[0])

0

1

1 (in[1])

1

0

0 (in[2])

1

1

1 (in[3])

Обязательно порешайте упражнения.