forked from RfidResearchGroup/proxmark3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfpga_pm3_top.v
417 lines (373 loc) · 14 KB
/
fpga_pm3_top.v
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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
//-----------------------------------------------------------------------------
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// See LICENSE.txt for the text of the license.
//-----------------------------------------------------------------------------
//
// The FPGA is responsible for interfacing between the A/D, the coil drivers,
// and the ARM. In the low-frequency modes it passes the data straight
// through, so that the ARM gets raw A/D samples over the SSP. In the high-
// frequency modes, the FPGA might perform some demodulation first, to
// reduce the amount of data that we must send to the ARM.
//-----------------------------------------------------------------------------
// These defines are for reference only, they are passed by the Makefile so do not uncomment them here
// Proxmark3 RDV4 target
//`define PM3RDV4
// Proxmark3 generic target
//`define PM3GENERIC
// iCopy-X with XC3S100E
//`define PM3ICOPYX
// Pass desired defines to compiler to enable required modules
// WITH_LF enables Low Frequency mode when defined else HF is enabled
//`define WITH_LF
// WITH_LF0 enables module reader
//`define WITH_LF0
// WITH_LF1 enables module edge detect
//`define WITH_LF1
// WITH_LF2 enables module passthrough
//`define WITH_LF2
// WITH_LF3 enables module ADC
//`define WITH_LF3
// WITH_HF0 enables module HF reader
//`define WITH_HF0
// WITH_HF1 enables module simulated tag
//`define WITH_HF1
// WITH_HF2 enables module ISO14443-A
//`define WITH_HF2
// WITH_HF3 enables module sniff
//`define WITH_HF3
// WITH_HF4 enables module ISO18092 FeliCa
//`define WITH_HF4
// WITH_HF5 enables module get trace
//`define WITH_HF5
//`ifdef WITH_LF `include "clk_divider.v" `endif
//`ifdef WITH_LF0 `include "lo_read.v" `endif
//`ifdef WITH_LF1 `include "lo_edge_detect.v" `endif
//`ifdef WITH_LF2 `include "lo_passthru.v" `endif
//`ifdef WITH_LF3 `include "lo_adc.v" `endif
//
//`ifdef WITH_HF0 `include "hi_reader.v" `endif
//`ifdef WITH_HF1 `include "hi_simulate.v" `endif
//`ifdef WITH_HF2 `include "hi_iso14443a.v" `endif
//`ifdef WITH_HF3 `include "hi_sniffer.v" `endif
//`ifdef WITH_HF4 `include "hi_flite.v" `endif
//`ifdef WITH_HF5 `include "hi_get_trace.v" `endif
module fpga_top(
input ck_1356meg,
input ck_1356megb,
input spck,
input pck0,
input ncs,
input [7:0] adc_d,
input cross_hi,
input cross_lo,
input mosi,
input ssp_dout,
output ssp_din,
output ssp_frame,
output ssp_clk,
output adc_clk,
output adc_noe,
output miso,
output pwr_lo,
output pwr_hi,
output pwr_oe1,
output pwr_oe2,
output pwr_oe3,
output pwr_oe4,
output dbg
);
// In all modes, let the ADC's outputs be enabled.
assign adc_noe = 1'b0;
//-----------------------------------------------------------------------------
// The SPI receiver. This sets up the configuration word, which the rest of
// the logic looks at to determine how to connect the A/D and the coil
// drivers (i.e., which section gets it). Also assign some symbolic names
// to the configuration bits, for use below.
//-----------------------------------------------------------------------------
// Receive 16bits of data from ARM here.
reg [15:0] shift_reg;
always @(posedge spck) if (~ncs) shift_reg <= {shift_reg[14:0], mosi};
reg trace_enable;
reg [7:0] lf_ed_threshold;
// adjustable frequency clock
wire [7:0] pck_cnt;
wire pck_divclk;
reg [7:0] divisor;
clk_divider div_clk(pck0, divisor, pck_cnt, pck_divclk);
`ifdef WITH_LF
reg [11:0] conf_word;
`else
reg [8:0] conf_word;
`endif
// We switch modes between transmitting to the 13.56 MHz tag and receiving
// from it, which means that we must make sure that we can do so without
// glitching, or else we will glitch the transmitted carrier.
always @(posedge ncs)
begin
// 4 bit command
case (shift_reg[15:12])
`ifdef WITH_LF
`FPGA_CMD_SET_CONFREG:
begin
// 12 bit data
conf_word <= shift_reg[11:0];
if (shift_reg[8:6] == `FPGA_MAJOR_MODE_LF_EDGE_DETECT) lf_ed_threshold <= 127; // default threshold
end
`FPGA_CMD_SET_DIVISOR:
divisor <= shift_reg[7:0]; // 8bits
`FPGA_CMD_SET_EDGE_DETECT_THRESHOLD:
lf_ed_threshold <= shift_reg[7:0]; // 8 bits
`else
`FPGA_CMD_SET_CONFREG: conf_word <= shift_reg[8:0];
`FPGA_CMD_TRACE_ENABLE: trace_enable <= shift_reg[0];
`endif
endcase
end
//-----------------------------------------------------------------------------
// And then we instantiate the modules corresponding to each of the FPGA's
// major modes, and use muxes to connect the outputs of the active mode to
// the output pins.
//-----------------------------------------------------------------------------
// ############################################################################
// # Enable Low Frequency Modules
`ifdef WITH_LF
// LF reader (generic)
`ifdef WITH_LF0
lo_read lr(
.pck0 (pck0),
.pck_divclk (pck_divclk),
.pck_cnt (pck_cnt),
.adc_d (adc_d),
.lf_field (conf_word[0]),
.ssp_din (mux0_ssp_din),
.ssp_frame (mux0_ssp_frame),
.ssp_clk (mux0_ssp_clk),
.adc_clk (mux0_adc_clk),
.pwr_lo (mux0_pwr_lo),
.pwr_hi (mux0_pwr_hi),
.pwr_oe1 (mux0_pwr_oe1),
.pwr_oe2 (mux0_pwr_oe2),
.pwr_oe3 (mux0_pwr_oe3),
.pwr_oe4 (mux0_pwr_oe4),
.debug (mux0_debug)
);
`endif
// LF edge detect (generic)
`ifdef WITH_LF1
lo_edge_detect le(
.pck0 (pck0),
.pck_divclk (pck_divclk),
.adc_d (adc_d),
.cross_lo (cross_lo),
.lf_field (conf_word[0]),
.lf_ed_toggle_mode (conf_word[1]),
.lf_ed_threshold (lf_ed_threshold),
.ssp_dout (ssp_dout),
.ssp_frame (mux1_ssp_frame),
.ssp_clk (mux1_ssp_clk),
.adc_clk (mux1_adc_clk),
.pwr_lo (mux1_pwr_lo),
.pwr_hi (mux1_pwr_hi),
.pwr_oe1 (mux1_pwr_oe1),
.pwr_oe2 (mux1_pwr_oe2),
.pwr_oe3 (mux1_pwr_oe3),
.pwr_oe4 (mux1_pwr_oe4),
.debug (mux1_debug)
);
`endif
// LF passthrough
`ifdef WITH_LF2
lo_passthru lp(
.pck_divclk (pck_divclk),
.cross_lo (cross_lo),
.ssp_dout (ssp_dout),
.ssp_din (mux2_ssp_din),
.adc_clk (mux2_adc_clk),
.pwr_lo (mux2_pwr_lo),
.pwr_hi (mux2_pwr_hi),
.pwr_oe1 (mux2_pwr_oe1),
.pwr_oe2 (mux2_pwr_oe2),
.pwr_oe3 (mux2_pwr_oe3),
.pwr_oe4 (mux2_pwr_oe4),
.debug (mux2_debug)
);
`endif
// LF ADC (read/write)
`ifdef WITH_LF3
lo_adc la(
.pck0 (pck0),
.adc_d (adc_d),
.divisor (divisor),
.lf_field (conf_word[0]),
.ssp_dout (ssp_dout),
.ssp_din (mux3_ssp_din),
.ssp_frame (mux3_ssp_frame),
.ssp_clk (mux3_ssp_clk),
.adc_clk (mux3_adc_clk),
.pwr_lo (mux3_pwr_lo ),
.pwr_hi (mux3_pwr_hi ),
.pwr_oe1 (mux3_pwr_oe1),
.pwr_oe2 (mux3_pwr_oe2),
.pwr_oe3 (mux3_pwr_oe3),
.pwr_oe4 (mux3_pwr_oe4),
.debug (mux3_debug)
);
`endif // WITH_LF3
assign mux6_pwr_lo = 1'b1;
// 7 -- SPARE
`else // if WITH_LF not defined
// ############################################################################
// # Enable High Frequency Modules
// HF reader
`ifdef WITH_HF0
hi_reader hr(
.ck_1356meg (ck_1356megb),
.adc_d (adc_d),
.subcarrier_frequency (conf_word[5:4]),
.minor_mode (conf_word[3:0]),
.ssp_dout (ssp_dout),
.ssp_din (mux0_ssp_din),
.ssp_frame (mux0_ssp_frame),
.ssp_clk (mux0_ssp_clk),
.adc_clk (mux0_adc_clk),
.pwr_lo (mux0_pwr_lo),
.pwr_hi (mux0_pwr_hi),
.pwr_oe1 (mux0_pwr_oe1),
.pwr_oe2 (mux0_pwr_oe2),
.pwr_oe3 (mux0_pwr_oe3),
.pwr_oe4 (mux0_pwr_oe4),
.debug (mux0_debug)
);
`endif // WITH_HF0
// HF simulated tag
`ifdef WITH_HF1
hi_simulate hs(
.ck_1356meg (ck_1356meg),
.adc_d (adc_d),
.mod_type (conf_word[3:0]),
.ssp_dout (ssp_dout),
.ssp_din (mux1_ssp_din),
.ssp_frame (mux1_ssp_frame),
.ssp_clk (mux1_ssp_clk),
.adc_clk (mux1_adc_clk),
.pwr_lo (mux1_pwr_lo),
.pwr_hi (mux1_pwr_hi),
.pwr_oe1 (mux1_pwr_oe1),
.pwr_oe2 (mux1_pwr_oe2),
.pwr_oe3 (mux1_pwr_oe3),
.pwr_oe4 (mux1_pwr_oe4),
.debug (mux1_debug)
);
`endif // WITH_HF1
// HF ISO14443-A
`ifdef WITH_HF2
hi_iso14443a hisn(
.ck_1356meg (ck_1356meg),
.adc_d (adc_d),
.mod_type (conf_word[3:0]),
.ssp_dout (ssp_dout),
.ssp_din (mux2_ssp_din),
.ssp_frame (mux2_ssp_frame),
.ssp_clk (mux2_ssp_clk),
.adc_clk (mux2_adc_clk),
.pwr_lo (mux2_pwr_lo),
.pwr_hi (mux2_pwr_hi),
.pwr_oe1 (mux2_pwr_oe1),
.pwr_oe2 (mux2_pwr_oe2),
.pwr_oe3 (mux2_pwr_oe3),
.pwr_oe4 (mux2_pwr_oe4),
.debug (mux2_debug)
);
`endif // WITH_HF2
// HF sniff
`ifdef WITH_HF3
hi_sniffer he(
.ck_1356meg (ck_1356megb),
.adc_d (adc_d),
.ssp_din (mux3_ssp_din),
.ssp_frame (mux3_ssp_frame),
.ssp_clk (mux3_ssp_clk),
.adc_clk (mux3_adc_clk),
.pwr_lo (mux3_pwr_lo),
.pwr_hi (mux3_pwr_hi),
.pwr_oe1 (mux3_pwr_oe1),
.pwr_oe2 (mux3_pwr_oe2),
.pwr_oe3 (mux3_pwr_oe3),
.pwr_oe4 (mux3_pwr_oe4)
);
`endif //WITH_HF3
// HF ISO18092 FeliCa
`ifdef WITH_HF4
hi_flite hfl(
.ck_1356meg (ck_1356megb),
.adc_d (adc_d),
.mod_type (conf_word[3:0]),
.ssp_dout (ssp_dout),
.ssp_din (mux4_ssp_din),
.ssp_frame (mux4_ssp_frame),
.ssp_clk (mux4_ssp_clk),
.adc_clk (mux4_adc_clk),
.pwr_lo (mux4_pwr_lo),
.pwr_hi (mux4_pwr_hi),
.pwr_oe1 (mux4_pwr_oe1),
.pwr_oe2 (mux4_pwr_oe2),
.pwr_oe3 (mux4_pwr_oe3),
.pwr_oe4 (mux4_pwr_oe4),
.debug (mux4_debug)
);
`endif // WITH_HF4
// HF get trace
`ifdef WITH_HF5
hi_get_trace gt(
.ck_1356megb (ck_1356megb),
.adc_d (adc_d),
.trace_enable (trace_enable),
.major_mode (conf_word[8:6]),
.ssp_din (mux5_ssp_din),
.ssp_frame (mux5_ssp_frame),
.ssp_clk (mux5_ssp_clk)
);
`endif // WITH_HF5
`endif // WITH_LF
// These assignments must agree with the defines in fpgaloader.h
// Major modes Low Frequency
// mux0 = LF reader (generic)
// mux1 = LF edge detect (generic)
// mux2 = LF passthrough
// mux3 = LF ADC (read/write)
// mux4 = SPARE
// mux5 = SPARE
// mux6 = SPARE
// mux7 = FPGA_MAJOR_MODE_OFF
// Major modes High Frequency
// mux0 = HF reader
// mux1 = HF simulated tag
// mux2 = HF ISO14443-A
// mux3 = HF sniff
// mux4 = HF ISO18092 FeliCa
// mux5 = HF get trace
// mux6 = unused
// mux7 = FPGA_MAJOR_MODE_OFF
mux8 mux_ssp_clk (.sel(conf_word[8:6]), .y(ssp_clk ), .x0(mux0_ssp_clk ), .x1(mux1_ssp_clk ), .x2(mux2_ssp_clk ), .x3(mux3_ssp_clk ), .x4(mux4_ssp_clk ), .x5(mux5_ssp_clk ), .x6(mux6_ssp_clk ), .x7(mux7_ssp_clk ) );
mux8 mux_ssp_din (.sel(conf_word[8:6]), .y(ssp_din ), .x0(mux0_ssp_din ), .x1(mux1_ssp_din ), .x2(mux2_ssp_din ), .x3(mux3_ssp_din ), .x4(mux4_ssp_din ), .x5(mux5_ssp_din ), .x6(mux6_ssp_din ), .x7(mux7_ssp_din ) );
mux8 mux_ssp_frame (.sel(conf_word[8:6]), .y(ssp_frame), .x0(mux0_ssp_frame), .x1(mux1_ssp_frame), .x2(mux2_ssp_frame), .x3(mux3_ssp_frame), .x4(mux4_ssp_frame), .x5(mux5_ssp_frame), .x6(mux6_ssp_frame), .x7(mux7_ssp_frame) );
mux8 mux_pwr_oe1 (.sel(conf_word[8:6]), .y(pwr_oe1 ), .x0(mux0_pwr_oe1 ), .x1(mux1_pwr_oe1 ), .x2(mux2_pwr_oe1 ), .x3(mux3_pwr_oe1 ), .x4(mux4_pwr_oe1 ), .x5(mux5_pwr_oe1 ), .x6(mux6_pwr_oe1 ), .x7(mux7_pwr_oe1 ) );
mux8 mux_pwr_oe2 (.sel(conf_word[8:6]), .y(pwr_oe2 ), .x0(mux0_pwr_oe2 ), .x1(mux1_pwr_oe2 ), .x2(mux2_pwr_oe2 ), .x3(mux3_pwr_oe2 ), .x4(mux4_pwr_oe2 ), .x5(mux5_pwr_oe2 ), .x6(mux6_pwr_oe2 ), .x7(mux7_pwr_oe2 ) );
mux8 mux_pwr_oe3 (.sel(conf_word[8:6]), .y(pwr_oe3 ), .x0(mux0_pwr_oe3 ), .x1(mux1_pwr_oe3 ), .x2(mux2_pwr_oe3 ), .x3(mux3_pwr_oe3 ), .x4(mux4_pwr_oe3 ), .x5(mux5_pwr_oe3 ), .x6(mux6_pwr_oe3 ), .x7(mux7_pwr_oe3 ) );
mux8 mux_pwr_oe4 (.sel(conf_word[8:6]), .y(pwr_oe4 ), .x0(mux0_pwr_oe4 ), .x1(mux1_pwr_oe4 ), .x2(mux2_pwr_oe4 ), .x3(mux3_pwr_oe4 ), .x4(mux4_pwr_oe4 ), .x5(mux5_pwr_oe4 ), .x6(mux6_pwr_oe4 ), .x7(mux7_pwr_oe4 ) );
mux8 mux_pwr_lo (.sel(conf_word[8:6]), .y(pwr_lo ), .x0(mux0_pwr_lo ), .x1(mux1_pwr_lo ), .x2(mux2_pwr_lo ), .x3(mux3_pwr_lo ), .x4(mux4_pwr_lo ), .x5(mux5_pwr_lo ), .x6(mux6_pwr_lo ), .x7(mux7_pwr_lo ) );
mux8 mux_pwr_hi (.sel(conf_word[8:6]), .y(pwr_hi ), .x0(mux0_pwr_hi ), .x1(mux1_pwr_hi ), .x2(mux2_pwr_hi ), .x3(mux3_pwr_hi ), .x4(mux4_pwr_hi ), .x5(mux5_pwr_hi ), .x6(mux6_pwr_hi ), .x7(mux7_pwr_hi ) );
mux8 mux_adc_clk (.sel(conf_word[8:6]), .y(adc_clk ), .x0(mux0_adc_clk ), .x1(mux1_adc_clk ), .x2(mux2_adc_clk ), .x3(mux3_adc_clk ), .x4(mux4_adc_clk ), .x5(mux5_adc_clk ), .x6(mux6_adc_clk ), .x7(mux7_adc_clk ) );
mux8 mux_dbg (.sel(conf_word[8:6]), .y(dbg ), .x0(mux0_debug ), .x1(mux1_debug ), .x2(mux2_debug ), .x3(mux3_debug ), .x4(mux4_debug ), .x5(mux5_debug ), .x6(mux6_debug ), .x7(mux7_debug ) );
endmodule