Merge branch 'MPSU:master' into master

This commit is contained in:
Mikhail Popov
2023-09-29 03:01:49 +03:00
committed by GitHub
57 changed files with 8358 additions and 11018 deletions

56
.github/SUMMARY.md vendored Normal file
View File

@@ -0,0 +1,56 @@
# Summary
[Порядок выполнения лабораторных работ для групп](index.md)
[Что такое Язык Описания Аппаратуры](Introduction/What%20is%20HDL.md)
[Как работает ПЛИС](Introduction/How%20FPGA%20works.md)
---
# Цикл лабораторных работ
- [Лабораторная №1. Сумматор](Labs/01.%20Adder/README.md)
- [Лабораторная №2. АЛУ](Labs/02.%20Arithmetic-logic%20unit/README.md)
- [Лабораторная №3. Регистровый файл и внешняя память](Labs/03.%20Register%20file%20and%20memory/README.md)
- [Лабораторная №4. Простейшее программируемое устройство](Labs/04.%20Primitive%20programmable%20device/README.md)
- [Лабораторная №5. Основной дешифратор](Labs/05.%20Main%20decoder/README.md)
- [Лабораторная №6. Тракт данных](Labs/06.%20Datapath/README.md)
- [Лабораторная №7. Внешняя память]()
- [Лабораторная №8. Блок загрузки и сохранения](Labs/08.%20Load-store%20unit/README.md)
- [Лабораторная №9. Интеграция LSU](Labs/09.%20LSU%20Integration/README.md)
- [Лабораторная №10. Подсистема прерываний](Labs/10.%20Interrupt%20subsystem/README.md)
- [Лабораторная №11. Интеграция подсистемы прерываний](Labs/11.%20Interrupt%20integration/README.md)
- [Лабораторная №12. Периферийные устройства](Labs/12.%20Peripheral%20units/README.md)
- [Лабораторная №13. Программирование](Labs/13.%20Programming/README.md)
---
# Базовые структуры языка SystemVerilog
- [Модули](Basic%20Verilog%20structures/Modules.md)
- [Мультиплексоры](Basic%20Verilog%20structures/Multiplexors.md)
- [Регистры](Basic%20Verilog%20structures/Registers.md)
- [Конкатенация](Basic%20Verilog%20structures/Concatenation.md)
- [Контроллеры](Basic%20Verilog%20structures/Controllers.md)
- [Тестовое окружение](Basic%20Verilog%20structures/Testbench.md)
---
# Основы Vivado
- [Руководство по установке Vivado](Vivado%20Basics/Install%20Vivado.md)
- [Создание проекта в Vivado](Vivado%20Basics/Vivado%20trainer.md)
- [Структура директорий в проекте Vivado](Vivado%20Basics/Folder%20Structure%20In%20The%20Project.md)
- [Как сгенерировать схему](Vivado%20Basics/How%20to%20open%20a%20schematic.md)
- [Ошибки элаборации](Vivado%20Basics/Elaboration%20failed.md)
- [Шаги имплементации](Vivado%20Basics/Implementation%20steps.md)
- [Запуск симуляции](Vivado%20Basics/Run%20Simulation.md)
- [Руководство по поиску ошибок](Vivado%20Basics/Debug%20manual.md)
- [Руководство по прошивке ПЛИС](Vivado%20Basics/Program%20nexys%20a7.md)
- [Заголовочные файлы в Verilog](Vivado%20Basics/Verilog%20Header.md)
- [Как добавить файл, инициализирующий память](Vivado%20Basics/How%20to%20add%20a%20mem-file.md)
# Остальное
- [RV32I - Стандартный набор целочисленных инструкций RISC-V](Other/rv32i.md)
- [Список типичных ошибок при работе с Vivado и SystemVerilog](Other/FAQ.md)
- [Студенческий сервер](Other/Students%20server.md)

6
.github/book.toml vendored Normal file
View File

@@ -0,0 +1,6 @@
[book]
authors = ["Andrei Solodovnikov"]
language = "ru"
multilingual = true
src = "./"
title = "Архитектуры процессорных систем"

49
.github/index.md vendored Normal file
View File

@@ -0,0 +1,49 @@
# Курс лабораторных работ
## Полезное
- [Студенческий сервер](Other/Students%20server.md)
- [Создание базового проекта с прошивкой ПЛИС в Vivado](Vivado%20Basics/Vivado%20trainer.md)
- [Базовые конструкции Verilog](Basic%20Verilog%20structures/)
- [Список типичных ошибок в Vivado и SystemVerilog](Other/FAQ.md)
- [Тестовое окружение](Basic%20Verilog%20structures/Testbench.md)
## Порядок выполнения лабораторных работ для групп
### ИБ, ИКТ, КТ, РТ
1. Сумматор ([01. Adder](Labs/01.%20Adder))
2. АЛУ ([02. Arithmetic-logic unit](Labs/02.%20Arithmetic-logic%20unit))
3. Регистровый файл и внешняя память ([03. Register file and memory](Labs/03.%20Register%20file%20and%20memory))
4. Простейшее программируемое устройство ([04. Primitive programmable device](Labs/04.%20Primitive%20programmable%20device))
### ПИН, ПМ
1. Сумматор ([01. Adder](Labs/01.%20Adder))
2. АЛУ ([02. Arithmetic-logic unit](Labs/02.%20Arithmetic-logic%20unit))
3. Регистровый файл и внешняя память ([03. Register file and memory](Labs/03.%20Register%20file%20and%20memory))
4. Простейшее программируемое устройство ([04. Primitive programmable device](Labs/04.%20Primitive%20programmable%20device))
5. Основной дешифратор ([05. Main decoder](Labs/05.%20Main%20decoder))
6.
1. Тракт данных ([06. Datapath](Labs/06.%20Datapath))
2. Интеграция блока загрузки и сохранения ([09. LSU Integration](Labs/09.%20LSU%20Integration))
3. Интеграция подсистемы прерываний ([11. Interrupt Integration](Labs/11.%20Interrupt%20integration))
7. Периферийные устройства ([12. Peripheral units](Labs/12.%20Peripheral%20units))
8. Программирование ([13. Programming](Labs/13.%20Programming))
### ИВТ
1. АЛУ ([02. Arithmetic-logic unit](Labs/02.%20Arithmetic-logic%20unit))
2.
1. Память ([03. Register file and memory](Labs/03.%20Register%20file%20and%20memory)),
2. Простейшее программируемое устройство ([04. Primitive programmable device](Labs/04.%20Primitive%20programmable%20device))
3. Основной дешифратор ([05. Main decoder](Labs/05.%20Main%20decoder))
4. Тракт данных ([06. Datapath](Labs/06.%20Datapath))
5.
1. Модуль загрузки и сохранения ([08. Load-store unit](Labs/08.%20Load-store%20unit))
2. Интеграция блока загрузки и сохранения ([09. LSU Integration](Labs/09.%20LSU%20Integration))
6.
1. Контроллер прерываний ([10. Interrupt subsystem](Labs/10.%20Interrupt%20subsystem))
2. Интеграция подсистемы прерываний ([11. Interrupt Integration](Labs/11.%20Interrupt%20integration))
7. Периферийные устройства ([12. Peripheral units](Labs/12.%20Peripheral%20units))
8. Программирование ([13. Programming](Labs/13.%20Programming))

4
.github/prepare.sh vendored Normal file
View File

@@ -0,0 +1,4 @@
#!/bin/bash
mkdir src
cp .github/book.toml .github/SUMMARY.md .github/index.md ./

62
.github/workflows/mdbook.yml vendored Normal file
View File

@@ -0,0 +1,62 @@
# Sample workflow for building and deploying a mdBook site to GitHub Pages
#
# To get started with mdBook see: https://rust-lang.github.io/mdBook/index.html
#
name: Deploy mdBook site to Pages
on:
# Runs on pushes targeting the default branch
push:
branches: ["master"]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
# Build job
build:
runs-on: ubuntu-latest
env:
MDBOOK_VERSION: 0.4.21
steps:
- uses: actions/checkout@v3
- name: Install mdBook
run: |
chmod +x .github/prepare.sh
.github/prepare.sh
mkdir bin
curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.34/mdbook-v0.4.34-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin
bin/mdbook build
- name: Setup Pages
id: pages
uses: actions/configure-pages@v3
- name: Build with mdBook
run: bin/mdbook build
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
with:
path: ./book
# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

After

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -2,7 +2,7 @@
Для того, чтобы лучше понять, что от вас требуется в рамках лабораторной работы по периферийным устройствам, рассмотрим процесс разработки структурной схемы (не SystemVerilog-описания) для контроллера светодиодов. Для того, чтобы лучше понять, что от вас требуется в рамках лабораторной работы по периферийным устройствам, рассмотрим процесс разработки структурной схемы (не SystemVerilog-описания) для контроллера светодиодов.
В первую очередь, здесь будет продублирована выдержка из спецификации на этот контроллер (общая часть раздела "[Описание контроллеров периферийных устройств](../../Labs/7.%20Peripheral%20units/README.md#описание-контроллеров-периферийных-устройств)", а также подраздел "[Светодиоды](../../Labs/7.%20Peripheral%20units/README.md#светодиоды)"): В первую очередь, здесь будет продублирована выдержка из спецификации на этот контроллер (общая часть раздела "[Описание контроллеров периферийных устройств](../Labs/12.%20Peripheral%20units/README.md#описание-контроллеров-периферийных-устройств)", а также подраздел "[Светодиоды](../Labs/12.%20Peripheral%20units/README.md#светодиоды)"):
## Спецификация контроллера ## Спецификация контроллера
@@ -28,7 +28,7 @@
В случае отсутствия **запроса на чтения**, на выход `read_data_o` должно подаваться значение `32'hfa11_1eaf`. Это никак не повлияет на работу процессора, но будет удобно в процессе отладки на временной диаграмме (тоже самое было сделано в процессе разработки памяти данных). В случае отсутствия **запроса на чтения**, на выход `read_data_o` должно подаваться значение `32'hfa11_1eaf`. Это никак не повлияет на работу процессора, но будет удобно в процессе отладки на временной диаграмме (тоже самое было сделано в процессе разработки памяти данных).
Если пришел **запрос на запись** или **чтение**, это еще не значит, что контроллер должен его выполнить. В случае, если запрос происходит по адресу, не поддерживающему этот запрос (например **запрос на запись** по адресу поддерживающему только чтение или наоборот), данный запрос должен игнорироваться, а на выходе `read_data_o` должно появиться значение `32'hdead_beef`. Если пришел **запрос на запись** или **чтение**, это еще не значит, что контроллер должен его выполнить. В случае, если запрос происходит по адресу, не поддерживающему этот запрос (например **запрос на запись** по адресу поддерживающему только чтение), данный запрос должен игнорироваться. В случае **запроса на чтение** по недоступному адресу, на выходе `read_data_o` должно появиться значение `32'hdead_beef`.
К примеру, в случае запроса на чтение по адресу `0x0100004` (четвертый байт в адресном пространстве периферийного устройства "переключатели"), на выходе `read_data_o` должно оказаться значение `32'hdead_beef`. В случае отсутствия запроса на чтение (`req_i == 0` или `write_enable_i == 1`), на выходе `read_data_o` контроллера переключателей должно оказаться значение `32'hfa11_1eaf`. К примеру, в случае запроса на чтение по адресу `0x0100004` (четвертый байт в адресном пространстве периферийного устройства "переключатели"), на выходе `read_data_o` должно оказаться значение `32'hdead_beef`. В случае отсутствия запроса на чтение (`req_i == 0` или `write_enable_i == 1`), на выходе `read_data_o` контроллера переключателей должно оказаться значение `32'hfa11_1eaf`.

View File

@@ -124,7 +124,7 @@ end
```SystemVerilog ```SystemVerilog
logic Y; logic Y;
always @(*) begin always_comb begin
case(S) // Описываем блок case, где значение сигнала S case(S) // Описываем блок case, где значение сигнала S
// будет сравниваться с различными возможными его значениями // будет сравниваться с различными возможными его значениями
1'b0: Y <= D0; // Если S==0, то Y = D0 1'b0: Y <= D0; // Если S==0, то Y = D0

View File

@@ -4,20 +4,20 @@
После этого наше устройство будет выглядеть так: После этого наше устройство будет выглядеть так:
![../../../.pic/Labs/board%20files/board%20files/nexys_adder1.png](../../../.pic/Labs/board%20files/board%20files/nexys_adder1.png) ![../../../.pic/Labs/board%20files/nexys_adder1.png](../../../.pic/Labs/board%20files/nexys_adder1.png)
Подключенное окружение позволяет производить ввод входных значений (А, В и Pin) с помощью переключателей (номер переключателя отображен на самом краю платы), расположенных на плате. Операнд А задается переключателями 15-8, В: 7-0, Pin: тактовая кнопка BTND (нижняя из 5-ти, расположенных вместе в форме крестовины). Семисегментные индикаторы в шестнадцатиричном формате отображают на левом блоке слагаемые А и В, а на правом - результат сложения. На светодиодах, расположенных над переключателями отображается результат в двоичном формате. Подключенное окружение позволяет производить ввод входных значений (А, В и Pin) с помощью переключателей (номер переключателя отображен на самом краю платы), расположенных на плате. Операнд А задается переключателями 15-8, В: 7-0, Pin: тактовая кнопка BTND (нижняя из 5-ти, расположенных вместе в форме крестовины). Семисегментные индикаторы в шестнадцатиричном формате отображают на левом блоке слагаемые А и В, а на правом - результат сложения. На светодиодах, расположенных над переключателями отображается результат в двоичном формате.
Управление сумматором через плату Управление сумматором через плату
![../../../.pic/Labs/board%20files/board%20files/nexys_adder2.png](../../../.pic/Labs/board%20files/board%20files/nexys_adder2.png) ![../../../.pic/Labs/board%20files/nexys_adder2.png](../../../.pic/Labs/board%20files/nexys_adder2.png)
Для прошивки ПЛИС подключите утройство через USB, включите питание переключателем, выполните синтез и имплементацию вашего дизайна и сгенерируйте битстрим. Если на этом этапе у вас возникают ошибки, постарайтесь исправить из с помощью [`инструкции по работе с ошибками синтеза`](../../../Vivado%20Basics/Elaboration%20failed.md). После этого выберите в левом меню `Open Target` - `Auto Connect`, затем `Program Device` и ваше устройство прошьется. Для прошивки ПЛИС подключите утройство через USB, включите питание переключателем, выполните синтез и имплементацию вашего дизайна и сгенерируйте битстрим. Если на этом этапе у вас возникают ошибки, постарайтесь исправить из с помощью [`инструкции по работе с ошибками синтеза`](../../../Vivado%20Basics/Elaboration%20failed.md). После этого выберите в левом меню `Open Target` - `Auto Connect`, затем `Program Device` и ваше устройство прошьется.
Генерация битстрима Генерация битстрима
![../../../.pic/Labs/board%20files/board%20files/Program_Device1.png](../../../.pic/Labs/board%20files/board%20files/Program_Device1.png) ![../../../.pic/Labs/board%20files/Program_Device1.png](../../../.pic/Labs/board%20files/Program_Device1.png)
Прошивка ПЛИС Прошивка ПЛИС
![../../../.pic/Labs/board%20files/board%20files/Program_Device2.png](../../../.pic/Labs/board%20files/board%20files/Program_Device2.png) ![../../../.pic/Labs/board%20files/Program_Device2.png](../../../.pic/Labs/board%20files/Program_Device2.png)
Попробуйте выставить на переключателях различные слагаемые, убедитесь, что все работает исправно и сдавайте работу. Попробуйте выставить на переключателях различные слагаемые, убедитесь, что все работает исправно и сдавайте работу.

