Skip to content

Problem 07: CPU v1

Viktor Prutyanov edited this page Apr 15, 2019 · 9 revisions

Подготовка

Перейдите в каталог problems/07_cpu_v1 в вашей локальной копии репозитория. Для синхронизации локального репозтория используется команда git pull.

В этом и в следующих заданиях, чтобы узнать подробности работы и поля команды используйте спецификацию RISC-V ISA и таблицу инструкций RISC-V.

Часть №1

Эта часть посвящена написанию кода, необходимого для работы инструкции ADDI.

Задача №1 (АЛУ)

В файле alu.v опишите модуль арифметико-логического устройства (АЛУ). Заголовок модуля должен быть следующий:

module alu(
    input [31:0]src_a,  // Вход первого операнда
    input [31:0]src_b,  // Вход второго операнда
    input [2:0]op,      // Вход выбора номера операции, всего 8 различных операций

    output reg [31:0]res // Результат выполнения операции
);

АЛУ — комбинационная схема, выполняющая одну выбираемую входом op операцию, над входами-операндами src_A и src_B.

Начните с двух операций:

  • op = 0: тождественная операция (возвращает операнд A в качестве результата)
  • op = 1: cложение операнда A и операнда B

Пока остальные операции не определены, пусть АЛУ возвращает 0 для неиспользованных значений op, для этого внутри блока case-endcase можно использовать ключевое слово default.

Задача №2 (регистровый файл)

В файле reg_file.v опишите модуль регистрового файла со следующим заголовком:

module reg_file(        
    input clk,          
    input [4:0]raddr0,   // Адрес чтения №0
    input [4:0]raddr1,   // Адрес чтения №1
    input [4:0]waddr,    // Адрес записи
    input [31:0]wdata,   // Данные для записи
    input we,            // Вход разрешения записи
                        
    output [31:0]rdata0, // Прочитанные данные №0
    output [31:0]rdata1  // Прочитанные данные №1
);                      

У регистрового файла должно быть 2 порта чтения и 1 порт записи. Всего должно быть 32 32-разрядных регистра. Чтение регистра x0 должно всегда возвращать 0.

Задача №3 (устройство управления)

В файле control.v доделайте устройство управления. Шины opcode и funct3 должны соответствовать одноименным полям текущей инструкции.

Задача №4 (ядро)

В модуле core допишите определения шин rd, rs1, rs2, так чтобы они соответствовали одноименным полям текущей инструкции.

Опишите логику расширения знака c 12 бит до 32 бит для шин imm12 и imm32. Можно воспользоваться модулем, сделанным в задании (Problem 01: Sign extension block). Это нужно для правильного сложения отрицательных чисел.

Задача №5

В файле cpu_top.v опишите правильные соединения ядра core и модуля памяти команд rom.

Задача №6

Проверьте корректность работы процессора в симуляторе Icarus Verilog на тестовой программе samples/addi.txt.

Код этой программы (без меток и директив ассемблера) следующий:

addi x5,  x0,  11
addi x7,  x5,   9
nop
addi x11, x7,   0
addi x7,  x7,  -5
nop
nop
nop

При запуске make test произойдёт автоматическая проверка лога симуляции и эталонного лога. Если после строки grep "CPUv1" cpu.log | diff cpu_test.log - никакого вывода нет, значит всё работает правильно.

Часть №2

Эта часть посвящена остальным инструкциям форматов Type-I и Type-R.

Подготовка

Чтобы не писать программы в двоичном виде, а пользоваться ассемблером, нужно установить соответвующие инструменты. Руководство по установке ассемблера и сборке программ находится на этой странице.

Теперь можно писать свои собственные тестовые программы. Кроме того, в каталоге samples находится файл test_v1.s, из которого можно собрать тестовую программу для этого задания.

Задача №1

Добавьте поддержку команд XORI, ORI и ANDI.

Поскольку эти инструкции выполняют новые операции (^, |, &), нужно добавить их поддеружку в модуль alu по аналогии с операцией +. Кроме того, нужно добавить декодирование этих инструкций в модуль control аналогии с инструкцией ADDI.

Задача №2

Добавьте поддержку команд ADD, XOR, OR и AND.

Эти инструкции выполняют уже определенные в АЛУ операции, поэтому теперь нужно только правильно управлять сигналом alu_op из модуля control. Ещё следует добавить в control декодирование битов [31:25]. Для того, чтобы декодер не обращал внимание на эти биты при декодировании инструкций ADDI, XORI, ORI, ANDI, можно использовать знак ? вместо 0 или 1 при описании вариантов в блоке case-endcase. Кроме того, для этих и других инструкций формата Type-R, в модуле core нужно подавать операнд АЛУ alu_b_src не из imm32, а из rf_rdata1.

Задача №3 (*)

Добавьте инструкции SUB, SLTI, SLTIU, SLL, SLT, SLTU, SRL, SRA, SLLI, SRLI, SRAI.

Clone this wiki locally