128 lines
7.6 KiB
Markdown
128 lines
7.6 KiB
Markdown
```
|
|
qbits n
|
|
cbits n
|
|
qregs n
|
|
cregs n
|
|
mem n
|
|
|
|
<code>
|
|
```
|
|
|
|
The order of the headers is important and should not be changed. The `qbits` header specifies the number of
|
|
qubits in each quantum register. The `cbits` header specifies the number of classical bits in each classical
|
|
register. The `qregs` header specifies the number of quantum registers. The `cregs` header specifies the number
|
|
of classical registers. The `n` after each header is any integer number. Operands/arguments for all
|
|
instructions are delimited by spaces and not commas.
|
|
|
|
Code execution should always end at a `hlt` instruction. If the emulator reaches the end of code but does not
|
|
encounter a `hlt` instruction, it will end with a "PC out of bounds" error.
|
|
|
|
## Quantum Instructions
|
|
The general format for quantum instructions are:
|
|
```
|
|
op qn <other arguments>
|
|
```
|
|
Where `op` is the name/opcode, `qn` specifies a specific qubit `n` of the currently selected quantum register.
|
|
`<other arguments>` can include more qubits as arguments, or in the case of some instructions, a rotation expressed
|
|
as a rational multiple of pi, in the format `[n]pi[/n]`, where `n` can be any integer number, and items
|
|
in `[]` are optional. Quantum registers can be selected via the `qsel` instruction, which has the general format
|
|
`qsel qrn` where `n` is any non-negative number.
|
|
|
|
List of currently implemented quantum instructions:
|
|
|
|
| Quantum Gate | Instruction name | Syntax example | Explanation |
|
|
| ------------------- | ---------------- | ------------------- | ----------- |
|
|
| Hadamard | h | `h q0` | Applies a Hadamard to qubit 0 |
|
|
| CNOT | cnot | `cnot q0 q1` | Applies a CNOT to qubit 1 with qubit 0 being the control |
|
|
| CCNOT/Toffoli | ccnot | `ccnot q0 q1 q2` | Applies a Toffoli to qubit 2 with qubit 0 and qubit 1 being the controls |
|
|
| Pauli X | x | `x q0` | Applies a Pauli X to qubit 0 |
|
|
| Pauli Y | y | `y q0` | Applies a Pauli Y to qubit 0 |
|
|
| Pauli Z | z | `z q0` | Applies a Pauli Z to qubit 0 |
|
|
| Rx | rx | `rx q0 pi/3` | Rotates the statevector of qubit 0 by pi/3 radians along X axis on bloch sphere |
|
|
| Ry | ry | `ry q0 pi` | Rotates the statevector of qubit 0 by pi radians along Y axis on bloch sphere |
|
|
| Rz | rz | `rz q0 pi/4` | Rotates the statevector of qubit 0 by pi/4 radians along Z axis on bloch sphere |
|
|
| U gate | u | `u q0 pi pi/3 pi/6` | Rotates the statevector of qubit 0 by the 3 Euler angles pi, pi/3, pi/6 |
|
|
| S gate | s | `s q0` | Applies an S gate to qubit 0 |
|
|
| T gate | t | `t q0` | Applies a T gate to qubit 0 |
|
|
| S-dagger | sdg | `sdg q0` | Applies a S-dagger or the inverse of S gate to qubit 0 |
|
|
| T-dagger | tdg | `tdg q0` | Applies a T-dagger or the inverse of T gate to qubit 0 |
|
|
| Phase gate | p | `p q0 pi/3` | Applies a relative phase of pi/3 radians to qubit 0 |
|
|
| Controlled Hadamard | ch | `ch q0 q1` | Applies a controlled Hadamard to qubit 1 with qubit 0 being the control |
|
|
| Controlled Pauli Y | cy | `cy q0 q1` | Applies a controlled Pauli Y to qubit 1 with qubit 0 being the control |
|
|
| Controlled Pauli Z | cz | `cz q0 q1` | Applies a controlled Pauli Z to qubit 1 with qubit 0 being the control |
|
|
| Controlled Phase | cp | `cp q0 q1 pi/2` | Applies a controlled Phase gate to qubit 1 of pi/2 radians with qubit 0 being the control |
|
|
| Swap | swap | `swap q0 q1` | Swaps the state of qubits 0 and 1 |
|
|
| Square Root NOT | sqrtx | `sqrtx q0 ` | Applies a sqrt(NOT)/sqrt(X) to qubit 0 |
|
|
| Square Root Swap | sqrtswp | `sqrtswp q0 q1` | Applies a sqrt(Swap) to qubits 0 and 1, halfway swapping their state |
|
|
| Controlled Swap | cswap | `cswap q0 q1 q2` | Swaps the state of qubits 1 and 2 with qubit 0 being the control |
|
|
| Measure | m | `m q0 cr1 c3` | Measures the state of qubit 0 into 3rd bit of classical register 1 |
|
|
|
|
*Note: Remove any measurement operations before running the emulator with `--print-state` (or `-p`) as the emulator does not ignore them currently when run with that flag set*
|
|
|
|
## Classical Instructions
|
|
General format for classical instructions are:
|
|
```
|
|
op <operands>
|
|
```
|
|
Where `op` is the name/opcode, operands may include `crn`, which specifies a specific classical register `n`, or
|
|
an immediate literal value (for now non-negative due to not implemented in parser yet) Other than these differences,
|
|
they behave basically the same as any other assembly language instructions.
|
|
|
|
List of currently implemented classical instructions:
|
|
|
|
*Note: The value of a register refers to the value stored in the register. The value of an immediate is the immediate number itself.*
|
|
|
|
*Note 2: An operand can either be a register or immediate unless a restriction is specified.*
|
|
|
|
| Instruction name | Description |
|
|
| ---------------- | ----------- |
|
|
| add | op1 = op2 + op3. op1 is always a register. |
|
|
| sub | op1 = op2 - op3. op1 is always a register. |
|
|
| mult | op1 = op2 * op3. op1 is always a register. All values are treated unsigned. |
|
|
| umult | op1 = (op2 * op3) >> (cbits/2). op1 is always a register. All values are treated unsigned. |
|
|
| div | op1 = op2 / op3. op1 is always a register. Performs integer division. All values are treated unsigned. |
|
|
| smult | op1 = op2 * op3. op1 is always a register. All values are treated signed. |
|
|
| sumult | op1 = (op2 * op3) >> (cbits/2). op1 is always a register. All values are treated signed. |
|
|
| sdiv | op1 = op2 / op3. op1 is always a register. Performs integer division. All values are treated signed. |
|
|
| not | op1 = ~op2. op1 is always a register. |
|
|
| and | op1 = op2 & op3. op1 is always a register. |
|
|
| or | op1 = op2 \| op3. op1 is always a register. |
|
|
| xor | op1 = op2 ^ op3. op1 is always a register. |
|
|
| nand | op1 = ~(op2 & op3). op1 is always a register. |
|
|
| nor | op1 = ~(op2 \| op3). op1 is always a register. |
|
|
| xnor | op1 = ~(op2 ^ op3). op1 is always a register. |
|
|
|
|
## Misc. Instructions
|
|
These instructions are here because.
|
|
|
|
| Instruction name | Description |
|
|
| ---------------- | ----------- |
|
|
| qsel | Selects a quantum register so that proceeding quantum instructions act on that qreg. |
|
|
| cmp | Updates flags based on comparing values in op1 and op2. op1 is always a register. |
|
|
| jmp | Unconditionally jump to a label. |
|
|
| jeq | Jump to label if comparison resulted in EQ flag set. |
|
|
| jne | Jump to label if comparsion did not result in EQ flag set. |
|
|
| jg | Jump to label if comparison resulted in GREATER flag set. |
|
|
| jge | Jump to label if comparison resulted in GREATER or EQ flag set. |
|
|
| jl | Jump to label if comparison resulted in LESSER flag set. |
|
|
| jle | Jump to label if comparison resulted in LESSER or EQ flag set. |
|
|
| hlt | Halt the program. |
|
|
|
|
# Examples
|
|
This program simulates the $\ket{\Phi^+}$ bell state:
|
|
```
|
|
qbits 2
|
|
cbits 2
|
|
qregs 1
|
|
cregs 1
|
|
|
|
qsel qr0
|
|
h q0
|
|
cnot q0 q1
|
|
|
|
m q0 cr0 c0
|
|
m q1 cr0 c1
|
|
|
|
hlt
|
|
```
|