View File

@@ -30,12 +30,12 @@ reg [15:0] LEDr;
fulladder32 DUT fulladder32 DUT
( (
.A (A), .a_i (A),
.B (B), .b_i (B),
.Pin (Pin), .carry_i (Pin),
.S (S), .sum_o (S),
.Pout (Pout) .carry_o (Pout)
); );
assign B = {24'b0,SW[7:0]}; assign B = {24'b0,SW[7:0]};
@@ -127,4 +127,4 @@ always @(posedge CLK100) begin
end end
end end
endmodule endmodule

View File

@@ -20,7 +20,7 @@
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
module tb_fulladder32(); module tb_fulladder32();
`define __debug__
parameter TIME_OPERATION = 100; parameter TIME_OPERATION = 100;
parameter TEST_VALUES = 3000; parameter TEST_VALUES = 3000;

View File

@@ -32,11 +32,11 @@
На рис. 1 изображен пример АЛУ, используемый в книге "Цифровая схемотехника и архитектура компьютера" Харрис и Харрис. На входы `A` и `B` поступают операнды с разрядностью *N*. На трехбитный вход `F` подается код операции. Например, если туда подать `000`, то на выходе `Y` появится результат операции *логическое И* между битами операндов `A` и `B`. Если на `F` подать `010`, то на выходе появится результат сложения. Это лишь пример, разрядность и коды могут отличаться в зависимости от количества выполняемых операций и архитектуры. На рис. 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*-битное число, дополняя нулями слева. Рассмотрим на примере все того же АЛУ 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)). К одному из входов этих операционных устройств подключен `A` без изменений, а ко второму подключен выход двухвходового мультиплексора, управляемого оставшимся битом *F*. То есть `F[2]` определяет, что будет вторым операндом: `B` или `~B`. Вдобавок `F[2]` подается на входной перенос сумматора, то есть, когда `F[2] == 1` на выходе сумматора появляется результат операции `A + ~B + 1`, что (с учетом [дополнительного кода](https://ru.wikipedia.org/wiki/Дополнительный_код)) эквивалентно `A  B`.
![../../.pic/Labs/lab_02_alu/fig_02.png](../../.pic/Labs/lab_02_alu/fig_02.png) ![../../.pic/Labs/lab_02_alu/fig_02.png](../../.pic/Labs/lab_02_alu/fig_02.png)

View File

@@ -4,20 +4,20 @@
После этого наше устройство будет выглядеть так: После этого наше устройство будет выглядеть так:
![../../../.pic/Labs/board%20files/board%20files/alu_9.png](../../../.pic/Labs/board%20files/board%20files/alu_9.png) ![../../../.pic/Labs/board%20files/alu_9.png](../../../.pic/Labs/board%20files/alu_9.png)
Подключенное окружение позволяет производить ввод входных значений (А и В) и управляющего сигнала (ALUOp) с помощью переключателей (номер переключателя отображен на самом краю платы), расположенных на плате. А: 15-11, В: 10-6, ALUOp: 4-0, а переключатель №5 активирует семисегментные индикаторы, на которых отображается на левом блоке операнды А и В, а на правом - ALUOp. На светодиодах, расположенных над переключателями отображается выходное значение в двоичном формате, а 15-й светодиод отвечает за сигнал `Flag` Подключенное окружение позволяет производить ввод входных значений (А и В) и управляющего сигнала (ALUOp) с помощью переключателей (номер переключателя отображен на самом краю платы), расположенных на плате. А: 15-11, В: 10-6, ALUOp: 4-0, а переключатель №5 активирует семисегментные индикаторы, на которых отображается на левом блоке операнды А и В, а на правом - ALUOp. На светодиодах, расположенных над переключателями отображается выходное значение в двоичном формате, а 15-й светодиод отвечает за сигнал `Flag`
Управление АЛУ через плату Управление АЛУ через плату
![../../../.pic/Labs/board%20files/board%20files/nexys_alu.png](../../../.pic/Labs/board%20files/board%20files/nexys_alu.png) ![../../../.pic/Labs/board%20files/nexys_alu.png](../../../.pic/Labs/board%20files/nexys_alu.png)
Для прошивки ПЛИС подключите утройство через USB, включите питание переключателем, выполните синтез и имплементацию вашего дизайна и сгенерируйте битстрим. Если на этом этапе у вас возникают ошибки, постарайтесь исправить из с помощью [`инструкции по работе с ошибками синтеза`](../../../Vivado%20Basics/Synthesis%20failed.md). После этого выберите в левом меню `Open Target` - `Auto Connect`, затем `Program Device` и ваше устройство прошьется. Для прошивки ПЛИС подключите утройство через USB, включите питание переключателем, выполните синтез и имплементацию вашего дизайна и сгенерируйте битстрим. Если на этом этапе у вас возникают ошибки, постарайтесь исправить из с помощью [`инструкции по работе с ошибками синтеза`](../../../Vivado%20Basics/Synthesis%20failed.md). После этого выберите в левом меню `Open Target` - `Auto Connect`, затем `Program Device` и ваше устройство прошьется.
Генерация битстрима Генерация битстрима
![../../../.pic/Labs/board%20files/board%20files/Program_Device1.png](../../../.pic/Labs/board%20files/board%20files/Program_Device1.png) ![../../../.pic/Labs/board%20files/Program_Device1.png](../../../.pic/Labs/board%20files/Program_Device1.png)
Прошивка ПЛИС Прошивка ПЛИС
![../../../.pic/Labs/board%20files/board%20files/Program_Device2.png](../../../.pic/Labs/board%20files/board%20files/Program_Device2.png) ![../../../.pic/Labs/board%20files/Program_Device2.png](../../../.pic/Labs/board%20files/Program_Device2.png)
Попробуйте выставить на переключателях различные опкоды, такие как сложение, вычитание, сдвиг и сравнения, убедитесь, что все работает исправно и сдавайте работу. Попробуйте выставить на переключателях различные опкоды, такие как сложение, вычитание, сдвиг и сравнения, убедитесь, что все работает исправно и сдавайте работу.

View File

@@ -26,12 +26,12 @@ reg minus;
alu_riscv DUT alu_riscv DUT
( (
.ALUOp (operator_i), .alu_op_i (operator_i),
.A (operand_a_i), .a_i (operand_a_i),
.B (operand_b_i), .b_i (operand_b_i),
.Result (result_o), .result_o (result_o),
.Flag (comparison_result_o) .flag_o (comparison_result_o)
); );
assign operator_i = SW[4:0]; assign operator_i = SW[4:0];
@@ -93,4 +93,4 @@ always @(posedge CLK100) begin
end end
end end
endmodule endmodule

View File

@@ -60,6 +60,7 @@ reg [102:0] running_line;
initial initial
begin begin
running_line <= 0;
$display( "\nStart test: \n\n==========================\nCLICK THE BUTTON 'Run All'\n==========================\n"); $stop(); $display( "\nStart test: \n\n==========================\nCLICK THE BUTTON 'Run All'\n==========================\n"); $stop();
for ( i = 0; i < TEST_VALUES; i = i + 1 ) for ( i = 0; i < TEST_VALUES; i = i + 1 )
begin begin
@@ -10097,7 +10098,7 @@ initial line_dump = {
103'h3f27ac46eaaae4027700000000, 103'h3f27ac46eaaae4027700000000,
103'h16570085a76566615400000000, 103'h16570085a76566615400000000,
103'h3cfd0b67e68d12a83e00000000, 103'h3cfd0b67e68d12a83e00000000,
103'h32d7053ffce4132de500000000, 103'hxxxxxxxxxxxxxxxxx000000000,
103'h073ec21038e11e95ca00000000 103'h073ec21038e11e95ca00000000
}; };

View File

@@ -49,7 +49,7 @@
- установить сигнал `write_enable` в состояние разрешения записи (как правило это 1) и - установить сигнал `write_enable` в состояние разрешения записи (как правило это 1) и
- дождаться нужного фронта `clk` — в этот момент данные будут записаны по указанному адресу. При этом, на выходе `read_data` будут старые данные, хранящиеся по адресу `addr`. На одном такте происходит одновременное считывание информации и запись новой. - дождаться нужного фронта `clk` — в этот момент данные будут записаны по указанному адресу. При этом, на выходе `read_data` будут старые данные, хранящиеся по адресу `addr`. На одном такте происходит одновременное считывание информации и запись новой.
Так же возможна реализация, в которой вход `read_data` и выход `write_data` объединены в единый вход/выход `data`. В этом случае операции чтения и записи разделены во времени и используют для этого один единый порт ввода-вывода (`inout`, двунаправленный порт) `data`. Так же возможна реализация, в которой вход `write_data` и выход `read_data` объединены в единый вход/выход `data`. В этом случае операции чтения и записи разделены во времени и используют для этого один единый порт ввода-вывода (`inout`, двунаправленный порт) `data`.
![../../.pic/Labs/lab_03_memory/fig_01.drawio.png](../../.pic/Labs/lab_03_memory/fig_01.drawio.png) ![../../.pic/Labs/lab_03_memory/fig_01.drawio.png](../../.pic/Labs/lab_03_memory/fig_01.drawio.png)
@@ -223,14 +223,13 @@ mоdulе instr_mеm(
); );
``` ```
Не смотря на разрядность адреса, на практике, внутри данного модуля вы должны будете реализовать память с 1024-мя 32-битными ячейками (в ПЛИС попросту не хватит ресурсов на реализации памяти с 2<sup>32</sup> ячеек).
Из [теории про память](#теория-про-память) вы могли догадаться, что такой модуль описывает память ёмкостью `4 GiB`. Однако в реальности, наша память будет куда меньше (в ПЛИС попросту не хватит ресурсов на реализацию памяти подобного объёма). На практике, внутри данного модуля вы должны будете реализовать память с 1024-мя 32-битными ячейками.
При этом по спецификации процессор RISC-V использует память с побайтовой адресацией. Байтовая адресация означает, что процессор способен обращаться к отдельным байтам в памяти (за каждым байтом памяти закреплен свой индивидуальный адрес). При этом по спецификации процессор RISC-V использует память с побайтовой адресацией. Байтовая адресация означает, что процессор способен обращаться к отдельным байтам в памяти (за каждым байтом памяти закреплен свой индивидуальный адрес).
Однако, если у памяти будут 32-рязрядные ячейки, доступ к конкретному байту будет осложнен, ведь каждая ячейка — это 4 байта. Как получить данные третьего байта памяти? Если обратиться к третьей ячейке в массиве — придут данные 12-15-ых байт байт (поскольку каждая ячейка содержит по 4 байта). Чтобы получить данные третьего байта, необходимо разделить пришедший адрес на 4 (отбросив остаток от деления). `3 / 4 = 0` — и действительно, если обратиться к нулевой ячейке памяти — будут получены данные 3-го, 2-го, 1-го и 0-го байт. То что помимо значения третьего байта есть еще данные других байт нас в данный момент не интересует, важна только сама возможность указать адрес конкретного байта. Однако, если у памяти будут 32-рязрядные ячейки, доступ к конкретному байту будет осложнен, ведь каждая ячейка — это 4 байта. Как получить данные третьего байта памяти? Если обратиться к третьей ячейке в массиве — придут данные 12-15-ых байт (поскольку каждая ячейка содержит по 4 байта). Чтобы получить данные третьего байта, необходимо разделить пришедший адрес на 4 (отбросив остаток от деления). `3 / 4 = 0` — и действительно, если обратиться к нулевой ячейке памяти — будут получены данные 3-го, 2-го, 1-го и 0-го байт. То что помимо значения третьего байта есть еще данные других байт нас в данный момент не интересует, важна только сама возможность указать адрес конкретного байта.
Деление на `2<sup>n</sup>` можно осуществить отбросив `n` младших бит числа. Таким образом на выход память инструкций должна выдавать данные, расположенные по адресу addr_i[31:2]; Деление на 2<sup>n</sup> можно осуществить отбросив `n` младших бит числа. Таким образом на выход память инструкций должна выдавать данные, расположенные по адресу addr_i[31:2];
Обращение в память по адресам, превышающим `4095` должно выдавать значение `32'd0`. Почему именно `4095`? `4095 / 4 = 1023` — индекс последней ячейки памяти. Обращение в память по адресам, превышающим `4095` должно выдавать значение `32'd0`. Почему именно `4095`? `4095 / 4 = 1023` — индекс последней ячейки памяти.
@@ -346,7 +345,7 @@ mоdulе rf_r𝚒sсv(
1. В `Design Sources` проекта создайте `SystemVerilog`-файл `rf_riscv.sv`. 1. В `Design Sources` проекта создайте `SystemVerilog`-файл `rf_riscv.sv`.
2. Опишите в нем модуль регистрового файла с таким же именем и портами, как указано в задании. 2. Опишите в нем модуль регистрового файла с таким же именем и портами, как указано в задании.
1. Обратите внимание, что имя памяти (не название модуля, а имя объекта памяти внутри модуля) должно быть `rf_mem`. Такое имя необходимо для корректной работы верификационного окружения. 1. Обратите внимание, что имя памяти (не название модуля, а имя объекта памяти внутри модуля) должно быть `rf_mem`. Такое имя необходимо для корректной работы верификационного окружения.
2. В отличии от памяти инструкций и данных, ячейки памяти регистрового файла должны быть 32-битными (а на 8-битными). Это означает, что реализация портов чтения и записи будет проще. 2. Как и у памяти инструкций, порты чтения регистрового файла должны быть **асинхронными**.
3. Не забывайте, что у вас 2 порта на чтение и 1 порт на запись, при этом каждый порт не зависит от остальных (в модуле 3 независимых входа адреса). 3. Не забывайте, что у вас 2 порта на чтение и 1 порт на запись, при этом каждый порт не зависит от остальных (в модуле 3 независимых входа адреса).
4. Чтение из нулевого регистра (чтение по адресу 0) всегда должно возвращать нулевое значение. Этого можно добиться двумя путями: 4. Чтение из нулевого регистра (чтение по адресу 0) всегда должно возвращать нулевое значение. Этого можно добиться двумя путями:
1. Путем добавления мультиплексора перед выходным сигналом чтения (мультиплексор будет определять, пойдут ли на выход данные из ячейки регистрового файла, либо в случае если адрес равен нулю, на выход пойдет константа ноль). 1. Путем добавления мультиплексора перед выходным сигналом чтения (мультиплексор будет определять, пойдут ли на выход данные из ячейки регистрового файла, либо в случае если адрес равен нулю, на выход пойдет константа ноль).

File diff suppressed because it is too large Load Diff

View File

@@ -21,8 +21,9 @@
module tb_data_mem(); module tb_data_mem();
parameter ADDR_SIZE = 4096; parameter ADDR_SIZE = 16384;
parameter TIME_OPERATION = 50; parameter TIME_OPERATION = 20;
parameter STEP = 8;
logic CLK; logic CLK;
logic REQ; logic REQ;
@@ -41,9 +42,7 @@ parameter TIME_OPERATION = 50;
); );
logic [31:0] RDa; logic [31:0] RDa;
integer i, err_count = 0; integer i, err_count = 0;
assign A = i; assign A = i;
parameter CLK_FREQ_MHz = 100; parameter CLK_FREQ_MHz = 100;
@@ -57,7 +56,7 @@ parameter TIME_OPERATION = 50;
$display( "\nStart test: \n\n==========================\nCLICK THE BUTTON 'Run All'\n==========================\n"); $stop(); $display( "\nStart test: \n\n==========================\nCLICK THE BUTTON 'Run All'\n==========================\n"); $stop();
REQ = 1; REQ = 1;
WE = 0; WE = 0;
i = 1; #10; i = 0; #10;
if (RD !== 32'hx) begin if (RD !== 32'hx) begin
$display("The data memory should not be initialized by the $readmemh function"); $display("The data memory should not be initialized by the $readmemh function");
err_count = err_count + 1; err_count = err_count + 1;
@@ -67,8 +66,8 @@ parameter TIME_OPERATION = 50;
WE = 1; WE = 1;
WD = $urandom; WD = $urandom;
end end
for (i = 0; i < (ADDR_SIZE+1); i = i + 1) begin for (i = 0; i < (ADDR_SIZE+STEP); i = i + 1 + $urandom() % STEP) begin
if (i != (ADDR_SIZE+1)) begin if (i < (ADDR_SIZE)) begin
REQ = |($urandom %10); REQ = |($urandom %10);
WE = 0; WE = 0;
#TIME_OPERATION; #TIME_OPERATION;
@@ -87,10 +86,11 @@ parameter TIME_OPERATION = 50;
end end
end end
else begin else begin
WE = 0;
REQ = 1; REQ = 1;
#TIME_OPERATION; #TIME_OPERATION;
if (RD !== 32'd3735928559) begin if (RD !== 32'd3735928559) begin
$display("When reading (write_enable_i = %h) at an address greater than 4095, it should return dead_beef yor data: %h_%h, time: %t", WE, RD[31:16],RD[15:0], $time); $display("When reading (write_enable_i = %h) at address greater than 16383 (current addr = %d), it should return dead_beef, but your data: %h_%h, time: %t", WE, A, RD[31:16],RD[15:0], $time);
err_count = err_count + 1; err_count = err_count + 1;
end end
end end
@@ -98,29 +98,34 @@ parameter TIME_OPERATION = 50;
end end
#TIME_OPERATION; #TIME_OPERATION;
REQ = 1; REQ = 1;
WE = 1;
#TIME_OPERATION;
for (i = 0; i < 8; i = i + 4) begin
WD = i? 32'hfecd_ba98: 32'h7654_3210;
#TIME_OPERATION;
end
WE = 0; WE = 0;
i = 2;
#TIME_OPERATION; #TIME_OPERATION;
if (RD !== 32'hba98_7654) begin for (i = 0; i < 4; i = i + 1) begin
$display("data is being written to the cell incorrectly. RAM [0:7] must be 0x0123456789abcdef, time: %t", $time); if(i==0) begin
repeat(2)@(posedge CLK);
#1; RDa = RD;
end else
if(RD !== RDa) begin
$display("incorrect conversion of the reading address = %h, time: %t", A, $time);
err_count = err_count + 1; err_count = err_count + 1;
end
#TIME_OPERATION;
end end
@(posedge CLK) i = 0; WE = 0; REQ = 1;
i = 0; @(posedge CLK);
@(negedge CLK); @(negedge CLK);
if (RD !== 32'hba98_7654) begin i = 4;
#1; RDa = RD;
@(posedge CLK); #1;
if (RD == RDa) begin
$display("reading from data memory must be synchronous, time: %t", $time); $display("reading from data memory must be synchronous, time: %t", $time);
err_count = err_count + 1; err_count = err_count + 1;
end end
@(posedge CLK); #5; @(posedge CLK);
if (RD !== 32'h7654_3210) begin i = {14{1'b1}};
$display("synchronous data memory read error, time: %t", $time); repeat(2) @(posedge CLK);
if (RD === 'd3735928559) begin
$display("incorrect reading from address = %d, data = %h", A, RD);
err_count = err_count + 1; err_count = err_count + 1;
end end
$display("Number of errors: %d", err_count); $display("Number of errors: %d", err_count);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,380 +1,95 @@
21 00074221
42 00000202
07 10844001
00 00119463
02 10046001
02 0006000c
00 0001400d
00 0000020e
01 0000002f
40 10b0400c
84 10b4400d
10 10b8400e
63 10bc400f
94 00100010
11 00018011
00 00001412
01 00000073
60 00000022
04 00000043
10 00000084
0c 00000105
00 00000206
06 00000407
00 00000808
0d 00001009
40 00001fea
01 2004000b
00 30040000
0e 30040000
02 30040000
00 30040000
00 30040000
2f 30040000
00 30040000
00 30040000
00 30040000
0c 7ea97ec0
40 13ad400b
b0 7c2c4520
10 7c2c6540
0d 7c2c8560
40 7c2ca580
b4 7c2cc5a0
10 7c2ce5c0
0e 7c2d05e0
40 7c2d2600
b8 13866014
10 7c500200
0f 13864014
40 7c500200
bc 13862014
10 7c500200
10 13860014
00 7c500200
10 1385e014
00 7c500200
11 1385c014
80 7c500200
01 1385a014
00 7c500200
12 13858014
14 7c500200
00 bc040400
00 13066001
73 bc0403c0
00 13064001
00 bc040380
00 13062001
22 bc040340
00 13060001
00 bc040300
00 1305e001
43 bc0402c0
00 1305c001
00 bc040280
00 1305a001
84 bc040240
00 13058001
00 bc040200
00 12066001
05 bc0401c0
01 12064001
00 bc040180
00 12062001
06 bc040140
02 12060001
00 bc040100
00 1205e001
07 bc0400c0
04 1205c001
00 bc040080
00 1205a001
08 bc040040
08 12058001
00 bc041760
00
09
10
00
00
ea
1f
00
00
0b
00
04
20
00
00
04
30
00
00
04
30
00
00
04
30
00
00
04
30
00
00
04
30
00
00
04
30
00
00
04
30
00
00
04
30
00
00
04
30
c0
7e
a9
7e
0b
40
ad
13
20
45
2c
7c
40
65
2c
7c
60
85
2c
7c
80
a5
2c
7c
a0
c5
2c
7c
c0
e5
2c
7c
e0
05
2d
7c
00
26
2d
7c
14
60
86
13
00
02
50
7c
14
40
86
13
00
02
50
7c
14
20
86
13
00
02
50
7c
14
00
86
13
00
02
50
7c
14
e0
85
13
00
02
50
7c
14
c0
85
13
00
02
50
7c
14
a0
85
13
00
02
50
7c
14
80
85
13
00
02
50
7c
00
04
04
bc
01
60
06
13
c0
03
04
bc
01
40
06
13
80
03
04
bc
01
20
06
13
40
03
04
bc
01
00
06
13
00
03
04
bc
01
e0
05
13
c0
02
04
bc
01
c0
05
13
80
02
04
bc
01
a0
05
13
40
02
04
bc
01
80
05
13
00
02
04
bc
01
60
06
12
c0
01
04
bc
01
40
06
12
80
01
04
bc
01
20
06
12
40
01
04
bc
01
00
06
12
00
01
04
bc
01
e0
05
12
c0
00
04
bc
01
c0
05
12
80
00
04
bc
01
a0
05
12
40
00
04
bc
01
80
05
12
60
17
04
bc

View File

@@ -1,24 +1,6 @@
E1 0FFFFFE1
FF 20000002
FF 00000023
0F 10046001
02 4F045FE0
00 80040000
00
20
23
00
00
00
01
60
04
10
E0
5F
04
4F
00
00
04
80

View File

@@ -144,7 +144,7 @@
[cyberconverter](cyberconverter.cpp) — это программа, которая преобразует текстовый файл с инструкциями архитектуры CYBERcobra в текстовый файл, который сможет принять память инструкций. [cyberconverter](cyberconverter.cpp) — это программа, которая преобразует текстовый файл с инструкциями архитектуры CYBERcobra в текстовый файл, который сможет принять память инструкций.
cyberconverter может обрабатывать файлы, содержащие комментарии (начинающиеся с `//`), пробелы и пустые строки, а так же наборы символов `0` и `1`. Комментарии, пробелы и пустые строки удаляются, после чего оставшиеся строки из 32 нулей и единиц нарезаются на четверки по 8 бит, конвертируются в шестнадцатиричные значения и записываются в выходной файл. cyberconverter может обрабатывать файлы, содержащие комментарии (начинающиеся с `//`), пробелы и пустые строки, а так же наборы символов `0` и `1`. Комментарии, пробелы и пустые строки удаляются, после чего оставшиеся строки из 32 нулей и единиц конвертируются в шестнадцатиричные значения и записываются в выходной файл.
cyberconverter принимает до двух аргументов. Порядок запуска следующий: cyberconverter принимает до двух аргументов. Порядок запуска следующий:

