@@ -5,23 +5,39 @@ import (
55 "math"
66)
77
8+ // InstrKind is a enum for the PIO instruction type. It only represents the kind of
9+ // instruction. It cannot store the arguments.
10+ type InstrKind uint8
11+
12+ const (
13+ InstrJMP InstrKind = iota
14+ InstrWAIT
15+ InstrIN
16+ InstrOUT
17+ InstrPUSH
18+ InstrPULL
19+ InstrMOV
20+ InstrIRQ
21+ InstrSET
22+ )
23+
824// This file contains the primitives for creating instructions dynamically
925const (
10- INSTR_BITS_JMP = 0x0000
11- INSTR_BITS_WAIT = 0x2000
12- INSTR_BITS_IN = 0x4000
13- INSTR_BITS_OUT = 0x6000
14- INSTR_BITS_PUSH = 0x8000
15- INSTR_BITS_PULL = 0x8080
16- INSTR_BITS_MOV = 0xa000
17- INSTR_BITS_IRQ = 0xc000
18- INSTR_BITS_SET = 0xe000
26+ _INSTR_BITS_JMP = 0x0000
27+ _INSTR_BITS_WAIT = 0x2000
28+ _INSTR_BITS_IN = 0x4000
29+ _INSTR_BITS_OUT = 0x6000
30+ _INSTR_BITS_PUSH = 0x8000
31+ _INSTR_BITS_PULL = 0x8080
32+ _INSTR_BITS_MOV = 0xa000
33+ _INSTR_BITS_IRQ = 0xc000
34+ _INSTR_BITS_SET = 0xe000
1935
2036 // Bit mask for instruction code
21- INSTR_BITS_Msk = 0xe000
37+ _INSTR_BITS_Msk = 0xe000
2238)
2339
24- type SrcDest uint16
40+ type SrcDest uint8
2541
2642const (
2743 SrcDestPins SrcDest = 0
@@ -37,125 +53,122 @@ const (
3753 SrcExecOut SrcDest = 7
3854)
3955
40- func MajorInstrBits (instr uint16 ) uint16 {
41- return instr & INSTR_BITS_Msk
42- }
56+ type JmpCond uint8
4357
44- func EncodeInstrAndArgs (instr uint16 , arg1 uint16 , arg2 uint16 ) uint16 {
45- return instr | (arg1 << 5 ) | (arg2 & 0x1f )
46- }
58+ const (
59+ // No condition, always jumps.
60+ JmpAlways JmpCond = iota
61+ // Jump if X is zero.
62+ JmpXZero
63+ // Jump if X is not zero, prior to decrement of X.
64+ JmpXNZeroDec
65+ // Jump if Y is zero.
66+ JmpYZero
67+ // Jump if Y is not zero, prior to decrement of Y.
68+ JmpYNZeroDec
69+ // Jump if X is not equal to Y.
70+ JmpXNotEqualY
71+ // Jump if EXECCTRL_JMP_PIN (state machine configured) is high.
72+ JmpPinInput
73+ // Compares the bits shifted out since last pull with the shift count theshold
74+ // (configured by SHIFTCTRL_PULL_THRESH) and jumps if there are remaining bits to shift.
75+ JmpOSRNotEmpty
76+ )
4777
48- func EncodeInstrAndSrcDest (instr uint16 , dest SrcDest , value uint16 ) uint16 {
49- return EncodeInstrAndArgs (instr , uint16 (dest )& 7 , value )
78+ // EncodeInstr encodes an arbitrary PIO instruction with the given arguments.
79+ func EncodeInstr (instr InstrKind , delaySideset , arg1_3b , arg2_5b uint8 ) uint16 {
80+ return uint16 (instr & 0b111 )<< 13 | uint16 (delaySideset & 0x1f )<< 8 | uint16 (arg1_3b & 0b111 )<< 5 | uint16 (arg2_5b & 0x1f )
5081}
5182
52- func EncodeDelay ( cycles uint16 ) uint16 {
53- return cycles << 8
83+ func majorInstrBits ( instr uint16 ) uint16 {
84+ return instr & _INSTR_BITS_Msk
5485}
5586
56- func EncodeSideSet ( bitCount uint16 , value uint16 ) uint16 {
57- return value << ( 13 - bitCount )
87+ func encodeInstrAndArgs ( instr uint16 , arg1 uint8 , arg2 uint8 ) uint16 {
88+ return instr | ( uint16 ( arg1 ) << 5 ) | uint16 ( arg2 & 0x1f )
5889}
5990
60- func EncodeSetSetOpt ( bitCount uint16 , value uint16 ) uint16 {
61- return 0x1000 | value << ( 12 - bitCount )
91+ func encodeInstrAndSrcDest ( instr uint16 , dest SrcDest , value uint8 ) uint16 {
92+ return encodeInstrAndArgs ( instr , uint8 ( dest ) & 7 , value )
6293}
6394
64- func EncodeJmp ( addr uint16 ) uint16 {
65- return EncodeInstrAndArgs ( INSTR_BITS_JMP , 0 , addr )
95+ func EncodeDelay ( cycles uint8 ) uint16 {
96+ return 0b11111 & ( uint16 ( cycles ) << 8 )
6697}
6798
68- func EncodeIRQ (relative bool , irq uint16 ) uint16 {
69- instr := irq
99+ func EncodeSideSet (bitCount , value uint8 ) uint16 {
100+ return uint16 (value ) << (13 - bitCount )
101+ }
70102
71- if relative {
72- instr |= 0x10
73- }
103+ func EncodeSetSetOpt ( bitCount uint8 , value uint8 ) uint16 {
104+ return 0x1000 | uint16 ( value ) << ( 12 - bitCount )
105+ }
74106
75- return instr
107+ func EncodeJmp (addr uint8 , condition JmpCond ) uint16 {
108+ return encodeInstrAndArgs (_INSTR_BITS_JMP , uint8 (condition & 0b111 ), addr )
76109}
77110
78- func EncodeWaitGPIO (polarity bool , pin uint16 ) uint16 {
79- flag := uint16 (0 )
80- if polarity {
81- flag = 0x4
82- }
111+ func encodeIRQ (relative bool , irq uint8 ) uint8 {
112+ return boolAsU8 (relative ) << 4
113+ }
83114
84- return EncodeInstrAndArgs (INSTR_BITS_WAIT , 0 | flag , pin )
115+ func EncodeWaitGPIO (polarity bool , pin uint8 ) uint16 {
116+ flag := boolAsU8 (polarity ) << 2
117+ return encodeInstrAndArgs (_INSTR_BITS_WAIT , 0 | flag , pin )
85118}
86119
87- func EncodeWaitPin (polarity bool , pin uint16 ) uint16 {
88- flag := uint16 (0 )
89- if polarity {
90- flag = 0x4
91- }
120+ func EncodeWaitPin (polarity bool , pin uint8 ) uint16 {
121+ flag := boolAsU8 (polarity ) << 2
92122
93- return EncodeInstrAndArgs ( INSTR_BITS_WAIT , 1 | flag , pin )
123+ return encodeInstrAndArgs ( _INSTR_BITS_WAIT , 1 | flag , pin )
94124}
95125
96- func EncodeWaitIRQ (polarity bool , relative bool , irq uint16 ) uint16 {
97- flag := uint16 (0 )
98- if polarity {
99- flag = 0x4
100- }
126+ func EncodeWaitIRQ (polarity bool , relative bool , irq uint8 ) uint16 {
127+ flag := boolAsU8 (polarity ) << 2
101128
102- return EncodeInstrAndArgs ( INSTR_BITS_WAIT , 2 | flag , EncodeIRQ (relative , irq ))
129+ return encodeInstrAndArgs ( _INSTR_BITS_WAIT , 2 | flag , encodeIRQ (relative , irq ))
103130}
104131
105- func EncodeIn (src SrcDest , value uint16 ) uint16 {
106- return EncodeInstrAndSrcDest ( INSTR_BITS_IN , src , value )
132+ func EncodeIn (src SrcDest , value uint8 ) uint16 {
133+ return encodeInstrAndSrcDest ( _INSTR_BITS_IN , src , value )
107134}
108135
109- func EncodeOut (dest SrcDest , value uint16 ) uint16 {
110- return EncodeInstrAndSrcDest ( INSTR_BITS_OUT , dest , value )
136+ func EncodeOut (dest SrcDest , value uint8 ) uint16 {
137+ return encodeInstrAndSrcDest ( _INSTR_BITS_OUT , dest , value )
111138}
112139
113140func EncodePush (ifFull bool , block bool ) uint16 {
114- arg := uint16 (0 )
115- if ifFull {
116- arg |= 2
117- }
118- if block {
119- arg |= 1
120- }
121-
122- return EncodeInstrAndArgs (INSTR_BITS_PUSH , arg , 0 )
141+ arg := boolAsU8 (ifFull )<< 1 | boolAsU8 (block )
142+ return encodeInstrAndArgs (_INSTR_BITS_PUSH , arg , 0 )
123143}
124144
125145func EncodePull (ifEmpty bool , block bool ) uint16 {
126- arg := uint16 (0 )
127- if ifEmpty {
128- arg |= 2
129- }
130- if block {
131- arg |= 1
132- }
133-
134- return EncodeInstrAndArgs (INSTR_BITS_PULL , arg , 0 )
146+ arg := boolAsU8 (ifEmpty )<< 1 | boolAsU8 (block )
147+ return encodeInstrAndArgs (_INSTR_BITS_PULL , arg , 0 )
135148}
136149
137150func EncodeMov (dest SrcDest , src SrcDest ) uint16 {
138- return EncodeInstrAndSrcDest ( INSTR_BITS_MOV , dest , uint16 (src )& 7 )
151+ return encodeInstrAndSrcDest ( _INSTR_BITS_MOV , dest , uint8 (src )& 7 )
139152}
140153
141154func EncodeMovNot (dest SrcDest , src SrcDest ) uint16 {
142- return EncodeInstrAndSrcDest ( INSTR_BITS_MOV , dest , (1 << 3 )| (uint16 (src )& 7 ))
155+ return encodeInstrAndSrcDest ( _INSTR_BITS_MOV , dest , (1 << 3 )| (uint8 (src )& 7 ))
143156}
144157
145158func EncodeMovReverse (dest SrcDest , src SrcDest ) uint16 {
146- return EncodeInstrAndSrcDest ( INSTR_BITS_MOV , dest , (2 << 3 )| (uint16 (src )& 7 ))
159+ return encodeInstrAndSrcDest ( _INSTR_BITS_MOV , dest , (2 << 3 )| (uint8 (src )& 7 ))
147160}
148161
149- func EncodeIRQSet (relative bool , irq uint16 ) uint16 {
150- return EncodeInstrAndArgs ( INSTR_BITS_IRQ , 0 , EncodeIRQ (relative , irq ))
162+ func EncodeIRQSet (relative bool , irq uint8 ) uint16 {
163+ return encodeInstrAndArgs ( _INSTR_BITS_IRQ , 0 , encodeIRQ (relative , irq ))
151164}
152165
153- func EncodeIRQClear (relative bool , irq uint16 ) uint16 {
154- return EncodeInstrAndArgs ( INSTR_BITS_IRQ , 2 , EncodeIRQ (relative , irq ))
166+ func EncodeIRQClear (relative bool , irq uint8 ) uint16 {
167+ return encodeInstrAndArgs ( _INSTR_BITS_IRQ , 2 , encodeIRQ (relative , irq ))
155168}
156169
157- func EncodeSet (dest SrcDest , value uint16 ) uint16 {
158- return EncodeInstrAndSrcDest ( INSTR_BITS_SET , dest , value )
170+ func EncodeSet (dest SrcDest , value uint8 ) uint16 {
171+ return encodeInstrAndSrcDest ( _INSTR_BITS_SET , dest , value )
159172}
160173
161174func EncodeNOP () uint16 {
@@ -196,3 +209,10 @@ func splitClkdiv(clkdiv uint64) (whole uint16, frac uint8, err error) {
196209 frac = uint8 (clkdiv % 256 )
197210 return whole , frac , nil
198211}
212+
213+ func boolAsU8 (b bool ) uint8 {
214+ if b {
215+ return 1
216+ }
217+ return 0
218+ }
0 commit comments