Уровень 44: Мозг процессора
Задание
Реализуйте дешифратор инструкций (Control Unit) — ключевой узел процессора, который преобразует код операции (opcode) в управляющие сигналы.
Модуль ControlUnit принимает 4-битный opcode и выдаёт 4 управляющих сигнала:
- RegWrite — разрешение записи в регистр (ADD, AND).
- MemWrite — запись в память (STA).
- ALUSel — выбор операции АЛУ: 0=сложение, 1=AND.
- Branch — сигнал перехода (JMP).
Распознаваемые опкоды (мини-ISA):
| opcode | Инструкция | RegWrite | MemWrite | ALUSel | Branch |
|---|---|---|---|---|---|
| 0 (0000) | ADD | 1 | 0 | 0 | 0 |
| 1 (0001) | AND | 1 | 0 | 1 | 0 |
| 2 (0010) | STA | 0 | 1 | 0 | 0 |
| 3 (0011) | JMP | 0 | 0 | 0 | 1 |
| 4–15 | NOP | 0 | 0 | 0 | 0 |
Используйте только вентили AND, OR, NOT (структурный подход). Запрещены assign, if, case, always.
Материалы по теме
- Пульс системы — дешифратор команд в гейт-режиме
- Verilog — это не программирование — схемное мышление
Решение
Дешифратор строится как комбинация деревьев распознавания для каждого опкода. Алгоритм:
- Инвертируем все биты opcode: n0 = NOT opcode[0], …, n3 = NOT opcode[3].
- Детектируем каждый опкод AND-деревом из инвертированных/прямых битов.
- Объединяем сигналы через OR для выходов, активных на нескольких опкодах.
module ControlUnit(
input wire [3:0] opcode,
output wire RegWrite,
output wire MemWrite,
output wire ALUSel,
output wire Branch
);
wire n0, n1, n2, n3;
not g0(n0, opcode[0]);
not g1(n1, opcode[1]);
not g2(n2, opcode[2]);
not g3(n3, opcode[3]);
// opcode=0 (ADD): все биты 0
wire add_t1, add_t2, op_add;
and ga1(add_t1, n0, n1);
and ga2(add_t2, n2, n3);
and ga3(op_add, add_t1, add_t2);
// opcode=1 (AND): opcode[0]=1, остальные 0
wire and_t1, and_t2, op_and;
and gb1(and_t1, opcode[0], n1);
and gb2(and_t2, n2, n3);
and gb3(op_and, and_t1, and_t2);
// opcode=2 (STA): opcode[1]=1, остальные 0
wire sta_t1, sta_t2, op_sta;
and gc1(sta_t1, n0, opcode[1]);
and gc2(sta_t2, n2, n3);
and gc3(op_sta, sta_t1, sta_t2);
// opcode=3 (JMP): opcode[0]=1, opcode[1]=1
wire jmp_t1, jmp_t2, op_jmp;
and gd1(jmp_t1, opcode[0], opcode[1]);
and gd2(jmp_t2, n2, n3);
and gd3(op_jmp, jmp_t1, jmp_t2);
// Выходы: OR объединяет опкоды
or grw(RegWrite, op_add, op_and);
or galusel(ALUSel, op_and, op_and);
or gmem(MemWrite, op_sta, op_sta);
or gbr(Branch, op_jmp, op_jmp);
endmodule
Всего: 4×NOT, 12×AND, 4×OR. Каждый опкод детектируется тремя AND: два AND объединяют пары битов, третий AND объединяет результаты. Opcode 4–15 не активируют ни одного детектора → все выходы = 0 (NOP).