View File

@@ -12,7 +12,7 @@ void print_help(const std::string program_name)
cout << "CYBERcobra program file may contain only comments (starting with \"//\"),\n"; cout << "CYBERcobra program file may contain only comments (starting with \"//\"),\n";
cout << "whitespaces and binary digits '0' or '1'.\n"; cout << "whitespaces and binary digits '0' or '1'.\n";
cout << "This program will erase this parts from every line and then convert\n"; cout << "This program will erase this parts from every line and then convert\n";
cout << "32-bits binary strings into 4 little endian 8-bit strings in hex-format.\n\n"; cout << "in hex-format.\n\n";
cout << "If output file omitted, the <input_file_base>_converted.<input_file_ext>\n"; cout << "If output file omitted, the <input_file_base>_converted.<input_file_ext>\n";
cout << "will be produced.\n\n"; cout << "will be produced.\n\n";
cout << "If input file omitted, program.txt will be used.\n\n"; cout << "If input file omitted, program.txt will be used.\n\n";
@@ -109,26 +109,20 @@ int main(int argc, char ** argv)
cerr << "line " << line_counter << " length is not equal 32 after trimming comments and whitespaces" << endl; cerr << "line " << line_counter << " length is not equal 32 after trimming comments and whitespaces" << endl;
return -2; return -2;
} }
// split 32-bits binary line into 4 little-endian hex lines and write them into file // Convert into hex lines and write them into file
for (size_t i = 0; i < 4; i++) size_t valid_char_num;
uint32_t cur_word = std::stoll(str, &valid_char_num, 2);
if(valid_char_num != 32)
{ {
// For every 8-bit part of 32-bit line get int representation. cerr << "Illegal character '" << str.at(valid_char_num) <<
// If illegal character found, throw error. "' found in line " << line_counter << ": \"" << str << "\"\n";
size_t valid_char_num; cerr << "Should be only '0' or '1'." << endl;
string byte_substr = str.substr(8*(3-i), 8); return -3;
int cur_byte = std::stoi(byte_substr, &valid_char_num, 2);
if(valid_char_num != 8)
{
cerr << "Illegal character '" << byte_substr.at(valid_char_num) <<
"' found in line " << line_counter << ": \"" << str << "\"\n";
cerr << "Should be only '0' or '1'." << endl;
return -3;
}
char hex_byte_str[3];
// convert int representation into hex string
snprintf(hex_byte_str, 3, "%02x", cur_byte);
ofs << hex_byte_str << "\n";
} }
char hex_byte_str[9];
// convert int representation into hex string
snprintf(hex_byte_str, 9, "%08x", cur_word);
ofs << hex_byte_str << "\n";
} }
ifs.close(); ifs.close();
ofs.close(); ofs.close();

View File

