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-описания) для контроллера светодиодов.
В первую очередь, здесь будет продублирована выдержка из спецификации на этот контроллер (общая часть раздела "[Описание контроллеров периферийных устройств](../../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'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`.

View File

@@ -124,7 +124,7 @@ end
```SystemVerilog
logic Y;
always @(*) begin
always_comb begin
case(S) // Описываем блок case, где значение сигнала S
// будет сравниваться с различными возможными его значениями
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-ти, расположенных вместе в форме крестовины). Семисегментные индикаторы в шестнадцатиричном формате отображают на левом блоке слагаемые А и В, а на правом - результат сложения. На светодиодах, расположенных над переключателями отображается результат в двоичном формате.
Управление сумматором через плату
![../../../.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` и ваше устройство прошьется.
Генерация битстрима
![../../../.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
(
.A (A),
.B (B),
.Pin (Pin),
.a_i (A),
.b_i (B),
.carry_i (Pin),
.S (S),
.Pout (Pout)
.sum_o (S),
.carry_o (Pout)
);
assign B = {24'b0,SW[7:0]};
@@ -127,4 +127,4 @@ always @(posedge CLK100) begin
end
end
endmodule
endmodule

View File

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

View File

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

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`
Управление АЛУ через плату
![../../../.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` и ваше устройство прошьется.
Генерация битстрима
![../../../.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
(
.ALUOp (operator_i),
.A (operand_a_i),
.B (operand_b_i),
.alu_op_i (operator_i),
.a_i (operand_a_i),
.b_i (operand_b_i),
.Result (result_o),
.Flag (comparison_result_o)
.result_o (result_o),
.flag_o (comparison_result_o)
);
assign operator_i = SW[4:0];
@@ -93,4 +93,4 @@ always @(posedge CLK100) begin
end
end
endmodule
endmodule

View File

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

View File

@@ -49,7 +49,7 @@
- установить сигнал `write_enable` в состояние разрешения записи (как правило это 1) и
- дождаться нужного фронта `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)
@@ -223,14 +223,13 @@ mоdulе instr_mеm(
);
```
Из [теории про память](#теория-про-память) вы могли догадаться, что такой модуль описывает память ёмкостью `4 GiB`. Однако в реальности, наша память будет куда меньше (в ПЛИС попросту не хватит ресурсов на реализацию памяти подобного объёма). На практике, внутри данного модуля вы должны будете реализовать память с 1024-мя 32-битными ячейками.
Не смотря на разрядность адреса, на практике, внутри данного модуля вы должны будете реализовать память с 1024-мя 32-битными ячейками (в ПЛИС попросту не хватит ресурсов на реализации памяти с 2<sup>32</sup> ячеек).
При этом по спецификации процессор 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` — индекс последней ячейки памяти.
@@ -346,7 +345,7 @@ mоdulе rf_r𝚒sсv(
1. В `Design Sources` проекта создайте `SystemVerilog`-файл `rf_riscv.sv`.
2. Опишите в нем модуль регистрового файла с таким же именем и портами, как указано в задании.
1. Обратите внимание, что имя памяти (не название модуля, а имя объекта памяти внутри модуля) должно быть `rf_mem`. Такое имя необходимо для корректной работы верификационного окружения.
2. В отличии от памяти инструкций и данных, ячейки памяти регистрового файла должны быть 32-битными (а на 8-битными). Это означает, что реализация портов чтения и записи будет проще.
2. Как и у памяти инструкций, порты чтения регистрового файла должны быть **асинхронными**.
3. Не забывайте, что у вас 2 порта на чтение и 1 порт на запись, при этом каждый порт не зависит от остальных (в модуле 3 независимых входа адреса).
4. Чтение из нулевого регистра (чтение по адресу 0) всегда должно возвращать нулевое значение. Этого можно добиться двумя путями:
1. Путем добавления мультиплексора перед выходным сигналом чтения (мультиплексор будет определять, пойдут ли на выход данные из ячейки регистрового файла, либо в случае если адрес равен нулю, на выход пойдет константа ноль).

File diff suppressed because it is too large Load Diff

View File

@@ -21,8 +21,9 @@
module tb_data_mem();
parameter ADDR_SIZE = 4096;
parameter TIME_OPERATION = 50;
parameter ADDR_SIZE = 16384;
parameter TIME_OPERATION = 20;
parameter STEP = 8;
logic CLK;
logic REQ;
@@ -41,9 +42,7 @@ parameter TIME_OPERATION = 50;
);
logic [31:0] RDa;
integer i, err_count = 0;
assign A = i;
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();
REQ = 1;
WE = 0;
i = 1; #10;
i = 0; #10;
if (RD !== 32'hx) begin
$display("The data memory should not be initialized by the $readmemh function");
err_count = err_count + 1;
@@ -67,8 +66,8 @@ parameter TIME_OPERATION = 50;
WE = 1;
WD = $urandom;
end
for (i = 0; i < (ADDR_SIZE+1); i = i + 1) begin
if (i != (ADDR_SIZE+1)) begin
for (i = 0; i < (ADDR_SIZE+STEP); i = i + 1 + $urandom() % STEP) begin
if (i < (ADDR_SIZE)) begin
REQ = |($urandom %10);
WE = 0;
#TIME_OPERATION;
@@ -87,10 +86,11 @@ parameter TIME_OPERATION = 50;
end
end
else begin
WE = 0;
REQ = 1;
#TIME_OPERATION;
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;
end
end
@@ -98,29 +98,34 @@ parameter TIME_OPERATION = 50;
end
#TIME_OPERATION;
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;
i = 2;
#TIME_OPERATION;
if (RD !== 32'hba98_7654) begin
$display("data is being written to the cell incorrectly. RAM [0:7] must be 0x0123456789abcdef, time: %t", $time);
for (i = 0; i < 4; i = i + 1) begin
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;
end
#TIME_OPERATION;
end
@(posedge CLK)
i = 0;
i = 0; WE = 0; REQ = 1;
@(posedge 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);
err_count = err_count + 1;
end
@(posedge CLK); #5;
if (RD !== 32'h7654_3210) begin
$display("synchronous data memory read error, time: %t", $time);
@(posedge CLK);
i = {14{1'b1}};
repeat(2) @(posedge CLK);
if (RD === 'd3735928559) begin
$display("incorrect reading from address = %d, data = %h", A, RD);
err_count = err_count + 1;
end
$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
42
07
00
02
02
00
00
01
40
84
10
63
94
11
00
01
60
04
10
0c
00
06
00
0d
40
01
00
0e
02
00
00
2f
00
00
00
0c
40
b0
10
0d
40
b4
10
0e
40
b8
10
0f
40
bc
10
10
00
10
00
11
80
01
00
12
14
00
00
73
00
00
00
22
00
00
00
43
00
00
00
84
00
00
00
05
01
00
00
06
02
00
00
07
04
00
00
08
08
00
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
00074221
00000202
10844001
00119463
10046001
0006000c
0001400d
0000020e
0000002f
10b0400c
10b4400d
10b8400e
10bc400f
00100010
00018011
00001412
00000073
00000022
00000043
00000084
00000105
00000206
00000407
00000808
00001009
00001fea
2004000b
30040000
30040000
30040000
30040000
30040000
30040000
30040000
30040000
30040000
7ea97ec0
13ad400b
7c2c4520
7c2c6540
7c2c8560
7c2ca580
7c2cc5a0
7c2ce5c0
7c2d05e0
7c2d2600
13866014
7c500200
13864014
7c500200
13862014
7c500200
13860014
7c500200
1385e014
7c500200
1385c014
7c500200
1385a014
7c500200
13858014
7c500200
bc040400
13066001
bc0403c0
13064001
bc040380
13062001
bc040340
13060001
bc040300
1305e001
bc0402c0
1305c001
bc040280
1305a001
bc040240
13058001
bc040200
12066001
bc0401c0
12064001
bc040180
12062001
bc040140
12060001
bc040100
1205e001
bc0400c0
1205c001
bc040080
1205a001
bc040040
12058001
bc041760

View File

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

View File

@@ -144,7 +144,7 @@
[cyberconverter](cyberconverter.cpp) — это программа, которая преобразует текстовый файл с инструкциями архитектуры CYBERcobra в текстовый файл, который сможет принять память инструкций.
cyberconverter может обрабатывать файлы, содержащие комментарии (начинающиеся с `//`), пробелы и пустые строки, а так же наборы символов `0` и `1`. Комментарии, пробелы и пустые строки удаляются, после чего оставшиеся строки из 32 нулей и единиц нарезаются на четверки по 8 бит, конвертируются в шестнадцатиричные значения и записываются в выходной файл.
cyberconverter может обрабатывать файлы, содержащие комментарии (начинающиеся с `//`), пробелы и пустые строки, а так же наборы символов `0` и `1`. Комментарии, пробелы и пустые строки удаляются, после чего оставшиеся строки из 32 нулей и единиц конвертируются в шестнадцатиричные значения и записываются в выходной файл.
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 << "whitespaces and binary digits '0' or '1'.\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 << "will be produced.\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;
return -2;
}
// split 32-bits binary line into 4 little-endian hex lines and write them into file
for (size_t i = 0; i < 4; i++)
// Convert into hex lines and write them into file
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.
// If illegal character found, throw error.
size_t valid_char_num;
string byte_substr = str.substr(8*(3-i), 8);
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";
cerr << "Illegal character '" << str.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[9];
// convert int representation into hex string
snprintf(hex_byte_str, 9, "%08x", cur_word);
ofs << hex_byte_str << "\n";
}
ifs.close();
ofs.close();

View File

@@ -18,7 +18,9 @@
## Порядок выполнения работы
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` в качестве управляющего сигнала которого подана единица, а выбор осуществляется не по значениям, а по сигналам:
```SystemVerilog

View File

@@ -1,4 +1,4 @@
# Лабораторная работа 7 "Периферийные устройства"
# Лабораторная работа 12 "Периферийные устройства"
На прошлой лабораторной работе вы реализовали свой собственный RISC-V процессор. Однако пока что он находится "в вакууме" и никак не связан с внешним миром. Для исправления этого недостатка вами будет реализована системная шина, через которую к процессору смогут подключаться различные периферийные устройства.
@@ -35,15 +35,15 @@
### Адресное пространство
Архитектура RISC-V подразумевает использование совместного адресного пространства, это значит, что в лабораторной работе будет использована единая шина для подключения памяти и регистров управления периферийными устройствами. При обращении по одному диапазону адресов процессор будет
попадать в память, при обращении по другим взаимодействовать с регистрами управления/статуса периферийного устройства. Например, можно разделить 32-битное адресное пространство на 256 частей, отдав старшие 8 бит адреса под указание конкретного периферийного устройства. Тогда каждое из периферийных устройств получит 24-битное адресное пространство (16 MiB). Допустим, мы распределили эти части адресного пространства в следующем порядке (от младшего диапазона адресов к старшему):
Архитектура RISC-V подразумевает использование совместного адресного пространства, это значит, что в лабораторной работе будет использована единая шина для подключения памяти и регистров управления периферийными устройствами. При обращении по одному диапазону адресов процессор будет попадать в память, при обращении по другим взаимодействовать с регистрами управления/статуса периферийного устройства. Например, можно разделить 32-битное адресное пространство на 256 частей, отдав старшие 8 бит адреса под указание конкретного периферийного устройства. Тогда каждое из периферийных устройств получит 24-битное адресное пространство (16 MiB). Допустим, мы распределили эти части адресного пространства в следующем порядке (от младшего диапазона адресов к старшему):
0. Переключатели
1. Светодиоды
2. Клавиатура PS/2
3. Семисегментные индикаторы
4. UART-приемник
5. UART-передатчик
0. Память данных
1. Переключатели
2. Светодиоды
3. Клавиатура PS/2
4. Семисегментные индикаторы
5. UART-приемник
6. UART-передатчик
В таком случае, если мы захотим обратиться в четвертый регистр семисегментных индикаторов, мы должны будем использовать адрес `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)
_Рисунок 1. Итоговая структура процессорной системы_
### Активация выбранного устройства
В зависимости от интерфейса используемой шины, периферийные устройства либо знают какой диапазон адресов им выделен (например, в интерфейсе 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`.
Для реализации такого кодирования достаточно выполнить сдвиг влево `255'd1` на значение `data_addr_o[31:24]`.
Для реализации такого кодирования достаточно выполнить сдвиг влево константы `255'd1` на значение `data_addr_o[31:24]`.
### Дополнительные правки модуля riscv_unit
@@ -91,7 +93,7 @@ module riscv_unit(
endmodule
```
Эти входы порты подключены к одноименным портам ваших контроллеров периферии (речь идет только о реализуемых вами контроллерах, остальные порты должны остаться неподключенными).
Эти порты подключены к одноименным портам ваших контроллеров периферии (речь идет только о реализуемых вами контроллерах, остальные порты должны остаться неподключенными).
Обратите внимание на то, что изменился сигнал сброса (`resetn_i`). Буква `n` на конце означает, что сброс работает по уровню `0` (когда сигнал равен нулю — это сброс, когда единице — не сброс).
@@ -99,8 +101,8 @@ endmodule
Для этого необходимо:
1. Подключить файл [`sys_clk_rst_gen.v`](sys_clk_rst_gen.v) в ваш проект.
2. Подключить этот модуль внутри `riscv_unit` следующим образом:
1. Подключить файл [`sys_clk_rst_gen.sv`](sys_clk_rst_gen.sv) в ваш проект.
2. Подключить этот модуль в начале описания модуля `riscv_unit` следующим образом:
```SystemVerilog
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 должны реализовать контроллеры переключателей и светодиодов.
2. Те кому достались варианты ИЗ 6-15 должны реализовать контроллеры клавиатуры PS/2 и семисегментных индикаторов.
3. Те кому достались варианты BP 16-29 должны реализовать контроллеры приемника и передатчика UART.
![Карта памяти](../../.pic/Labs/riscv_periph_memory_map.png)
![Карта памяти](../../.pic/Labs/lab_12_periph/fig_02.png)
Работа с картой осуществляется следующим образом. Под названием каждого периферийного устройства указана старшая часть адреса (чему должны быть равны старшие 8 бит адреса, чтобы было сформировано обращение к данному периферийному устройству). Например, для переключателей это значение равно `0x01`, для светодиодов `0x02` и т.п.
В самом левом столбце указаны используемые/неиспользуемые адреса в адресном пространстве данного периферийного устройства. Например для переключателей есть только один используемый адрес: `0x000000`. Его функциональное назначение и разрешения на доступ указаны в столбце соответствующего периферийного устройства. Возвращаясь к адресу `0x000000` для переключателей мы видим следующее:
* (R) означает что разрешен доступ только на чтение (операция записи по этому адресу должна игнорироваться вашим контроллером).
* "Выставленное на переключателях значение" означает ровно то что и означает. Если процессор выполняет операцию чтения по адресу 0x01000000 (`0x01` (старшая часть адреса переключателей) + `0x000000` (младшая часть адреса для получения выставленного на переключателях значения) ), то контроллер должен выставить на выходной сигнал RD значение на переключателях (о том как получить это значение будет рассказано чуть позже).
* **(R)** означает что разрешен доступ только на чтение (операция записи по этому адресу должна игнорироваться вашим контроллером).
* **"Выставленное на переключателях значение"** означает ровно то что и означает. Если процессор выполняет операцию чтения по адресу `0x01000000` (`0x01` (старшая часть адреса переключателей) + `0x000000` (младшая часть адреса для получения выставленного на переключателях значения) ), то контроллер должен выставить на выходной сигнал `RD` значение на переключателях (о том как получить это значение будет рассказано чуть позже).
Рассмотрим еще один пример. При обращении по адресу `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).
4. Обновите модуль `riscv_unit` в соответствии с разделом ["Дополнительные правки модуля riscv_unit"](#дополнительные-правки-модуля-riscv_unit).
1. Подключите в проект файл `sys_clk_rst_gen.sv`.
2. Добавьте в модуль `riscv_unit` входы и выходы периферии.
3. Подключите к модулю `riscv_unit` модуль `sys_clk_rst_gen` скопировав приведенный фрагмент кода.
2. Добавьте в модуль `riscv_unit` входы и выходы периферии. Необходимо добавить порты даже тех периферийных устройств, которые вы не будете реализовывать.
3. Создайте в начале описания модуля `riscv_unit` экземпляр модуля `sys_clk_rst_gen`, скопировав приведенный фрагмент кода.
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. При интеграции вы должны подключить только модули-контроллеры вашего варианта. Контроллеры периферии других вариантов подключать не надо.
2. При этом во время интеграции, вы должны использовать старшую часть адреса, представленную в карте памяти для формирования сигнала `req_i` для ваших модулей-контроллеров.
3. Даже если вы не используете какие-то входные/выходные сигналы в модуле `riscv_unit` (например по варианту вам не достался контроллер клавиатуры и поэтому вы не используете сигналы `kclk_i` и `kdata_i`), вы все равно должны их описать во входах и выходах модуля `riscv_unit`.
6. Проинициализируйте память инструкций с помощью предоставленной для каждой пары контроллеров программы.
6. Проверьте работу процессорной системы с помощью моделирования.
1. Для каждой пары контроллеров периферии предложено две программы: с обновлением данных по опросу и по прерываниям. Запустите моделирование сначала для одной программы, затем для другой (для этого необходимо обновить файл, инициализирующий память инструкций). После проверки работоспособности процессора, сравните поведение сигналов LSU для этих программ.
7. Подключите к проекту файл ограничений ([nexys_a7_100t.xdc](nexys_a7_100t.xdc)), если тот еще не был подключен, либо замените его содержимое данными из файла к этой лабораторной работе.
8. Проверьте работу вашей процессорной системы с помощью отладочного стенда с ПЛИС и (при соответствующем варианте) клавиатуры/рабочего компьютера.
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'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`.
@@ -201,7 +204,7 @@ module sw_sb_ctrl(
Часть интерфейса модуля, отвечающая за подключение к системной шине
*/
input logic clk_i,
input logic rst_i
input logic rst_i,
input logic req_i,
input logic write_enable_i,
input logic [31:0] addr_i,
@@ -237,7 +240,7 @@ module led_sb_ctrl(
Часть интерфейса модуля, отвечающая за подключение к системной шине
*/
input logic clk_i,
input logic rst_i
input logic rst_i,
input logic req_i,
input logic write_enable_i,
input logic [31:0] addr_i,
@@ -318,7 +321,7 @@ logic scan_code_is_unread;
endmodule
```
В первую очередь, вы должны инстанциировать модуль `PS2Receiver` внутри вашего модуля-контроллера, соединив соответствующие входы. Для подключения к выходам необходимо создать дополнительные провода.
В первую очередь, вы должны создать экземпляр модуля `PS2Receiver` внутри вашего модуля-контроллера, соединив соответствующие входы. Для подключения к выходам необходимо создать дополнительные провода.
По каждому восходящему фронту сигнала `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, // Битовая маска для включения/отключения
// отдельных индикаторов
output logic [6:0] hex_led_o // Сигнал, контролирующий каждый отдельный
output logic [6:0] hex_led_o, // Сигнал, контролирующий каждый отдельный
// светодиод индикатора
output logic [7:0] hex_sel_o // Сигнал, указывающий на какой индикатор
// выставляется hex_led
@@ -408,14 +411,14 @@ endmodule
|Адрес|Режим доступа|Допустимые значения| Функциональное назначение |
|-----|-------------|-------------------|---------------------------------------------------------|
|0x00 | RW | [0:31] | Регистр, хранящий значение, выводимое на hex0 |
|0x04 | RW | [0:31] | Регистр, хранящий значение, выводимое на hex1 |
|0x08 | RW | [0:31] | Регистр, хранящий значение, выводимое на hex2 |
|0x0C | RW | [0:31] | Регистр, хранящий значение, выводимое на hex3 |
|0x10 | RW | [0:31] | Регистр, хранящий значение, выводимое на hex4 |
|0x14 | RW | [0:31] | Регистр, хранящий значение, выводимое на hex5 |
|0x18 | RW | [0:31] | Регистр, хранящий значение, выводимое на hex6 |
|0x1C | RW | [0:31] | Регистр, хранящий значение, выводимое на hex7 |
|0x00 | RW | [0:15] | Регистр, хранящий значение, выводимое на hex0 |
|0x04 | RW | [0:15] | Регистр, хранящий значение, выводимое на hex1 |
|0x08 | RW | [0:15] | Регистр, хранящий значение, выводимое на hex2 |
|0x0C | RW | [0:15] | Регистр, хранящий значение, выводимое на hex3 |
|0x10 | RW | [0:15] | Регистр, хранящий значение, выводимое на hex4 |
|0x14 | RW | [0:15] | Регистр, хранящий значение, выводимое на hex5 |
|0x18 | RW | [0:15] | Регистр, хранящий значение, выводимое на hex6 |
|0x1C | RW | [0:15] | Регистр, хранящий значение, выводимое на hex7 |
|0x20 | RW | [0:255] | Регистр, управляющий включением/отключением индикаторов |
|0x24 | W | 1 | Запись сигнала сброса |
@@ -472,7 +475,7 @@ module uart_rx_sb_ctrl(
Часть интерфейса модуля, отвечающая за подключение к системной шине
*/
input logic clk_i,
input logic rst_i
input logic rst_i,
input logic [31:0] addr_i,
input logic req_i,
input logic [31:0] write_data_i,
@@ -502,7 +505,7 @@ module uart_tx_sb_ctrl(
Часть интерфейса модуля, отвечающая за подключение к системной шине
*/
input logic clk_i,
input logic rst_i
input logic rst_i,
input logic [31:0] addr_i,
input logic req_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)
- [Создание базового проекта с прошивкой ПЛИС в 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/)
- [Список типичных ошибок в Vivado и SystemVerilog](../Other/FAQ.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)
1.1 [Не запускается симуляция: FATAL_ERROR: PrivateChannel: Error creating client socket](#не-запускается-симуляция-fatal_error-privatechannel-error-creating-client-socket)
1.2 [Не запускается симуляция: boot::filesystem::remove: Процесс не может получить доступ к файлу, т.к. этот файл занят другим процессом](#не-запускается-симуляция-boot-filesystem-remove-процесс-не-может-получить-доступ-к-файлу)
1.3 [Вылетает Vivado при попытке открыть схему](#вылетает-vivado-при-попытке-открыть-схему)
1.4 [Не устанавливается Vivado: The following fatal error encountered while installing files: Unable to open archive](#не-устанавливается-vivado-unable-to-open-archive)
- [Список типичных ошибок при работе с Vivado и SystemVerilog](#список-типичных-ошибок-при-работе-с-vivado-и-systemverilog)
- [Содержание](#содержание)
- [Ошибки связанные с САПР Vivado](#ошибки-связанные-с-сапр-vivado)
- [Не запускается симуляция FATAL\_ERROR PrivateChannel Error creating client socket](#не-запускается-симуляция-fatal_error-privatechannel-error-creating-client-socket)
- [Не запускается симуляция 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
@@ -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` является регистром.
```Verilog
```SystemVerilog
module alu(input a, input b,
input [3:0] alu_op,
output reg flag,
output reg result
input logic [3:0] alu_op,
output logic flag,
output logic result
);
assign flag = alu_op[3] ? (a > b) : 1'b0; // ошибка
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` является проводом.
@@ -110,14 +110,14 @@ end
endmodule
```
---
--- -->
### имя сигнала is not a type
Скорее всего, компилятор не распознал присваивание, поскольку оно было записано с ошибками. Вне блоков `always` и `initial` можно выполнять только непрерывное присваивание (через `assign`).
```Verilog
module adder(input a, input b, output c);
```SystemVerilog
module half_adder(input logic a, input logic b, output logic c);
c = a ^ b; // ошибка, для непрерывного присваивания
// необходимо ключевое слово assign
endmodule
@@ -131,17 +131,17 @@ endmodule
Пример
```Verilog
module adder(input a, input b, output c);
```SystemVerilog
module half_adder(input logic a, input logic b, output logic c);
assign c = a ^ b;
endmodule
endmodule
module testbench();
reg A, B;
wire C;
logic A, B, C;
adder DUT(
.A(A), // <- здесь будет ошибка,
// т.к. в модуле adder нет порта 'A'
// т.к. в модуле half_adder нет порта 'A'
.b(B),
.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/))
- дополнительные материалы и литературу (WIP)
- популярные материалы (WIP)
- дополнительные материалы и литературу ([Other/Further readings.md](Other/Further%20readings.md))
- популярные материалы ([Other/Extras.md](Other/Extras.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)).
Имея доступ к этой странице ты имеешь доступ ко всему курсу АПС.