1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227 | --
-- Copyright (C) 2022 Jeremy Grosser <jeremy@synack.me>
--
-- SPDX-License-Identifier: BSD-3-Clause
--
with Ada.Unchecked_Conversion;
package RP.PIO.Encoding
with Preelaborate
is
type JMP_Condition is
(Always,
Scratch_X_Zero, -- !X
Scratch_X_Nonzero_Decrement, -- X--
Scratch_Y_Zero, -- !Y
Scratch_Y_Nonzero_Decrement, -- Y--
X_Notequal_Y, -- X!=Y
Input_Pin, -- PIN
OSRE_Not_Empty) -- !OSRE
with Size => 3;
type JMP is record
Opcode : HAL.UInt3 := 2#000#;
Delay_Sideset : HAL.UInt5 := 0;
Condition : JMP_Condition := Always;
Address : HAL.UInt5 := 0;
end record
with Size => 16;
for JMP use record
Opcode at 0 range 13 .. 15;
Delay_Sideset at 0 range 8 .. 12;
Condition at 0 range 5 .. 7;
Address at 0 range 0 .. 4;
end record;
type WAIT_Source is
(GPIO, PIN, WAIT_IRQ)
with Size => 2;
type WAIT is record
Opcode : HAL.UInt3 := 2#001#;
Delay_Sideset : HAL.UInt5 := 0;
Polarity : Boolean := False;
Source : WAIT_Source := GPIO;
Index : HAL.UInt5 := 0;
end record
with Size => 16;
for WAIT use record
Opcode at 0 range 13 .. 15;
Delay_Sideset at 0 range 8 .. 12;
Polarity at 0 range 7 .. 7;
Source at 0 range 5 .. 6;
Index at 0 range 0 .. 4;
end record;
type SHIFT_IN_Source is
(PINS, X, Y, ZERO, ISR, OSR)
with Size => 3;
for SHIFT_IN_Source use
(PINS => 2#000#,
X => 2#001#,
Y => 2#010#,
ZERO => 2#011#,
ISR => 2#110#,
OSR => 2#111#);
type SHIFT_IN is record
Opcode : HAL.UInt3 := 2#010#;
Delay_Sideset : HAL.UInt5 := 0;
Source : SHIFT_IN_Source := PINS;
Bit_Count : HAL.UInt5; -- 0 = 32
end record
with Size => 16;
for SHIFT_IN use record
Opcode at 0 range 13 .. 15;
Delay_Sideset at 0 range 8 .. 12;
Source at 0 range 5 .. 7;
Bit_Count at 0 range 0 .. 4;
end record;
type SHIFT_OUT_Destination is
(PINS, X, Y, DISCARD, PINDIRS, PC, ISR, EXEC)
with Size => 3;
for SHIFT_OUT_Destination use
(PINS => 2#000#,
X => 2#001#,
Y => 2#010#,
DISCARD => 2#011#,
PINDIRS => 2#100#,
PC => 2#101#,
ISR => 2#110#,
EXEC => 2#111#);
type SHIFT_OUT is record
Opcode : HAL.UInt3 := 2#011#;
Delay_Sideset : HAL.UInt5 := 0;
Destination : SHIFT_OUT_Destination := PINS;
Bit_Count : HAL.UInt5; -- 0 = 32
end record
with Size => 16;
for SHIFT_OUT use record
Opcode at 0 range 13 .. 15;
Delay_Sideset at 0 range 8 .. 12;
Destination at 0 range 5 .. 7;
Bit_Count at 0 range 0 .. 4;
end record;
type PUSH is record
Opcode : HAL.UInt3 := 2#100#;
Delay_Sideset : HAL.UInt5 := 0;
Opcode_2 : Boolean := False;
If_Full : Boolean := False;
Block : Boolean := False;
Opcode_3 : HAL.UInt5 := 0;
end record
with Size => 16;
for PUSH use record
Opcode at 0 range 13 .. 15;
Delay_Sideset at 0 range 8 .. 12;
Opcode_2 at 0 range 7 .. 7;
If_Full at 0 range 6 .. 6;
Block at 0 range 5 .. 5;
Opcode_3 at 0 range 0 .. 4;
end record;
type PULL is record
Opcode : HAL.UInt3 := 2#100#;
Delay_Sideset : HAL.UInt5 := 0;
Opcode_2 : Boolean := True;
If_Empty : Boolean := False;
Block : Boolean := False;
Opcode_3 : HAL.UInt5 := 0;
end record
with Size => 16;
for PULL use record
Opcode at 0 range 13 .. 15;
Delay_Sideset at 0 range 8 .. 12;
Opcode_2 at 0 range 7 .. 7;
If_Empty at 0 range 6 .. 6;
Block at 0 range 5 .. 5;
Opcode_3 at 0 range 0 .. 4;
end record;
type MOV_Target is
(PINS, X, Y, EXEC, PC, ISR, OSR)
with Size => 3;
for MOV_Target use
(PINS => 2#000#,
X => 2#001#,
Y => 2#010#,
EXEC => 2#100#,
PC => 2#101#,
ISR => 2#110#,
OSR => 2#111#);
type MOV_Operation is
(None, Invert, Bit_Reverse)
with Size => 2;
type MOV is record
Opcode : HAL.UInt3 := 2#101#;
Delay_Sideset : HAL.UInt5 := 0;
Destination : MOV_Target := PINS;
Operation : MOV_Operation := None;
Source : MOV_Target := PINS;
end record
with Size => 16;
for MOV use record
Opcode at 0 range 13 .. 15;
Delay_Sideset at 0 range 8 .. 12;
Destination at 0 range 5 .. 7;
Operation at 0 range 3 .. 4;
Source at 0 range 0 .. 2;
end record;
type IRQ is record
Opcode : HAL.UInt3 := 2#110#;
Delay_Sideset : HAL.UInt5 := 0;
Opcode_2 : Boolean := False;
Clear : Boolean := False;
Wait : Boolean := False;
Index : HAL.UInt5;
end record
with Size => 16;
for IRQ use record
Opcode at 0 range 13 .. 15;
Delay_Sideset at 0 range 8 .. 12;
Opcode_2 at 0 range 7 .. 7;
Clear at 0 range 6 .. 6;
Wait at 0 range 5 .. 5;
Index at 0 range 0 .. 4;
end record;
type SET_Destination is
(PINS, X, Y, PINDIRS)
with Size => 3;
for SET_Destination use
(PINS => 2#000#,
X => 2#001#,
Y => 2#010#,
PINDIRS => 2#100#);
type SET is record
Opcode : HAL.UInt3 := 2#111#;
Delay_Sideset : HAL.UInt5 := 0;
Destination : SET_Destination := PINS;
Data : HAL.UInt5 := 0;
end record
with Size => 16;
for SET use record
Opcode at 0 range 13 .. 15;
Delay_Sideset at 0 range 8 .. 12;
Destination at 0 range 5 .. 7;
Data at 0 range 0 .. 4;
end record;
function Encode is new Ada.Unchecked_Conversion (JMP, PIO_Instruction);
function Encode is new Ada.Unchecked_Conversion (WAIT, PIO_Instruction);
function Encode is new Ada.Unchecked_Conversion (SHIFT_IN, PIO_Instruction);
function Encode is new Ada.Unchecked_Conversion (SHIFT_OUT, PIO_Instruction);
function Encode is new Ada.Unchecked_Conversion (PUSH, PIO_Instruction);
function Encode is new Ada.Unchecked_Conversion (PULL, PIO_Instruction);
function Encode is new Ada.Unchecked_Conversion (MOV, PIO_Instruction);
function Encode is new Ada.Unchecked_Conversion (IRQ, PIO_Instruction);
function Encode is new Ada.Unchecked_Conversion (SET, PIO_Instruction);
end RP.PIO.Encoding;
|