mirror of
https://github.com/MPSU/APS.git
synced 2025-09-16 09:40:10 +00:00
Initial commit
This commit is contained in:
292
Labs/02. Arithmetic-logic unit/README.md
Normal file
292
Labs/02. Arithmetic-logic unit/README.md
Normal file
@@ -0,0 +1,292 @@
|
||||
# Лабораторная работа 2. Арифметико-логическое устройство
|
||||
|
||||
Так как основной задачей процессора является обработка цифровых данных, одним из его основных блоков является арифметико-логическое устройство (АЛУ). Задача АЛУ производить над входными данным арифметические и поразрядно логические операции.
|
||||
|
||||
## Цель
|
||||
|
||||
Используя навыки по описанию мультиплексоров, писать блок арифметико-логического устройства (АЛУ) на языке SystemVerilog.
|
||||
|
||||
## Допуск к лабораторной работе
|
||||
|
||||
Освоить [описание мультиплексора на языке SystemVerilog](../../Basic%20Verilog%20structures/Multiplexors.md).
|
||||
|
||||
## Общий ход выполнения работы
|
||||
|
||||
1. Изучить устройство и принцип работы АЛУ (раздел [#теория](#теория))
|
||||
2. Изучить языковые конструкции SystemVerilog для реализации АЛУ (раздел [#инструменты](#инструменты))
|
||||
3. Внимательно ознакомиться с заданием (раздел [#задание](#задание))
|
||||
4. Описать модуль АЛУ, проверить его предоставленным верификационным окружением.
|
||||
5. Проверить работу АЛУ в ПЛИС.
|
||||
|
||||
## Теория
|
||||
|
||||
Арифметико-логическое устройство (АЛУ, Arithmetic Logic Unit – ALU) – это блок процессора, выполняющий арифметические и поразрядно логические операции. Разница между арифметическими и логическими операциями в отсутствии у последних бита переноса, так как логические операции происходят между однобитными числами и дают однобитный результат, а в случае АЛУ (в рамках данной лабораторной работы) одновременно между 32-мя однобитными парами чисел. В логических операциях результаты значений отдельных битов друг с другом никак не связаны.
|
||||
|
||||
Также, кроме результата операций, АЛУ формирует флаги, которые показывают выполняется ли заданное условие. Например, выведет `1`, если один операнд меньше другого.
|
||||
|
||||
Обычно АЛУ представляет собой комбинационную схему (то есть без элементов памяти), на входы которой поступают информационные (операнды) и управляющие (код операции) сигналы, в ответ на что на выходе появляется результат заданной операции. АЛУ бывает не комбинационной схемой, но это скорее исключение.
|
||||
|
||||

|
||||
|
||||
*Рисунок 1. Структурное обозначение элемента АЛУ*
|
||||
|
||||
На рис. 1 изображен пример АЛУ, используемый в книге "Цифровая схемотехника и архитектура компьютера" Харрис и Харрис. На входы `A` и `B` поступают операнды с разрядностью *N*. На трехбитный вход `F` подается код операции. Например, если туда подать `000`, то на выходе `Y` появится результат операции *логическое И* между битами операндов `A` и `B`. Если на `F` подать `010`, то на выходе появится результат сложения. Это лишь пример, разрядность и коды могут отличаться в зависимости от количества выполняемых операций и архитектуры.
|
||||
|
||||
Существует несколько подходов к реализации АЛУ, отличающиеся внутренней организацией. Некоторые из подходов освещаются на [`лекции 3`](../../Lectures/03.%20Digital%20arithmetics.md). В лабораторных работах применяется повсеместно используемый подход мультиплексирования операций, то есть подключения нескольких операционных устройств (которые выполняют какие-то операции, например сложения, логическое И и т.п.) к мультиплексору, который будет передавать результат нужного операционного устройства на выходы АЛУ.
|
||||
|
||||
Рассмотрим на примере все того же АЛУ MIPS из книги Харрисов. На рис. 2, в левой его части, изображена внутренняя организация этого АЛУ, справа – таблица соответствия кодов операциям. На выходе схемы (внизу) стоит четырехвходовый мультиплексор, управляемый двумя из трех битов `F`. К его входам подключены *N* логических И (побитовое И *N*-разрядных операндов), *N* логических ИЛИ, *N*-разрядный сумматор и Zero Extend – устройство делающее из однобитного числа *N*-битное число, дополняя нулями слева.
|
||||
|
||||
К одному из входов этих операционных устройств подключен `A` без изменений, а ко второму подключен выход двухвходового мультиплексора, управляемого оставшимся битом *F*. То есть `F[2]` определяет, что будет вторым операндом: `B` или `~B`. Вдобавок `F[2]` подается на входной перенос сумматора, то есть, когда `F[2] == 1` на выходе сумматора появляется результат операции `A + ~B + 1`, что (с учетом [дополнительного кода](https://ru.wikipedia.org/wiki/Дополнительный_код)) эквивалентно `A – B` (о сумматорах, входных переносах и вычитании на [`лекции 3`](../../Lectures/03.%20Digital%20arithmetics.md)).
|
||||
|
||||

|
||||
|
||||
*Рисунок 2. Структурная схема АЛУ MIPS*
|
||||
|
||||
Посмотрим, что произойдет, если на вход `F` такого АЛУ подать `111`. Будет выполняться операция `SLT`(сокращение от `Set Less Then`) – выдать `1`, если `A` меньше `B`, в противном случае — выдать `0`. Биты `F[1:0]` переключат мультиплексор на выход блока Zero Extend. На вход Zero Extend поступает старший бит выхода сумматора, этот бит отвечает за знак результата. Так как `F[2] == 1`, сумматор вычисляет `A + ~B + 1`, то есть `A – B`, значит, если `A < B`, то результат вычитания будет отрицательный, а старший бит `Y[N-1] == 1`. Если `A` не меньше `B`, то разность будет неотрицательна, а `Y[N-1] == 0`, как и требуется от этой операции.
|
||||
|
||||

|
||||
|
||||
*Рисунок 3. Пример исполнения операции АЛУ*
|
||||
|
||||
Преимущество такой организации АЛУ в его простой модификации, настройке под нужные коды операций, читаемости кода и масштабируемости. Можно легко добавить или убрать требуемые операции. Подумайте, как бы вы обновили данную схему, если бы от вас потребовалось расширить её функционал операциями XOR (Исключающее ИЛИ) и (SGE операция "больше либо равно")?
|
||||
|
||||
## Инструменты
|
||||
|
||||
Как было сказано выше, АЛУ можно реализовать, [мультиплексируя](../../Basic%20Verilog%20structures/Multiplexors.md) результаты нескольких операционных устройств.
|
||||
|
||||
При описании очередной комбинации управляющего сигнала, выходу мультиплексора можно сразу присваивать необходимое логическое выражение (например результат побитового ИЛИ можно подать на выход сразу в виде выражения: `a | b`, однако в некоторых случаях выражения будут сложнее из-за различных особенностей реализации, о которых будет рассказано в задании).
|
||||
|
||||
### Параметры
|
||||
|
||||
Очень удобным на практике оказывается использование параметров. Параметры добавляют модулю гибкости, позволяя убрать "магические" константы из описания модулей, подставляя вместо них выразительное символьное имя. Параметры отдаленно схожи с макросами `#define` в языке Си, однако стоит понимать, параметры используются на этапе синтеза схемы, в отличие от макросов в языке Си, которые заменяются препроцессором еще до этапа компиляции.
|
||||
|
||||
Допустим, ваше устройство должно включить тостер, если на вход ему придет сигнал `32'haf3c5bd0`. Человек, не знакомый с устройством, при прочтении этого кода будет недоумевать, что это за число и почему используется именно оно. Однако, скрыв его за параметром `TOASTER_EN`, читающий поймет, что это код включения тостера. Кроме того, если некоторая константа должна использоваться в нескольких местах кода, то определив её через в виде параметра, можно будет менять её в одном месте, и она тут же поменяется везде.
|
||||
|
||||
Параметры позволяют влиять на структуру модуля. К примеру, описывая сумматор, можно параметризовать его разрядность и использовать этот параметр при описании модуля (например в блоке `generate for`). В этом случае вы сможете создавать множество сумматоров различных разрядностей, подставляя при создании нужное вам значение параметра.
|
||||
|
||||
Параметр может быть объявлен в модуле двумя способами:
|
||||
|
||||
- в прототипе модуля;
|
||||
- в теле описания модуля.
|
||||
|
||||
В первом случае для указания параметра после имени модуля ставится символ `#`, за которым в круглых скобках пишется ключевое слово `parameter` затем указывается тип параметра (по умолчанию знаковое 32-битное число), после чего указывается имя и (опционально) значение по умолчанию.
|
||||
|
||||
Пример:
|
||||
|
||||
```SystemVerilog
|
||||
module overflow #(parameter WIDTH = 32)(
|
||||
input logic [WIDTH-1 : 0] a, b,
|
||||
output logic overflow
|
||||
);
|
||||
|
||||
logic [WIDТН : 0] sum;
|
||||
|
||||
ass𝚒gn sum = a + b;
|
||||
ass𝚒gn overflow = sum[WIDTH];
|
||||
|
||||
endmodule
|
||||
```
|
||||
|
||||
Только таким способом объявления параметр может влиять на разрядность портов модуля.
|
||||
|
||||
В случае, если параметр не влияет на разрядность портов, его можно объявить в теле модуля:
|
||||
|
||||
```SystemVerilog
|
||||
module toaster(
|
||||
input logic [31:0] command,
|
||||
output logic power
|
||||
)
|
||||
|
||||
parameter TOASTER_EN = 32'haf3c5bd0;
|
||||
|
||||
assign power = command == TOASTER_EN;
|
||||
|
||||
endmodule
|
||||
```
|
||||
|
||||
В случае АЛУ будет удобно использовать параметры для обозначения кодов команд. Во-первых, для того чтобы в `case` не допустить ошибок, а во-вторых – чтобы можно было легко менять управляющие коды для повторного использования АЛУ в других проектах.
|
||||
|
||||
Сравните сами:
|
||||
|
||||
```SystemVerilog
|
||||
//parameter SLT = 5'b00011;
|
||||
//parameter BEQ = 5'b11000;
|
||||
|
||||
//...
|
||||
|
||||
always_comb
|
||||
case(ALUOp)
|
||||
//...
|
||||
5'b00011: //... // вообще же ничего не понятно
|
||||
5'b11000: //... // никуда не годится
|
||||
```
|
||||
|
||||
и
|
||||
|
||||
```SystemVerilog
|
||||
parameter SLT = 5'b00011;
|
||||
parameter BEQ = 5'b11000;
|
||||
|
||||
//...
|
||||
|
||||
аlwауs_comb
|
||||
case(ALUOp)
|
||||
//...
|
||||
SLT: //... // очень понятно
|
||||
BEQ: //... // так лаконично и красиво
|
||||
```
|
||||
|
||||
С параметрами гораздо взрослее, серьезнее и понятнее смотрится. Кстати, сразу на заметку: в SystemVerilog можно объединять группу параметров в **пакет**(package), а затем импортировать его внутрь модуля, позволяя переиспользовать параметры без повторного их прописывания для других модулей.
|
||||
|
||||
Делается это следующим образом.
|
||||
|
||||
Сперва создается SystemVerilog-файл, который будет содержать пакет (к примеру содержимое файла может быть таким):
|
||||
|
||||
```SystemVerilog
|
||||
package riscv_params_pkg;
|
||||
parameter ISA_WIDTH = 32;
|
||||
parameter ANOTHER_EX = 15;
|
||||
endpackage
|
||||
```
|
||||
|
||||
Далее, внутри модуля, которому нужны параметры из этого пакета, необходимо сделать соответствующий импорт этих параметров. Это можно сделать либо для каждого параметра отдельно, либо импортировать все параметры сразу:
|
||||
|
||||
```SystemVerilog
|
||||
module riscv_processor(
|
||||
//...Порты
|
||||
);
|
||||
|
||||
import riscv_params_pkg::ISA_WIDTH; // Если необходимо импортировать
|
||||
import riscv_params_pkg::ANOTHER_EX; // все параметры в пакете,эти две строчки
|
||||
// могут быть заменены закомментированной
|
||||
// ниже строкой:
|
||||
//import riscv_params_pkg::*;
|
||||
|
||||
endmodule
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
При реализации АЛУ, вам также потребуется использовать [операции сдвига](https://ru.wikipedia.org/wiki/Битовый_сдвиг), к которым относятся:
|
||||
|
||||
- `<<` — логический сдвиг влево
|
||||
- `>>` — логический сдвиг вправо
|
||||
- `>>>` — арифметический сдвиг вправо
|
||||
|
||||
<br><br><br><br><br>
|
||||
|
||||
---
|
||||
|
||||
### Особенности реализации сдвига
|
||||
|
||||
**Для ВСЕХ операций сдвига вы должны брать только 5 младших бит операнда B.**
|
||||
|
||||
Сами посмотрите: пятью битами можно описать 32 комбинации [0-31], а у операнда А будет использоваться ровно 32 бита. **Это обязательное требование**, поскольку старшие биты в дальнейшем будут использоваться по другому назначению и если вы упустите это, ваш будущий процессор станет работать неправильно.
|
||||
|
||||
---
|
||||
|
||||
<br><br><br><br><br>
|
||||
|
||||
## Задание
|
||||
|
||||
Необходимо на языке SystemVerilog реализовать АЛУ в соответствии со следующим прототипом:
|
||||
|
||||
```SystemVerilog
|
||||
|
||||
module аlu_r𝚒sсv (
|
||||
𝚒nput logic [31:0] a_i,
|
||||
𝚒nput logic [31:0] b_i,
|
||||
𝚒nput logic [4:0] alu_op_i,
|
||||
оutput logic flag_o,
|
||||
оutput logic [31:0] result_o
|
||||
);
|
||||
|
||||
import alu_opcodes_pkg::*; // импорт параметров, содержащих
|
||||
// коды операций для АЛУ
|
||||
|
||||
endmodule
|
||||
```
|
||||
|
||||
Для стандартного набора целочисленных операций архитектуры RISC-V требуется выполнять 16 различных операций. Для кодирования 16 операций было бы достаточно 4 бит, но в лабораторной работе предлагается использовать 5-битный код, что связано с особенностями кодирования инструкций (будет рассмотрено в лекциях 6 и 7). Видно, что старший бит кода операции указывает на то, является ли операция вычислительной или это операция сравнения.
|
||||
|
||||
|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 = А ≥ В | Беззнаковое сравнение **≥** |
|
||||
|
||||
**Выражения в этой таблице приведены для примера. Не все из них можно просто переписать — часть этих выражений надо дополнить. Чтобы вы не копировали выражения, в них вставлены неподдерживаемые символы.**
|
||||
|
||||
Обратите внимание на инструкции сравнения. У нас есть две похожие пары инструкций:
|
||||
|
||||
- `LTS`
|
||||
- `LTU`
|
||||
- `SLTS`
|
||||
- `SLTU`
|
||||
|
||||
Первая пара инструкций вычисляет "ветвительный" результат. Результат операции будет подан на выходной сигнал `Flag` и использован непосредственно при ветвлении.
|
||||
|
||||
Вторые две инструкции используются для получения "вычислительного" результата. Т.е. результат сравнения будет подан на выходной сигнал `Result` так же, как подается результат операции `ADD`, и будет использован в неких вычислениях, избегая при этом условного перехода.
|
||||
|
||||
К примеру, нам необходимо пройтись по массиву из миллиона элементов и убедиться, что все они были неотрицательны. Об этом будет сигнализировать переменная `num_of_err`, значение которой должно быть равно числу элементов массива, меньших нуля. Вычислить значение этой переменной можно двумя способами:
|
||||
|
||||
1. В каждой итерации цикла сделать ветвление: в одном случае инкрементировать переменную, в другом случае — нет (для ветвления использовать "ветвительную" операцию `LTS`).
|
||||
2. В каждой итерации цикла складывать текущее значение переменной с результатом "вычислительной" операции `SLTS`.
|
||||
|
||||
Операции ветвления очень сильно влияют (в худшую сторону) на производительность конвейерного процессора. В первом случае мы получим миллион операций ветвления, во втором — ни одной! Разумеется потом переменную `num_of_err` скорее всего сравнят с нулем что приведет к ветвлению, но при вычислении значения этой переменной ветвления можно будет избежать.
|
||||
|
||||
Различие между `SLTS` и `SLTU` (или `LTS` и `LTU`) заключается в том, как мы интерпретируем операнды: как знаковые числа (операции `STLS` и `LTS`) или как беззнаковые (операциии `SLTU` и `LTU`).
|
||||
|
||||
Предположим, мы сравниваем два двоичных числа: `1011` и `0100`. Если интерпретировать эти числа как беззнаковые, то это `11` и `4`, результат: `11 > 4`. Однако если интерпретировать эти числа как знаковые, то теперь это числа `-5` и `4` и в этом случае `-5 < 4`.
|
||||
|
||||
Как мы видим, результат одной и той же операции над одними и теми же двоичными числами может зависеть от того, каким образом мы интерпретируем эти двоичные числа. Для большинства операций в АЛУ это не важно: например, сложение будет работать одинаково в обоих случаях, благодаря свойствам дополнительного кода, а побитовые операции работают с отдельными битами двоичного числа. А вот для операции арифметического сдвига это важно — **операнд А в арифметическом сдвиге должен интерпретироваться как знаковый**.
|
||||
|
||||
По умолчанию SystemVerilog интерпретирует все сигналы как беззнаковые, если мы хотим изменить это поведение, необходимо воспользоваться конструкцией `$signed`.
|
||||
|
||||
Конструкция `$signed` говорит САПР интерпретировать число, переданное в качестве операнда, как знаковое.
|
||||
|
||||
```SystemVerilog
|
||||
аss𝚒gn Rеsult = $s𝚒gnеd(А) >>> В[4:0];
|
||||
```
|
||||
|
||||
В этом примере некоторому сигналу `Result` присваивают результат сдвига знакового числа `A` на значение количества бит получаемых из младших 5 бит сигнала `B`.
|
||||
|
||||
Так как используются не все возможные комбинации управляющего сигнала АЛУ, то **при описании через `case` не забывайте использовать `default`**. Если описать АЛУ как задумано, то получится что-то похожее на картинку ниже. Но не обязательно, зависит от вашего описания.
|
||||
|
||||

|
||||
|
||||
### Порядок выполнения задания
|
||||
|
||||
1. Добавьте в проект файл [`alu_opcodes_pkg.sv`](alu_opcodes_pkg.sv). Этот файл содержит объявление пакета `alu_opcodes_pkg`, в котором прописаны все опкоды АЛУ.
|
||||
2. В `Design Sources` проекта создайте `SystemVerilog`-файл `аlu_r𝚒sсv.sv`.
|
||||
3. Опишите в нем модуль АЛУ с таким же именем и портами, как указано в [задании](#задание).
|
||||
1. Поскольку у вас два выходных сигнала, зависящих от сигнала `alu_op_i`, вам потребуется описать два разных [мультиплексора](../../Basic%20Verilog%20structures/Multiplexors.md) (их лучше всего описывать через два отдельных блока `case`). При описании, используйте `default` на оставшиеся комбинации сигнала `alu_op_i`.
|
||||
2. Следите за разрядностью ваших сигналов.
|
||||
3. Для реализации АЛУ, руководствуйтесь таблицей с операциями, а не схемой в конце задания, которая приведена в качестве референса. Обратите внимание, в одной половине операций `flag_o` должен быть равен нулю, в другой `result_o` (т.е. всегда либо один, либо другой сигнал должен быть равен нулю). Именно поэтому удобней всего будет описывать АЛУ в двух разных блоках `case`.
|
||||
4. Вам не нужно переписывать опкоды из таблицы в качестве вариантов для блока `case`. Вместо этого используйте символьные имена с помощью параметров, импортированных из пакета `alu_opcodes_pkg`.
|
||||
5. При операции сложения вы **должны** использовать ваш 32-битный сумматор из первой лабораторной (описывая вычитание сумматор использовать не надо, можно использовать `-`).
|
||||
1. При подключении сумматора, на входной бит переноса необходимо подать значение `1'b0`. Если не подать значение на входной бит переноса, результат суммы будет не определен (т.к. не определено одно из слагаемых).
|
||||
2. Выходной бит переноса при подключении сумматора можно не указывать, т.к. он использоваться не будет.
|
||||
6. При реализации операций сдвига, руководствуйтесь [особенностями реализации сдвигов](#особенности-реализации-сдвига).
|
||||
4. После реализации модуля АЛУ его нужно будет проверить с помощью тестового окружения.
|
||||
1. Добавьте файл [`tb_miriscv_alu.sv`](tb_miriscv_alu.sv) в `Simulation sources`.
|
||||
2. Для запуска симуляции воспользуйтесь [`этой инструкцией`](../../Vivado%20Basics/Run%20Simulation.md).
|
||||
3. Перед запуском симуляции убедитесь, что в качестве top-level модуля выбран модуль `tb_miriscv_alu`.
|
||||
4. Убедитесь, что симуляция завершена (об этом будет соответствующее сообщение в консоли). По завершению симуляции, в случае отсутствия ошибок, будет выведено сообщение "SUCCESS", в противном случае будут выведены сообщения об этих ошибках.
|
||||
5. В случае, если были найдены ошибки, вы должны найти и исправить их. Для этого руководствуйтесь [документом](../../Vivado%20Basics/Debug%20manual.md).
|
||||
5. Добавьте в проект модуль верхнего уровня ([nexys_alu.sv](board%20files/nexys_alu.sv)), соединяющий АЛУ с периферией в ПЛИС. Описание модуля находится [здесь](board%20files)
|
||||
6. Подключите к проекту файл ограничений ([nexys_a7_100t.xdc](board%20files/nexys_a7_100t.xdc), файл ограничений, добавленный в первой лабораторной содержит другие данные, вам необходимо вставить содержимое файла для текущей лабы).
|
||||
7. Проверьте работу АЛУ в ПЛИС.
|
28
Labs/02. Arithmetic-logic unit/alu_opcodes_pkg.sv
Normal file
28
Labs/02. Arithmetic-logic unit/alu_opcodes_pkg.sv
Normal file
@@ -0,0 +1,28 @@
|
||||
package alu_opcodes_pkg;
|
||||
parameter ALU_OP_WIDTH = 5;
|
||||
|
||||
parameter ALU_ADD = 5'b00000;
|
||||
parameter ALU_SUB = 5'b01000;
|
||||
|
||||
parameter ALU_XOR = 5'b00100;
|
||||
parameter ALU_OR = 5'b00110;
|
||||
parameter ALU_AND = 5'b00111;
|
||||
|
||||
// shifts
|
||||
parameter ALU_SRA = 5'b01101;
|
||||
parameter ALU_SRL = 5'b00101;
|
||||
parameter ALU_SLL = 5'b00001;
|
||||
|
||||
// comparisons
|
||||
parameter ALU_LTS = 5'b11100;
|
||||
parameter ALU_LTU = 5'b11110;
|
||||
parameter ALU_GES = 5'b11101;
|
||||
parameter ALU_GEU = 5'b11111;
|
||||
parameter ALU_EQ = 5'b11000;
|
||||
parameter ALU_NE = 5'b11001;
|
||||
|
||||
// set lower than operations
|
||||
parameter ALU_SLTS = 5'b00010;
|
||||
parameter ALU_SLTU = 5'b00011;
|
||||
|
||||
endpackage
|
23
Labs/02. Arithmetic-logic unit/board files/README.md
Normal file
23
Labs/02. Arithmetic-logic unit/board files/README.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Проверка работы арифметико-логического устройства в ПЛИС
|
||||
|
||||
После того, как вы создали свое АЛУ и проверили его на прохождение тестирующего модуля, вы можете использовать предложенный модуль окружения [`nexys_alu.v`](nexys_alu.v), который позволяет связать вашу логику с периферией, расположенной на плате `Nexys-A7`. Для его подключения, скачайте и добавьте файл в проект, либо скопируйте содержимое в новый `.v` файл вашего проекта. В окне `Sources` нажмите на него ПКМ и выберите `Set as Top`, после чего в иерархии он станет главным, подключив ваш собственный модуль АЛУ. Для того, чтобы дизайн мог физически подключиться к периферии, нужно в проекте выбрать `Add Sources`, `Add or create constraints` и подключить файл [`nexys_a7_100t.xdc`](nexys_a7_100t.xdc). Если у вас уже подключен этот файл, необходимо заменить данные на те, которые предложены в текущей лабе.
|
||||
|
||||
После этого наше устройство будет выглядеть так:
|
||||
|
||||

|
||||
|
||||
Подключенное окружение позволяет производить ввод входных значений (А и В) и управляющего сигнала (ALUOp) с помощью переключателей (номер переключателя отображен на самом краю платы), расположенных на плате. А: 15-11, В: 10-6, ALUOp: 4-0, а переключатель №5 активирует семисегментные индикаторы, на которых отображается на левом блоке операнды А и В, а на правом - ALUOp. На светодиодах, расположенных над переключателями отображается выходное значение в двоичном формате, а 15-й светодиод отвечает за сигнал `Flag`
|
||||
|
||||
Управление АЛУ через плату
|
||||
|
||||

|
||||
|
||||
Для прошивки ПЛИС подключите утройство через USB, включите питание переключателем, выполните синтез и имплементацию вашего дизайна и сгенерируйте битстрим. Если на этом этапе у вас возникают ошибки, постарайтесь исправить из с помощью [`инструкции по работе с ошибками синтеза`](../../../Vivado%20Basics/Synthesis%20failed.md). После этого выберите в левом меню `Open Target` - `Auto Connect`, затем `Program Device` и ваше устройство прошьется.
|
||||
|
||||
Генерация битстрима
|
||||

|
||||
|
||||
Прошивка ПЛИС
|
||||

|
||||
|
||||
Попробуйте выставить на переключателях различные опкоды, такие как сложение, вычитание, сдвиг и сравнения, убедитесь, что все работает исправно и сдавайте работу.
|
211
Labs/02. Arithmetic-logic unit/board files/nexys_a7_100t.xdc
Normal file
211
Labs/02. Arithmetic-logic unit/board files/nexys_a7_100t.xdc
Normal file
@@ -0,0 +1,211 @@
|
||||
## This file is a general .xdc for the Nexys A7-100T
|
||||
## To use it in a project:
|
||||
## - uncomment the lines corresponding to used pins
|
||||
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
|
||||
|
||||
# Clock signal
|
||||
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { CLK100 }]; #IO_L12P_T1_MRCC_35 Sch=clk100mhz
|
||||
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {CLK100}];
|
||||
|
||||
|
||||
#Switches
|
||||
set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { SW[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
|
||||
set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { SW[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
|
||||
set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { SW[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
|
||||
set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { SW[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
|
||||
set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { SW[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4]
|
||||
set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { SW[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5]
|
||||
set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { SW[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6]
|
||||
set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { SW[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7]
|
||||
set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { SW[8] }]; #IO_L24N_T3_34 Sch=sw[8]
|
||||
set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { SW[9] }]; #IO_25_34 Sch=sw[9]
|
||||
set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { SW[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10]
|
||||
set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { SW[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11]
|
||||
set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { SW[12] }]; #IO_L24P_T3_35 Sch=sw[12]
|
||||
set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { SW[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13]
|
||||
set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { SW[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14]
|
||||
set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { SW[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15]
|
||||
|
||||
### LEDs
|
||||
set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { LED[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
|
||||
set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { LED[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
|
||||
set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { LED[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
|
||||
set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { LED[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
|
||||
set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { LED[4] }]; #IO_L7P_T1_D09_14 Sch=led[4]
|
||||
set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { LED[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5]
|
||||
set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { LED[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6]
|
||||
set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { LED[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7]
|
||||
set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { LED[8] }]; #IO_L16N_T2_A15_D31_14 Sch=led[8]
|
||||
set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { LED[9] }]; #IO_L14N_T2_SRCC_14 Sch=led[9]
|
||||
set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { LED[10] }]; #IO_L22P_T3_A05_D21_14 Sch=led[10]
|
||||
set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { LED[11] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=led[11]
|
||||
set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { LED[12] }]; #IO_L16P_T2_CSI_B_14 Sch=led[12]
|
||||
set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { LED[13] }]; #IO_L22N_T3_A04_D20_14 Sch=led[13]
|
||||
set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { LED[14] }]; #IO_L20N_T3_A07_D23_14 Sch=led[14]
|
||||
set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { LED[15] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=led[15]
|
||||
|
||||
## RGB LEDs
|
||||
#set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { LED16_B }]; #IO_L5P_T0_D06_14 Sch=led16_b
|
||||
#set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { LED16_G }]; #IO_L10P_T1_D14_14 Sch=led16_g
|
||||
#set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { LED16_R }]; #IO_L11P_T1_SRCC_14 Sch=led16_r
|
||||
#set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { LED17_B }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=led17_b
|
||||
#set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { LED17_G }]; #IO_0_14 Sch=led17_g
|
||||
#set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { LED17_R }]; #IO_L11N_T1_SRCC_14 Sch=led17_r
|
||||
|
||||
##7 segment display
|
||||
set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { CA }]; #IO_L24N_T3_A00_D16_14 Sch=ca
|
||||
set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { CB }]; #IO_25_14 Sch=cb
|
||||
set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { CC }]; #IO_25_15 Sch=cc
|
||||
set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { CD }]; #IO_L17P_T2_A26_15 Sch=cd
|
||||
set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { CE }]; #IO_L13P_T2_MRCC_14 Sch=ce
|
||||
set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { CF }]; #IO_L19P_T3_A10_D26_14 Sch=cf
|
||||
set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { CG }]; #IO_L4P_T0_D04_14 Sch=cg
|
||||
#set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { DP }]; #IO_L19N_T3_A21_VREF_15 Sch=dp
|
||||
set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { AN[0] }]; #IO_L23P_T3_FOE_B_15 Sch=an[0]
|
||||
set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { AN[1] }]; #IO_L23N_T3_FWE_B_15 Sch=an[1]
|
||||
set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { AN[2] }]; #IO_L24P_T3_A01_D17_14 Sch=an[2]
|
||||
set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { AN[3] }]; #IO_L19P_T3_A22_15 Sch=an[3]
|
||||
set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { AN[4] }]; #IO_L8N_T1_D12_14 Sch=an[4]
|
||||
set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { AN[5] }]; #IO_L14P_T2_SRCC_14 Sch=an[5]
|
||||
set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { AN[6] }]; #IO_L23P_T3_35 Sch=an[6]
|
||||
set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { AN[7] }]; #IO_L23N_T3_A02_D18_14 Sch=an[7]
|
||||
|
||||
##Buttons
|
||||
set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { resetn }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn
|
||||
#set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { BTNC }]; #IO_L9P_T1_DQS_14 Sch=btnc
|
||||
#set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { BTNU }]; #IO_L4N_T0_D05_14 Sch=btnu
|
||||
#set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { BTNL }]; #IO_L12P_T1_MRCC_14 Sch=btnl
|
||||
#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { BTNR }]; #IO_L10N_T1_D15_14 Sch=btnr
|
||||
#set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { BTND }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd
|
||||
|
||||
|
||||
##Pmod Headers
|
||||
##Pmod Header JA
|
||||
#set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { JA[1] }]; #IO_L20N_T3_A19_15 Sch=ja[1]
|
||||
#set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { JA[2] }]; #IO_L21N_T3_DQS_A18_15 Sch=ja[2]
|
||||
#set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { JA[3] }]; #IO_L21P_T3_DQS_15 Sch=ja[3]
|
||||
#set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { JA[4] }]; #IO_L18N_T2_A23_15 Sch=ja[4]
|
||||
#set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { JA[7] }]; #IO_L16N_T2_A27_15 Sch=ja[7]
|
||||
#set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { JA[8] }]; #IO_L16P_T2_A28_15 Sch=ja[8]
|
||||
#set_property -dict { PACKAGE_PIN F18 IOSTANDARD LVCMOS33 } [get_ports { JA[9] }]; #IO_L22N_T3_A16_15 Sch=ja[9]
|
||||
#set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { JA[10] }]; #IO_L22P_T3_A17_15 Sch=ja[10]
|
||||
|
||||
##Pmod Header JB
|
||||
#set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { JB[1] }]; #IO_L1P_T0_AD0P_15 Sch=jb[1]
|
||||
#set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { JB[2] }]; #IO_L14N_T2_SRCC_15 Sch=jb[2]
|
||||
#set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { JB[3] }]; #IO_L13N_T2_MRCC_15 Sch=jb[3]
|
||||
#set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { JB[4] }]; #IO_L15P_T2_DQS_15 Sch=jb[4]
|
||||
#set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { JB[7] }]; #IO_L11N_T1_SRCC_15 Sch=jb[7]
|
||||
#set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports { JB[8] }]; #IO_L5P_T0_AD9P_15 Sch=jb[8]
|
||||
#set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { JB[9] }]; #IO_0_15 Sch=jb[9]
|
||||
#set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { JB[10] }]; #IO_L13P_T2_MRCC_15 Sch=jb[10]
|
||||
|
||||
##Pmod Header JC
|
||||
#set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { JC[1] }]; #IO_L23N_T3_35 Sch=jc[1]
|
||||
#set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { JC[2] }]; #IO_L19N_T3_VREF_35 Sch=jc[2]
|
||||
#set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { JC[3] }]; #IO_L22N_T3_35 Sch=jc[3]
|
||||
#set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { JC[4] }]; #IO_L19P_T3_35 Sch=jc[4]
|
||||
#set_property -dict { PACKAGE_PIN E7 IOSTANDARD LVCMOS33 } [get_ports { JC[7] }]; #IO_L6P_T0_35 Sch=jc[7]
|
||||
#set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports { JC[8] }]; #IO_L22P_T3_35 Sch=jc[8]
|
||||
#set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { JC[9] }]; #IO_L21P_T3_DQS_35 Sch=jc[9]
|
||||
#set_property -dict { PACKAGE_PIN E6 IOSTANDARD LVCMOS33 } [get_ports { JC[10] }]; #IO_L5P_T0_AD13P_35 Sch=jc[10]
|
||||
|
||||
##Pmod Header JD
|
||||
#set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { JD[1] }]; #IO_L21N_T3_DQS_35 Sch=jd[1]
|
||||
#set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports { JD[2] }]; #IO_L17P_T2_35 Sch=jd[2]
|
||||
#set_property -dict { PACKAGE_PIN G1 IOSTANDARD LVCMOS33 } [get_ports { JD[3] }]; #IO_L17N_T2_35 Sch=jd[3]
|
||||
#set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { JD[4] }]; #IO_L20N_T3_35 Sch=jd[4]
|
||||
#set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { JD[7] }]; #IO_L15P_T2_DQS_35 Sch=jd[7]
|
||||
#set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { JD[8] }]; #IO_L20P_T3_35 Sch=jd[8]
|
||||
#set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { JD[9] }]; #IO_L15N_T2_DQS_35 Sch=jd[9]
|
||||
#set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { JD[10] }]; #IO_L13N_T2_MRCC_35 Sch=jd[10]
|
||||
|
||||
##Pmod Header JXADC
|
||||
#set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVCMOS33 } [get_ports { XA_N[1] }]; #IO_L9N_T1_DQS_AD3N_15 Sch=xa_n[1]
|
||||
#set_property -dict { PACKAGE_PIN A13 IOSTANDARD LVCMOS33 } [get_ports { XA_P[1] }]; #IO_L9P_T1_DQS_AD3P_15 Sch=xa_p[1]
|
||||
#set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVCMOS33 } [get_ports { XA_N[2] }]; #IO_L8N_T1_AD10N_15 Sch=xa_n[2]
|
||||
#set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVCMOS33 } [get_ports { XA_P[2] }]; #IO_L8P_T1_AD10P_15 Sch=xa_p[2]
|
||||
#set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVCMOS33 } [get_ports { XA_N[3] }]; #IO_L7N_T1_AD2N_15 Sch=xa_n[3]
|
||||
#set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVCMOS33 } [get_ports { XA_P[3] }]; #IO_L7P_T1_AD2P_15 Sch=xa_p[3]
|
||||
#set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { XA_N[4] }]; #IO_L10N_T1_AD11N_15 Sch=xa_n[4]
|
||||
#set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 } [get_ports { XA_P[4] }]; #IO_L10P_T1_AD11P_15 Sch=xa_p[4]
|
||||
|
||||
##VGA Connector
|
||||
#set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[0] }]; #IO_L8N_T1_AD14N_35 Sch=vga_r[0]
|
||||
#set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[1] }]; #IO_L7N_T1_AD6N_35 Sch=vga_r[1]
|
||||
#set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[2] }]; #IO_L1N_T0_AD4N_35 Sch=vga_r[2]
|
||||
#set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[3] }]; #IO_L8P_T1_AD14P_35 Sch=vga_r[3]
|
||||
#set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[0] }]; #IO_L1P_T0_AD4P_35 Sch=vga_g[0]
|
||||
#set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=vga_g[1]
|
||||
#set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[2] }]; #IO_L2N_T0_AD12N_35 Sch=vga_g[2]
|
||||
#set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[3] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=vga_g[3]
|
||||
#set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[0] }]; #IO_L2P_T0_AD12P_35 Sch=vga_b[0]
|
||||
#set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[1] }]; #IO_L4N_T0_35 Sch=vga_b[1]
|
||||
#set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[2] }]; #IO_L6N_T0_VREF_35 Sch=vga_b[2]
|
||||
#set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[3] }]; #IO_L4P_T0_35 Sch=vga_b[3]
|
||||
#set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { VGA_HS }]; #IO_L4P_T0_15 Sch=vga_hs
|
||||
#set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { VGA_VS }]; #IO_L3N_T0_DQS_AD1N_15 Sch=vga_vs
|
||||
|
||||
##Micro SD Connector
|
||||
#set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { SD_RESET }]; #IO_L14P_T2_SRCC_35 Sch=sd_reset
|
||||
#set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { SD_CD }]; #IO_L9N_T1_DQS_AD7N_35 Sch=sd_cd
|
||||
#set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { SD_SCK }]; #IO_L9P_T1_DQS_AD7P_35 Sch=sd_sck
|
||||
#set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { SD_CMD }]; #IO_L16N_T2_35 Sch=sd_cmd
|
||||
#set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[0] }]; #IO_L16P_T2_35 Sch=sd_dat[0]
|
||||
#set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[1] }]; #IO_L18N_T2_35 Sch=sd_dat[1]
|
||||
#set_property -dict { PACKAGE_PIN F1 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[2] }]; #IO_L18P_T2_35 Sch=sd_dat[2]
|
||||
#set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[3] }]; #IO_L14N_T2_SRCC_35 Sch=sd_dat[3]
|
||||
|
||||
##Accelerometer
|
||||
#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { ACL_MISO }]; #IO_L11P_T1_SRCC_15 Sch=acl_miso
|
||||
#set_property -dict { PACKAGE_PIN F14 IOSTANDARD LVCMOS33 } [get_ports { ACL_MOSI }]; #IO_L5N_T0_AD9N_15 Sch=acl_mosi
|
||||
#set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { ACL_SCLK }]; #IO_L14P_T2_SRCC_15 Sch=acl_sclk
|
||||
#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { ACL_CSN }]; #IO_L12P_T1_MRCC_15 Sch=acl_csn
|
||||
#set_property -dict { PACKAGE_PIN B13 IOSTANDARD LVCMOS33 } [get_ports { ACL_INT[1] }]; #IO_L2P_T0_AD8P_15 Sch=acl_int[1]
|
||||
#set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { ACL_INT[2] }]; #IO_L20P_T3_A20_15 Sch=acl_int[2]
|
||||
|
||||
##Temperature Sensor
|
||||
#set_property -dict { PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports { TMP_SCL }]; #IO_L1N_T0_AD0N_15 Sch=tmp_scl
|
||||
#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { TMP_SDA }]; #IO_L12N_T1_MRCC_15 Sch=tmp_sda
|
||||
#set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 } [get_ports { TMP_INT }]; #IO_L6N_T0_VREF_15 Sch=tmp_int
|
||||
#set_property -dict { PACKAGE_PIN B14 IOSTANDARD LVCMOS33 } [get_ports { TMP_CT }]; #IO_L2N_T0_AD8N_15 Sch=tmp_ct
|
||||
|
||||
##Omnidirectional Microphone
|
||||
#set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { M_CLK }]; #IO_25_35 Sch=m_clk
|
||||
#set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { M_DATA }]; #IO_L24N_T3_35 Sch=m_data
|
||||
#set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS33 } [get_ports { M_LRSEL }]; #IO_0_35 Sch=m_lrsel
|
||||
|
||||
##PWM Audio Amplifier
|
||||
#set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { AUD_PWM }]; #IO_L4N_T0_15 Sch=aud_pwm
|
||||
#set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { AUD_SD }]; #IO_L6P_T0_15 Sch=aud_sd
|
||||
|
||||
##USB-RS232 Interface
|
||||
#set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { UART_TXD_IN }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
|
||||
#set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { UART_RXD_OUT }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out
|
||||
#set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { UART_CTS }]; #IO_L12N_T1_MRCC_35 Sch=uart_cts
|
||||
#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { UART_RTS }]; #IO_L5N_T0_AD13N_35 Sch=uart_rts
|
||||
|
||||
##USB HID (PS/2)
|
||||
#set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { PS2_CLK }]; #IO_L13P_T2_MRCC_35 Sch=ps2_clk
|
||||
#set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { PS2_DATA }]; #IO_L10N_T1_AD15N_35 Sch=ps2_data
|
||||
|
||||
##SMSC Ethernet PHY
|
||||
#set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports { ETH_MDC }]; #IO_L11P_T1_SRCC_16 Sch=eth_mdc
|
||||
#set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { ETH_MDIO }]; #IO_L14N_T2_SRCC_16 Sch=eth_mdio
|
||||
#set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { ETH_RSTN }]; #IO_L10P_T1_AD15P_35 Sch=eth_rstn
|
||||
#set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports { ETH_CRSDV }]; #IO_L6N_T0_VREF_16 Sch=eth_crsdv
|
||||
#set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { ETH_RXERR }]; #IO_L13N_T2_MRCC_16 Sch=eth_rxerr
|
||||
#set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { ETH_RXD[0] }]; #IO_L13P_T2_MRCC_16 Sch=eth_rxd[0]
|
||||
#set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { ETH_RXD[1] }]; #IO_L19N_T3_VREF_16 Sch=eth_rxd[1]
|
||||
#set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports { ETH_TXEN }]; #IO_L11N_T1_SRCC_16 Sch=eth_txen
|
||||
#set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { ETH_TXD[0] }]; #IO_L14P_T2_SRCC_16 Sch=eth_txd[0]
|
||||
#set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { ETH_TXD[1] }]; #IO_L12N_T1_MRCC_16 Sch=eth_txd[1]
|
||||
#set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { ETH_REFCLK }]; #IO_L11P_T1_SRCC_35 Sch=eth_refclk
|
||||
#set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { ETH_INTN }]; #IO_L12P_T1_MRCC_16 Sch=eth_intn
|
||||
|
||||
##Quad SPI Flash
|
||||
#set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[0] }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0]
|
||||
#set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[1] }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1]
|
||||
#set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[2] }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2]
|
||||
#set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[3] }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3]
|
||||
#set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { QSPI_CSN }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_csn
|
96
Labs/02. Arithmetic-logic unit/board files/nexys_alu.sv
Normal file
96
Labs/02. Arithmetic-logic unit/board files/nexys_alu.sv
Normal file
@@ -0,0 +1,96 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module nexys_alu(
|
||||
input CLK100,
|
||||
input resetn,
|
||||
input [15:0] SW,
|
||||
output [15:0] LED,
|
||||
output CA, CB, CC, CD, CE, CF, CG,
|
||||
output [7:0] AN
|
||||
);
|
||||
import alu_opcodes_pkg::*;
|
||||
wire [4:0] operator_i;
|
||||
wire [31:0] operand_a_i;
|
||||
wire [31:0] operand_b_i;
|
||||
|
||||
wire [31:0] result_o;
|
||||
wire comparison_result_o;
|
||||
|
||||
localparam pwm = 1000;
|
||||
reg [9:0] counter;
|
||||
reg [3:0] semseg;
|
||||
reg [7:0] ANreg;
|
||||
reg CAr, CBr, CCr, CDr, CEr, CFr, CGr;
|
||||
reg [15:0] LEDr;
|
||||
reg minus;
|
||||
|
||||
alu_riscv DUT
|
||||
(
|
||||
.ALUOp (operator_i),
|
||||
.A (operand_a_i),
|
||||
.B (operand_b_i),
|
||||
|
||||
.Result (result_o),
|
||||
.Flag (comparison_result_o)
|
||||
);
|
||||
|
||||
assign operator_i = SW[4:0];
|
||||
assign operand_b_i = {{28{SW[10]}},SW[9:6]};
|
||||
assign operand_a_i = {{28{SW[15]}},SW[14:11]};
|
||||
|
||||
assign LED[15:0] = LEDr[15:0];
|
||||
|
||||
assign AN[7:0] = ANreg[7:0];
|
||||
assign {CA, CB, CC, CD, CE, CF, CG} = {CAr, CBr, CCr, CDr, CEr, CFr, CGr};
|
||||
|
||||
initial ANreg[7:0] = 8'b11111110;
|
||||
|
||||
always @(posedge CLK100) begin
|
||||
if (!resetn) begin
|
||||
LEDr[15:0] <= 'b0;
|
||||
counter <= 'b0;
|
||||
ANreg[7:0] <= 8'b11111111;
|
||||
{CAr, CBr, CCr, CDr, CEr, CFr, CGr} <= 7'b1111111;
|
||||
end
|
||||
else begin
|
||||
LEDr[14:0] <= result_o[14:0];
|
||||
LEDr[15] <= comparison_result_o;
|
||||
if (counter < pwm) counter = counter + 'b1;
|
||||
else begin
|
||||
counter = 'b0;
|
||||
ANreg[1] <= ANreg[0];
|
||||
ANreg[2] <= ANreg[1];
|
||||
ANreg[3] <= ANreg[2];
|
||||
ANreg[4] <= ANreg[3];
|
||||
ANreg[5] <= ANreg[4];
|
||||
ANreg[6] <= ANreg[5];
|
||||
ANreg[7] <= ANreg[6];
|
||||
ANreg[0] <= !(SW[5] && (ANreg[6:0] == 7'b1111111));
|
||||
end
|
||||
case (1'b0)
|
||||
ANreg[0]: semseg <= result_o[31] ? ( ~result_o + 1 ) % 4'd10: (result_o ) % 4'd10;
|
||||
ANreg[1]: semseg <= result_o[31] ? ((~result_o + 1) / 'd10 ) % 4'd10: (result_o / 'd10 ) % 4'd10;
|
||||
ANreg[2]: semseg <= result_o[31] ? ((~result_o + 1) / 'd100 ) % 4'd10: (result_o / 'd100 ) % 4'd10;
|
||||
ANreg[3]: semseg <= result_o[31] ? ((~result_o + 1) / 'd1000) % 4'd10: (result_o / 'd1000) % 4'd10;
|
||||
ANreg[4]: semseg <= operand_b_i[31] ? ( ~operand_b_i + 1 ) % 4'd10: (operand_b_i ) % 4'd10;
|
||||
ANreg[5]: semseg <= operand_b_i[31] ? ((~operand_b_i + 1) / 'd10) % 4'd10: (operand_b_i / 'd10) % 4'd10;
|
||||
ANreg[6]: semseg <= operand_a_i[31] ? ( ~operand_a_i + 1 ) % 4'd10: (operand_a_i ) % 4'd10;
|
||||
ANreg[7]: semseg <= operand_a_i[31] ? ((~operand_a_i + 1) / 'd10) % 4'd10: (operand_a_i / 'd10) % 4'd10;
|
||||
endcase
|
||||
minus <= (operator_i == ALU_ADD || operator_i == ALU_SUB || operator_i == ALU_SLTS || operator_i == ALU_SRA || operator_i == ALU_LTS || operator_i == ALU_GES);
|
||||
case (semseg)
|
||||
4'd0: {CAr, CBr, CCr, CDr, CEr, CFr, CGr} <= (((!ANreg[5] & operand_b_i[31]) || (!ANreg[7] & operand_a_i[31]) || (!ANreg[3] & result_o[31])) && minus) ? 7'b1111110: 7'b0000001;
|
||||
4'd1: {CAr, CBr, CCr, CDr, CEr, CFr, CGr} <= (((!ANreg[5] & operand_b_i[31]) || (!ANreg[7] & operand_a_i[31]) || (!ANreg[3] & result_o[31])) && minus) ? 7'b1001110: 7'b1001111;
|
||||
4'd2: {CAr, CBr, CCr, CDr, CEr, CFr, CGr} <= 7'b0010010;
|
||||
4'd3: {CAr, CBr, CCr, CDr, CEr, CFr, CGr} <= 7'b0000110;
|
||||
4'd4: {CAr, CBr, CCr, CDr, CEr, CFr, CGr} <= 7'b1001100;
|
||||
4'd5: {CAr, CBr, CCr, CDr, CEr, CFr, CGr} <= 7'b0100100;
|
||||
4'd6: {CAr, CBr, CCr, CDr, CEr, CFr, CGr} <= 7'b0100000;
|
||||
4'd7: {CAr, CBr, CCr, CDr, CEr, CFr, CGr} <= 7'b0001111;
|
||||
4'd8: {CAr, CBr, CCr, CDr, CEr, CFr, CGr} <= 7'b0000000;
|
||||
4'd9: {CAr, CBr, CCr, CDr, CEr, CFr, CGr} <= 7'b0000100;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
10104
Labs/02. Arithmetic-logic unit/tb_miriscv_alu.sv
Normal file
10104
Labs/02. Arithmetic-logic unit/tb_miriscv_alu.sv
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user