Virtual machine and interpreter
- asm - синтаксис ассемблера. Необходима поддержка label-ов.
- risc - система команд должна быть упрощенной, в духе RISC архитектур.
- neum - фон Неймановская архитектура.
- hw - hardwired. Control Unit реализуется как часть модели.
- instr -- процессор необходимо моделировать с точностью до каждой инструкции (наблюдается состояние после каждой инструкции). (Так как в варианте прерывания, было удобнее сделать вывод потактово, чтобы явно показать где случилось прерывание)
- struct -- в виде высокоуровневой структуры данных. Считается, что одна инструкция укладывается в одно машинное слово, за исключением CISC архитектур. (Усложнил до варианта binary)
- trap -- Ввод-вывод осуществляется токенами через систему прерываний.
- mem -- memory mapped output
<letter> ::= [a-z] | [A-Z]
<digit> ::= [0-9]
<digit_list> ::= <digit> | <digit> <digit_list>
<digit_or_letter> ::= <letter> | <digit>
<digit_or_letter_list> ::= <sign> | <sign> <digit_or_letter_list>
<identifier> ::= <letter> | <letter> <digit_or_letter_list>
<sign> ::= "-" | "+"
<comment> ::= ";" <digit_or_letter_list>
<register> ::= "ZR" | "mtvec" | "mepc" | x[3-6]
<immediate> ::= <digit_list>
<shift> ::= <sign> <immediate> "(" <register> ")"
<no_args_op> ::= "halt"
<one_args_op> ::= "jmp" | "jg" | "bne" | "beq"
<two_args_op> ::= "ld" | "sw" | "cmp"
<three_arg_op> ::= "addi" | "add" | "rem" | "mul"
<one_args_instr> ::= <one_args_op> <identifier>
<two_args_instr> ::= <two_arg_op> <register> <shift> | <two_arg_op> <register> <immediate>
<three_args_instr> ::= <three_arg_op> <register> <register> <immediate> | <three_arg_op> <register> <register>
<instruction> ::= <no_args_op> <comment> | <one_args_op> <comment> | <two_args_instr> <comment> | <three_args_instr> <comment> | <comment>
<label> ::= <identifier>
<program_line> ::= <label> <instruction> | <label> | <instruction>
<program_line_list> ::= <program_line> | <program_line> <program_line_list>
<section> ::= "section" <identifier> <program_line_list>
<section_list> ::= <section> | <section> <section_list>
<program> ::= <section_list>
section .text
_start:
ld x4, +120(ZR) ; Load symbol from input device(cell #0)
sw x4, +121(ZR) ; Save symbol to output device(cell #1)
halt
label:
- метка (для выполнения иструкций перехода)._start:
- обязательная метка, сигнализирующая начало программы, может находиться где угодно, главное чтобы указывала на инструкцию.- На одни и те же инструкции (команды и данные) могут быть указаны несколько меток, однако метки не могут дублироваться, и одни и те же метки указывать на разные инструкции.
- Область видимости глобальная.
section <name>
- создать секцию с именем<name>
. Данные внутри секций идут последовательно..text
- секция для кода.data
- секция для данных
Название управляющего сигнала | Назнчение |
---|---|
PCWrite | Разрешение защелкнуть значение в регистре PC |
AdrSrc | Коммутировать мультиплексор ведущий от PC |
IOOp | Выставление флага операции на КВУ |
MemWrite | Разрешение записи в память |
IRWrite | Защелкнуть значение в IR регистре |
WDSrc | Коммутировать мультиплексор ведущий к WD |
ImmSrc | Выставить флаг расширения на SignExpand |
ALUControl | Выставить флаг операции ALU |
ALUSrcB | Коммутировать мультиплексор ведущий ко входу B |
ALUSrcA | Коммутировать мультиплексор ведущий ко входу A |
RegWrite | Разрешение записи в регистровый файл |
Zero | Флаг нулевого результата выходящий из ALU |
PositiveFlag | Флаг позитивного результата выходящий из ALU |
- Память одна на команды и данные(согласно варианту). Память адресуется с помощью 17-битного адреса.
- При попытке исполнить данные как инструкцию программа падает с ошибкой.
- Scope в языке глобальный.
- Размер машинного слова 16 бит. Адресация абсолютная.
- Структура памяти неоднородная, первые 32 ячейки зарезервированы под устройства ввода-вывода.
- Пользователю доступны 6 регистров(остальные два - CSR регистры)
Название регистра | Алиас | Назначение |
---|---|---|
x0 | ZR | Регистр всегда хранит 0 |
x1 | - | Регистр общего назначения |
x2 | - | Регистр общего назначения |
x3 | - | Регистр общего назначения |
x4 | - | Регистр общего назначения |
x5 | - | Регистр общего назначения |
x6 | mtvec | Interrupt vector address |
x7 | mepc | Previous PC value |
Memory (for data and instructions)
+----------------------------------+
| ... |
| 0x00: var1 |
| 0x20: var2 |
| 0x40: cmd1 |
| 0x60: cmd2 |
| ... |
| mtvec_val interruption handler 0 |
| ... |
+----------------------------------+
Инструкции и данные не перемешиваются(сначала данные, потом инструкции). Обработчик прерывания размещается в последних 4 машинных словах.
-
Машинное слово -- 17 бит, знаковое.
-
Память данных и команд:
- Адресуется через DR.
- Адрес следующей команды хранится в аккумуляторе
- Регистр x0 не может изменятся, там статично лежит значение 0.
-
Ввод-вывод - memory-mapped. Ячейки 120, 121 зарезервированы под внешние устройства.
-
Program_counter - счетчик команд. Инкрементируется с каждой инструкцией, может быть перезаписан командой перехода.
-
Прерываний есть, состояние PC, ALUResult, и состояние шины инструкции сохраняется . После обработки прерывания работа программы возобновляется.
-
Машина поддерживает только абсолютную адресацию.
-
Присутствует флаг Z (zero), PositiveFlag(flag if alu result is positive) для команд перехода.
№ | Название команды | Назначение | 4 бит | 3 бит | 3 бит | 3 бит | 4 бит | Кол-во тактов |
---|---|---|---|---|---|---|---|---|
0 | ADDI reg1, reg2, IMM | reg1 = reg2 + IMM | IMM[6:3] | IMM[2:0] | reg2 | reg1 | OPCODE | 4 |
1 | ADD reg1, reg2, reg3 | reg1 = reg2 + reg3 | reg3 | reg2 | reg1 | OPCODE | 4 | |
2 | REM reg1, reg2, reg3 | reg1 = reg2 % reg3 | reg3 | reg2 | reg1 | OPCODE | 4 | |
3 | MUL reg1, reg2, reg3 | reg1 = reg2 * reg3 | reg3 | reg2 | reg1 | OPCODE | 4 | |
4 | DIV reg1, reg2, reg3 | reg1 = reg2 // reg3 | reg3 | reg2 | reg1 | OPCODE | 4 | |
5 | LD reg1, IMM(reg2) | reg1 = MEM(reg2 + IMM) | IMM[6:3] | IMM[2:0] | reg2 | reg1 | OPCODE | 4 |
6 | SW reg1, IMM(reg2) | MEM(reg2 + IMM) = reg1 | IMM[6:3] | reg1 | reg2 | IMM[2:0] | OPCODE | 4 |
7 | CMP reg1, IMM(reg2) | SET FLAGS (reg1 - reg2) | IMM[6:3] | reg1 | reg2 | IMM[2:0] | OPCODE | 4 |
8 | JMP IMM(reg1) | PC = reg1 + IMM | IMM[6:3] | IMM[2:0] | reg1 | OPCODE | 3 | |
9 | JG IMM(reg1) | PC = reg1 + IMM IF PositiveFlag | IMM[6:3] | IMM[2:0] | reg1 | OPCODE | 3 | |
10 | BNE IMM(reg1) | PC = reg1 + IMM IF NOT ZeroFlag | IMM[6:3] | IMM[2:0] | reg1 | OPCODE | 3 | |
11 | BEQ IMM(reg1) | PC = reg1 + IMM IF ZeroFlag | IMM[6:3] | IMM[2:0] | reg1 | OPCODE | 3 | |
12 | HALT | Останов. | OPCODE | 2 |