Esoteric Verilog

From Esolang
Jump to navigation Jump to search

This is an idea (not complete) of a experimental (and partially impossible) extension of Verilog with strange things, such as:

  • Quantum computing
  • Halting oracles
  • INTERCAL operations: ABSTAIN, REINSTATE, IGNORE, REMEMBER, bit interleave (Morton numbers), possibly also bit select and various other things too
  • Mechanical components
  • Time travel
  • More logical values (other than 0,1,x,z)
  • Reversible computing
  • Biological (e.g. DNA tic-tac-toe game (which always wins), made-up animals as the "DESosaur", etc)
  • Temperature
  • Self-modification
  • Roman numerals
  • Recursive module calls
  • Chemical reactions (some overlap with "biological", so some commands need to be used both)
  • INTERCAL-style STEAL/SMUGGLE networking
  • Physical errors (faulty components)/imperfect computing
  • Specify energy usages
  • Tape memory (including finite and infinite tapes, with one or more tracks)

Some of these things might be able to compile into standard Verilog, while some other of these things are completely impossible, and others are varying in this way. (Obviously, in esoteric programming, such considerations are unimportant.)

Extensions of Verilog-AMS can also be used in Esoteric Verilog.

It is permitted to combine all of these things together, even in cases that seems difficult.

(These should be made into sections once they get defined)

Keyword summary


(* = not yet defined; there are still more not listed here yet, too.)


This extension allows to define and link multiple containers of "digital matter". During execution an alternative process will run an abstract simulation of matter interaction in the system. Unless otherwise stated, the system uses real-life table of elements.

Control flow is achieved by defining the structure of the container network and assigning valves and gauges. The main causality comes from chemical reactions in the system. During the execution all of the gauges are always instantenously readable to the program.


Delay expressions with # are allowed to be a single delay or min/typ/max everywhere in the program, even where ordinary Verilog uses only a single delay. Such thing might be used for optimization purposes.

Roman numerals

You can have a roman constant with the format "'r" after the number of bits, and afterward you can put the roman numbers in uppercase. If there is a question mark it doesn't care and the compiler can be whatever you want (including to do strange things, if the different possible values cause strange effects!), but it is always one letter, which might go; this means "8'r?V" it might be IV or XV or LV or CV for example (DV won't fit in eight bits).

You can also output with roman numbers.

Halting oracles

You can have module call that says "oracle" before the only output parameter it has. Instead of receiving the actual output from the module call, it receives 0 if it is not ever going to change and 1 if it is going to change (it assume it will set to 1 if it has "halted").

Recursive module calls

A module is allowed to call itself, which can result in infinite amount of memory.

Quantum computing

Quantum registers can be declared by the qureg command (like normal register can be defined with the reg command).

There is also quwire (TODO: figure out and explain how this works).

Defining a quantum operator by a matrix can be done by the quprimitive command (like the primitive command does for ordinary gates). The number of input bits and output bits are required to be the same, and the matrix (inside of a matrix ... endmatrix block) is required to be unitary. Complex numbers can be specified inside of the matrix by (3,5) for 3+5i and so on. This matrix is automatically normalized by multiplying it by the correct positive scalar amount, to make it unitary, if such a thing is possible; if it is not possible, then it results in undefined behavior. This matrix also needs to have the number of rows being a power of two.

Built-in quantum primitives include: paulix, pauliy, pauliz, cnot, quswap, hadamard, toffoli, fredkin, phase90, and phase45. You can also use rotate and an angle (in degrees) in parentheses; in addition, after a quantum gate and parameters, you may include the keyword controls followed by additional inputs, which are used to make a controlled gate from any other gates (whether built-in or user-defined).

A quantum gate can be used as a primitive at top-level (but with quantum wires and registers, rather than classical signals), it can be used as a function in a continuous assign, and they can be used in <= and = assignments in always blocks. However, if a quantum register or part of one is in use, you cannot reuse the same one while it is still in use.

Inside of a always or initial block (but not in a continuous assign) you can initialize and measure quantum registers. If you use a classical value where a quantum value is expected, it initializes a quantum value (possibly causing other quantum registers to get mixed up if it is entangled and so on). If you use a quantum value where a classical value is expected, it will measure the quantum value.

The "quantum bogosort" algorithm involves destroy the entire universe (an impossible operation; included for (esoteric) completeness). The command to destroy the entire universe is destroy and is allowed in a initial or always block. For example, one way that a quantum register might be initialized (due to some circumstances it can be imperfect, such as if it is already initialized):

qureg [15:0] reg1;
initial if(|reg1) destroy;

Imperfect computing

There is the #% operator which is followed by a constant percentage (normally 0 to 100, but you can use numbers outside of this range too), meaning the probability that it is giving the correct answer, rather than just acting at random or whatever. You can have a single probability or min/typ/max probabilities. This operator can be used wherever the # delay operator is allowed.

Such things should be deleted if being compiled into a FPGA that does not support these kind of things. However, the optimizer might cause it to make race conditions or bus conflicts or whatever if the minimum probability is not greater than zero, even in a FPGA without these kind of imperfection, if it is able to support race condition/bus conflict in these ways; however, the optimizer is not obligated to do so.