@@ -18,7 +18,9 @@
## Порядок выполнения работы ## Порядок выполнения работы
1. Интегрируйте модули `csr_controller` и `irq_controller` в модуль `riscv_core`. 1. Интегрируйте модули `csr_controller` и `irq_controller` в модуль `riscv_core`.
1. Обратите внимание, что что в модуле `riscv_core` появились новые входные и выходные сигналы. Эти сигналы должны быть подключены и в модуле `riscv_unit` (просто в виде проводов, которые с другой стороны не подключены ни к чему, в следующей лабораторной мы найдем им применение). 1. Обратите внимание, что что в модуле `riscv_core` появились новые входные и выходные сигналы: `irq_req_i` и `irq_ret_o`. Эти сигналы должны быть использованы при подключении `riscv_core` в модуле `riscv_unit`.
1. На вход `irq_req_i` пока что необходимо подать `32'd0` (в следующей лабораторной это будет изменено).
2. При подключении сигнала `irq_ret_o` можно ничего не указывать (до следующей лабораторной к нему ничего не будет подключено).
2. Большой мультиплексор на схеме, определяющий записываемое в `PC` значение является мультиплексором с приоритетами (в первую очередь проверяется сигнал `trap`, затем, если он равен нулю, проверяется сигнал `mret`, и только если оба предыдущих равны нулю выдается значение `default`). Такой мультиплексор можно описать как на цепочке выражений `if-else-if`, так и с помощью выражения `case` в качестве управляющего сигнала которого подана единица, а выбор осуществляется не по значениям, а по сигналам: 2. Большой мультиплексор на схеме, определяющий записываемое в `PC` значение является мультиплексором с приоритетами (в первую очередь проверяется сигнал `trap`, затем, если он равен нулю, проверяется сигнал `mret`, и только если оба предыдущих равны нулю выдается значение `default`). Такой мультиплексор можно описать как на цепочке выражений `if-else-if`, так и с помощью выражения `case` в качестве управляющего сигнала которого подана единица, а выбор осуществляется не по значениям, а по сигналам:
```SystemVerilog ```SystemVerilog

View File

