-
Notifications
You must be signed in to change notification settings - Fork 24
Encoding scheme
NOTE : The short forms used in this encoding doc are as follows :
C : constant (value is the constant specified) V : variable (value is the address where variable V is located) Arr[C] => V (since, the final value is address(Arr) + C, viz a variable).
Note that V will be used instead of Arr[C] throughout the document.
Arr[V] : array indexed by variable V
(I should probably write how the variable stuff work here... and also how the doc is structured)
The SET instruction is of the form
SET x, y
where x (operand-1) can be either V or Arr[v] whereas y (operand-2) can be either C, V, Arr[v].
The general function of this instruction is to set variable values. (In some cases it is also used to create variables)
There are many possible ways a SET instruction can be used based on how we choose x and y There are three possible opcodes (as given below) that handle all conditions of x, y.
OPCODE used : 0x10 (16) to 0x12 (18)
This is a 32 bit instruction. This instruction is the case when operand-1 is a V or A[c] and opernad-2 is a constant (max 16 bit).
opcode
0x10 (16)
operation
Sets the value of variable V to the 16 bit int value C.
If V has not been previously defined, it creates and assigns.
encoding format (each value separated by a comma takes one byte)
OPCODE, VARIABLE, CONST-hi, CONST-lo
Byte3 : 0001-0000 : (OPCODE - Fixed)
Byte2 : VARIABLE : (address of the variable V)
Byte1 : CONST-hi : (MS-byte of constant C)
Byte0 : CONST-lo : (LS-byte of constant C)
Example
coming soon :)
This is a 32 bit instruction. This instruction is the case when operand-1 and operand-2 are either V (or Arr[c])
opcode
0x11 (17)
operation
Sets the value of variable V1 to the value of variable V2.
If V1 has not been previously defined, it creates and assigns.
(give some more explanation? or put that in the examples? - I think in example is better)
encoding format (each value separated by a comma takes one byte)
OPCODE, VARIABLE, unused, VARIABLE
Byte3 : OPCODE : 0001-0001 (OPCODE - Fixed)
Byte2 : VARIABLE : (address of the variable V1)
Byte1 : unused : (unused)
Byte0 : VARIABLE : (address of the variable V2)
Example
coming soon :)
This is a 64 bit instruction. This instruction is the case when either x (operand-1) or y (operand-2) is of the form Arr[v].
The possible forms of instructions :
SET V1, Arr[V2]
SET Arr[V], 280
SET Arr[V1], V2
SET Arr[V1], Arr[V2]
opcode
0x12 (18)
operation
Sets the value of variable "x" to the value of "y"
If "x" is a variable (not Arr[v]) and has not been previously defined, it creates and assigns.
If "x" is of type Arr[v], and Arr has not been defined, it is an error.
encoding format (each value separated by a comma takes one byte)
OPCODE, OP_type , OP1.b, OP1.a
unused, unused , OP2.b, OP2.a
(OP1 : x, OP2 : y)
Byte3 : OPCODE : 0001-0010 (OPCODE - Fixed)
Byte2 : OP_type : (operand type - since the operands can be of any type, this indicates what the operands are)
Byte1 : OP1.b : (reserved for operator 1, actual value depends on OP_decider)
Byte0 : OP1.a : (reserved for operator 1, actual value depends on OP_decider)
Byte4 : OP2.b : (reserved for operator 2, actual value depends on OP_decider)
Byte5 : OP2.a : (reserved for operator 2, actual value depends on OP_decider)
Byte6 : unused : unused
Byte7 : unused : unused
OP_Type (8 bits)
00 00 - 0000
\ / \ / \ /
x y unused
bit 7,6 : type of operand x
bit 5,4 : type of operand y
bit encoding that indicate what the corresponding operators are :
(and what they represent in the encoding in each case)
00 => C (Constant)
OP.a : Const-lo
OP.b : Const-hi
01 => V (Variable)
OP.a : Variable address of V
OP.b : unused
10 => Arr[V]
OP.a : Variable address of V
OP.b : Array address of Arr.
(add a simple example here)
Example
coming soon :)
This instruction is of the form
SET RES[x], y
Where RES is a reserved array variable such as DIO, PWM, COM, TMR, AIO;
x can be either C or V where as y (operand-2) can be either C, V, Arr[v].
This behaves like a regular SET instruction, but has been given special opcodes as :
- These instruction use reserved arrays
- They are used often, so giving exclusive byte code makes execution faster on the PRU
- Normally these sort of instructions will take 64bits; whereas here all take only 32bits
Hence these inst are not compiled as a part of normal SET instruction.
OPCODE used : 0x01 (1) to 0xFF (15)
This is a 32 bit instruction. Here x and y can be either a Constant (C) or Vriable(V).
The possible forms of the instruction :
SET DIO[C], C
SET DIO[C], V
SET DIO[V], C
SET DIO[V], V
opcode
0x01 (01)
operation
Sets the specified digital output to either high or low
(see more in the examples)
encoding format
OPCODE, OP_type, OP1, OP2
Byte3 : OPCODE : 0000-0001 (OPCODE - Fixed)
Byte2 : OP_type : (operand type - this indicates what type the operands are)
Byte1 : OP1 : (not exactly operand1, but rather 'x' in DIO[x])
Byte0 : OP2 : (operand2, (i.e.) "y"))
Note : actual value of OP1 and OP2 will depend on type of "x" and "y".
and the type information is encoded in OP_type as given below.
OP_type (making sense of the 8 bits)
0 0 00-0000
| | \ /
x y unused
bit 7 - type of "x"
bit 6 - type of "y"
semantics
0 => type is constant C
1 => type is Variable V
(add a simple example here)
Example
coming soon :)
This is a 32 bit instruction. Here first operand is DIO indexed by a Constant (C) and the second operand is a variable indexed Array (Arr[v]).
opcode
0x02 (02)
operation
Sets the specified digital output to either high or low
(see more in the examples)
encoding format
OPCODE, CONST, Arr, VARIABLE
Byte3 : OPCODE : 0000-0010 (OPCODE - Fixed)
Byte2 : CONST : CONSTANT value C
Byte1 : Arr : Array address
Byte0 : VARIABLE : address of variable V
(add a simple example here)
Example
coming soon :)
This is a 32 bit instruction. Here first operand is DIO indexed by a Variable (V1) and the second operand is a variable indexed Array (Arr[v2]).
opcode
0x03 (03)
operation
Sets the specified digital output to either high or low
(see more in the examples)
encoding format
OPCODE, VARIABLE, Arr, VARIABLE
Byte3 : OPCODE : 0000-0010 (OPCODE - Fixed)
Byte2 : VARIABLE : address of variable V1
Byte1 : Arr : Array address
Byte0 : VARIABLE : the array index value - variable value V2
(add a simple example here)
Example
coming soon :)
This is a 32 bit instruction. Here x and y can be either a Constant (C) or Vriable(V).
The possible forms of the instruction :
SET PWM[C], C
SET PWM[C], V
SET PWM[V], C
SET PWM[V], V
opcode
0x04 (04)
operation
Sets the specified PWM output to the mentioned value
(see more in the examples)
encoding format
Same as 2.a (change only opcode)
Example
coming soon :) - or see 2.a again?
This is a 32 bit instruction. Here first operand is DIO indexed by a Constant (C) and the second operand is a variable indexed Array (Arr[v]).
opcode
0x05 (05)
operation
Sets the specified PWM output to the mentioned value
(see more in the examples)
encoding format
same as 2.a
Example
coming soon :)
This is a 32 bit instruction. Here first operand is DIO indexed by a Variable (V1) and the second operand is a variable indexed Array (Arr[v2]).
opcode
0x06 (06)
operation
Sets the specified PWM output to the mentioned value
(see more in the examples)
encoding format
same as 2.a
Example
coming soon :)
Just like DIO & PWM, the above mentioned instructions have 3 opcodes for each of the following instruction type
- SET RES[C], C/V
- SET RES[C], Arr[V]
- SET RES[V], Arr[V]
Only things that change are the operation and OPCODE. (encoding and examples are more or less the same)
AIO : Sets the value of the anolog output
COM : Writes the value to the indexed com port.
TMR : Sets the timer value
AIO : 0x07, 0x08, 0x09
COM : 0x0A, 0x0B, 0x0C
TMR : 0x0D, 0x0E, 0x0F
This instruction is of the form
IF ( x <cond> y ) GOTO z
Where x (first operand), y (second operand), z (third operand) can be any of C, V, Arr[V]. Here is a relational operator such as '>', '<', '==', '!=' etc.
There is no different cases for this instruction, rather one 64 bit instruction which handles all possible variable types internally.
opcode
The **OPCODE** starts from 0x20 (0b0010-0000) and ends at 0x2F (0b0010-1111).
How this works is this instruction reserves the "0b0010-xxxx" instruction space.
The last 4 bits takes its value based upon <cond>. The mapping is as shown below.
cond_code = {
'==' : 0b0000,
'!=' : 0b0001,
'>=' : 0b0010,
'<=' : 0b0011,
'>' : 0b0100,
'<' : 0b0101
}
operation
The comparision is carried out between "x" and "y", if the result is true, then the IP (inst pointer) jumps to the inst number specified by "x"
encoding
OPCODE, OP_type, OP1.b, OP1.a
OP3.b , OP3.a, OP2.b, OP2.a
(x : OP1, y: OP2, z : OP3)
Byte3 : OPCODE : 0001-0010 (OPCODE - Fixed)
Byte2 : OP_type : (operand type - since the operands can be of any type, this indicates what the operands are)
Byte1 : OP1.b : (reserved for operator 1, actual value depends on OP_decider)
Byte0 : OP1.a : (reserved for operator 1, actual value depends on OP_decider)
Byte4 : OP2.b : (reserved for operator 2, actual value depends on OP_decider)
Byte5 : OP2.a : (reserved for operator 2, actual value depends on OP_decider)
Byte6 : OP3.a : (reserved for operator 3, actual value depends on OP_decider)
Byte7 : OP3.b : (reserved for operator 3, actual value depends on OP_decider)
Note : actual value of OP1 and OP2 will depend on type of "x" and "y".
and the type information is encoded in OP_type as given below.
OP_type (making sense of the 8 bits)
00 00 - 00 00
\ / \ / \ /\ /
x y z unused
bit 7,6 : type of operand x
bit 5,4 : type of operand y
bit 3,2 : type of operand z
bit encoding that indicate what types the corresponding operators are :
(and how they are placed in the byte encoding in each case)
00 => C (Constant)
OP.a : Const
OP.b : unused
01 => V (Variable)
OP.a : Variable address of V
OP.b : unused
10 => Arr[V]
OP.a : Variable address of V
OP.b : Array address of Arr.
(add a simple example here)
Example
coming soon :)
This instruction is of the form
WAIT x
where x (the only operand) can be of type C or V or Arr[v]
This is a 32 bit instruction.
opcode
0x14 (20)
operation
Executing this command will pause the execution of the running script for
"x" mili seconds. (The wait is non blocking - more about this later)
encoding
OPCODE, OP_type, OP.b, OP.a
since the operand can be any of three types, the OP_type will tell us the
type of "x" in the instruction.
The OP_type is encoded as follows
00 00 - 0000
\/ \ /
x unused
bit value to type of OP ("x") mapping :
00 => OP is of type 'C'
OP.a = Const
OP.b = unused
01 => OP is of type 'V'
OP.a = VARIABLE
OP.b = unused
10 => OP is of type Arr[V]
OP.a = VARIABLE
OP.b = ARR
examples
coming soon :)
This instruction is of the form
GOTO x
where x (the only operand) can be of type C or V or Arr[v]
This is a 32 bit instruction.
opcode
0x15 (21)
operation
Executing this command will cause the IP (instruction pointer) to jump to instruction number "x"
encoding
OPCODE, OP_type, OP.b, OP.a
since the operand can be any of three types, the OP_type will tell us the
type of "x" in the instruction.
The OP_type is encoded as follows
00 00 - 0000
\/ \ /
x unused
bit value to type of OP ("x") mapping :
00 => OP is of type 'C'
OP.a = Const
OP.b = unused
01 => OP is of type 'V'
OP.a = VARIABLE
OP.b = unused
10 => OP is of type Arr[V]
OP.a = VARIABLE
OP.b = ARR
examples
coming soon :)
This instruction is of the form
GET x
where x (the only operand) can be of type C or V or Arr[v]
This is a 32 bit instruction.
opcode
0x16 (22)
operation
Executing this command will return the value of "x"
encoding
OPCODE, OP_type, OP.b, OP.a
since the operand can be any of three types, the OP_type will tell us the
type of "x" in the instruction.
The OP_type is encoded as follows
00 00 - 0000
\/ \ /
x unused
bit value to type of OP ("x") mapping :
00 => OP is of type 'C'
OP.a = Const
OP.b = unused
01 => OP is of type 'V'
OP.a = VARIABLE
OP.b = unused
10 => OP is of type Arr[V]
OP.a = VARIABLE
OP.b = ARR
examples
coming soon :)
This instruction is of the form
INS x, y
where INS is a arithmetic or bitwise operation command; x (operand1) and y (operand2) can be of type C or V or Arr[v]
There are 32 bit and 64 bit variations for each instruction.
opcode
Each INST uses 2 opcodes (one for 32 bit encoding, another for 64 bit) based on what the x, y values are. opcode starts from 48 (0011-0000), ends at 79 (0100-1111). Bit excoding is done based on this map containing INST to the LS nibble value of the corresponding OPCODE.
opcode_dict = {
#These inst own the (0011-XXXX) address space
'ADD' : 48,
'SUB' : 50,
'MUL' : 52,
'DIV' : 54,
'MOD' : 56,
#These inst own the (0100-XXXX) address space
'BSL' : 64,
'BSR' : 66,
'AND' : 68,
'OR' : 70,
'NOT' : 72
}
This is a 32 bit instruction where y can be a variable or constant.
opcode
0x30 (48)
operation
Executing this command will add y to V and return the new value of V
encoding
OPCODE, OP_type, VARIABLE, OP
Byte3 : OPCODE : 0011-0000 (OPCODE - Fixed)
Byte2 : OP_type : (operand type - since the operands can be of any type, this indicates what the operands are)
Byte1 : VARIABLE : (the address of variable V)
Byte0 : OP : (reserved for operator 1, actual value depends on OP_decider)
since the operand can be C or V, the OP_type will tell us the type of "y" in the instruction.
The OP_type (8bits) is encoded as follows :
1000 - 0000
|
y
if bit 6 == 0
type(y) = C
OP -> C
if bit 6 == 1
type(y) = VARIABLE
OP -> address of variable "y"
examples
coming soon :)
This is a 64 bit instruction where either x or y is of type Arr[V] Note that x can't be of type C, while y can be of any type.
opcode
0x31 (49)
operation
Executing this command will add y to x and return the new value of x
encoding
OPCODE, OP_type , OP1.b, OP1.a
unused, unused , OP2.b, OP2.a
(OP1 : x, OP2 : y)
Byte3 : OPCODE : 0011-0001 (OPCODE - Fixed)
Byte2 : OP_type : (operand type - since the operands can be of any type, this indicates what the operands are)
Byte1 : OP1.b : (reserved for operator 1, actual value depends on OP_decider)
Byte0 : OP1.a : (reserved for operator 1, actual value depends on OP_decider)
Byte4 : OP2.b : (reserved for operator 2, actual value depends on OP_decider)
Byte5 : OP2.a : (reserved for operator 2, actual value depends on OP_decider)
Byte6 : unused : unused
Byte7 : unused : unused
OP_Type (8 bits)
00 00 - 0000
\ / \ / \ /
x y unused
bit 7,6 : type of operand x
bit 5,4 : type of operand y
bit encoding that indicate what the corresponding operators are :
(and what they represent in the encoding in each case)
00 => C (Constant)
OP.a : Const-lo
OP.b : Const-hi
01 => V (Variable)
OP.a : Variable address of V
OP.b : unused
10 => Arr[V]
OP.a : Variable address of V
OP.b : Array address of Arr.
(add a simple example here)
examples
coming soon :)
These instructions are similar to ADD discussed above. Each have two versions - 32bit and 64 bit version. The opcode for the 32 bit version has been mentioned at the begining of section 7, the OPCODE for 64 bit is opcode for 32 bit + 1 The encoding pattern is the same, only thing that changes is the pattern operation
SUB x, y : x = x - y, return x
MUL x, y : x = x * y, return x
DIV x, y : x = x / y, return x
AND x, y : x = x & y, return x
OR x, y : x = x | y, return x
BSL x, y : x = x >> y, return x
BSR x, y : x = x << y, return x
NOT x, y : x = ~y, return x
Simple instruction with no operands
opcode
0x7F (127)
operation
Executing this instruction halts an ongoing BotSpeak script in the PRU.
If no script is running, this instruction does nothing.
encoding
OPCODE, unused, unused, unused
Byte3 : OPCODE : 0111-1111 (fixed)
Byte2-0 : unused : unused
examples
coming soon
These instructions are known as control instructions. They are not run on the PRU, rather are interpreted on the Linux side. (userspace python lib for now, may later be moved to the kernel)
opcode
None - it is not compiled,
rather the compiler framework itself interprets the cmd and does the needful.
operation
ABORT : kills the current script, all variables and arrays defined are freed.
DEBUG : streams the PRU Speak variables and state to the userspace.
SCRIPT : marks the starting of a script.
ENDSCRIPT : marks the ending of a script.
RUN : runs the most recently defined script.
encoding
NO enccoding
examples
coming soon