Skip to content

Commit

Permalink
readme
Browse files Browse the repository at this point in the history
  • Loading branch information
ruskaof committed Dec 18, 2023
1 parent 283f852 commit ed5a4c2
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 3 deletions.
164 changes: 162 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

Любое выражение в скобках (s-expression) возвращает значение.
Поддерживаются числовые и строковые литералы.
Типизация динамическая, поддерживаются два типа: целые числа и строки. Причем
функции `get_char`, `print_char` работают именно с целыми числами.

```bnf
program = s_expression
Expand All @@ -25,9 +27,11 @@ expression = defun_expr
| if_expr
| while_expr
| setq_exp
| print_int_exp
| print_char_exp
| print_string_exp
| user_defined_function_call_exp
| progn_exp
| import_expr
defun_expr = "(" "defun" identifier "(" identifiers ")" s_expression ")"
Expand All @@ -39,7 +43,9 @@ while_expr = "(" "while" s_expression s_expression ")"
setq_exp = "(" "setq" identifier s_expression ")"
print_int_exp = "(" "print_int" s_expression ")"
print_char_exp = "(" "print_char" s_expression ")"
print_string_exp = "(" "print_string" s_expression ")"
user_defined_function_call_exp = "(" identifier s_expressions ")"
Expand All @@ -54,8 +60,162 @@ idenitfier_symbol = letter | "_"
string_literal = "\"" *any symbol* "\""
```

* `defun` - определение функции, возвращает 0. Рекурсивные функции не поддерживаются, так как не требовались.
* `if` - условный оператор, возвращает значение второго выражения, если первое не равно 0, иначе третье.
Обязательно должно быть три выражения - условие, ветка иначе, ветка истины.
* `while` - цикл с предусловием, возвращает результат последнего выражения в теле цикла в последней итерации.
* `setq` - присваивание, возвращает значение присвоенной переменной.
* `print_char` - выводит символ с кодом, равным значению выражения, возвращает код символа.
* `print_string` - выводит строку, равную значению выражения, возвращает выведенную строку.
* `progn` - последовательное выполнение выражений, возвращает результат последнего выражения.
* вызов функции - возвращает результат функции (последнего выражения в теле функции).
* литералы - возвращают сами себя.
* идентификаторы - возвращают значение переменной, к которой они привязаны.
Использование идентификатора функции без ее вызова недопустимо.

## Организация памяти

Фон Неймановская архитектура.

Память представляет из себя три секции:

```angular2html
+-----------------+
| JMP_TO_CODE |
+-----------------+
| STATIC_DATA |
| |
| |
| |
+-----------------+
| CODE |
| |
| |
| |
+-----------------+
| STACK |
| |
| |
+-----------------+
```

* `JMP_TO_CODE` - единственная инструкция, которая по своей сути является адресной командой
JMP, которая переходит на начало секции `CODE`.

* `STATIC_DATA` - секция, в которой хранятся строки (строковые литералы, а также строки, введенные пользователем)
Строки расположены в том порядке, в котором они встречаются в AST программы (в этом контексте объявление буффера для
ввода пользователя - тоже строка)

* `CODE` - секция, в которой хранятся инструкции.

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

Функции хранятся в секции `CODE` в виде списка инструкций, которые выполняются последовательно. Перед
телом функции идет инструкция `JMP`, которая позоляет перепрыгнуть через ее тело.

Все переменные аллоцируются на стеке. Если при этом переменная была объявлена внутри функции,
область ее видимости ограничивается телом функции.

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

Так как у процессора аккумуляторная архитектура, то в аккумуляторе всегда хранится лишь результат последнего
вычисленного выражения, дополнительных регистров для хранения исключительно переменных нет.

## Система команд

* Машинное слово - 64 бита, знаковое.
* Так как архитектура аккумуляторная, все команды имеют всего один аргумент (или ни одного), а регистр
общего назначения всего один.
* Ввод-вывод осущетсвляется как поток токенов, port-mapped.
* Поток управления:
* Поддерживаются условные и безусловные переходы.
* В случае, если инструкция не касается переходов, то после нее инкрементится IP (Instruction Pointer).

