updated the uniq.yaml workflow to be case insensitive
[RRG-proxmark3.git] / fpga / fpga_icopyx_lf.v
blobd1495498acf90374645b132a94295510abce6ef7
1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
17 // The FPGA is responsible for interfacing between the A/D, the coil drivers,
18 // and the ARM. In the low-frequency modes it passes the data straight
19 // through, so that the ARM gets raw A/D samples over the SSP. In the high-
20 // frequency modes, the FPGA might perform some demodulation first, to
21 // reduce the amount of data that we must send to the ARM.
22 //-----------------------------------------------------------------------------
24 module fpga_lf(
25 input spck,
26 output miso,
27 input mosi,
28 input ncs,
29 input pck0,
30 input ck_1356meg,
31 input ck_1356megb,
32 output pwr_lo,
33 output pwr_hi,
34 output pwr_oe1,
35 output pwr_oe2,
36 output pwr_oe3,
37 output pwr_oe4,
38 input [7:0] adc_d,
39 output adc_clk,
40 output adc_noe,
41 output ssp_frame,
42 output ssp_din,
43 input ssp_dout,
44 output ssp_clk,
45 input cross_hi,
46 input cross_lo,
47 output debug,
48 output PWR_LO_EN
51 //-----------------------------------------------------------------------------
52 // The SPI receiver. This sets up the configuration word, which the rest of
53 // the logic looks at to determine how to connect the A/D and the coil
54 // drivers (i.e., which section gets it). Also assign some symbolic names
55 // to the configuration bits, for use below.
56 //-----------------------------------------------------------------------------
58 // Receive 16bits of data from ARM here.
59 reg [15:0] shift_reg;
60 always @(posedge spck) if (~ncs) shift_reg <= {shift_reg[14:0], mosi};
62 reg [11:0] conf_word;
64 // select module (outputs) based on major mode
65 wire [2:0] major_mode = conf_word[8:6];
66 // parameter to be passed to modules
67 wire lf_field = conf_word[0];
68 wire lf_ed_toggle_mode = conf_word[1];
69 reg [7:0] lf_ed_threshold;
71 wire [7:0] pck_cnt;
72 wire pck_divclk;
73 reg [7:0] divisor;
75 clk_divider div_clk(
76 .clk (pck0),
77 .divisor (divisor),
78 .div_cnt (pck_cnt),
79 .div_clk (pck_divclk)
82 // We switch modes between transmitting to the 13.56 MHz tag and receiving
83 // from it, which means that we must make sure that we can do so without
84 // glitching, or else we will glitch the transmitted carrier.
85 always @(posedge ncs)
86 begin
87 // 4 bit command
88 case (shift_reg[15:12])
89 `FPGA_CMD_SET_CONFREG:
90 begin
91 // 12 bit data
92 conf_word <= shift_reg[11:0];
93 if (shift_reg[8:6] == `FPGA_MAJOR_MODE_LF_EDGE_DETECT)
94 begin
95 lf_ed_threshold <= 127; // default threshold
96 end
97 end
99 `FPGA_CMD_SET_DIVISOR:
100 divisor <= shift_reg[7:0]; // 8bits
102 `FPGA_CMD_SET_EDGE_DETECT_THRESHOLD:
103 lf_ed_threshold <= shift_reg[7:0]; // 8 bits
104 endcase
107 //-----------------------------------------------------------------------------
108 // And then we instantiate the modules corresponding to each of the FPGA's
109 // major modes, and use muxes to connect the outputs of the active mode to
110 // the output pins.
111 //-----------------------------------------------------------------------------
113 // 0 -- LF reader (generic)
114 lo_read lr(
115 .pck0 (pck0),
116 .pck_cnt (pck_cnt),
117 .pck_divclk (pck_divclk),
118 .pwr_lo (lr_pwr_lo),
119 .pwr_hi (lr_pwr_hi),
120 .pwr_oe1 (lr_pwr_oe1),
121 .pwr_oe2 (lr_pwr_oe2),
122 .pwr_oe3 (lr_pwr_oe3),
123 .pwr_oe4 (lr_pwr_oe4),
124 .adc_d (adc_d),
125 .adc_clk (lr_adc_clk),
126 .ssp_frame (lr_ssp_frame),
127 .ssp_din (lr_ssp_din),
128 .ssp_clk (lr_ssp_clk),
129 .debug (lr_debug),
130 .lf_field (lf_field)
133 // 1 -- LF edge detect (generic)
134 lo_edge_detect le(
135 .pck0 (pck0),
136 .pck_divclk (pck_divclk),
137 .pwr_lo (le_pwr_lo),
138 .pwr_hi (le_pwr_hi),
139 .pwr_oe1 (le_pwr_oe1),
140 .pwr_oe2 (le_pwr_oe2),
141 .pwr_oe3 (le_pwr_oe3),
142 .pwr_oe4 (le_pwr_oe4),
143 .adc_d (adc_d),
144 .adc_clk (le_adc_clk),
145 .ssp_frame (le_ssp_frame),
146 .ssp_dout (ssp_dout),
147 .ssp_clk (le_ssp_clk),
148 .cross_lo (cross_lo),
149 .debug (le_debug),
150 .lf_field (lf_field),
151 .lf_ed_toggle_mode (lf_ed_toggle_mode),
152 .lf_ed_threshold (lf_ed_threshold)
155 // 2 -- LF passthrough
156 lo_passthru lp(
157 .pck_divclk (pck_divclk),
158 .pwr_lo (lp_pwr_lo),
159 .pwr_hi (lp_pwr_hi),
160 .pwr_oe1 (lp_pwr_oe1),
161 .pwr_oe2 (lp_pwr_oe2),
162 .pwr_oe3 (lp_pwr_oe3),
163 .pwr_oe4 (lp_pwr_oe4),
164 .adc_clk (lp_adc_clk),
165 .ssp_din (lp_ssp_din),
166 .ssp_dout (ssp_dout),
167 .cross_lo (cross_lo),
168 .debug (lp_debug)
171 // 3 -- LF ADC (read/write)
172 lo_adc la(
173 .pck0 (pck0),
174 .pwr_lo (la_pwr_lo ),
175 .pwr_hi (la_pwr_hi ),
176 .pwr_oe1 (la_pwr_oe1),
177 .pwr_oe2 (la_pwr_oe2),
178 .pwr_oe3 (la_pwr_oe3),
179 .pwr_oe4 (la_pwr_oe4),
180 .adc_d (adc_d),
181 .adc_clk (la_adc_clk),
182 .ssp_frame (la_ssp_frame),
183 .ssp_din (la_ssp_din),
184 .ssp_dout (ssp_dout),
185 .ssp_clk (la_ssp_clk),
186 .debug (la_debug),
187 .divisor (divisor),
188 .lf_field (lf_field)
191 // Major modes:
192 // x0 = LF reader (generic)
193 // x1 = LF edge detect (generic)
194 // x2 = LF passthrough
195 // x3 = LF ADC (read/write)
196 // x4 = SPARE
197 // x5 = SPARE
198 // x6 = SPARE
199 // x7 = FPGA_MAJOR_MODE_OFF
201 mux8 mux_ssp_clk (.sel(major_mode), .y(ssp_clk ), .x0(lr_ssp_clk ), .x1(le_ssp_clk ), .x2(1'b0 ), .x3(la_ssp_clk ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) );
202 mux8 mux_ssp_din (.sel(major_mode), .y(ssp_din ), .x0(lr_ssp_din ), .x1(1'b0 ), .x2(lp_ssp_din), .x3(la_ssp_din ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) );
203 mux8 mux_ssp_frame (.sel(major_mode), .y(ssp_frame), .x0(lr_ssp_frame), .x1(le_ssp_frame), .x2(1'b0 ), .x3(la_ssp_frame), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) );
204 mux8 mux_pwr_oe1 (.sel(major_mode), .y(pwr_oe1 ), .x0(lr_pwr_oe1 ), .x1(le_pwr_oe1 ), .x2(lp_pwr_oe1), .x3(la_pwr_oe1 ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) );
205 mux8 mux_pwr_oe2 (.sel(major_mode), .y(pwr_oe2 ), .x0(lr_pwr_oe2 ), .x1(le_pwr_oe2 ), .x2(lp_pwr_oe2), .x3(la_pwr_oe2 ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) );
206 mux8 mux_pwr_oe3 (.sel(major_mode), .y(pwr_oe3 ), .x0(lr_pwr_oe3 ), .x1(le_pwr_oe3 ), .x2(lp_pwr_oe3), .x3(la_pwr_oe3 ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) );
207 mux8 mux_pwr_oe4 (.sel(major_mode), .y(pwr_oe4 ), .x0(lr_pwr_oe4 ), .x1(le_pwr_oe4 ), .x2(lp_pwr_oe4), .x3(la_pwr_oe4 ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) );
208 mux8 mux_pwr_lo (.sel(major_mode), .y(pwr_lo ), .x0(lr_pwr_lo ), .x1(le_pwr_lo ), .x2(lp_pwr_lo ), .x3(la_pwr_lo ), .x4(1'b0), .x5(1'b0), .x6(1'b1), .x7(1'b0) );
209 mux8 mux_pwr_hi (.sel(major_mode), .y(pwr_hi ), .x0(lr_pwr_hi ), .x1(le_pwr_hi ), .x2(lp_pwr_hi ), .x3(la_pwr_hi ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) );
210 mux8 mux_adc_clk (.sel(major_mode), .y(adc_clk ), .x0(lr_adc_clk ), .x1(le_adc_clk ), .x2(lp_adc_clk), .x3(la_adc_clk ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) );
211 mux8 mux_dbg (.sel(major_mode), .y(debug ), .x0(lr_debug ), .x1(le_debug ), .x2(lp_debug ), .x3(la_debug ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) );
212 mux8 mux_ant (.sel(major_mode), .y(PWR_LO_EN), .x0(1'b1 ), .x1(1'b1 ), .x2(1'b1 ), .x3(1'b1 ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) );
214 // In all modes, let the ADC's outputs be enabled.
215 assign adc_noe = 1'b0;
217 endmodule