@@ -1,4 +1,4 @@
# Лабораторная работа 7 "Периферийные устройства" # Лабораторная работа 12 "Периферийные устройства"
На прошлой лабораторной работе вы реализовали свой собственный RISC-V процессор. Однако пока что он находится "в вакууме" и никак не связан с внешним миром. Для исправления этого недостатка вами будет реализована системная шина, через которую к процессору смогут подключаться различные периферийные устройства. На прошлой лабораторной работе вы реализовали свой собственный RISC-V процессор. Однако пока что он находится "в вакууме" и никак не связан с внешним миром. Для исправления этого недостатка вами будет реализована системная шина, через которую к процессору смогут подключаться различные периферийные устройства.
@@ -35,15 +35,15 @@
### Адресное пространство ### Адресное пространство
Архитектура RISC-V подразумевает использование совместного адресного пространства, это значит, что в лабораторной работе будет использована единая шина для подключения памяти и регистров управления периферийными устройствами. При обращении по одному диапазону адресов процессор будет Архитектура RISC-V подразумевает использование совместного адресного пространства, это значит, что в лабораторной работе будет использована единая шина для подключения памяти и регистров управления периферийными устройствами. При обращении по одному диапазону адресов процессор будет попадать в память, при обращении по другим взаимодействовать с регистрами управления/статуса периферийного устройства. Например, можно разделить 32-битное адресное пространство на 256 частей, отдав старшие 8 бит адреса под указание конкретного периферийного устройства. Тогда каждое из периферийных устройств получит 24-битное адресное пространство (16 MiB). Допустим, мы распределили эти части адресного пространства в следующем порядке (от младшего диапазона адресов к старшему):
попадать в память, при обращении по другим взаимодействовать с регистрами управления/статуса периферийного устройства. Например, можно разделить 32-битное адресное пространство на 256 частей, отдав старшие 8 бит адреса под указание конкретного периферийного устройства. Тогда каждое из периферийных устройств получит 24-битное адресное пространство (16 MiB). Допустим, мы распределили эти части адресного пространства в следующем порядке (от младшего диапазона адресов к старшему):
0. Переключатели 0. Память данных
1. Светодиоды 1. Переключатели
2. Клавиатура PS/2 2. Светодиоды
3. Семисегментные индикаторы 3. Клавиатура PS/2
4. UART-приемник 4. Семисегментные индикаторы
5. UART-передатчик 5. UART-приемник
6. UART-передатчик
В таком случае, если мы захотим обратиться в четвертый регистр семисегментных индикаторов, мы должны будем использовать адрес `0x03000004`. Старшие 8 бит (`0x03`) определяют выбранное периферийное устройство, оставшиеся 24 бита определяют конкретный адрес в адресном пространстве этого устройства. В таком случае, если мы захотим обратиться в четвертый регистр семисегментных индикаторов, мы должны будем использовать адрес `0x03000004`. Старшие 8 бит (`0x03`) определяют выбранное периферийное устройство, оставшиеся 24 бита определяют конкретный адрес в адресном пространстве этого устройства.
@@ -51,11 +51,13 @@
![../../.pic/Labs/lab_12_periph/fig_01.drawio.png](../../.pic/Labs/lab_12_periph/fig_01.drawio.png) ![../../.pic/Labs/lab_12_periph/fig_01.drawio.png](../../.pic/Labs/lab_12_periph/fig_01.drawio.png)
_Рисунок 1. Итоговая структура процессорной системы_
### Активация выбранного устройства ### Активация выбранного устройства
В зависимости от интерфейса используемой шины, периферийные устройства либо знают какой диапазон адресов им выделен (например, в интерфейсе I²C), либо нет (интерфейс APB). В первом случае, устройство понимает что к нему обратились непосредственно по адресу в данном обращении, во втором случае — по специальному сигналу. В зависимости от интерфейса используемой шины, периферийные устройства либо знают какой диапазон адресов им выделен (например, в интерфейсе I²C), либо нет (интерфейс APB). В первом случае, устройство понимает что к нему обратились непосредственно по адресу в данном обращении, во втором случае — по специальному сигналу.
На приведенной выше схеме используется второй вариант — устройство понимает, что к нему обратились по специальному сигналу `req_i`. Данный сигнал формируется из двух частей: сигнала `req` исходящего из процессорного ядра (сигнал о том, обращение в память вообще происходит) и специального сигнала-селектора исходящего из 256-разрядной шины. Формирование значения на этой шине происходит с помощью [унитарного](https://ru.wikipedia.org/wiki/Унитарный_код) ([one-hot](https://en.wikipedia.org/wiki/One-hot)) кодирования. Процесс кодирования достаточно прост. В любой момент времени на выходной шине должен быть **ровно один** бит, равный единице. Индекс этого бита совпадает со значением старших восьми бит адреса. Поскольку для восьмибитного значения существует 256 комбинаций значений, именно такая разрядность будет на выходе кодировщика. Это означает, что в данной системе можно связать процессор с 256 устройствами (одним из которых будет память данных). На _рис. 1_ используется второй вариант — устройство понимает, что к нему обратились по специальному сигналу `req_i`. Данный сигнал формируется из двух частей: сигнала `req` исходящего из процессорного ядра (сигнал о том, обращение в память вообще происходит) и специального сигнала-селектора исходящего из 256-разрядной шины. Формирование значения на этой шине происходит с помощью [унитарного](https://ru.wikipedia.org/wiki/Унитарный_код) ([one-hot](https://en.wikipedia.org/wiki/One-hot)) кодирования. Процесс кодирования достаточно прост. В любой момент времени на выходной шине должен быть **ровно один** бит, равный единице. Индекс этого бита совпадает со значением старших восьми бит адреса. Поскольку для восьмибитного значения существует 256 комбинаций значений, именно такая разрядность будет на выходе кодировщика. Это означает, что в данной системе можно связать процессор с 256 устройствами (одним из которых будет память данных).
Реализация такого кодирования предельно проста: Реализация такого кодирования предельно проста:
@@ -64,7 +66,7 @@
* ... * ...
* Двести пятьдесят пятый бит шины будет равен единице только если `data_addr_o[31:24] = 8'd255`. * Двести пятьдесят пятый бит шины будет равен единице только если `data_addr_o[31:24] = 8'd255`.
Для реализации такого кодирования достаточно выполнить сдвиг влево `255'd1` на значение `data_addr_o[31:24]`. Для реализации такого кодирования достаточно выполнить сдвиг влево константы `255'd1` на значение `data_addr_o[31:24]`.
### Дополнительные правки модуля riscv_unit ### Дополнительные правки модуля riscv_unit
@@ -91,7 +93,7 @@ module riscv_unit(
endmodule endmodule
``` ```
Эти входы порты подключены к одноименным портам ваших контроллеров периферии (речь идет только о реализуемых вами контроллерах, остальные порты должны остаться неподключенными). Эти порты подключены к одноименным портам ваших контроллеров периферии (речь идет только о реализуемых вами контроллерах, остальные порты должны остаться неподключенными).
Обратите внимание на то, что изменился сигнал сброса (`resetn_i`). Буква `n` на конце означает, что сброс работает по уровню `0` (когда сигнал равен нулю — это сброс, когда единице — не сброс). Обратите внимание на то, что изменился сигнал сброса (`resetn_i`). Буква `n` на конце означает, что сброс работает по уровню `0` (когда сигнал равен нулю — это сброс, когда единице — не сброс).
@@ -99,8 +101,8 @@ endmodule
Для этого необходимо: Для этого необходимо:
1. Подключить файл [`sys_clk_rst_gen.v`](sys_clk_rst_gen.v) в ваш проект. 1. Подключить файл [`sys_clk_rst_gen.sv`](sys_clk_rst_gen.sv) в ваш проект.
2. Подключить этот модуль внутри `riscv_unit` следующим образом: 2. Подключить этот модуль в начале описания модуля `riscv_unit` следующим образом:
```SystemVerilog ```SystemVerilog
logic sysclk, rst; logic sysclk, rst;
@@ -113,19 +115,19 @@ sys_clk_rst_gen divider(.ex_clk_i(clk_i),.ex_areset_n_i(resetn_i),.div_i(10),.sy
## Задание ## Задание
В рамках данной лабораторной работы необходимо реализовать модули-контроллеры двух периферийных устройств, реализующих управление в соответствии с приведенной ниже картой памяти и встроить их в процессорную систему, используя используя схему приведенную выше. На карте приведено шесть периферийных устройств, вам необходимо взять только два из них в зависимости от вашего варианта индивидуального задания (ИЗ) по следующему правилу: В рамках данной лабораторной работы необходимо реализовать модули-контроллеры двух периферийных устройств, реализующих управление в соответствии с приведенной ниже картой памяти и встроить их в процессорную систему, используя используя [_рис. 1_](../../.pic/Labs/lab_12_periph/fig_01.drawio.png). На карте приведено шесть периферийных устройств, вам необходимо взять только два из них в зависимости от вашего варианта индивидуального задания (ИЗ) по следующему правилу:
1. Те кому достались варианты ИЗ 1-5 должны реализовать контроллеры переключателей и светодиодов. 1. Те кому достались варианты ИЗ 1-5 должны реализовать контроллеры переключателей и светодиодов.
2. Те кому достались варианты ИЗ 6-15 должны реализовать контроллеры клавиатуры PS/2 и семисегментных индикаторов. 2. Те кому достались варианты ИЗ 6-15 должны реализовать контроллеры клавиатуры PS/2 и семисегментных индикаторов.
3. Те кому достались варианты BP 16-29 должны реализовать контроллеры приемника и передатчика UART. 3. Те кому достались варианты BP 16-29 должны реализовать контроллеры приемника и передатчика UART.
![Карта памяти](../../.pic/Labs/riscv_periph_memory_map.png) ![Карта памяти](../../.pic/Labs/lab_12_periph/fig_02.png)
Работа с картой осуществляется следующим образом. Под названием каждого периферийного устройства указана старшая часть адреса (чему должны быть равны старшие 8 бит адреса, чтобы было сформировано обращение к данному периферийному устройству). Например, для переключателей это значение равно `0x01`, для светодиодов `0x02` и т.п. Работа с картой осуществляется следующим образом. Под названием каждого периферийного устройства указана старшая часть адреса (чему должны быть равны старшие 8 бит адреса, чтобы было сформировано обращение к данному периферийному устройству). Например, для переключателей это значение равно `0x01`, для светодиодов `0x02` и т.п.
В самом левом столбце указаны используемые/неиспользуемые адреса в адресном пространстве данного периферийного устройства. Например для переключателей есть только один используемый адрес: `0x000000`. Его функциональное назначение и разрешения на доступ указаны в столбце соответствующего периферийного устройства. Возвращаясь к адресу `0x000000` для переключателей мы видим следующее: В самом левом столбце указаны используемые/неиспользуемые адреса в адресном пространстве данного периферийного устройства. Например для переключателей есть только один используемый адрес: `0x000000`. Его функциональное назначение и разрешения на доступ указаны в столбце соответствующего периферийного устройства. Возвращаясь к адресу `0x000000` для переключателей мы видим следующее:
* (R) означает что разрешен доступ только на чтение (операция записи по этому адресу должна игнорироваться вашим контроллером). * **(R)** означает что разрешен доступ только на чтение (операция записи по этому адресу должна игнорироваться вашим контроллером).
* "Выставленное на переключателях значение" означает ровно то что и означает. Если процессор выполняет операцию чтения по адресу 0x01000000 (`0x01` (старшая часть адреса переключателей) + `0x000000` (младшая часть адреса для получения выставленного на переключателях значения) ), то контроллер должен выставить на выходной сигнал RD значение на переключателях (о том как получить это значение будет рассказано чуть позже). * **"Выставленное на переключателях значение"** означает ровно то что и означает. Если процессор выполняет операцию чтения по адресу `0x01000000` (`0x01` (старшая часть адреса переключателей) + `0x000000` (младшая часть адреса для получения выставленного на переключателях значения) ), то контроллер должен выставить на выходной сигнал `RD` значение на переключателях (о том как получить это значение будет рассказано чуть позже).
Рассмотрим еще один пример. При обращении по адресу `0x02000024` (`0x02` (старшая часть адреса контроллера светодиодов) + `0x000024` (младшая часть адреса для доступа на запись к регистру сброса) ) должна произойти запись в регистр сброса, который должен сбросить значения в регистре управления зажигаемых светодиодов и регистре управления режимом "моргания" светодиодов (подробнее о том как должны работать эти регистры будет ниже). Рассмотрим еще один пример. При обращении по адресу `0x02000024` (`0x02` (старшая часть адреса контроллера светодиодов) + `0x000024` (младшая часть адреса для доступа на запись к регистру сброса) ) должна произойти запись в регистр сброса, который должен сбросить значения в регистре управления зажигаемых светодиодов и регистре управления режимом "моргания" светодиодов (подробнее о том как должны работать эти регистры будет ниже).
@@ -145,14 +147,15 @@ sys_clk_rst_gen divider(.ex_clk_i(clk_i),.ex_areset_n_i(resetn_i),.div_i(10),.sy
3. Реализуйте модули контроллеров периферии. Имена модулей и их порты будут указаны в [описании контроллеров](#описание-контроллеров-периферийных-устройств). Пример разработки контроллера приведен [здесь](../../Basic%20Verilog%20structures/Controllers.md). 3. Реализуйте модули контроллеров периферии. Имена модулей и их порты будут указаны в [описании контроллеров](#описание-контроллеров-периферийных-устройств). Пример разработки контроллера приведен [здесь](../../Basic%20Verilog%20structures/Controllers.md).
4. Обновите модуль `riscv_unit` в соответствии с разделом ["Дополнительные правки модуля riscv_unit"](#дополнительные-правки-модуля-riscv_unit). 4. Обновите модуль `riscv_unit` в соответствии с разделом ["Дополнительные правки модуля riscv_unit"](#дополнительные-правки-модуля-riscv_unit).
1. Подключите в проект файл `sys_clk_rst_gen.sv`. 1. Подключите в проект файл `sys_clk_rst_gen.sv`.
2. Добавьте в модуль `riscv_unit` входы и выходы периферии. 2. Добавьте в модуль `riscv_unit` входы и выходы периферии. Необходимо добавить порты даже тех периферийных устройств, которые вы не будете реализовывать.
3. Подключите к модулю `riscv_unit` модуль `sys_clk_rst_gen` скопировав приведенный фрагмент кода. 3. Создайте в начале описания модуля `riscv_unit` экземпляр модуля `sys_clk_rst_gen`, скопировав приведенный фрагмент кода.
4. Замените подключение тактового сигнала исходных подмодулей `riscv_unit` на появившийся сигнал `sysclk`. Убедитесь, что на модули имеющие сигнал сброса приходит сигнал `rst`. 4. Замените подключение тактового сигнала исходных подмодулей `riscv_unit` на появившийся сигнал `sysclk`. Убедитесь, что на модули имеющие сигнал сброса приходит сигнал `rst`.
5. Интегрируйте модули контроллеров периферии в процессорную систему по приведенной схеме руководствуясь старшими адресами контроллеров, представленными на карте памяти. Это означает, что если вы реализуете контроллер светодиодов, на его входов `req_i` должна подаваться единица в случае если `mem_req_o == 1` и старшие 8 бит адреса равны `0x02`. 5. Интегрируйте модули контроллеров периферии в процессорную систему по приведенной схеме руководствуясь старшими адресами контроллеров, представленными на карте памяти ([_рис. 2_](../../.pic/Labs/lab_12_periph/fig_02.png)). Это означает, что если вы реализуете контроллер светодиодов, на его вход `req_i` должна подаваться единица в случае если `mem_req_o == 1` и старшие 8 бит адреса равны `0x02`.
1. При интеграции вы должны подключить только модули-контроллеры вашего варианта. Контроллеры периферии других вариантов подключать не надо. 1. При интеграции вы должны подключить только модули-контроллеры вашего варианта. Контроллеры периферии других вариантов подключать не надо.
2. При этом во время интеграции, вы должны использовать старшую часть адреса, представленную в карте памяти для формирования сигнала `req_i` для ваших модулей-контроллеров. 2. При этом во время интеграции, вы должны использовать старшую часть адреса, представленную в карте памяти для формирования сигнала `req_i` для ваших модулей-контроллеров.
3. Даже если вы не используете какие-то входные/выходные сигналы в модуле `riscv_unit` (например по варианту вам не достался контроллер клавиатуры и поэтому вы не используете сигналы `kclk_i` и `kdata_i`), вы все равно должны их описать во входах и выходах модуля `riscv_unit`. 3. Даже если вы не используете какие-то входные/выходные сигналы в модуле `riscv_unit` (например по варианту вам не достался контроллер клавиатуры и поэтому вы не используете сигналы `kclk_i` и `kdata_i`), вы все равно должны их описать во входах и выходах модуля `riscv_unit`.
6. Проинициализируйте память инструкций с помощью предоставленной для каждой пары контроллеров программы. 6. Проверьте работу процессорной системы с помощью моделирования.
1. Для каждой пары контроллеров периферии предложено две программы: с обновлением данных по опросу и по прерываниям. Запустите моделирование сначала для одной программы, затем для другой (для этого необходимо обновить файл, инициализирующий память инструкций). После проверки работоспособности процессора, сравните поведение сигналов LSU для этих программ.
7. Подключите к проекту файл ограничений ([nexys_a7_100t.xdc](nexys_a7_100t.xdc)), если тот еще не был подключен, либо замените его содержимое данными из файла к этой лабораторной работе. 7. Подключите к проекту файл ограничений ([nexys_a7_100t.xdc](nexys_a7_100t.xdc)), если тот еще не был подключен, либо замените его содержимое данными из файла к этой лабораторной работе.
8. Проверьте работу вашей процессорной системы с помощью отладочного стенда с ПЛИС и (при соответствующем варианте) клавиатуры/рабочего компьютера. 8. Проверьте работу вашей процессорной системы с помощью отладочного стенда с ПЛИС и (при соответствующем варианте) клавиатуры/рабочего компьютера.
1. Обратите внимание, что в данной лабораторной уже не будет модуля верхнего уровня `nexys_...`, так как ваш модуль процессорной системы уже полностью самостоятелен и взаимодействует непосредственно с ножками ПЛИС через модули, управляемые контроллерами периферии. 1. Обратите внимание, что в данной лабораторной уже не будет модуля верхнего уровня `nexys_...`, так как ваш модуль процессорной системы уже полностью самостоятелен и взаимодействует непосредственно с ножками ПЛИС через модули, управляемые контроллерами периферии.
@@ -183,7 +186,7 @@ sys_clk_rst_gen divider(.ex_clk_i(clk_i),.ex_areset_n_i(resetn_i),.div_i(10),.sy
В случае отсутствия **запроса на чтения**, на выход `read_data_o` должно подаваться значение `32'hfa11_1eaf`. Это никак не повлияет на работу процессора, но будет удобно в процессе отладки на временной диаграмме (тоже самое было сделано в процессе разработки памяти данных). В случае отсутствия **запроса на чтения**, на выход `read_data_o` должно подаваться значение `32'hfa11_1eaf`. Это никак не повлияет на работу процессора, но будет удобно в процессе отладки на временной диаграмме (тоже самое было сделано в процессе разработки памяти данных).
Если пришел **запрос на запись** или **чтение**, это еще не значит, что контроллер должен его выполнить. В случае, если запрос происходит по адресу, не поддерживающему этот запрос (например **запрос на запись** по адресу поддерживающему только чтение или наоборот), данный запрос должен игнорироваться, а на выходе `read_data_o` должно появиться значение `32'hdead_beef`. Если пришел **запрос на запись** или **чтение**, это еще не значит, что контроллер должен его выполнить. В случае, если запрос происходит по адресу, не поддерживающему этот запрос (например **запрос на запись** по адресу поддерживающему только чтение), данный запрос должен игнорироваться. В случае **запроса на чтение** по недоступному адресу, на выходе `read_data_o` должно появиться значение `32'hdead_beef`.
К примеру, в случае запроса на чтение по адресу `0x0100004` (четвертый байт в адресном пространстве периферийного устройства "переключатели"), на выходе `read_data_o` должно оказаться значение `32'hdead_beef`. В случае отсутствия запроса на чтение (`req_i == 0` или `write_enable_i == 1`), на выходе `read_data_o` контроллера переключателей должно оказаться значение `32'hfa11_1eaf`. К примеру, в случае запроса на чтение по адресу `0x0100004` (четвертый байт в адресном пространстве периферийного устройства "переключатели"), на выходе `read_data_o` должно оказаться значение `32'hdead_beef`. В случае отсутствия запроса на чтение (`req_i == 0` или `write_enable_i == 1`), на выходе `read_data_o` контроллера переключателей должно оказаться значение `32'hfa11_1eaf`.
@@ -201,7 +204,7 @@ module sw_sb_ctrl(
Часть интерфейса модуля, отвечающая за подключение к системной шине Часть интерфейса модуля, отвечающая за подключение к системной шине
*/ */
input logic clk_i, input logic clk_i,
input logic rst_i input logic rst_i,
input logic req_i, input logic req_i,
input logic write_enable_i, input logic write_enable_i,
input logic [31:0] addr_i, input logic [31:0] addr_i,
@@ -237,7 +240,7 @@ module led_sb_ctrl(
Часть интерфейса модуля, отвечающая за подключение к системной шине Часть интерфейса модуля, отвечающая за подключение к системной шине
*/ */
input logic clk_i, input logic clk_i,
input logic rst_i input logic rst_i,
input logic req_i, input logic req_i,
input logic write_enable_i, input logic write_enable_i,
input logic [31:0] addr_i, input logic [31:0] addr_i,
@@ -318,7 +321,7 @@ logic scan_code_is_unread;
endmodule endmodule
``` ```
В первую очередь, вы должны инстанциировать модуль `PS2Receiver` внутри вашего модуля-контроллера, соединив соответствующие входы. Для подключения к выходам необходимо создать дополнительные провода. В первую очередь, вы должны создать экземпляр модуля `PS2Receiver` внутри вашего модуля-контроллера, соединив соответствующие входы. Для подключения к выходам необходимо создать дополнительные провода.
По каждому восходящему фронту сигнала `clk_i` вы должны проверять выход `keycode_valid_o` и если тот равен единице, записать значение с выхода `keycode_o` в регистр `scan_code`. При этом значение регистра `scan_code_is_unread` необходимо выставить в единицу. По каждому восходящему фронту сигнала `clk_i` вы должны проверять выход `keycode_valid_o` и если тот равен единице, записать значение с выхода `keycode_o` в регистр `scan_code`. При этом значение регистра `scan_code_is_unread` необходимо выставить в единицу.
@@ -355,7 +358,7 @@ module hex_digits(
input logic [7:0] bitmask_i, // Битовая маска для включения/отключения input logic [7:0] bitmask_i, // Битовая маска для включения/отключения
// отдельных индикаторов // отдельных индикаторов
output logic [6:0] hex_led_o // Сигнал, контролирующий каждый отдельный output logic [6:0] hex_led_o, // Сигнал, контролирующий каждый отдельный
// светодиод индикатора // светодиод индикатора
output logic [7:0] hex_sel_o // Сигнал, указывающий на какой индикатор output logic [7:0] hex_sel_o // Сигнал, указывающий на какой индикатор
// выставляется hex_led // выставляется hex_led
@@ -408,14 +411,14 @@ endmodule
|Адрес|Режим доступа|Допустимые значения| Функциональное назначение | |Адрес|Режим доступа|Допустимые значения| Функциональное назначение |
|-----|-------------|-------------------|---------------------------------------------------------| |-----|-------------|-------------------|---------------------------------------------------------|
|0x00 | RW | [0:31] | Регистр, хранящий значение, выводимое на hex0 | |0x00 | RW | [0:15] | Регистр, хранящий значение, выводимое на hex0 |
|0x04 | RW | [0:31] | Регистр, хранящий значение, выводимое на hex1 | |0x04 | RW | [0:15] | Регистр, хранящий значение, выводимое на hex1 |
|0x08 | RW | [0:31] | Регистр, хранящий значение, выводимое на hex2 | |0x08 | RW | [0:15] | Регистр, хранящий значение, выводимое на hex2 |
|0x0C | RW | [0:31] | Регистр, хранящий значение, выводимое на hex3 | |0x0C | RW | [0:15] | Регистр, хранящий значение, выводимое на hex3 |
|0x10 | RW | [0:31] | Регистр, хранящий значение, выводимое на hex4 | |0x10 | RW | [0:15] | Регистр, хранящий значение, выводимое на hex4 |
|0x14 | RW | [0:31] | Регистр, хранящий значение, выводимое на hex5 | |0x14 | RW | [0:15] | Регистр, хранящий значение, выводимое на hex5 |
|0x18 | RW | [0:31] | Регистр, хранящий значение, выводимое на hex6 | |0x18 | RW | [0:15] | Регистр, хранящий значение, выводимое на hex6 |
|0x1C | RW | [0:31] | Регистр, хранящий значение, выводимое на hex7 | |0x1C | RW | [0:15] | Регистр, хранящий значение, выводимое на hex7 |
|0x20 | RW | [0:255] | Регистр, управляющий включением/отключением индикаторов | |0x20 | RW | [0:255] | Регистр, управляющий включением/отключением индикаторов |
|0x24 | W | 1 | Запись сигнала сброса | |0x24 | W | 1 | Запись сигнала сброса |
@@ -472,7 +475,7 @@ module uart_rx_sb_ctrl(
Часть интерфейса модуля, отвечающая за подключение к системной шине Часть интерфейса модуля, отвечающая за подключение к системной шине
*/ */
input logic clk_i, input logic clk_i,
input logic rst_i input logic rst_i,
input logic [31:0] addr_i, input logic [31:0] addr_i,
input logic req_i, input logic req_i,
input logic [31:0] write_data_i, input logic [31:0] write_data_i,
@@ -502,7 +505,7 @@ module uart_tx_sb_ctrl(
Часть интерфейса модуля, отвечающая за подключение к системной шине Часть интерфейса модуля, отвечающая за подключение к системной шине
*/ */
input logic clk_i, input logic clk_i,
input logic rst_i input logic rst_i,
input logic [31:0] addr_i, input logic [31:0] addr_i,
input logic req_i, input logic req_i,
input logic [31:0] write_data_i, input logic [31:0] write_data_i,

View File

@@ -1,21 +0,0 @@
93 04 10 00
13 09 a0 0a
93 02 a0 0a
13 19 89 00
33 09 59 00
93 09 50 55
93 02 50 00
93 99 49 00
b3 89 59 00
37 0e 00 01
b7 0e 00 02
03 2a 0e 00
63 0a 2a 01
63 0c 3a 01
23 a0 4e 01
23 a2 0e 00
ef f2 df fe
23 a2 9e 02
ef f2 5f fe
23 a2 9e 00
ef f2 df fd

View File

@@ -0,0 +1,32 @@
01400293
30529073
00200293
30429073
00000063
34202373
00200393
06731063
01000337
00032383
0000BE37
AAAE0E13
01C39463
FCDFF06F
00005E37
555E0E13
01C38A63
02000E37
007E2023
000E2223
02C0006F
02000E37
004E0E13
00100E93
01DE2023
0180006F
02000E37
024E0E13
00100E93
01DE2023
0040006F
30200073

View File

@@ -0,0 +1,21 @@
00100493
0aa00913
0aa00293
00891913
00590933
55500993
00500293
00499993
005989b3
01000e37
02000eb7
000e2a03
012a0a63
013a0c63
014ea023
000ea223
fedff2ef
029ea223
fe5ff2ef
009ea223
fddff2ef

View File

@@ -0,0 +1,54 @@
module sys_clk_rst_gen#(
parameter DIV_WIDTH = 4
)(
input logic ex_clk_i,
input logic ex_areset_n_i,
input logic [DIV_WIDTH-1:0] div_i,
output logic sys_clk_o,
output logic sys_reset_o
);
logic [1:0] ex_arstn_buf;
logic [1:0] sys_rstn_buf;
logic ex_arstn_buffered;
assign ex_arstn_buffered = ex_arstn_buf[1];
assign sys_reset_o = !sys_rstn_buf[1];
always_ff @(posedge ex_clk_i or negedge ex_areset_n_i) begin
if(!ex_areset_n_i) begin
ex_arstn_buf <= 2'b0;
end
else begin
ex_arstn_buf <= {ex_arstn_buf[0], 1'b1};
end
end
logic [DIV_WIDTH-1:0] cnt;
logic clk_div;
always_ff @(posedge ex_clk_i or negedge ex_arstn_buffered) begin
if ( ~ex_arstn_buffered ) begin
cnt <= 0;
clk_div <= 0;
end else if ( cnt == 0 ) begin
cnt <= div_i;
clk_div <= !clk_div;
end else begin
cnt <= cnt - 1;
end
end
BUFG clkbuf (.O(sys_clk_o),.I(clk_div));
always_ff @(posedge sys_clk_o or negedge ex_arstn_buffered) begin
if(!ex_arstn_buffered) begin
sys_rstn_buf <= 2'b0;
end
else begin
sys_rstn_buf <= {sys_rstn_buf[0], 1'b1};
end
end
endmodule

View File

@@ -1,54 +0,0 @@
module sys_clk_rst_gen#(
parameter DIV_WIDTH = 4
)(
input ex_clk_i,
input ex_areset_n_i,
input [DIV_WIDTH-1:0] div_i,
output sys_clk_o,
output sys_reset_o
);
reg [1:0] ex_arstn_buf;
reg [1:0] sys_rstn_buf;
wire ex_arstn_buffered;
assign ex_arstn_buffered = ex_arstn_buf[1];
assign sys_reset_o = !sys_rstn_buf[1];
always @(posedge ex_clk_i or negedge ex_areset_n_i) begin
if(!ex_areset_n_i) begin
ex_arstn_buf <= 2'b0;
end
else begin
ex_arstn_buf <= {ex_arstn_buf[0], 1'b1};
end
end
reg [DIV_WIDTH-1:0] cnt;
reg clk_div;
always@( posedge ex_clk_i or negedge ex_arstn_buffered ) begin
if ( ~ex_arstn_buffered ) begin
cnt <= 0;
clk_div <= 0;
end else if ( cnt == 0 ) begin
cnt <= div_i;
clk_div <= !clk_div;
end else begin
cnt <= cnt - 1;
end
end
BUFG clkbuf (.O(sys_clk_o),.I(clk_div));
always @(posedge sys_clk_o or negedge ex_arstn_buffered) begin
if(!ex_arstn_buffered) begin
sys_rstn_buf <= 2'b0;
end
else begin
sys_rstn_buf <= {sys_rstn_buf[0], 1'b1};
end
end
endmodule

View File

@@ -1,4 +1,4 @@
# Лабораторная работа 8 "Высокоуровневое программирование" # Лабораторная работа 13 "Высокоуровневое программирование"
## Цель ## Цель

View File

@@ -0,0 +1,7 @@
# Заготовленные модули
Все лабораторные работы курса построены по последовательному принципу: модули предыдущих лабораторных работ используются для описания модулей следующих лабораторных работ.
Это приводит к тому, что нельзя выполнить очередную лабу, не выполнив все предыдущие. В случае, если нужен модуль из лабы, которой нет в учебном плане, либо по какой-то причине вы не появились на лабораторном занятии / не успели сделать лабу, у вас всё ещё остается возможность продолжить обучение. Для этого, вы можете воспользоваться реализациями модулей из данной папки.
Обратите внимание на то, что реализации этих модулей неоптимальны, странны и намеренным образом сделаны так, чтобы было тяжело разобраться в принципе их работы. Это сделано для того, чтобы сохранить таинство выполнения соответствующей этому модулю лабы и разумеется ни один из этих модулей не может использоваться на защите лабораторной работы, посвященной этому модулю.

View File

@@ -0,0 +1,11 @@
module fulladder32(
input logic [31:0] a_i,
input logic [31:0] b_i,
input logic carry_i,
output logic [31:0] sum_o,
output logic carry_o
);
assign {carry_o, sum_o} = a_i + b_i + carry_i;
endmodule

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,45 @@
module data_mem (
input logic clk_i,
input logic [31:0] addr_i,
input logic [31:0] write_data_i,
input logic write_enable_i,
input logic mem_req_i,
output logic [31:0] read_data_o
);
`define akjsdnnaskjdndat $clog2(128)
`define cdyfguvhbjnmkdat $clog2(`akjsdnnaskjdndat)
`define qwenklfsaklasddat $clog2(`cdyfguvhbjnmkdat)
`define asdasdhkjasdsadat (34>>`cdyfguvhbjnmkdat)
logic [31:0] RAM [0:4095];
logic [31:0] addr;
assign addr = {2'b0, addr_i[31:2]};
always_ff @(posedge clk_i) begin
if(write_enable_i&mem_req_i) RAM[addr[{1'b1,2'b0}:'hBA & 'h45]][{5{1'b1}}:{3'd7,2'b00}] <= write_data_i['h1f:'h1c];
if(write_enable_i&mem_req_i) RAM[addr[{1'b1,2'b0}:'hBA & 'h45]][19:{1'b1,4'h0}] <= write_data_i[42-23-:`asdasdhkjasdsadat];
if(write_enable_i&mem_req_i) RAM[addr[{1'b1,2'b0}:'hBA & 'h45]][{3{1'b1}}:{1'b1,2'h0}] <= write_data_i[`akjsdnnaskjdndat-:`asdasdhkjasdsadat];
if(write_enable_i&mem_req_i) RAM[addr[{1'b1,2'b0}:'hBA & 'h45]][23:{{2{2'b10}},1'b0}] <= write_data_i[42-19-:`asdasdhkjasdsadat];
if(write_enable_i&mem_req_i) RAM[addr[{1'b1,2'b0}:'hBA & 'h45]][27:{2'b11,3'b000}] <= write_data_i['h1b:'h18];
if(write_enable_i&mem_req_i) RAM[addr[{1'b1,2'b0}:'hBA & 'h45]][11:{1'b1,{3{1'b0}}}] <= write_data_i[`akjsdnnaskjdndat+`asdasdhkjasdsadat:(`akjsdnnaskjdndat+`asdasdhkjasdsadat)-`cdyfguvhbjnmkdat];
if(write_enable_i&mem_req_i) RAM[addr[{1'b1,2'b0}:'hBA & 'h45]][{2{1'b1}}:{3{1'b0}}] <= write_data_i[`akjsdnnaskjdndat-`asdasdhkjasdsadat-:`asdasdhkjasdsadat];
if(write_enable_i&mem_req_i) RAM[addr[{1'b1,2'b0}:'hBA & 'h45]][{4{1'b1}}:4'b1100] <= write_data_i[(`akjsdnnaskjdndat<<(`asdasdhkjasdsadat-`cdyfguvhbjnmkdat)) + (`asdasdhkjasdsadat-`cdyfguvhbjnmkdat):12];
end
always_ff@(posedge clk_i) begin
case(1)
!mem_req_i||write_enable_i: read_data_o <= 'd4195425967;
mem_req_i&&(addr_i<={14{1'b1}}): begin
read_data_o['h1f:'h1c]<=RAM[addr[{1'b1,2'b0}:'hBA & 'h45]][{5{1'b1}}:{3'd7,2'b00}];
read_data_o[42-23-:`asdasdhkjasdsadat]<=RAM[addr[{1'b1,2'b0}:'hBA & 'h45]][19:{1'b1,4'h0}];
read_data_o[`akjsdnnaskjdndat-:`asdasdhkjasdsadat]<=RAM[addr[{1'b1,2'b0}:'hBA & 'h45]][{3{1'b1}}:{1'b1,2'h0}];
read_data_o[42-19-:`asdasdhkjasdsadat]<=RAM[addr[{1'b1,2'b0}:'hBA & 'h45]][23:{{2{2'b10}},1'b0}];
read_data_o['h1b:'h18]<=RAM[addr[{1'b1,2'b0}:'hBA & 'h45]][27:{2'b11,3'b000}];
read_data_o[`akjsdnnaskjdndat+`asdasdhkjasdsadat:(`akjsdnnaskjdndat+`asdasdhkjasdsadat)-`cdyfguvhbjnmkdat]<=RAM[addr[{1'b1,2'b0}:'hBA & 'h45]][11:8];
read_data_o[`akjsdnnaskjdndat-`asdasdhkjasdsadat-:`asdasdhkjasdsadat]<=RAM[addr[{1'b1,2'b0}:'hBA & 'h45]][3:0];
read_data_o[(`akjsdnnaskjdndat<<(`asdasdhkjasdsadat-`cdyfguvhbjnmkdat))+(`asdasdhkjasdsadat-`cdyfguvhbjnmkdat):12]<=RAM[addr[{1'b1,2'b0}:'hBA & 'h45]][{4{1'b1}}:12];
end
default: read_data_o <= 'd3735928559;
endcase
end
endmodule

View File

@@ -0,0 +1,29 @@
module instr_mem(
input logic [31:0] addr_i,
output logic [31:0] read_data_o
);
`define akjsdnnaskjdn $clog2(128)
`define cdyfguvhbjnmk $clog2(`akjsdnnaskjdn)
`define qwenklfsaklasd $clog2(`cdyfguvhbjnmk)
`define asdasdhkjasdsa (34 >> `cdyfguvhbjnmk)
reg [31:0] RAM [0:1023];
initial $readmemh("program.txt", RAM);
always_comb begin
case(addr_i > {12{1'b1}})
0: begin
read_data_o['h1f:'h1c]=RAM[{2'b00, addr_i[{5{1'b1}}:2]}][{5{1'b1}}:{3'd7,2'b00}];
read_data_o[42-23-:`asdasdhkjasdsa]=RAM[{2'b00, addr_i[{5{1'b1}}:2]}][19:{1'b1,4'h0}];
read_data_o[`akjsdnnaskjdn-:`asdasdhkjasdsa]=RAM[{2'b00, addr_i[{5{1'b1}}:2]}][{3{1'b1}}:{1'b1,2'h0}];
read_data_o[42-19-:`asdasdhkjasdsa]=RAM[{2'b00, addr_i[{5{1'b1}}:2]}][23:{{2{2'b10}},1'b0}];
read_data_o['h1b:'h18]=RAM[{2'b00, addr_i[{5{1'b1}}:2]}][27:{2'b11,3'b000}];
read_data_o[`akjsdnnaskjdn+`asdasdhkjasdsa:(`akjsdnnaskjdn+`asdasdhkjasdsa)-`cdyfguvhbjnmk]=RAM[{2'b00, addr_i[{5{1'b1}}:2]}][11:8];
read_data_o[`akjsdnnaskjdn-`asdasdhkjasdsa-:`asdasdhkjasdsa]=RAM[{2'b00, addr_i[{5{1'b1}}:2]}][3:0];
read_data_o[(`akjsdnnaskjdn<<(`asdasdhkjasdsa-`cdyfguvhbjnmk)) + (`asdasdhkjasdsa-`cdyfguvhbjnmk):12 ]=RAM[{2'b00, addr_i[{5{1'b1}}:2]}][{4{1'b1}}:12];
end
default: read_data_o = 'hBA & 'h45;
endcase
end
endmodule

View File

@@ -0,0 +1,63 @@
module rf_riscv(
input logic clk_i,
input logic write_enable_i,
input logic [ 4:0] write_addr_i,
input logic [ 4:0] read_addr1_i,
input logic [ 4:0] read_addr2_i,
input logic [31:0] write_data_i,
output logic [31:0] read_data1_o,
output logic [31:0] read_data2_o
);
`define akjsdnnaskjdnreg $clog2(128)
`define cdyfguvhbjnmkreg $clog2(`akjsdnnaskjdnreg)
`define qwenklfsaklasdreg $clog2(`cdyfguvhbjnmkreg)
`define asdasdhkjasdsareg (34 >> `cdyfguvhbjnmkreg)
logic [(`asdasdhkjasdsareg<<`qwenklfsaklasdreg)+15:0] rf_mem [`asdasdhkjasdsareg*8];
always_ff @(posedge clk_i) begin
if(write_enable_i) rf_mem[write_addr_i[{1'b1,2'b0}:'hBA & 'h45]][{5{1'b1}}:{3'd7,2'b00}] <= write_data_i['h1f:'h1c];
if(write_enable_i) rf_mem[write_addr_i[{1'b1,2'b0}:'hBA & 'h45]][19:{1'b1,4'h0}] <= write_data_i[42-23-:`asdasdhkjasdsareg];
if(write_enable_i) rf_mem[write_addr_i[{1'b1,2'b0}:'hBA & 'h45]][{3{1'b1}}:{1'b1,2'h0}] <= write_data_i[`akjsdnnaskjdnreg-:`asdasdhkjasdsareg];
if(write_enable_i) rf_mem[write_addr_i[{1'b1,2'b0}:'hBA & 'h45]][23:{{2{2'b10}},1'b0}] <= write_data_i[42-19-:`asdasdhkjasdsareg];
if(write_enable_i) rf_mem[write_addr_i[{1'b1,2'b0}:'hBA & 'h45]][27:{2'b11,3'b000}] <= write_data_i['h1b:'h18];
if(write_enable_i) rf_mem[write_addr_i[{1'b1,2'b0}:'hBA & 'h45]][11:{1'b1,{3{1'b0}}}] <= write_data_i[`akjsdnnaskjdnreg+`asdasdhkjasdsareg:(`akjsdnnaskjdnreg+`asdasdhkjasdsareg)-`cdyfguvhbjnmkreg];
if(write_enable_i) rf_mem[write_addr_i[{1'b1,2'b0}:'hBA & 'h45]][{2{1'b1}}:{3{1'b0}}] <= write_data_i[`akjsdnnaskjdnreg-`asdasdhkjasdsareg-:`asdasdhkjasdsareg];
if(write_enable_i) rf_mem[write_addr_i[{1'b1,2'b0}:'hBA & 'h45]][{4{1'b1}}:4'b1100] <= write_data_i[(`akjsdnnaskjdnreg<<(`asdasdhkjasdsareg-`cdyfguvhbjnmkreg)) + (`asdasdhkjasdsareg-`cdyfguvhbjnmkreg):12];
end
always_comb begin
case(read_addr1_i === ('hBA & 'h45))
0: begin
read_data1_o['h1f:'h1c]=rf_mem[read_addr1_i[{1'b1,2'b0}:'hBA & 'h45]][{5{1'b1}}:{3'd7,2'b00}];
read_data1_o[42-23-:`asdasdhkjasdsareg]=rf_mem[read_addr1_i[{1'b1,2'b0}:'hBA & 'h45]][19:{1'b1,4'h0}];
read_data1_o[`akjsdnnaskjdnreg-:`asdasdhkjasdsareg]=rf_mem[read_addr1_i[{1'b1,2'b0}:'hBA & 'h45]][{3{1'b1}}:{1'b1,2'h0}];
read_data1_o[42-19-:`asdasdhkjasdsareg]=rf_mem[read_addr1_i[{1'b1,2'b0}:'hBA & 'h45]][23:{{2{2'b10}},1'b0}];
read_data1_o['h1b:'h18]=rf_mem[read_addr1_i[{1'b1,2'b0}:'hBA & 'h45]][27:{2'b11,3'b000}];
read_data1_o[`akjsdnnaskjdnreg+`asdasdhkjasdsareg:(`akjsdnnaskjdnreg+`asdasdhkjasdsareg)-`cdyfguvhbjnmkreg]=rf_mem[read_addr1_i[{1'b1,2'b0}:'hBA & 'h45]][11:8];
read_data1_o[`akjsdnnaskjdnreg-`asdasdhkjasdsareg-:`asdasdhkjasdsareg]=rf_mem[read_addr1_i[{1'b1,2'b0}:'hBA & 'h45]][3:0];
read_data1_o[(`akjsdnnaskjdnreg<<(`asdasdhkjasdsareg-`cdyfguvhbjnmkreg)) + (`asdasdhkjasdsareg-`cdyfguvhbjnmkreg):12 ]=rf_mem[read_addr1_i[{1'b1,2'b0}:'hBA & 'h45]][{4{1'b1}}:12];
end
default: read_data1_o = 'hBA & 'h45;
endcase
end
always_comb begin
case(read_addr2_i === ('hBA & 'h45))
0: begin
read_data2_o['h1f:'h1c]=rf_mem[read_addr2_i[{1'b1,2'b0}:'hBA & 'h45]][{5{1'b1}}:{3'd7,2'b00}];
read_data2_o[42-23-:`asdasdhkjasdsareg]=rf_mem[read_addr2_i[{1'b1,2'b0}:'hBA & 'h45]][19:{1'b1,4'h0}];
read_data2_o[`akjsdnnaskjdnreg-:`asdasdhkjasdsareg]=rf_mem[read_addr2_i[{1'b1,2'b0}:'hBA & 'h45]][{3{1'b1}}:{1'b1,2'h0}];
read_data2_o[42-19-:`asdasdhkjasdsareg]=rf_mem[read_addr2_i[{1'b1,2'b0}:'hBA & 'h45]][23:{{2{2'b10}},1'b0}];
read_data2_o['h1b:'h18]=rf_mem[read_addr2_i[{1'b1,2'b0}:'hBA & 'h45]][27:{2'b11,3'b000}];
read_data2_o[`akjsdnnaskjdnreg+`asdasdhkjasdsareg:(`akjsdnnaskjdnreg+`asdasdhkjasdsareg)-`cdyfguvhbjnmkreg]=rf_mem[read_addr2_i[{1'b1,2'b0}:'hBA & 'h45]][11:8];
read_data2_o[`akjsdnnaskjdnreg-`asdasdhkjasdsareg-:`asdasdhkjasdsareg]=rf_mem[read_addr2_i[{1'b1,2'b0}:'hBA & 'h45]][3:0];
read_data2_o[(`akjsdnnaskjdnreg<<(`asdasdhkjasdsareg-`cdyfguvhbjnmkreg)) + (`asdasdhkjasdsareg-`cdyfguvhbjnmkreg):12 ]=rf_mem[read_addr2_i[{1'b1,2'b0}:'hBA & 'h45]][{4{1'b1}}:12];
end
default: read_data2_o = 'hBA & 'h45;
endcase
end
endmodule

View File

@@ -28,11 +28,10 @@
- [Студенческий сервер](../Other/Students%20server.md) - [Студенческий сервер](../Other/Students%20server.md)
- [Создание базового проекта с прошивкой ПЛИС в Vivado](../Vivado%20Basics/Vivado%20trainer.md) - [Создание базового проекта с прошивкой ПЛИС в Vivado](../Vivado%20Basics/Vivado%20trainer.md)
- [Что такое язык описания аппаратуры HDL](../Introduction/What%20is%20HDL.md)
- [Как работает ПЛИС](../Introduction/How%20FPGA%20works.md)
- [Синтаксис языка Verilog](../Basic%20Verilog%20structures/Verilog%20syntax.md)
- [Базовые конструкции Verilog](../Basic%20Verilog%20structures/) - [Базовые конструкции Verilog](../Basic%20Verilog%20structures/)
- [Список типичных ошибок в Vivado и SystemVerilog](../Other/FAQ.md)
- [Тестовое окружение](../Basic%20Verilog%20structures/Testbench.md) - [Тестовое окружение](../Basic%20Verilog%20structures/Testbench.md)
- [Готовые модули](Made-up%20modules)
## Порядок выполнения лабораторных работ для групп ## Порядок выполнения лабораторных работ для групп

21
Other/Extras.md Normal file
View File

@@ -0,0 +1,21 @@
# Полезные ресурсы и материалы в Интернете
## Про архитектуру RISC-V
- [Официальный сайт RISC-V International](https://riscv.org) На официальном сайте можно найти много полезной информации: официальная спецификация на архитектуру, ссылки на проекты с открытыми и закрытыми процессорными ядрами, программное обеспечение, учебные материалы и тому подобное
- [RISC-V-Awesome-List](https://github.com/NickolayTernovoy/risc-v_awesome_list) Список полезных ресурсов связанных с темой RISC-V от единственного русскоговорящего амбассадора RISC-V в СНГ
- [Записки CPU designer'a](https://t.me/cpu_design) Телеграм-канал от того же амбассадора, на котором публикуются различные новости по этой же теме
## Про программируемые логические интегральные схемы (ПЛИС) и Verilog
- [fpga-systems.ru](https://fpga-systems.ru) FPGA-Systems это не только интернет-ресурс с различными статьями о ПЛИС, но и живое, постоянно обновляемое и растущее сообщество разработчиков, которое организует тематические конференции, а участники обмениваются вопросами/ответами в коллективных чатах, ссылки на которые можно найти на сайте. В российском сегменте интернета очень полезный ресурс для тех, кто хочет развивать навыки разработчика под ПЛИС
- [FPGA-Awesome-List](https://github.com/FPGA-Systems/fpga-awesome-list) Список полезных ресурсов связанных с темой ПЛИС от сообщества FPGA-Systems, тут много полезной информации
- [opencores.org](https://opencores.org/projects) Сайт, на котором собраны открытые (бесплатные, то есть скачать можно) IP-блоки самых разных цифровых устройств, написанные на разных языках описания аппаратуры, например, в разделе "Processors" можно найти процессоры с самыми различными архитектурами, скачать их, прошить, посмотреть, потрогать, поэкспериментировать. Процессоры с RISC-V там тоже, конечно же, есть. Не все IP-блоки написаны на Verilog
- [Problem sets Verilog syntax](https://hdlbits.01xz.net/wiki/Problem_sets) Крутой самоучитель по Verilog, но на английском. Все очень удобно разбито по темам, рассчитано на самого начинающего. Даже Vivado запускать не надо, можно вбивать и проверять код прямо на сайте, пушка!
## Про систему контроля версий Git
- [Pro Git](https://git-scm.com/book/ru/v2) Книга на русском про систему контроля версий Git. Читаешь ее и больше вопросов по Git не будет
- [Шпаргалка по Git](https://training.github.com/downloads/ru/github-git-cheat-sheet/) Краткая выжимка основных команд для Git
- [Чёрт побери, Git!?!](https://dangitgit.com/ru) Краткая выжимка решения типичных проблем (в юмористической форме)
- [Тренажер Git](https://learngitbranching.js.org/?locale=ru_RU) Отличный онлайн-тренажер, чтобы отточить навыки работы с Git

View File

@@ -1,18 +1,18 @@
# Список типичных ошибок при работе с Vivado и Verilog # Список типичных ошибок при работе с Vivado и SystemVerilog
## Содержание ## Содержание
1. [Ошибки, связанные с САПР Vivado](#ошибки-связанные-с-сапр-vivado) - [Список типичных ошибок при работе с Vivado и SystemVerilog](#список-типичных-ошибок-при-работе-с-vivado-и-systemverilog)
1.1 [Не запускается симуляция: FATAL_ERROR: PrivateChannel: Error creating client socket](#не-запускается-симуляция-fatal_error-privatechannel-error-creating-client-socket) - [Содержание](#содержание)
1.2 [Не запускается симуляция: boot::filesystem::remove: Процесс не может получить доступ к файлу, т.к. этот файл занят другим процессом](#не-запускается-симуляция-boot-filesystem-remove-процесс-не-может-получить-доступ-к-файлу) - [Ошибки связанные с САПР Vivado](#ошибки-связанные-с-сапр-vivado)
1.3 [Вылетает Vivado при попытке открыть схему](#вылетает-vivado-при-попытке-открыть-схему) - [Не запускается симуляция FATAL\_ERROR PrivateChannel Error creating client socket](#не-запускается-симуляция-fatal_error-privatechannel-error-creating-client-socket)
1.4 [Не устанавливается Vivado: The following fatal error encountered while installing files: Unable to open archive](#не-устанавливается-vivado-unable-to-open-archive) - [Не запускается симуляция boot filesystem remove Процесс не может получить доступ к файлу](#не-запускается-симуляция-boot-filesystem-remove-процесс-не-может-получить-доступ-к-файлу)
- [Вылетает Vivado при попытке открыть схему](#вылетает-vivado-при-попытке-открыть-схему)
- [Не устанавливается Vivado Unable to open archive](#не-устанавливается-vivado-unable-to-open-archive)
- [Ошибки синтаксиса языка SystemVerilog](#ошибки-синтаксиса-языка-systemverilog)
- [имя сигнала is not a type](#имя-сигнала-is-not-a-type)
- [cannot find port on this module](#cannot-find-port-on-this-module)
2. [Ошибки синтаксиса языка Verilog](#ошибки-синтаксиса-языка-verilog)
2.1 [concurrent assignment to a non-net is not permitted](#concurrent-assignment-to-a-non-net-is-not-permitted)
2.2 [procedural assignment to a non-register test is not permitted, left-hand side should be reg/integer/time/genvar](#procedural-assignment-to-a-non-register-test-is-not-permitted-left-hand-side-should-be-reg)
2.3 ['имя сигнала' is not a type](#имя-сигнала-is-not-a-type)
2.4 [cannot find port on this module](#cannot-find-port-on-this-module)
## Ошибки связанные с САПР Vivado ## Ошибки связанные с САПР Vivado
@@ -78,26 +78,26 @@
--- ---
## Ошибки синтаксиса языка Verilog ## Ошибки синтаксиса языка SystemVerilog
### concurrent assignment to a non-net is not permitted <!-- ### concurrent assignment to a non-net is not permitted
Запрещено выполнять непрерывное присваивание (`assign`) к объектам, не являющимися цепями. Скорее всего, вы пытались выполнить `assign b = a;`, где `b` является регистром. Запрещено выполнять непрерывное присваивание (`assign`) к объектам, не являющимися цепями. Скорее всего, вы пытались выполнить `assign b = a;`, где `b` является регистром.
```Verilog ```SystemVerilog
module alu(input a, input b, module alu(input a, input b,
input [3:0] alu_op, input logic [3:0] alu_op,
output reg flag, output logic flag,
output reg result output logic result
); );
assign flag = alu_op[3] ? (a > b) : 1'b0; // ошибка assign flag = alu_op[3] ? (a > b) : 1'b0; // ошибка
endmodule endmodule
``` ```
--- --- -->
### procedural assignment to a non-register test is not permitted left-hand side should be reg <!-- ### procedural assignment to a non-register test is not permitted left-hand side should be reg
Запрещено использовать процедурное присваивание (присваивание в блоке `always` или `initial`) объектам, не являющимися регистрами. Скорее всего, вы пытались выполнить `b = a;` или `b <= a;` блоке `always`/`initial`, где `b` является проводом. Запрещено использовать процедурное присваивание (присваивание в блоке `always` или `initial`) объектам, не являющимися регистрами. Скорее всего, вы пытались выполнить `b = a;` или `b <= a;` блоке `always`/`initial`, где `b` является проводом.
@@ -110,14 +110,14 @@ end
endmodule endmodule
``` ```
--- --- -->
### имя сигнала is not a type ### имя сигнала is not a type
Скорее всего, компилятор не распознал присваивание, поскольку оно было записано с ошибками. Вне блоков `always` и `initial` можно выполнять только непрерывное присваивание (через `assign`). Скорее всего, компилятор не распознал присваивание, поскольку оно было записано с ошибками. Вне блоков `always` и `initial` можно выполнять только непрерывное присваивание (через `assign`).
```Verilog ```SystemVerilog
module adder(input a, input b, output c); module half_adder(input logic a, input logic b, output logic c);
c = a ^ b; // ошибка, для непрерывного присваивания c = a ^ b; // ошибка, для непрерывного присваивания
// необходимо ключевое слово assign // необходимо ключевое слово assign
endmodule endmodule
@@ -131,17 +131,17 @@ endmodule
Пример Пример
```Verilog ```SystemVerilog
module adder(input a, input b, output c); module half_adder(input logic a, input logic b, output logic c);
assign c = a ^ b; assign c = a ^ b;
endmodule endmodule
module testbench(); module testbench();
reg A, B; logic A, B, C;
wire C;
adder DUT( adder DUT(
.A(A), // <- здесь будет ошибка, .A(A), // <- здесь будет ошибка,
// т.к. в модуле adder нет порта 'A' // т.к. в модуле half_adder нет порта 'A'
.b(B), .b(B),
.c(C) .c(C)
); );

82
Other/Further readings.md Normal file
View File

@@ -0,0 +1,82 @@
# Список дополнительной литературы
В приведенном ниже списке будут даны описания книг, а так же способы их получения: покупка/чтение в электронной библиотеке/получение экземпляра книги в универитетской библиотеке. <!--Руководство по работе с электронной библиотекой вы можете найти [здесь](<placeholder>)-->.
- [Список дополнительной литературы](#список-дополнительной-литературы)
- [Митио Сибуя и Такаси Тонаги: Центральный процессор. Образовательная манга](#митио-сибуя-и-такаси-тонаги-центральный-процессор-образовательная-манга)
- [Чарльз Петцольд: Код. Тайный язык информатики](#чарльз-петцольд-код-тайный-язык-информатики)
- [Дэвид М. Харрис и Сара Л. Харрис: Цифровая схемотехника и архитектура компьютера: RISC-V](#дэвид-м-харрис-и-сара-л-харрис-цифровая-схемотехника-и-архитектура-компьютера-risc-v)
- [Дэвид М. Харрис и Сара Л. Харрис: Цифровая схемотехника и архитектура компьютера. Дополнение по архитектуре ARM\*](#дэвид-м-харрис-и-сара-л-харрис-цифровая-схемотехника-и-архитектура-компьютера-дополнение-по-архитектуре-arm)
- [под редакцией Романова А.Ю. и Панчула Ю.В.: Цифровой синтез: практический курс](#под-редакцией-романова-аю-и-панчула-юв-цифровой-синтез-практический-курс)
- [Д. Паттерсон и Дж. Хеннесси: Архитектура компьютера и проектирование компьютерных систем](#д-паттерсон-и-дж-хеннесси-архитектура-компьютера-и-проектирование-компьютерных-систем)
- [Д. Паттерсон и Дж. Хеннесси: Архитектура компьютера. Количественный подход](#д-паттерсон-и-дж-хеннесси-архитектура-компьютера-количественный-подход)
- [С.А. Орлов и Б.Я. Цилькер: Организация ЭВМ и систем](#са-орлов-и-бя-цилькер-организация-эвм-и-систем)
- [Д.Н. Беклемишев, А.Н. Орлов, А.Л. Переверзев, М.Г. Попов, А.В. Горячев, А.И.Кононова: Микропроцессорные средства и системы. Курс лекций](#дн-беклемишев-ан-орлов-ал-переверзев-мг-попов-ав-горячев-аикононова-микропроцессорные-средства-и-системы-курс-лекций)
- [Э. Таненбаум и Т. Остин: Архитектура компьютера](#э-таненбаум-и-т-остин-архитектура-компьютера)
- [Дональд Томас: Логическое проектирование и верификация систем на SystemVerilog](#дональд-томас-логическое-проектирование-и-верификация-систем-на-systemverilog)
## Митио Сибуя и Такаси Тонаги: Центральный процессор. Образовательная манга
Самый лайтовый вариант усвоения основных концепций изучаемой дисциплины. Про архитектуру процессора в виде манги. По сюжету девушка Каиураги Дюми, чемпион по японским шахматам сёги, встречает незнакомца, который предлагает ей сыграть с компьютером. Конечно же она сливает партию. И понеслось. Слово за слово и вот он уже рассказывает ей, как работает обыгравший ее компьютер. Не понять просто невозможно. А прочитав эту мангу любая книга ниже станет понятна абсолютно любому читателю. Манга [продается](https://dmkpress.com/catalog/manga/978-5-97060-507-3/) как в электронном, так и в печатном виде. В обозримом будущем будет доступна студентам МИЭТ в [электронной библотеке](https://e.lanbook.com/book/93581).
![../.pic/Other/Further%20readings/manga.jpg](../.pic/Other/Further%20readings/manga.jpg)
## Чарльз Петцольд: Код. Тайный язык информатики
Книга для тех, кому плохо пошел материал. Очень, очень классно рассказывается что такое цифровые устройства, как это работает и зачем это все нужно. На примере фонариков, азбуки Морзе, шрифта Брайля и штрих-кодов автор знакомит нас с основами кодирования информации. Из лампочек и батареек сначала собираются разные вроде бы пустяковые устройства, которые позже превращаются в полноценный компьютер. Отличная популярная литература. Если ты знаешь человека, которому с трудом дается понимание цифровой техники, то ты просто обязан порекомендовать ему эту книгу. В образовательных целях можно ознакомиться с ней в облаке. Почитать восхищенный отзыв о книге и ее содержании можно [тут](https://habr.com/ru/post/68365/). А дождаться, когда она начнет снова продаваться можно [тут](https://www.ozon.ru/context/detail/id/125884/). Либо поискать в магазинах.
![../.pic/Other/Further%20readings/code.jpg](../.pic/Other/Further%20readings/code.jpg)
## Дэвид М. Харрис и Сара Л. Харрис: Цифровая схемотехника и архитектура компьютера: RISC-V
Потрясающая книга, являющаяся более доступным вариантом изложения и иллюстрации книги "Архитектура компьютера и проектирование компьютерных систем", Паттерсона и Хеннесси. На примере архитектуры **RISC-V** рассказывается как построить процессор начиная с вопросов работы транзистора. Рассматриваются базовые конструкции языков описания аппаратуры **SystemVerilog** и **VHDL**. Эту книгу на чистом энтузиазме перевели на русский язык группа ученых и инженеров из стран бывшего СССР с подачи [Юрия Панчула](http://panchul.com/about_ru/). Электронный вариант для архитектуры **MIPS** распространяется бесплатно и абсолютно легально. Обязательна к ознакомлению каждому! Гораздо удобнее использовать печатный вариант, на этот случай ее можно приобрести [тут](https://dmkpress.com/catalog/electronics/circuit_design/978-5-97060-961-3/). Электронный вариант с архитектурой **MIPS** доступен в облаке и [электронной библотеке](https://e.lanbook.com/book/241166).
![../.pic/Other/Further%20readings/harris.png](../.pic/Other/Further%20readings/harris.png)
## Дэвид М. Харрис и Сара Л. Харрис: Цифровая схемотехника и архитектура компьютера. Дополнение по архитектуре ARM*
Как и следует из названия, эта книга дополняет предыдущие описанием отличий архитектуры **ARM** от **MIPS** и **RISC-V**. Книга состоит из глав, посвященных архитектуре процессоров **ARM**, их микроархитектуре, описанию подсистемы памяти и системы ввода-вывода. Также в приложении приведена система команд **ARM**. Почему такое пристальное внимание этой архитектуре? Потому что это одна из самых массово используемых архитектур в мире. Например, 98% всех мобильных телефонов работают на процессорах с архитектурой **ARM**. Книгу можно приобрести [тут](https://dmkpress.com/catalog/electronics/circuit_design/978-5-97060-650-6/), а так же прочесть в [электронной библиотеке](https://e.lanbook.com/book/111431).
![../.pic/Other/Further%20readings/arm.jpg](../.pic/Other/Further%20readings/arm.jpg)
## под редакцией Романова А.Ю. и Панчула Ю.В.: Цифровой синтез: практический курс
В дополнение к Харрисам отлично идет практический курс цифрового дизайна, в том числе, как раз, от того самого Юрия Панчула. Книга ориентирована в первую очередь на практику создания цифровой аппаратуры на ПЛИС с помощью **Verilog HDL**. Затрагиваются вопросы процесса создания **ASIC**. Очень хорошо написана, грамотно структурирована и имеет много полезной информации, требующейся на практике дизайнеру цифровой аппаратуры. Купить можно [тут](https://dmkpress.com/catalog/electronics/circuit_design/978-5-97060-850-0/), так же доступна в [электронной библиотеке](https://e.lanbook.com/book/179492).
![../.pic/Other/Further%20readings/digitaldesign.png](../.pic/Other/Further%20readings/digitaldesign.png)
## Д. Паттерсон и Дж. Хеннесси: Архитектура компьютера и проектирование компьютерных систем
Отцы архитектуры **RISC** делятся накопленным опытом. Не только рассказывают, как процессоры работают, но и как их построить, прививают принципы проектирования, красиво указывают на заблуждения, дают хитрые задания, да и вообще книга богата полезной информацией. Нетленка. Не зря на лицевой стороне книги написано *классика computer science*. Заканчивается книга разбором многоядерных, многопроцессорных параллельных систем. Если решишь поставить к себе на полку, то придется подождать когда она [вновь поступит в продажу](https://www.ozon.ru/context/detail/id/7425447/) или поискать на полках магазинов.
![../.pic/Other/Further%20readings/patterson1.jpg](../.pic/Other/Further%20readings/patterson1.jpg)
## Д. Паттерсон и Дж. Хеннесси Архитектура компьютера. Количественный подход
Дополнение к предыдущей книге, вся суть которой передана в названии. Рассматривается эффективность современных вычислительных машин в численном эквиваленте. Что и как влияет на производительность вычислительных систем и какие существуют зависимости. Уделяется большое внимание построению иерархии памяти и анализу результатов, исследуется параллелизм исполнения команд. В некотором смысле это библия анализа вычислительных систем. Авторы получили за нее премию Тьюринга. Рекомендуется к прочтению после прослушивания курса Архитектуры процессорных систем. В облаке лежит часть книги для ознакомления, а ее [физическая копия](https://www.ozon.ru/context/detail/id/35204637/) хорошо дополнит домашнюю библиотеку computer science.
![../.pic/Other/Further%20readings/patterson2.jpg](../.pic/Other/Further%20readings/patterson2.jpg)
## С.А. Орлов и Б.Я. Цилькер: Организация ЭВМ и систем
Фундаментальный курс по архитектуре и структуре современных компьютерных систем, написанный двумя опытными профессорами из питерских вузов. Книга написана излишне сухо, в советской манере, порой с излишним формализмом даже там, где этого можно было избежать. Однако, книга изобилует большим объемом полезной информации, богатым списком источников, в основном зарубежных. Рекомендуется использовать ее как дополнительное справочное пособие. В ней можно найти много оригинальной информации, не содержащейся в другой отечественной печатной продукции. Купить книжку можно, например, [здесь](https://www.ozon.ru/context/detail/id/147603179/).
![../.pic/Other/Further%20readings/orlov.jpg](../.pic/Other/Further%20readings/orlov.jpg)
## Д.Н. Беклемишев, А.Н. Орлов, А.Л. Переверзев, М.Г. Попов, А.В. Горячев, А.И.Кононова: Микропроцессорные средства и системы. Курс лекций
Курс лекций, читавшийся несколько лет назад. На данный момент книга является актуальной, но дисциплина организована несколько иначе. Из достоинств можно выделить хорошую организацию написанного материала, представленного в виде одинаковых порций разбитых на тематические лекции. Книга доступна в облаке и в университетской библиотеке. Отдельно стоит отметить, что часть читаемого на лекциях материала представлена только в этом издании.
![../.pic/Other/Further%20readings/vt.jpg](../.pic/Other/Further%20readings/vt.jpg)
## Э. Таненбаум и Т. Остин: Архитектура компьютера
Книга для изучения компьютерной архитектуры от всемирно известного специалиста в области информационных технологий, писателя и преподавателя, выходящая уже в шестом издании и посвящена структурной организации компьютера. В качестве примеров архитектур рассматриваются **Intel Core i7**, **Texas Instrument OMAP4430** и **Atmel ATmega168**. Книга рассчитана на широкий круг читателей, так что можешь читать ее без опасения что что-то не поймешь, хотя не все с этим согласятся, некоторым (включая автора этих строк) книга [не нравится](https://habr.com/ru/post/589091/). Чувствуется влияние того, что Таненбаум чаще взаимодействует с цифровой аппаратурой в роли программиста, а не разработчика. Вероятно это поможет в освоении материала обучающимся на соответствующих специальностях. Купить книгу можно [тут](https://www.piter.com/collection/all/product/arhitektura-kompyutera-6-e-izd-2).
![../.pic/Other/Further%20readings/tanenbaum.jpg](../.pic/Other/Further%20readings/tanenbaum.jpg)
## Дональд Томас: Логическое проектирование и верификация систем на SystemVerilog
Тем, кто не только пытается разобраться в принципах работы компьютера, но и сам хочет разрабатывать цифровые устройства потребуется более серьезно изучить какой-нибудь современный язык описания аппаратуры. Сходу, многие посоветуют SystemVerilog наиболее популярный вариант в индустрии. Он является более современной версией Verilog, лишенной некоторых его недостатков.
![../.pic/Other/Further%20readings/svbook.png](../.pic/Other/Further%20readings/svbook.png)

View File

@@ -12,12 +12,12 @@
Это путеводитель по дисциплине «Архитектуры процессорных систем». Здесь ты найдёшь ссылки на всю информацию генерируемую в данном курсе: Это путеводитель по дисциплине «Архитектуры процессорных систем». Здесь ты найдёшь ссылки на всю информацию генерируемую в данном курсе:
- конспекты лекций (WIP) - [Видеозаписи](https://www.youtube.com/c/%D0%90%D0%9F%D0%A1%D0%9F%D0%BE%D0%BF%D0%BE%D0%B2) и конспекты (WIP) лекций с прошлых лет.
- методички по лабораторным работам ([Labs](Labs/)) - методички по лабораторным работам ([Labs](Labs/))
- дополнительные материалы и литературу (WIP) - дополнительные материалы и литературу ([Other/Further readings.md](Other/Further%20readings.md))
- популярные материалы (WIP) - популярные материалы ([Other/Extras.md](Other/Extras.md))
- информацию о преподавателях, их расписание и контакты ([Other/Educators.md](Other/Educators.md)) - информацию о преподавателях, их расписание и контакты ([Other/Educators.md](Other/Educators.md))
- страницу с анонимной обратной связью (WIP). - страницу с анонимной обратной связью ([Google Forms](https://docs.google.com/forms/d/e/1FAIpQLSdoLdMCnFOv-RS_E4ztVjVzPqy-pqcCcaD7JNx6F4r8Kd_8iw/viewform?usp=sharing)).
Имея доступ к этой странице ты имеешь доступ ко всему курсу АПС. Имея доступ к этой странице ты имеешь доступ ко всему курсу АПС.