Skip to content
Martijn Bastiaan edited this page Jun 15, 2015 · 11 revisions

Single Sprockell

Like almost all processors, Sprockell deploys a decoder to split its given instruction into its components. These components are guaranteed to complete in one cycle, and their results will be used to either write to local memory, shared memory and registers. The diagram below illustrates how these components are (roughly) tied together:

Sprockell layout

Note that this image does not show all components, which you would have to look up in the source files.

Unlike "real" processors, the program is not stored in main memory and is therefore not changeable during runtime. By default, dmem can hold 128 words, although this is configurable in Sprockell.hs. The local memory also stores the stack.

On each cycle, the Sprockell fetches an instruction from the program memory and passes it to the decoder. The decoder is responsible for breaking these instructions into various input signals for specific components. For example, consider the operation store (storing means writing the value of a specific register to local memory):

Sprockell layout

As usual, the Sprockell fetches an instruction from the program memory and passes it to the decoder. The decoder will then signal both the deference- and store component to perform their duty. Note that the store component takes the output of the dereferencer as input. No consider all the other lines:

Sprockell layout

Surely these lines/wires cannot hold no values, as this makes no sense in hardware (a signal is either one or zero, but not 'nothing'). A simple solution would be to let each component take another signal to indicate whether they should be active or not. This however is expensive (in terms of hardware costs) and therefore not feasible. Instead, each component emits 'default' values. The ALU writes to register zero, and XORs with zero for example.

Stack

Because the stack is stored in the local memory of a Sprockell, it can (and will!) cause collisions with other data stored there if it grows too large. By convention, the stack starts at the highest address of the memory (default:127) and grows down until it reaches the smallest (0). Obviously, beyond this point no guarantees can be given about the behaviour of the Sprockell.

Sprockell stack

Registers

Each Sprockell has a number of registers with the following names (indexes):

Register Description
Zero Contains always the value zero (even after writing to it)
PC Program counter
SP Stack pointer. Points to the top of the stack.
SPID Contains the Sprockell ID. Only meaningful when deploying multiple Sprockells.
RegA, RegB, ..., RegE Registers available for user data

Multiple Sprockells

Multiple Sprockells are deployed by tying them together using shared memory. A single Sprockell communicates with the shared memory by using a bus, which is shown as dotted box in the first image on this page. A request to the shared memory has to pass through a queue, a message scheduler, io device and on its way back again through a queue. All in all, the diagram looks like:

The I/O mapper maps addresses to their respective I/O devices. The following addresses (hexadecimal) exist:

From To (inclusive) Description
0 0xFFFFFF Shared memory
0x1000000 0x1000000 Stdin / stdio

For example, one could write to stdout by issuing:

Write RegA (Addr 0x1000000)

while writing to address 127 (dec) of the shared memory would look like:

Write RegA (Addr 0x7F)

Note that the default shared memory size is thus 16 MiB (16.7 MB).

Clone this wiki locally