1use rhdl::prelude::*;
22
23use crate::fetch::{FetchIn, FetchReq, Fetcher};
24use crate::fetch::idle_fetch_req;
25use crate::ports::{AxiLiteIn, AxiLiteOut, AxiRead, AxiReadResp, idle_lite_in};
26
27#[derive(Clone, Copy, Debug, PartialEq, Digital, Default)]
29pub struct ServiceMap {
30 pub ap_ctrl: b12,
32 pub sign_count: b12,
34 pub verify_count: b12,
36 pub seed: b12,
38 pub key_mask: b12,
40 pub keys: b12,
42}
43
44pub const ED25519_MAP: ServiceMap = ServiceMap {
46 ap_ctrl: b12(0x000),
47 sign_count: b12(0x010),
48 verify_count: b12(0x014),
49 seed: b12(0x050),
50 key_mask: b12(0x070),
51 keys: b12(0x400),
52};
53
54#[derive(Clone, Copy, Debug, PartialEq, Digital, Default)]
56pub struct SetupIn {
57 pub start: bool,
59 pub map: ServiceMap,
61 pub n: b5,
63 pub sk: [b64; 4],
65 pub keys_base: b64,
67 pub svc: AxiLiteOut,
69 pub msg: AxiReadResp,
71}
72
73#[derive(Clone, Copy, Debug, PartialEq, Digital, Default)]
75pub struct SetupOut {
76 pub busy: bool,
78 pub done: bool,
80 pub svc: AxiLiteIn,
82 pub msg: AxiRead,
84}
85
86#[derive(Clone, Copy, Debug, PartialEq, Digital, Default)]
88pub struct SetupState {
89 pub step: b4,
92 pub word: b4,
94 pub slot: b5,
96 pub key: [b32; 8],
98 pub aw_done: bool,
100 pub w_done: bool,
102 pub b_wait: bool,
104 pub map: ServiceMap,
106 pub n: b5,
108 pub sk: [b64; 4],
110 pub keys_base: b64,
112}
113
114#[derive(Clone, Debug, Synchronous, SynchronousDQ)]
116pub struct Setup {
117 state: rhdl_fpga::core::dff::DFF<SetupState>,
118 fetch: Fetcher,
119}
120
121impl Default for Setup {
122 fn default() -> Self {
123 Self { state: rhdl_fpga::core::dff::DFF::new(SetupState::default()), fetch: Fetcher::default() }
124 }
125}
126
127impl SynchronousIO for Setup {
128 type I = SetupIn;
129 type O = SetupOut;
130 type Kernel = setup_kernel;
131}
132
133#[kernel]
135pub fn setup_kernel(_cr: ClockReset, i: SetupIn, q: SetupQ) -> (SetupOut, SetupD) {
136 let r = q.state;
137 let mut s = r;
138 let mut o = SetupOut { busy: false, done: false, svc: idle_lite_in(), msg: q.fetch.axi };
139 let mut f = FetchIn { req: idle_fetch_req(), axi: i.msg };
140 f.axi = i.msg;
141 o.msg = q.fetch.axi;
142 o.busy = r.step != b4(0);
143 if r.step == b4(0) && i.start {
144 s.step = b4(1);
145 s.word = b4(0);
146 s.slot = b5(0);
147 s.map = i.map;
148 s.n = i.n;
149 s.sk = i.sk;
150 s.keys_base = i.keys_base;
151 }
152 let mut write = false;
154 let mut addr = b12(0);
155 let mut data = b32(0);
156 if r.step == b4(1) {
157 write = true;
158 addr = r.map.seed + (r.word.resize::<12>() << b12(2));
159 let mut w = r.sk[0];
160 for k in 0..4 {
161 if (r.word >> b4(1)) == b4(k as u128) {
162 w = r.sk[k];
163 }
164 }
165 data = if (r.word & b4(1)) == b4(1) { (w >> b64(32)).resize() } else { w.resize() };
166 }
167 if r.step == b4(2) {
168 f.req = FetchReq { start: true, base: r.keys_base, word: r.slot.resize::<32>() << b32(3), count: b6(8) };
169 if !q.fetch.busy {
170 s.step = b4(3);
171 }
172 }
173 if r.step == b4(3) && q.fetch.done {
174 for k in 0..8 {
175 s.key[k] = q.fetch.words[k];
176 }
177 s.word = b4(0);
178 s.step = b4(4);
179 }
180 if r.step == b4(4) {
181 write = true;
182 addr = r.map.keys + (r.slot.resize::<12>() << b12(5)) + (r.word.resize::<12>() << b12(2));
183 let mut w = b32(0);
184 for k in 0..8 {
185 if r.word == b4(k as u128) {
186 w = r.key[k];
187 }
188 }
189 data = w;
190 }
191 if r.step == b4(5) {
192 write = true;
193 addr = r.map.key_mask;
194 data = (b32(1) << r.n.resize::<32>()) - b32(1);
195 }
196 if r.step == b4(6) {
197 write = true;
198 addr = r.map.sign_count;
199 data = !b32(0);
200 }
201 if r.step == b4(7) {
202 write = true;
203 addr = r.map.verify_count;
204 data = !b32(0);
205 }
206 if r.step == b4(8) {
207 write = true;
208 addr = r.map.ap_ctrl;
209 data = b32(1);
210 }
211 let mut wrote = false;
213 if write && !r.b_wait {
214 o.svc.aw_valid = !r.aw_done;
215 o.svc.aw_addr = addr;
216 o.svc.w_valid = !r.w_done;
217 o.svc.w_data = data;
218 o.svc.w_strb = b4(0xf);
219 let aw = r.aw_done || i.svc.aw_ready;
220 let w = r.w_done || i.svc.w_ready;
221 s.aw_done = aw;
222 s.w_done = w;
223 if aw && w {
224 s.b_wait = true;
225 }
226 }
227 if r.b_wait {
228 o.svc.b_ready = true;
229 if i.svc.b_valid {
230 s.b_wait = false;
231 s.aw_done = false;
232 s.w_done = false;
233 wrote = true;
234 }
235 }
236 if wrote {
237 if r.step == b4(1) {
239 s.word = r.word + b4(1);
240 if r.word == b4(7) {
241 s.step = b4(2);
242 }
243 }
244 if r.step == b4(4) {
245 s.word = r.word + b4(1);
246 if r.word == b4(7) {
247 s.slot = r.slot + b5(1);
248 s.step = if r.slot + b5(1) == r.n { b4(5) } else { b4(2) };
249 }
250 }
251 if r.step == b4(5) {
252 s.step = b4(6);
253 }
254 if r.step == b4(6) {
255 s.step = b4(7);
256 }
257 if r.step == b4(7) {
258 s.step = b4(8);
259 }
260 if r.step == b4(8) {
261 s.step = b4(0);
262 o.done = true;
263 }
264 }
265 (o, SetupD { state: s, fetch: f })
266}