Поддерживаются 4 вида адресации:
* Непосредственная
* Относительно стека
* Косвенная (относительно значения по переданному адресу)
* Адресная

Также команда может быть безадресной.

На выполнение каждой инструкции есть 4 цикла:
1. Цикл выборки инструкции.
2. Цикл выборки адреса (для адресации относительно стека и косвенной).
3. Цикл выборки операнда (для всех видов адресации, кроме непосредственной).
4. Цикл исполнения.

### Набор инструкций

| Инструкция | ард/безадр | Количество тактов в цикле исполнения | Описание |
|------------|------------|--------------------------------------|----------------------------------------------------------------------|
| `LD` | ард | 1 | AC <- MEM(ARD) |
| `ST` | ард | 1 | MEM(ARD) <- AC |
| `ADD` | ард | 1 | AC <- AC + MEM(ARD) |
| `SUB` | ард | 1 | AC <- AC - MEM(ARD) |
| `MUL` | ард | 1 | AC <- AC * MEM(ARD) |
| `DIV` | ард | 1 | AC <- AC / MEM(ARD) |
| `MOD` | ард | 1 | AC <- AC % MEM(ARD) |
| `EQ` | ард | 1 | if AC == MEM(ARD) then AC <- 1 else AC <- 0 |
| `GT` | ард | 1 | if AC > MEM(ARD) then AC <- 1 else AC <- 0 |
| `LT` | ард | 1 | if AC < MEM(ARD) then AC <- 1 else AC <- 0 |
| `JZ` | ард | 1 | if AC == 0 then IP <- ARD |
| `JNZ` | ард | 1 | if AC != 0 then IP <- ARD |
| `JMP` | ард | 1 | IP <- ARD |
| `PUSH` | безадр | 2 | SP <- SP - 1; MEM(SP) <- AC |
| `POP` | безадр | 1 | SP <- SP + 1 |
| `IN` | безадр | 1 | AC <- next_token |
| `OUT` | безадр | 1 | print AC |
| `CALL` | ард | 3 | SP <- SP - 1; MEM(SP) <- IP; IP <- ARD |
| `RET` | безадр | 2 | IP <- MEM(SP); SP <- SP + 1 |
| `HLT` | безадр | 1 | завершение работы программы |

## Траслятор
Транслятор состоит из двух частей:
* Лексер, реализован в [tokenizer](./computer_simulator/translator/tokenizer.py)
* Модуль, преобразующий токены в программу, реализован в [expression_translator](./computer_simulator/translator/expression_translator.py)

На вход принимает два файла:
* Файл с программой на языке высокого уровня.
* Путь к файлу, в который будет записана программа в машинных словах (в виде JSON)

## Модель процессора
Модель процессора реализована в [machine](./computer_simulator/machine)

### DataPath

![Processor](./resources/DataPath.png)

Реализован в классе `DataPath`

Элементы:
* `Z` - Флаг zero
* `DR` - Data Register
* `IP` - Instruction Pointer
* `SP` - Stack Pointer
* `AC` - Accumulator
* `ALU` - Arithmetic Logic Unit

### ControlUnit
Реализован в классе `ControlUnit`

![Processor](./resources/ControlUnit.png)

Основная работа с данными происходит на уровне DataPath, а ControlUnit с помощью
сигналов работает с этими данными. ControlUnit реализован как hardwired.

## Тестирование

Реализованы unit тесты для лексера ([test_tokenizer](./test/test_tokenizer.py))
Также реализованы golden тесты согласно примеру ([test_golden](./test/test_golden.py)):
* ([hello](./golden/hello.yml))
* ([cat](./golden/cat.yml)
* ([hello_user_name](./golden/hello_user.yml))
* ([prob1](./golden/prob1_very_small.yml))

Также реализованы некоторые дополнительные алгоритмы:


2 changes: 1 addition & 1 deletion computer_simulator/isa.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class Instruction:
def __str__(self) -> str:
r = f"{self.opcode}"
if self.arg:
r += f" arg[{self.arg}]"
r += f" arg[{self.arg}] "
if self.comment:
r += f" ({self.comment})"
return f"Instr({r})"
Binary file added resources/ControlUnit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/DataPath.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes.

0 comments on commit ed5a4c2

Please sign in to comment.