Уровень 45: Своя инструкция

Задание

Реализуйте 8-битный вычислитель (ALU) с тремя операциями, выбираемыми сигналом sel[1:0]:

  • sel=0 (ADD) — сложение: result = a + b (используйте Adder8)
  • sel=1 (AND) — побитовое И: result[i] = a[i] & b[i]
  • sel=2 (OR) — побитовое ИЛИ: result[i] = a[i] | b[i]

Модуль OpSelector принимает два 8-битных операнда a и b, 2-битный селектор sel и выдаёт 8-битный result. Используйте generate-for для побитовых операций и MUX.

Материалы по теме

Решение

Схема состоит из трёх частей:

  1. Adder8 — модуль сложения (уже в шаблоне): Adder8 add(sum, carry, a, b).
  2. Поразрядные AND/OR через generate-for (i=0..7): and(and_out[i], a[i], b[i]) и or(or_out[i], a[i], b[i]).
  3. Декодер sel + MUX: NOT sel[0], NOT sel[1] → AND-деревья для s_add (00), s_and (01), s_or (10). Для каждого бита j (generate-for): result[j] = (sum[j] & s_add) | (and_out[j] & s_and) | (or_out[j] & s_or).
module OpSelector(
    input wire [7:0] a,
    input wire [7:0] b,
    input wire [1:0] sel,
    output wire [7:0] result
);
  wire [7:0] sum;
  wire carry;
  Adder8 add(sum, carry, a, b);

  wire [7:0] and_out, or_out;
  generate
    genvar i;
    for (i = 0; i < 8; i = i + 1) begin : bit_gates
      and ga(and_out[i], a[i], b[i]);
      or  go(or_out[i], a[i], b[i]);
    end
  endgenerate

  wire n0, n1;
  not gn0(n0, sel[0]);
  not gn1(n1, sel[1]);
  wire s_add, s_and, s_or;
  and gs_add(s_add, n0, n1);
  and gs_and(s_and, sel[0], n1);
  and gs_or(s_or, n0, sel[1]);

  generate
    genvar j;
    for (j = 0; j < 8; j = j + 1) begin : mux
      wire r_s, r_a, r_o;
      and ma(r_s, sum[j], s_add);
      and mb(r_a, and_out[j], s_and);
      and mc(r_o, or_out[j], s_or);
      wire r01;
      or md(r01, r_s, r_a);
      or me(result[j], r01, r_o);
    end
  endgenerate
endmodule

Всего: 1×Adder8, 8×AND + 8×OR (побитовые), 2×NOT + 3×AND (декодер), 24×AND + 16×OR (MUX через generate-for). ~62 элемента.