Copyright © 2009 Purdea Andrei


The esoteric hardware description language.

Note, this is NOT an hardware implementation of a brainfuck interpreter. Something like that can be found here. This is a separate programming language that is based on the original Brainfuck programming language. After a quick search for "esoteric hdl" didn't turn up anything interesting i decided to extend brainfuck. In addition to the 8 well-known commands ( > ; < ; + ; - ; [ ; ] ; , ; . ), i added two more:

The entire brainfuckHDL program has one global data array, but each process has its own data pointer, and instruction pointer. These are reset to zero every time a process starts executing from the beginning, but they are left unchanged if the process continues execution after a # command.

The data array is partitioned into groups of 3 bytes. Each group represends a signal. The 3 bytes represent the old, current, and next values of a signal. These bytes can contain single bits, or up to 8 bit values. To detect an event on a signal, a brainfuckHDL process must compare the old and current values of the signal. To update a signal, a process must write the "next" byte of the signal. The old and current bytes are allowed to be used as temporary storage, because they are restored after a process has stopped executing. Note that these temporary values are not kept after a # command is executed.

Sensitivity lists or other event control statements are not needed. The interpreter keeps executing all processes in the same time tick, until none of the signals change (the current and next values are the same for all signals). In other words each process is triggered on ALL events, unless the said process is executing a # command.


Here is a d flip-flop (second process) together with a testbench(first process):


The previous example with comments can be found here

Other example pseudocode (not tested):

The Interpreter

A C implementation of the brainfuckHDL interpreter can be found here .

Interpreter Pseudocode:
initialize entire array to 0
do {
    next signals = current signals;
    do {
        old signals = current signals;
        current signals = next signals;
        s_old = old
        s_curr = curr
        for each process if wait == 0 {
            execute until #, or end of process
            if end of process {
                process.instruction_pointer = 0
                process.data_pointer = 0
            } else {
                process.waittime = *process.data_pointer;
            old = s_old // restore saved values
            curr = s_curr
    } while (next signals != current signals);

    if there is a nonzero wait time {
        time = time + min(processes[*].wait);
        processes[*].wait -= min(processes[*].wait);
} while (there was a nonzero wait time);