Skip to content
This repository was archived by the owner on Jun 6, 2025. It is now read-only.

Latest commit

 

History

History
81 lines (67 loc) · 2.35 KB

File metadata and controls

81 lines (67 loc) · 2.35 KB

Flow

Data flow in emulator

Memory structure

Memory is treated as a set of memory endpoints, which can be read and written. Endpoints are divided into three categories:
a. Register:
During execution cycle, provides constant read value, regardless of values being written to it. In the next cycle, written value is passed further.
b. Bus:
During execution cycle, reading from bus must be preceded with a write operation c. Disjointed:
Offering only a write or a read endpoint thus eliminating synchronization problems

Execution cycle

Step 1. An instruction is executed.
It consists of an array of forks with signal set arrays, of which every set gets executed procedurally.

Example add instruction w/ signals:
"add b a" : [
    FORKDESC(null),
    FORK(0) {
        [ b->ACCUMULATOR ],
        [ a->ALU_IN, alu_add, ACCUMULATOR->b ]
    }
]
Example conditional jump:
"jne PREV" : [
    FORKDESC(FLAG_EQUAL),
    FORK(0) {
        [ARG->INSTR_CNT]
    },
    FORK(1) {
        [INSTR_CNT++]
    }
]

Step 2. A set of signals is transformed.
Set is verified to contain only one write request for each memory endpoint. Set is divided into subsets where memory endpoints do not overlap over other sets. Then, each subset is ordered in sequence of memory transfers.
This step can and will be preprocessed to save processing power

Registers: [A] [B] [C] [D] [E] [F] [G] [B1] [B2]
Available signals: (a->b) (b->c) (c->a) (a->c) (c->b) (b->a) ...

Example valid set:
a->b, b->c
a->b, b->a    # Circular reference is valid, because
              # registers are read at a point in time

Example invalid set:
a->b, c->b    # Reason: multiple write assignments

Example subset division:
a->b, a->c, d->e, f->g
{a->b, a->c}, {d->e}, {f->g}

Example subset ordering:
d->e, a->b, c->d, b->c
a->b, b->c, c->d, d->e

B1->B2, B2->b, a->B1
a->B1, B1->B2, B2->b

Step 3. Signals in subsets are executed.
Memory transfers are realized sequentially.
This step could be split into multiple threads, but emulator only benefits from uncommon instructions containing signals that can be split into big amounts of subsets.

Step 4. Repeat.
Emulator does not provide any built-in instruction counter. It is on the architecture to provide a way to move to the next code segment, eg. incrementing arch-specific instruction register using a signal.