From 88b9aa51f303cae4cee45a95db3abfe646e652b9 Mon Sep 17 00:00:00 2001 From: Andrei Solodovnikov Date: Fri, 26 Jan 2024 15:45:23 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9B=D0=A02.=20=D0=A0=D0=B0=D0=B7=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8?= =?UTF-8?q?=D1=86=D1=8B=20=D0=BE=D0=BF=D0=BA=D0=BE=D0=B4=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=90=D0=9B=D0=A3=20=D0=BD=D0=B0=202=20=D1=87=D0=B0=D1=81?= =?UTF-8?q?=D1=82=D0=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Это должно повысить читаемость. --- Labs/02. Arithmetic-logic unit/README.md | 59 +++++++++++++++--------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/Labs/02. Arithmetic-logic unit/README.md b/Labs/02. Arithmetic-logic unit/README.md index 29ba46d..c4a7215 100644 --- a/Labs/02. Arithmetic-logic unit/README.md +++ b/Labs/02. Arithmetic-logic unit/README.md @@ -205,39 +205,52 @@ import alu_opcodes_pkg::*; // импорт параметров, содер endmodule ``` -Для стандартного набора целочисленных операций архитектуры RISC-V требуется выполнять 16 различных операций. Для кодирования 16 операций было бы достаточно 4 бит, но в лабораторной работе предлагается использовать 5-битный код, что связано с особенностями кодирования инструкций (будет рассмотрено в лекциях 6 и 7). Видно, что старший бит кода операции указывает на то, является ли операция вычислительной или это операция сравнения. +Для стандартного набора целочисленных операций архитектуры RISC-V требуется выполнять 16 различных операций. Для кодирования 16 операций было бы достаточно 4 бит, но в лабораторной работе предлагается использовать 5-битный код, что связано с особенностями кодирования инструкций. Видно, что старший бит кода операции указывает на то, является ли операция вычислительной или это операция сравнения. -|ALUOp|={flag, add/sub, aluop}|Result |Flag |Операция | -|-----|-----------------------|-----------------------------------|-----------------------------------|---------------------------------------------------| -| ADD | 0 0 000 |Result = А + В | Flаg = 0 | Сложение | -| SUB | 0 1 000 |Result = А – В | Flаg = 0 | Вычитание | -| SLL | 0 0 001 |Result = А << В | Flаg = 0 | Сдвиг влево | -| SLTS| 0 0 010 |Result = А < В (знаковое сравнение)| Flаg = 0 | Знаковое сравнение | -| SLTU| 0 0 011 |Result = А < В | Flаg = 0 | Беззнаковое сравнение | -| XOR | 0 0 100 |Result = А ^ В | Flаg = 0 | Побитовое исключающее **ИЛИ** | -| SRL | 0 0 101 |Result = А >> В | Flаg = 0 | Сдвиг вправо | -| SRA | 0 1 101 |Result = А >>> В | Flаg = 0 | Арифметический сдвиг вправо (операнд А — знаковый)| -| OR | 0 0 110 |Result = А \| В | Flаg = 0 | Побитовое логическое **ИЛИ** | -| AND | 0 0 111 |Result = А & В | Flаg = 0 | Побитовое логическое **И** | -| EQ | 1 1 000 |Result = 0 | Flаg = (А == В) | Выставить флаг, если **равны** | -| NE | 1 1 001 |Result = 0 | Flаg = (А != В) | Выставить флаг, если **не равны** | -| LTS | 1 1 100 |Result = 0 | Flаg = А < В (знаковое сравнение) | Знаковое сравнение **<** | -| GES | 1 1 101 |Result = 0 | Flаg = А ≥ В (знаковое сравнение) | Знаковое сравнение **≥** | -| LTU | 1 1 110 |Result = 0 | Flаg = А < В | Беззнаковое сравнение **<** | -| GEU | 1 1 111 |Result = 0 | Flаg = А ≥ В | Беззнаковое сравнение **≥** | +Для удобства чтения, список инструкций разбит на две таблицы. -**Выражения в этой таблице приведены для примера. Не все из них можно просто переписать — часть этих выражений надо дополнить. Чтобы вы не копировали выражения, в них вставлены неподдерживаемые символы.** +В первой таблице перечислены операции, вычисляющие значение сигнала `result_o`. **При любом коде операции `alu_op_i` не входящим в эту таблицу, сигнал `result_o` должен быть равен нулю**. -Обратите внимание на инструкции сравнения. У нас есть две похожие пары инструкций: +|alu_op_i|={cmp, add/sub, alu_op_i}|result_o |Операция | +|--------|-------------------------|-------------------------------------------|-------------------------------------------------------| +| ADD | 0 0 000 |result_o = a_i + b_i | Сложение | +| SUB | 0 1 000 |result_o = a_i – b_i | Вычитание | +| SLL | 0 0 001 |result_o = a_i << b_i | Сдвиг влево | +| SLTS | 0 0 010 |result_o = a_i < b_i (знаковое сравнение)| Знаковое сравнение | +| SLTU | 0 0 011 |result_o = a_i < b_i | Беззнаковое сравнение | +| XOR | 0 0 100 |result_o = a_i ^ b_i | Побитовое исключающее **ИЛИ** | +| SRL | 0 0 101 |result_o = a_i >> b_i | Сдвиг вправо | +| SRA | 0 1 101 |result_o = a_i >>> b_i | Арифметический сдвиг вправо (операнд `a_i` — знаковый)| +| OR | 0 0 110 |result_o = a_i \| b_i | Побитовое логическое **ИЛИ** | +| AND | 0 0 111 |result_o = a_i & b_i | Побитовое логическое **И** | + +*Таблица 1. Список вычислительных операций.* + +В первой таблице перечислены операции, вычисляющие значение сигнала `flag_o`. **При любом коде операции `alu_op_i` не входящим в эту таблицу, сигнал `flag_o` должен быть равен нулю**. + +|alu_op_i|={cmp, add/sub, alu_op_i}| flag_o | Операция | +|--------|-------------------------|------------------------------------------|-----------------------------------| +| EQ | 1 1 000 | flag_o = (a_i == b_i) | Выставить флаг, если **равны** | +| NE | 1 1 001 | flag_o = (a_i != b_i) | Выставить флаг, если **не равны** | +| LTS | 1 1 100 | flag_o = a_i < b_i (знаковое сравнение)| Знаковое сравнение **<** | +| GES | 1 1 101 | flag_o = a_i ≥ b_i (знаковое сравнение)| Знаковое сравнение **≥** | +| LTU | 1 1 110 | flag_o = a_i < b_i | Беззнаковое сравнение **<** | +| GEU | 1 1 111 | flag_o = a_i ≥ b_i | Беззнаковое сравнение **≥** | + +*Таблица 2. Список операций сравнения.* + +**Выражения в этих двух таблицах приведены для примера. Не все из них можно просто переписать — часть этих выражений надо дополнить. Чтобы вы не копировали выражения, в них вставлены неподдерживаемые символы.** + +Несмотря на разделение на вычислительные операции, и операции сравнения, в *Таблице 1* (вычислительных операция) оказалось две операции `SLTS` и `SLTU`, которые выполняют сравнения. В итоге у нас есть две похожие пары инструкций: - `LTS` - `LTU` - `SLTS` - `SLTU` -Первая пара инструкций вычисляет "ветвительный" результат. Результат операции будет подан на выходной сигнал `Flag` и использован непосредственно при ветвлении. +Первая пара инструкций вычисляет "ветвительный" результат. Результат операции будет подан на выходной сигнал `flag_o` и использован непосредственно при ветвлении. -Вторые две инструкции используются для получения "вычислительного" результата. Т.е. результат сравнения будет подан на выходной сигнал `Result` так же, как подается результат операции `ADD`, и будет использован в неких вычислениях, избегая при этом условного перехода. +Вторые две инструкции используются для получения "вычислительного" результата. Т.е. результат сравнения будет подан на выходной сигнал `result_o` так же, как подается результат операции `ADD`, и будет использован в неких вычислениях, избегая при этом условного перехода. К примеру, нам необходимо пройтись по массиву из миллиона элементов и убедиться, что все они были неотрицательны. Об этом будет сигнализировать переменная `num_of_err`, значение которой должно быть равно числу элементов массива, меньших нуля. Вычислить значение этой переменной можно двумя способами: