From c41c6858073c12f2948a5cc791190cf3f20bf688 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 24 Aug 2023 17:52:12 +0200 Subject: [PATCH 1/4] Merged hi_reader and hi_reader_15 into one file hi_reader_15 was a superset of hi_reader, now uses conditional compile from Makefile like the other files to select compilations options --- fpga/Makefile | 1 - fpga/fpga_pm3_top.v | 8 - fpga/hi_reader.v | 170 +++++++++++++--- fpga/hi_reader_15.v | 459 -------------------------------------------- 4 files changed, 139 insertions(+), 499 deletions(-) delete mode 100644 fpga/hi_reader_15.v diff --git a/fpga/Makefile b/fpga/Makefile index 068b75255..1731d4869 100644 --- a/fpga/Makefile +++ b/fpga/Makefile @@ -104,7 +104,6 @@ TARGET_COMMON_FILES += hi_flite.v TARGET_COMMON_FILES += hi_get_trace.v TARGET_COMMON_FILES += hi_iso14443a.v TARGET_COMMON_FILES += hi_reader.v -TARGET_COMMON_FILES += hi_reader_15.v TARGET_COMMON_FILES += hi_simulate.v TARGET_COMMON_FILES += hi_sniffer.v TARGET_COMMON_FILES += lf_edge_detect.v diff --git a/fpga/fpga_pm3_top.v b/fpga/fpga_pm3_top.v index 89bd2e56b..f200bf498 100644 --- a/fpga/fpga_pm3_top.v +++ b/fpga/fpga_pm3_top.v @@ -73,11 +73,7 @@ multiple outputs connected together therefore leading to a failed compilation //`ifdef WITH_LF2 `include "lo_passthru.v" `endif //`ifdef WITH_LF3 `include "lo_adc.v" `endif // -//`ifdef WITH_HF_15 -//`ifdef WITH_HF0 `include "hi_reader_15.v" `endif -//`else //`ifdef WITH_HF0 `include "hi_reader.v" `endif -//`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 @@ -277,11 +273,7 @@ assign mux6_pwr_lo = 1'b1; // HF reader `ifdef WITH_HF0 -`ifdef WITH_HF_15 -hi_reader_15 hr( -`else hi_reader hr( -`endif .ck_1356meg (ck_1356megb), .adc_d (adc_d), .subcarrier_frequency (conf_word[5:4]), diff --git a/fpga/hi_reader.v b/fpga/hi_reader.v index ffa2634d8..434215457 100644 --- a/fpga/hi_reader.v +++ b/fpga/hi_reader.v @@ -13,7 +13,7 @@ // // See LICENSE.txt for the text of the license. //----------------------------------------------------------------------------- -//`include "define.v" +// with optional support for iso15 2sc mode slected with compiler define WITH_HF_15 module hi_reader( input ck_1356meg, @@ -63,7 +63,6 @@ begin end end - // Let us report a correlation every 64 samples. I.e. // one Q/I pair after 4 subcarrier cycles for the 848kHz subcarrier, // one Q/I pair after 2 subcarrier cycles for the 424kHz subcarriers, @@ -71,10 +70,105 @@ end // We need a 6-bit counter for the timing. reg [5:0] corr_i_cnt; always @(negedge adc_clk) -begin corr_i_cnt <= corr_i_cnt + 1; -end +`ifdef WITH_HF_15 +reg [1:0] fskout = 2'd0; +reg last0 = 1'b0; + +reg [7:0] avg = 8'd0; +reg [127:0] avg128 = 128'd0; +reg [7:0] diff16 = 8'd0; +reg [7:0] diff28 = 8'd0; +reg [7:0] diff32 = 8'd0; + +reg [11:0] match16 = 12'd0; +reg [11:0] match32 = 12'd0; +reg [11:0] match28 = 12'd0; + +always @(negedge adc_clk) +begin + if (corr_i_cnt[0] == 1'b0) // every 2 clock + avg = adc_d[7:1]; + else + begin + avg = avg + adc_d[7:1]; + if (corr_i_cnt[0] == 1'b1) // every 2 clock + begin + if (avg > avg128[63:56]) + diff16 = avg - avg128[63:56]; + else + diff16 = avg128[63:56] - avg; + + if (avg > avg128[111:104]) + diff28 = avg - avg128[111:104]; + else + diff28 = avg128[111:104] - avg; + + if (avg > avg128[127:120]) + diff32 = avg - avg128[127:120]; + else + diff32 = avg128[127:120] - avg; + + avg128[127:8] = avg128[119:0]; + avg128[7:0] = avg; + + if (corr_i_cnt[4:1] == 4'b0000) // every 32 clock (8*4) + begin + match16 = diff16; + match28 = diff28; + match32 = diff32; + end + else + begin + match16 = match16 + diff16; + match28 = match28 + diff28; + match32 = match32 + diff32; + + if (corr_i_cnt[4:1] == 4'b1111) // every 32 clock (8*4) + begin + last0 = (fskout == 2'b0); + if (match16 < 12'd64 && last0) + fskout = 2'b00; // not yet started + else if ((match16 | match28 | match32) == 12'b0) + fskout = 2'b00; // signal likely ended + else if (((match16 <= match28 + 12'd16) && (match16 <= match32+ 12'd16)) || + (match28 <= 12'd16 && match32 <= 12'd16)) + begin + if (!last0) + fskout = 2'b11; // 16 match better than 28 or 32 but already started + end + else + begin + if (match28 < match32) + begin + diff28 = match32 - match28; + diff16 = match16 - match28; + if (diff28*2 > diff16) + fskout = 2'b01; + else if (!last0) + begin + fskout = 2'b01; + end + end + else //if (match32 <= match28) + begin + diff32 = match28 - match32; + diff16 = match16 - match32; + if (diff32*2 > diff16) + fskout = 2'b10; + else if (!last0) + begin + fskout = 2'b10; + end + end + end + end + end + end + end +end +`endif // A couple of registers in which to accumulate the correlations. From the 64 samples // we would add at most 32 times the difference between unmodulated and modulated signal. It should @@ -89,7 +183,6 @@ reg signed [13:0] corr_q_accum; reg signed [7:0] corr_i_out; reg signed [7:0] corr_q_out; - // the amplitude of the subcarrier is sqrt(ci^2 + cq^2). // approximate by amplitude = max(|ci|,|cq|) + 1/2*min(|ci|,|cq|) reg [13:0] corr_amplitude, abs_ci, abs_cq, max_ci_cq; @@ -122,7 +215,6 @@ begin end - // The subcarrier reference signals reg subcarrier_I; reg subcarrier_Q; @@ -130,23 +222,22 @@ reg subcarrier_Q; always @(*) begin if (subcarrier_frequency == `FPGA_HF_READER_SUBCARRIER_848_KHZ) - begin - subcarrier_I = ~corr_i_cnt[3]; - subcarrier_Q = ~(corr_i_cnt[3] ^ corr_i_cnt[2]); - end + begin + subcarrier_I = ~corr_i_cnt[3]; + subcarrier_Q = ~(corr_i_cnt[3] ^ corr_i_cnt[2]); + end else if (subcarrier_frequency == `FPGA_HF_READER_SUBCARRIER_212_KHZ) - begin - subcarrier_I = ~corr_i_cnt[5]; - subcarrier_Q = ~(corr_i_cnt[5] ^ corr_i_cnt[4]); - end + begin + subcarrier_I = ~corr_i_cnt[5]; + subcarrier_Q = ~(corr_i_cnt[5] ^ corr_i_cnt[4]); + end else - begin // 424 kHz - subcarrier_I = ~corr_i_cnt[4]; - subcarrier_Q = ~(corr_i_cnt[4] ^ corr_i_cnt[3]); - end + begin // 424 kHz + subcarrier_I = ~corr_i_cnt[4]; + subcarrier_Q = ~(corr_i_cnt[4] ^ corr_i_cnt[3]); + end end - // ADC data appears on the rising edge, so sample it on the falling edge always @(negedge adc_clk) begin @@ -157,9 +248,20 @@ begin begin if (minor_mode == `FPGA_HF_READER_MODE_SNIFF_AMPLITUDE) begin - // send amplitude plus 2 bits reader signal - corr_i_out <= corr_amplitude[13:6]; - corr_q_out <= {corr_amplitude[5:0], after_hysteresis_prev_prev, after_hysteresis_prev}; +`ifdef WITH_HF_15 + if (subcarrier_frequency == `FPGA_HF_READER_2SUBCARRIERS_424_484_KHZ) + begin + // send amplitude + 2 bits fsk (2sc) signal + 2 bits reader signal + corr_i_out <= corr_amplitude[13:6]; + corr_q_out <= {corr_amplitude[5:2], fskout, after_hysteresis_prev_prev, after_hysteresis_prev}; + end + else +`endif + begin + // send amplitude plus 2 bits reader signal + corr_i_out <= corr_amplitude[13:6]; + corr_q_out <= {corr_amplitude[5:0], after_hysteresis_prev_prev, after_hysteresis_prev}; + end end else if (minor_mode == `FPGA_HF_READER_MODE_SNIFF_IQ) begin @@ -183,13 +285,23 @@ begin end else if (minor_mode == `FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE) begin - // send amplitude - corr_i_out <= {2'b00, corr_amplitude[13:8]}; - corr_q_out <= corr_amplitude[7:0]; +`ifdef WITH_HF_15 + if (subcarrier_frequency == `FPGA_HF_READER_2SUBCARRIERS_424_484_KHZ) + begin + // send 2 bits fsk (2sc) signal + amplitude + corr_i_out <= {fskout, corr_amplitude[13:8]}; + corr_q_out <= corr_amplitude[7:0]; + end + else +`endif + begin + // send amplitude + corr_i_out <= {2'b00, corr_amplitude[13:8]}; + corr_q_out <= corr_amplitude[7:0]; + end end else if (minor_mode == `FPGA_HF_READER_MODE_RECEIVE_IQ) begin - // Send 8 bits of in phase tag signal if (corr_i_accum[13:11] == 3'b000 || corr_i_accum[13:11] == 3'b111) corr_i_out <= corr_i_accum[11:4]; @@ -251,7 +363,6 @@ begin end - // ssp clock and frame signal for communication to and from ARM // _____ _____ _____ _ // ssp_clk | |_____| |_____| |_____| @@ -262,7 +373,6 @@ end // // corr_i_cnt 0 1 2 3 4 5 6 7 8 9 10 11 12 ... // - always @(negedge adc_clk) begin if (corr_i_cnt[1:0] == 2'b00) @@ -280,10 +390,8 @@ begin ssp_frame <= 1'b0; end - assign ssp_din = corr_i_out[7]; - // a jamming signal reg jam_signal; reg [3:0] jam_counter; @@ -333,7 +441,7 @@ assign pwr_oe1 = 1'b0; assign pwr_oe3 = 1'b0; // Unused. -assign pwr_lo = 1'b0; +assign pwr_lo = 1'b0; assign pwr_oe2 = 1'b0; // Debug Output diff --git a/fpga/hi_reader_15.v b/fpga/hi_reader_15.v deleted file mode 100644 index ad41e771c..000000000 --- a/fpga/hi_reader_15.v +++ /dev/null @@ -1,459 +0,0 @@ -//----------------------------------------------------------------------------- -// 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. -//----------------------------------------------------------------------------- -// modified to add support for iso15 2sc mode - -module hi_reader_15( - input ck_1356meg, - input [7:0] adc_d, - input [1:0] subcarrier_frequency, - input [3:0] minor_mode, - input ssp_dout, - - output ssp_din, - output reg ssp_frame, - output reg ssp_clk, - output adc_clk, - output pwr_lo, - output reg pwr_hi, - output pwr_oe1, - output pwr_oe2, - output pwr_oe3, - output reg pwr_oe4, - output debug -); - -assign adc_clk = ck_1356meg; // sample frequency is 13,56 MHz - -// When we're a reader, we just need to do the BPSK demod; but when we're an -// eavesdropper, we also need to pick out the commands sent by the reader, -// using AM. Do this the same way that we do it for the simulated tag. -reg after_hysteresis, after_hysteresis_prev, after_hysteresis_prev_prev; -reg [11:0] has_been_low_for; -always @(negedge adc_clk) -begin - if (& adc_d[7:0]) after_hysteresis <= 1'b1; - else if (~(| adc_d[7:0])) after_hysteresis <= 1'b0; - - if (after_hysteresis) - begin - has_been_low_for <= 12'd0; - end - else - begin - if (has_been_low_for == 12'd4095) - begin - has_been_low_for <= 12'd0; - after_hysteresis <= 1'b1; - end - else - has_been_low_for <= has_been_low_for + 1; - end -end - - -// Let us report a correlation every 64 samples. I.e. -// one Q/I pair after 4 subcarrier cycles for the 848kHz subcarrier, -// one Q/I pair after 2 subcarrier cycles for the 424kHz subcarriers, -// one Q/I pair for each subcarrier cyle for the 212kHz subcarrier. -// We need a 6-bit counter for the timing. -reg [5:0] corr_i_cnt; -always @(negedge adc_clk) -begin - corr_i_cnt <= corr_i_cnt + 1; -end - - -reg [1:0] fskout = 2'd0; -reg last0 = 1'b0; - -reg [7:0] avg = 8'd0; -reg [127:0] avg128 = 128'd0; -reg [7:0] diff16 = 8'd0; -reg [7:0] diff28 = 8'd0; -reg [7:0] diff32 = 8'd0; - -reg [11:0] match16 = 12'd0; -reg [11:0] match32 = 12'd0; -reg [11:0] match28 = 12'd0; - -always @(negedge adc_clk) -begin - if (corr_i_cnt[0] == 1'b0) // every 2 clock - begin - avg = adc_d[7:1]; - end - else - begin - avg = avg + adc_d[7:1]; - if (corr_i_cnt[0] == 1'b1) // every 2 clock - begin - if (avg > avg128[63:56]) - diff16 = avg - avg128[63:56]; - else - diff16 = avg128[63:56] - avg; - - if (avg > avg128[111:104]) - diff28 = avg - avg128[111:104]; - else - diff28 = avg128[111:104] - avg; - - if (avg > avg128[127:120]) - diff32 = avg - avg128[127:120]; - else - diff32 = avg128[127:120] - avg; - - avg128[127:8] = avg128[119:0]; - avg128[7:0] = avg; - - - if (corr_i_cnt[4:1] == 4'b0000) // every 32 clock (8*4) - begin - match16 = diff16; - match28 = diff28; - match32 = diff32; - end - else - begin - match16 = match16 + diff16; - match28 = match28 + diff28; - match32 = match32 + diff32; - - if (corr_i_cnt[4:1] == 4'b1111) // every 32 clock (8*4) - begin - last0 = (fskout == 2'b0); - if (match16 < 12'd64 && last0) - fskout = 2'b00; // not yet started - else if ((match16 | match28 | match32) == 12'b0) - fskout = 2'b00; // signal likely ended - else if (((match16 <= match28 + 12'd16) && (match16 <= match32+ 12'd16)) || - (match28 <= 12'd16 && match32 <= 12'd16)) - begin - if (!last0) - fskout = 2'b11; // 16 match better than 28 or 32 but already started - end - else - begin - if (match28 < match32) - begin - diff28 = match32 - match28; - diff16 = match16 - match28; - if (diff28*2 > diff16) - fskout = 2'b01; - else if (!last0) - begin - fskout = 2'b01; - end - end - else //if (match32 <= match28) - begin - diff32 = match28 - match32; - diff16 = match16 - match32; - if (diff32*2 > diff16) - fskout = 2'b10; - else if (!last0) - begin - fskout = 2'b10; - end - end - end - end - end - end - end -end - - -// A couple of registers in which to accumulate the correlations. From the 64 samples -// we would add at most 32 times the difference between unmodulated and modulated signal. It should -// be safe to assume that a tag will not be able to modulate the carrier signal by more than 25%. -// 32 * 255 * 0,25 = 2040, which can be held in 11 bits. Add 1 bit for sign. -// Temporary we might need more bits. For the 212kHz subcarrier we could possible add 32 times the -// maximum signal value before a first subtraction would occur. 32 * 255 = 8160 can be held in 13 bits. -// Add one bit for sign -> need 14 bit registers but final result will fit into 12 bits. -reg signed [13:0] corr_i_accum; -reg signed [13:0] corr_q_accum; -// we will report maximum 8 significant bits -reg signed [7:0] corr_i_out; -reg signed [7:0] corr_q_out; - - -// the amplitude of the subcarrier is sqrt(ci^2 + cq^2). -// approximate by amplitude = max(|ci|,|cq|) + 1/2*min(|ci|,|cq|) -reg [13:0] corr_amplitude, abs_ci, abs_cq, max_ci_cq; -reg [12:0] min_ci_cq_2; // min_ci_cq / 2 - -always @(*) -begin - if (corr_i_accum[13] == 1'b0) - abs_ci <= corr_i_accum; - else - abs_ci <= -corr_i_accum; - - if (corr_q_accum[13] == 1'b0) - abs_cq <= corr_q_accum; - else - abs_cq <= -corr_q_accum; - - if (abs_ci > abs_cq) - begin - max_ci_cq <= abs_ci; - min_ci_cq_2 <= abs_cq / 2; - end - else - begin - max_ci_cq <= abs_cq; - min_ci_cq_2 <= abs_ci / 2; - end - - corr_amplitude <= max_ci_cq + min_ci_cq_2; - -end - - -// The subcarrier reference signals -reg subcarrier_I; -reg subcarrier_Q; - -always @(*) -begin - if (subcarrier_frequency == `FPGA_HF_READER_SUBCARRIER_848_KHZ) - begin - subcarrier_I = ~corr_i_cnt[3]; - subcarrier_Q = ~(corr_i_cnt[3] ^ corr_i_cnt[2]); - end - else if (subcarrier_frequency == `FPGA_HF_READER_SUBCARRIER_212_KHZ) - begin - subcarrier_I = ~corr_i_cnt[5]; - subcarrier_Q = ~(corr_i_cnt[5] ^ corr_i_cnt[4]); - end - else - begin // 424 kHz - subcarrier_I = ~corr_i_cnt[4]; - subcarrier_Q = ~(corr_i_cnt[4] ^ corr_i_cnt[3]); - end -end - - -// ADC data appears on the rising edge, so sample it on the falling edge -always @(negedge adc_clk) -begin - // These are the correlators: we correlate against in-phase and quadrature - // versions of our reference signal, and keep the (signed) results or the - // resulting amplitude to send out later over the SSP. - if (corr_i_cnt == 6'd0) - begin - if (minor_mode == `FPGA_HF_READER_MODE_SNIFF_AMPLITUDE) - begin - if (subcarrier_frequency == `FPGA_HF_READER_2SUBCARRIERS_424_484_KHZ) - begin - // send amplitude + 2 bits fsk (2sc) signal + 2 bits reader signal - corr_i_out <= corr_amplitude[13:6]; - corr_q_out <= {corr_amplitude[5:2], fskout, after_hysteresis_prev_prev, after_hysteresis_prev}; - end - else - begin - // send amplitude plus 2 bits reader signal - corr_i_out <= corr_amplitude[13:6]; - corr_q_out <= {corr_amplitude[5:0], after_hysteresis_prev_prev, after_hysteresis_prev}; - end - end - else if (minor_mode == `FPGA_HF_READER_MODE_SNIFF_IQ) - begin - // Send 7 most significant bits of in phase tag signal (signed), plus 1 bit reader signal - if (corr_i_accum[13:11] == 3'b000 || corr_i_accum[13:11] == 3'b111) - corr_i_out <= {corr_i_accum[11:5], after_hysteresis_prev_prev}; - else // truncate to maximum value - if (corr_i_accum[13] == 1'b0) - corr_i_out <= {7'b0111111, after_hysteresis_prev_prev}; - else - corr_i_out <= {7'b1000000, after_hysteresis_prev_prev}; - - // Send 7 most significant bits of quadrature phase tag signal (signed), plus 1 bit reader signal - if (corr_q_accum[13:11] == 3'b000 || corr_q_accum[13:11] == 3'b111) - corr_q_out <= {corr_q_accum[11:5], after_hysteresis_prev}; - else // truncate to maximum value - if (corr_q_accum[13] == 1'b0) - corr_q_out <= {7'b0111111, after_hysteresis_prev}; - else - corr_q_out <= {7'b1000000, after_hysteresis_prev}; - end - else if (minor_mode == `FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE) - begin - if (subcarrier_frequency == `FPGA_HF_READER_2SUBCARRIERS_424_484_KHZ) - begin - // send 2 bits fsk (2sc) signal + amplitude - corr_i_out <= {fskout, corr_amplitude[13:8]}; - corr_q_out <= corr_amplitude[7:0]; - end - else - begin - // send amplitude - corr_i_out <= {2'b00, corr_amplitude[13:8]}; - corr_q_out <= corr_amplitude[7:0]; - end - end - else if (minor_mode == `FPGA_HF_READER_MODE_RECEIVE_IQ) - begin - // Send 8 bits of in phase tag signal - if (corr_i_accum[13:11] == 3'b000 || corr_i_accum[13:11] == 3'b111) - corr_i_out <= corr_i_accum[11:4]; - else // truncate to maximum value - if (corr_i_accum[13] == 1'b0) - corr_i_out <= 8'b01111111; - else - corr_i_out <= 8'b10000000; - - // Send 8 bits of quadrature phase tag signal - if (corr_q_accum[13:11] == 3'b000 || corr_q_accum[13:11] == 3'b111) - corr_q_out <= corr_q_accum[11:4]; - else // truncate to maximum value - if (corr_q_accum[13] == 1'b0) - corr_q_out <= 8'b01111111; - else - corr_q_out <= 8'b10000000; - end - - // for each Q/I pair report two reader signal samples when sniffing. Store the 1st. - after_hysteresis_prev_prev <= after_hysteresis; - - // Initialize next correlation. - // Both I and Q reference signals are high when corr_i_nct == 0. Therefore need to accumulate. - corr_i_accum <= $signed({1'b0, adc_d}); - corr_q_accum <= $signed({1'b0, adc_d}); - end - else - begin - if (subcarrier_I) - corr_i_accum <= corr_i_accum + $signed({1'b0, adc_d}); - else - corr_i_accum <= corr_i_accum - $signed({1'b0, adc_d}); - - if (subcarrier_Q) - corr_q_accum <= corr_q_accum + $signed({1'b0, adc_d}); - else - corr_q_accum <= corr_q_accum - $signed({1'b0, adc_d}); - end - - // for each Q/I pair report two reader signal samples when sniffing. Store the 2nd. - if (corr_i_cnt == 6'd32) - after_hysteresis_prev <= after_hysteresis; - - // Then the result from last time is serialized and send out to the ARM. - // We get one report each cycle, and each report is 16 bits, so the - // ssp_clk should be the adc_clk divided by 64/16 = 4. - // ssp_clk frequency = 13,56MHz / 4 = 3.39MHz - - if (corr_i_cnt[1:0] == 2'b00) - begin - // Don't shift if we just loaded new data, obviously. - if (corr_i_cnt != 6'd0) - begin - corr_i_out[7:0] <= {corr_i_out[6:0], corr_q_out[7]}; - corr_q_out[7:1] <= corr_q_out[6:0]; - end - end - -end - - -// ssp clock and frame signal for communication to and from ARM -// _____ _____ _____ _ -// ssp_clk | |_____| |_____| |_____| -// _____ -// ssp_frame ___| |____________________________ -// ___________ ___________ ___________ _ -// ssp_d_in X___________X___________X___________X_ -// -// corr_i_cnt 0 1 2 3 4 5 6 7 8 9 10 11 12 ... -// - -always @(negedge adc_clk) -begin - if (corr_i_cnt[1:0] == 2'b00) - ssp_clk <= 1'b1; - - if (corr_i_cnt[1:0] == 2'b10) - ssp_clk <= 1'b0; - - // set ssp_frame signal for corr_i_cnt = 1..3 - // (send one frame with 16 Bits) - if (corr_i_cnt == 6'd1) - ssp_frame <= 1'b1; - - if (corr_i_cnt == 6'd3) - ssp_frame <= 1'b0; -end - - -assign ssp_din = corr_i_out[7]; - - -// a jamming signal -reg jam_signal; -reg [3:0] jam_counter; - -always @(negedge adc_clk) -begin - if (corr_i_cnt == 6'd0) - begin - jam_counter <= jam_counter + 1; - jam_signal <= jam_counter[1] ^ jam_counter[3]; - end -end - -always @(*) -begin - if (minor_mode == `FPGA_HF_READER_MODE_SEND_SHALLOW_MOD) - begin - pwr_hi = ck_1356meg; - pwr_oe4 = ssp_dout; - end - else if (minor_mode == `FPGA_HF_READER_MODE_SEND_FULL_MOD) - begin - pwr_hi = ck_1356meg & ~ssp_dout; - pwr_oe4 = 1'b0; - end - else if (minor_mode == `FPGA_HF_READER_MODE_SEND_JAM) - begin - pwr_hi = ck_1356meg & jam_signal; - pwr_oe4 = 1'b0; - end - else if (minor_mode == `FPGA_HF_READER_MODE_SNIFF_IQ - || minor_mode == `FPGA_HF_READER_MODE_SNIFF_AMPLITUDE - || minor_mode == `FPGA_HF_READER_MODE_SNIFF_PHASE) - begin // all off - pwr_hi = 1'b0; - pwr_oe4 = 1'b0; - end - else // receiving from tag - begin - pwr_hi = ck_1356meg; - pwr_oe4 = 1'b0; - end -end - -// always on -assign pwr_oe1 = 1'b0; -assign pwr_oe3 = 1'b0; - -// Unused. -assign pwr_lo = 1'b0; -assign pwr_oe2 = 1'b0; - -// Debug Output -assign debug = corr_i_cnt[3]; - -endmodule From 66b1758278170df8b66c645a163f32eb16988003 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 24 Aug 2023 18:06:44 +0200 Subject: [PATCH 2/4] Removed commented out includes Include statements in individual files are not required when compiling the code the correct way as a project with an explicitly defined work library. The Makefile exactly replicates the compilation process of the ISE environment and generates the required project files. --- fpga/fpga_icopyx_hf.v | 8 -------- fpga/fpga_icopyx_lf.v | 7 ------- fpga/fpga_icopyx_top.v | 5 ----- fpga/fpga_pm3_top.v | 15 +-------------- fpga/hi_get_trace.v | 1 - fpga/hi_iso14443a.v | 1 - fpga/hi_simulate.v | 1 - fpga/lf_edge_detect.v | 3 --- fpga/lo_edge_detect.v | 3 --- fpga/mux16.v | 3 --- fpga/mux2_onein.v | 15 +++++++++++++-- fpga/mux2_oneout.v | 15 +++++++++++++-- fpga/mux8.v | 3 --- 13 files changed, 27 insertions(+), 53 deletions(-) diff --git a/fpga/fpga_icopyx_hf.v b/fpga/fpga_icopyx_hf.v index b7730875d..233c1aeab 100644 --- a/fpga/fpga_icopyx_hf.v +++ b/fpga/fpga_icopyx_hf.v @@ -20,14 +20,6 @@ // frequency modes, the FPGA might perform some demodulation first, to // reduce the amount of data that we must send to the ARM. //----------------------------------------------------------------------------- -//`include "define.v" - -//`include "hi_reader.v" -//`include "hi_simulate.v" -//`include "hi_iso14443a.v" -//`include "hi_flite.v" -//`include "hi_sniffer.v" -//`include "hi_get_trace.v" module fpga_hf( input spck, diff --git a/fpga/fpga_icopyx_lf.v b/fpga/fpga_icopyx_lf.v index 0ca4739b7..b1b890b79 100644 --- a/fpga/fpga_icopyx_lf.v +++ b/fpga/fpga_icopyx_lf.v @@ -20,13 +20,6 @@ // frequency modes, the FPGA might perform some demodulation first, to // reduce the amount of data that we must send to the ARM. //----------------------------------------------------------------------------- -//`include "define.v" - -//`include "lo_read.v" -//`include "lo_passthru.v" -//`include "lo_edge_detect.v" -//`include "lo_adc.v" -//`include "clk_divider.v" module fpga_lf( input spck, diff --git a/fpga/fpga_icopyx_top.v b/fpga/fpga_icopyx_top.v index 81aacb73c..39981e6cf 100644 --- a/fpga/fpga_icopyx_top.v +++ b/fpga/fpga_icopyx_top.v @@ -20,11 +20,6 @@ // frequency modes, the FPGA might perform some demodulation first, to // reduce the amount of data that we must send to the ARM. //----------------------------------------------------------------------------- -//`include "fpga_lf.v" -//`include "fpga_hf.v" -//`include "mux2_onein.v" -//`include "mux2_oneout.v" -//`include "util.v" module fpga_top( input spck, diff --git a/fpga/fpga_pm3_top.v b/fpga/fpga_pm3_top.v index f200bf498..89b03d3ad 100644 --- a/fpga/fpga_pm3_top.v +++ b/fpga/fpga_pm3_top.v @@ -20,18 +20,8 @@ // frequency modes, the FPGA might perform some demodulation first, to // reduce the amount of data that we must send to the ARM. //----------------------------------------------------------------------------- -/* -Once upon a time the FPGA had a 16 input mux so we could have all LF and HF modules enabled and selectable -As the functionality grew, we run out of space in the FPGA and we had to split into an "LF only" and an "HF only" FPGA bitstream -But even then after a while it was not possible to fit all the HF functions at the same time so now we have multiple "HF only" bitstreams -For example "Felica but without ISO14443", or "ISO14443 but without Felica" or "HF_15 but without Felica and ISO14443" -Because of all of the above, you can not enable both HF and LF modes at the same time, because some LF modules outputs -map to the same mux inputs as some HF modules outputs (thanks to reducing the mux from 16 to 8 inputs) and you can not have -multiple outputs connected together therefore leading to a failed compilation -*/ - -// These defines are meant to be passed by the Makefile so do not uncomment them here +// 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 @@ -64,9 +54,6 @@ multiple outputs connected together therefore leading to a failed compilation // WITH_HF5 enables module get trace //`define WITH_HF5 -//`include "define.v" -//`include "util.v" -// //`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 diff --git a/fpga/hi_get_trace.v b/fpga/hi_get_trace.v index 9bf32bc64..cd33173b2 100644 --- a/fpga/hi_get_trace.v +++ b/fpga/hi_get_trace.v @@ -13,7 +13,6 @@ // // See LICENSE.txt for the text of the license. //----------------------------------------------------------------------------- -//`include "define.v" module hi_get_trace( input ck_1356megb, diff --git a/fpga/hi_iso14443a.v b/fpga/hi_iso14443a.v index 6fd450528..182b66f7e 100644 --- a/fpga/hi_iso14443a.v +++ b/fpga/hi_iso14443a.v @@ -14,7 +14,6 @@ // See LICENSE.txt for the text of the license. //----------------------------------------------------------------------------- // ISO14443-A support for the Proxmark III -//`include "define.v" module hi_iso14443a( input ck_1356meg, diff --git a/fpga/hi_simulate.v b/fpga/hi_simulate.v index 97346eb9b..2d8ff2771 100644 --- a/fpga/hi_simulate.v +++ b/fpga/hi_simulate.v @@ -30,7 +30,6 @@ // // Jonathan Westhues, October 2006 //----------------------------------------------------------------------------- -//`include "define.v" module hi_simulate( input ck_1356meg, diff --git a/fpga/lf_edge_detect.v b/fpga/lf_edge_detect.v index 2a58331d1..1e4cd0cce 100644 --- a/fpga/lf_edge_detect.v +++ b/fpga/lf_edge_detect.v @@ -15,9 +15,6 @@ // See LICENSE.txt for the text of the license. //----------------------------------------------------------------------------- -// input clk is 24MHz -//`include "min_max_tracker.v" - module lf_edge_detect( input clk, input [7:0] adc_d, diff --git a/fpga/lo_edge_detect.v b/fpga/lo_edge_detect.v index c820466f7..9bf408cc7 100644 --- a/fpga/lo_edge_detect.v +++ b/fpga/lo_edge_detect.v @@ -25,9 +25,6 @@ // - ssp_frame (wired to TIOA1 on the arm) for the edge detection/state // - ssp_clk: cross_lo -//`include "lp20khz_1MSa_iir_filter.v" -//`include "lf_edge_detect.v" - module lo_edge_detect( input pck0, input pck_divclk, diff --git a/fpga/mux16.v b/fpga/mux16.v index 1d9777706..b22ee6bf7 100644 --- a/fpga/mux16.v +++ b/fpga/mux16.v @@ -13,9 +13,6 @@ // // See LICENSE.txt for the text of the license. //----------------------------------------------------------------------------- -// -// General-purpose miscellany. -// // 16 inputs to 1 output multiplexer module mux16( diff --git a/fpga/mux2_onein.v b/fpga/mux2_onein.v index baefa72c8..24a53bbe4 100644 --- a/fpga/mux2_onein.v +++ b/fpga/mux2_onein.v @@ -1,9 +1,20 @@ //----------------------------------------------------------------------------- -// Two way MUX. +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. // -// kombi, 2020.05 +// 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. //----------------------------------------------------------------------------- +// 2 inputs to 1 output multiplexer module mux2_one( input [1:0] sel, output reg y, diff --git a/fpga/mux2_oneout.v b/fpga/mux2_oneout.v index fa61205a2..d312b68c6 100644 --- a/fpga/mux2_oneout.v +++ b/fpga/mux2_oneout.v @@ -1,9 +1,20 @@ //----------------------------------------------------------------------------- -// Two way MUX. +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. // -// kombi, 2020.05 +// 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. //----------------------------------------------------------------------------- +// 1 input to 2 outputs multiplexer module mux2_oneout( input [1:0] sel, input y, diff --git a/fpga/mux8.v b/fpga/mux8.v index d9118d243..1918db2d8 100644 --- a/fpga/mux8.v +++ b/fpga/mux8.v @@ -13,9 +13,6 @@ // // See LICENSE.txt for the text of the license. //----------------------------------------------------------------------------- -// -// General-purpose miscellany. -// // 8 inputs to 1 output multiplexer module mux8( From 3e4b7d07ff0a4effbc06b114a373bc3b4fa97764 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 24 Aug 2023 18:21:07 +0200 Subject: [PATCH 3/4] Whitespace, formatting --- fpga/clk_divider.v | 2 +- fpga/fpga_icopyx_lf.v | 8 +- fpga/hi_flite.v | 378 ++++++++++++++++++++--------------------- fpga/hi_get_trace.v | 16 +- fpga/hi_iso14443a.v | 49 ++---- fpga/hi_simulate.v | 19 +-- fpga/lf_edge_detect.v | 120 ++++++------- fpga/lo_edge_detect.v | 4 +- fpga/lo_read.v | 7 +- fpga/min_max_tracker.v | 82 ++++----- 10 files changed, 332 insertions(+), 353 deletions(-) diff --git a/fpga/clk_divider.v b/fpga/clk_divider.v index 0bcc2e608..7cb9925f3 100644 --- a/fpga/clk_divider.v +++ b/fpga/clk_divider.v @@ -22,7 +22,7 @@ module clk_divider( ); reg [7:0] div_cnt_ = 0; - reg div_clk_; + reg div_clk_ = 0; assign div_cnt = div_cnt_; assign div_clk = div_clk_; diff --git a/fpga/fpga_icopyx_lf.v b/fpga/fpga_icopyx_lf.v index b1b890b79..d1495498a 100644 --- a/fpga/fpga_icopyx_lf.v +++ b/fpga/fpga_icopyx_lf.v @@ -71,7 +71,13 @@ reg [7:0] lf_ed_threshold; wire [7:0] pck_cnt; wire pck_divclk; reg [7:0] divisor; -clk_divider div_clk(pck0, divisor, pck_cnt, pck_divclk); + +clk_divider div_clk( + .clk (pck0), + .divisor (divisor), + .div_cnt (pck_cnt), + .div_clk (pck_divclk) +); // 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 diff --git a/fpga/hi_flite.v b/fpga/hi_flite.v index ac9e7e069..d93d67d21 100644 --- a/fpga/hi_flite.v +++ b/fpga/hi_flite.v @@ -66,7 +66,7 @@ assign adc_clk = ck_1356meg; `define min_bitdelay_212 8 //minimum values and corresponding thresholds -reg [8:0] curmin=`imin; +reg [8:0] curmin=`imin; reg [8:0] curminthres=`ithrmin; reg [8:0] curmaxthres=`ithrmax; reg [8:0] curmax=`imax; @@ -75,10 +75,10 @@ reg [8:0] curmax=`imax; reg after_hysteresis = 1'b1; //state machine for envelope tracking -reg [1:0] state=1'd0; +reg [1:0] state = 1'd0; //lower edge detected, trying to detect first bit of SYNC (b24d, 1011001001001101) -reg try_sync=1'b0; +reg try_sync = 1'b0; //detected first sync bit, phase frozen reg did_sync=0; @@ -105,32 +105,32 @@ reg zero = 1'b0; // Manchester first halfbit low second high corresponds to this reg [8:0] ssp_cnt = 9'd0; always @(posedge adc_clk) - ssp_cnt <= (ssp_cnt + 1); + ssp_cnt <= (ssp_cnt + 1); //maybe change it so that ARM sends preamble as well. //then: ready bits sent to ARM, 8 bits sent from ARM (all ones), then preamble (all zeros, presumably) - which starts modulation always @(negedge adc_clk) begin - //count fc/64 - transfer bits to ARM at the rate they are received - if( ((~speed) && (ssp_cnt[5:0] == 6'b000000)) || (speed && (ssp_cnt[4:0] == 5'b00000))) - begin - ssp_clk <= 1'b1; - //send current bit (detected in SNIFF mode or the one being modulated in MOD mode, 0 otherwise) - ssp_din <= curbit; - end - if( ( (~speed) && (ssp_cnt[5:0] == 6'b100000)) ||(speed && ssp_cnt[4:0] == 5'b10000)) - ssp_clk <= 1'b0; + //count fc/64 - transfer bits to ARM at the rate they are received + if( ((~speed) && (ssp_cnt[5:0] == 6'b000000) ) || (speed && (ssp_cnt[4:0] == 5'b00000)) ) + begin + ssp_clk <= 1'b1; + //send current bit (detected in SNIFF mode or the one being modulated in MOD mode, 0 otherwise) + ssp_din <= curbit; + end + if( ( (~speed) && (ssp_cnt[5:0] == 6'b100000)) ||(speed && ssp_cnt[4:0] == 5'b10000)) + ssp_clk <= 1'b0; //create frame pulses. TBH, I still don't know what they do exactly, but they are crucial for ARM->FPGA transfer. If the frame is in the beginning of the byte, transfer slows to a crawl for some reason // took me a day to figure THAT out. - if(( (~speed) && (ssp_cnt[8:0] == 9'd31)) || (speed && ssp_cnt[7:0] == 8'd15)) - begin - ssp_frame <= 1'b1; - end - if(( (~speed) && (ssp_cnt[8:0] == 9'b1011111)) || (speed &&ssp_cnt[7:0] == 8'b101111) ) - begin - ssp_frame <= 1'b0; - end + if(( (~speed) && (ssp_cnt[8:0] == 9'd31)) || (speed && ssp_cnt[7:0] == 8'd15)) + begin + ssp_frame <= 1'b1; + end + if(( (~speed) && (ssp_cnt[8:0] == 9'b1011111)) || (speed &&ssp_cnt[7:0] == 8'b101111) ) + begin + ssp_frame <= 1'b0; + end end //previous signal value, mostly to detect SYNC @@ -144,206 +144,200 @@ reg[7:0] mid = 8'd128; // reg sending = 1'b0; // are we actively modulating? reg [11:0] bit_counts = 12'd0; // for timeslots. only support ts=0 for now, at 212 speed -512 fullbits from end of frame. One hopes. might remove those? - //we need some way to flush bit_counts triggers on mod_type changes don't compile reg dlay; always @(negedge adc_clk) // every data ping? begin - //envelope follow code... + //envelope follow code... //////////// - if (fccount == bitmlen) - begin + if (fccount == bitmlen) + begin if ((~try_sync) && (adc_d < curminthres) && disabl ) begin - fccount <= 1; - end - else - begin - fccount <= 0; - end - dlay <= ssp_dout; - if (bit_counts > 768) // should be over ts0 now, without ARM interference... stop counting... - begin - bit_counts <= 0; - end - else - if (power) - bit_counts <= 0; - else - bit_counts <= bit_counts + 1; + fccount <= 1; end else begin + fccount <= 0; + end + dlay <= ssp_dout; + if (bit_counts > 768) // should be over ts0 now, without ARM interference... stop counting... + begin + bit_counts <= 0; + end + else + if (power) + bit_counts <= 0; + else + bit_counts <= bit_counts + 1; + end + else + begin if((~try_sync) && (adc_d < curminthres) && disabl) begin - fccount <= 1; - end - else - begin - fccount <= fccount + 1; - end + fccount <= 1; end + else + begin + fccount <= fccount + 1; + end + end - // rising edge - if (adc_d > curmaxthres) - begin + // rising edge + if (adc_d > curmaxthres) + begin case (state) - 0: begin - curmax <= adc_d > `imax? adc_d : `imax; - state <= 2; + 0: begin + curmax <= adc_d > `imax? adc_d : `imax; + state <= 2; end - 1: begin - curminthres <= ((curmin >> 1) + (curmin >> 2) + (curmin >> 4) + (curmax >> 3) + (curmax >> 4)); //threshold: 0.1875 max + 0.8125 min - curmaxthres <= ((curmax >> 1) + (curmax >> 2) + (curmax >> 4) + (curmin >> 3) + (curmin >> 4)); - curmax <= adc_d > 155 ? adc_d : 155; // to hopefully prevent overflow from spikes going up to 255 - state <= 2; + 1: begin + curminthres <= ((curmin >> 1) + (curmin >> 2) + (curmin >> 4) + (curmax >> 3) + (curmax >> 4)); //threshold: 0.1875 max + 0.8125 min + curmaxthres <= ((curmax >> 1) + (curmax >> 2) + (curmax >> 4) + (curmin >> 3) + (curmin >> 4)); + curmax <= adc_d > 155 ? adc_d : 155; // to hopefully prevent overflow from spikes going up to 255 + state <= 2; end - 2: begin - if (adc_d > curmax) - curmax <= adc_d; - end - default: + 2: begin + if (adc_d > curmax) + curmax <= adc_d; + end + default: begin end endcase after_hysteresis <= 1'b1; if(try_sync) - tsinceedge <= 0; - end - else if (adc_d> 1) + (curmin >> 2) + (curmin >> 4) + (curmax >> 3) + (curmax >> 4)); curmaxthres <= ( (curmax >> 1) + (curmax >> 2) + (curmax >> 4) + (curmin >> 3) + (curmin >> 4)); curmin <= adc_d < `imin ? adc_d : `imin; state <= 1; - end - default: - begin - end - endcase - after_hysteresis <= 0; - if (~try_sync ) //begin modulation, lower edge... - begin - try_sync <= 1; - fccount <= 1; - did_sync <= 0; - curbit <= 0; - mid <= 8'd127; - tsinceedge <= 0; - prv <= 1; - end - else - begin - tsinceedge <= 0; - end - end - else //stable state, low or high - begin - curminthres <= ( (curmin >> 1) + (curmin >> 2) + (curmin >> 4) + (curmax >> 3) + (curmax >> 4)); - curmaxthres <= ( (curmax >> 1) + (curmax >> 2) + (curmax >> 4) + (curmin >> 3) + (curmin >> 4)); - state <= 0; - - if (try_sync ) - begin - if (tsinceedge >= (128)) - begin - //we might need to start counting... assuming ARM wants to reply to the frame. - bit_counts <= 1;// i think? 128 is about 2 bits passed... but 1 also works - try_sync <= 0; - did_sync <= 0;//desync - curmin <= `imin; //reset envelope - curmax <= `imax; - curminthres <= `ithrmin; - curmaxthres <= `ithrmax; - prv <= 1; - tsinceedge <= 0; - after_hysteresis <= 1'b1; - curbit <= 0; - mid <= 8'd128; - end - else - tsinceedge <= (tsinceedge + 1); - end - end - - - if (try_sync && tsinceedge < 128) + end + default: begin - //detect bits in their middle ssp sampling is in sync, so it would sample all bits in order - if (fccount == bithalf) - begin - if ((~did_sync) && ((prv == 1 && (mid > 128))||(prv == 0 && (mid <= 128)))) - begin - //sync the Zero, and set curbit roperly - did_sync <= 1'b1; - zero <= ~prv;// 1-prv - curbit <= 1; - end + end + endcase + after_hysteresis <= 0; + if (~try_sync ) //begin modulation, lower edge... + begin + try_sync <= 1; + fccount <= 1; + did_sync <= 0; + curbit <= 0; + mid <= 8'd127; + tsinceedge <= 0; + prv <= 1; + end + else + begin + tsinceedge <= 0; + end + end + else //stable state, low or high + begin + curminthres <= ( (curmin >> 1) + (curmin >> 2) + (curmin >> 4) + (curmax >> 3) + (curmax >> 4)); + curmaxthres <= ( (curmax >> 1) + (curmax >> 2) + (curmax >> 4) + (curmin >> 3) + (curmin >> 4)); + state <= 0; + + if (try_sync ) + begin + if (tsinceedge >= (128)) + begin + //we might need to start counting... assuming ARM wants to reply to the frame. + bit_counts <= 1;// i think? 128 is about 2 bits passed... but 1 also works + try_sync <= 0; + did_sync <= 0;//desync + curmin <= `imin; //reset envelope + curmax <= `imax; + curminthres <= `ithrmin; + curmaxthres <= `ithrmax; + prv <= 1; + tsinceedge <= 0; + after_hysteresis <= 1'b1; + curbit <= 0; + mid <= 8'd128; + end + else + tsinceedge <= (tsinceedge + 1); + end + end + + if (try_sync && tsinceedge < 128) + begin + //detect bits in their middle ssp sampling is in sync, so it would sample all bits in order + if (fccount == bithalf) + begin + if ((~did_sync) && ((prv == 1 && (mid > 128))||(prv == 0 && (mid <= 128)))) + begin + //sync the Zero, and set curbit roperly + did_sync <= 1'b1; + zero <= ~prv;// 1-prv + curbit <= 1; + end + else + curbit <= (mid > 128) ? (~zero) : zero; + + prv <= (mid > 128) ? 1 : 0; + + if (adc_d > curmaxthres) + mid <= 8'd129; + else if (adc_d < curminthres) + mid <= 8'd127; + else + begin + if (after_hysteresis) + begin + mid <= 8'd129; + end else - curbit <= (mid > 128) ? (~zero) : zero; - - prv <= (mid > 128) ? 1 : 0; - - if (adc_d > curmaxthres) - mid <= 8'd129; - else if (adc_d < curminthres) - mid <= 8'd127; - else - begin - if (after_hysteresis) - begin - mid <= 8'd129; - end - else - begin - mid <= 8'd127; - end - end - - end - else - begin - if (fccount==bitmlen) - begin - // fccount <= 0; - prv <= (mid > 128) ? 1 : 0; - mid <= 128; - end - else - begin + begin + mid <= 8'd127; + end + end + end + else + begin + if (fccount==bitmlen) + begin + // fccount <= 0; + prv <= (mid > 128) ? 1 : 0; + mid <= 128; + end + else + begin // minimum-maximum calc - if(adc_d > curmaxthres) - mid <= mid + 1; - else if (adc_d < curminthres) + if(adc_d > curmaxthres) + mid <= mid + 1; + else if (adc_d < curminthres) mid <= mid - 1; - else + else begin - if (after_hysteresis) - begin - mid <= mid + 1; - end - else - begin - mid <= mid - 1; - end + if (after_hysteresis) + begin + mid <= mid + 1; + end + else + begin + mid <= mid - 1; + end end - end - end end - else - begin - end -// sending <= 0; + end + end +// sending <= 0; end //put modulation here to maintain the correct clock. Seems that some readers are sensitive to that @@ -353,23 +347,23 @@ wire mod = ((fccount >= bithalf) ^ dlay) & (~disabl); always @(ck_1356meg or ssp_dout or power or disabl or mod) begin if (power) - begin + begin pwr_hi <= ck_1356meg; pwr_lo <= 1'b0; pwr_oe1 <= 1'b0;//mod; pwr_oe2 <= 1'b0;//mod; pwr_oe3 <= 1'b0;//mod; pwr_oe4 <= mod;//1'b0; - end + end else - begin + begin pwr_hi <= 1'b0; pwr_lo <= 1'b0; pwr_oe1 <= 1'b0; pwr_oe2 <= 1'b0; pwr_oe3 <= 1'b0; pwr_oe4 <= mod; - end + end end endmodule diff --git a/fpga/hi_get_trace.v b/fpga/hi_get_trace.v index cd33173b2..b577ff6be 100644 --- a/fpga/hi_get_trace.v +++ b/fpga/hi_get_trace.v @@ -105,13 +105,12 @@ begin write_enable1 <= 1'b0; write_enable2 <= 1'b0; if (previous_major_mode != `FPGA_MAJOR_MODE_OFF && previous_major_mode != `FPGA_MAJOR_MODE_HF_GET_TRACE) // just switched off - begin + begin start_addr <= addr; - end + end end end - // (2+1)k RAM reg [7:0] D_out1, D_out2; reg [7:0] ram1 [2047:0]; // 2048 u8 @@ -127,7 +126,7 @@ begin else D_out1 <= ram1[addr[10:0]]; if (write_enable2) -begin + begin ram2[addr[9:0]] <= adc_d; D_out2 <= adc_d; end @@ -135,7 +134,6 @@ begin D_out2 <= ram2[addr[9:0]]; end - reg [7:0] shift_out; always @(negedge ck_1356megb) @@ -150,10 +148,10 @@ begin shift_out <= D_out2; end else - begin - // or shift left - shift_out[7:1] <= shift_out[6:0]; - end + begin + // or shift left + shift_out[7:1] <= shift_out[6:0]; + end end ssp_clk <= ~clock_cnt[3]; // ssp_clk frequency = 13,56MHz / 16 = 847,5 kHz diff --git a/fpga/hi_iso14443a.v b/fpga/hi_iso14443a.v index 182b66f7e..0ceac6d95 100644 --- a/fpga/hi_iso14443a.v +++ b/fpga/hi_iso14443a.v @@ -104,8 +104,6 @@ begin end end - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Tag -> PM3 // filter the input for a tag's signal. The filter box needs the 4 previous input values and is a gaussian derivative filter @@ -132,7 +130,6 @@ wire [9:0] tmp2 = adc_d_times_2 + input_prev_1; // convert intermediate signals to signed and calculate the filter output wire signed [10:0] adc_d_filtered = {1'b0, tmp1} - {1'b0, tmp2}; - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // internal FPGA timing. Maximum required period is 128 carrier clock cycles for a full 8 Bit transfer to ARM. (i.e. we need a // 7 bit counter). Adjust its frequency to external reader's clock when simulating a tag or sniffing. @@ -176,7 +173,6 @@ begin end end - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Tag -> PM3: // determine best possible time for starting/resetting the modulation detector. @@ -208,7 +204,6 @@ begin end end - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Tag -> PM3: // modulation detector. Looks for the steepest falling and rising edges within a 16 clock period. If there is both a significant @@ -228,27 +223,27 @@ always @(negedge adc_clk) begin if(negedge_cnt[3:0] == mod_detect_reset_time) begin - if (mod_type == `FPGA_HF_ISO14443A_SNIFFER) - begin - // detect modulation signal: if modulating, there must have been a falling AND a rising edge - if ((rx_mod_falling_edge_max > `EDGE_DETECT_THRESHOLDHIGH) && (rx_mod_rising_edge_max < -`EDGE_DETECT_THRESHOLDHIGH)) - curbit <= 1'b1; // modulation - else - curbit <= 1'b0; // no modulation - end - else - begin - // detect modulation signal: if modulating, there must have been a falling AND a rising edge - if ((rx_mod_falling_edge_max > `EDGE_DETECT_THRESHOLD) && (rx_mod_rising_edge_max < -`EDGE_DETECT_THRESHOLD)) - curbit <= 1'b1; // modulation - else - curbit <= 1'b0; // no modulation - end + if (mod_type == `FPGA_HF_ISO14443A_SNIFFER) + begin + // detect modulation signal: if modulating, there must have been a falling AND a rising edge + if ((rx_mod_falling_edge_max > `EDGE_DETECT_THRESHOLDHIGH) && (rx_mod_rising_edge_max < -`EDGE_DETECT_THRESHOLDHIGH)) + curbit <= 1'b1; // modulation + else + curbit <= 1'b0; // no modulation + end + else + begin + // detect modulation signal: if modulating, there must have been a falling AND a rising edge + if ((rx_mod_falling_edge_max > `EDGE_DETECT_THRESHOLD) && (rx_mod_rising_edge_max < -`EDGE_DETECT_THRESHOLD)) + curbit <= 1'b1; // modulation + else + curbit <= 1'b0; // no modulation + end // reset modulation detector rx_mod_rising_edge_max <= 0; rx_mod_falling_edge_max <= 0; end - else // look for steepest edges (slopes) + else // look for steepest edges (slopes) begin if (adc_d_filtered > 0) begin @@ -264,7 +259,6 @@ begin end - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Tag+Reader -> PM3 // sample 4 bits reader data and 4 bits tag data for sniffing @@ -280,7 +274,6 @@ begin end end - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PM3 -> Reader: // a delay line to ensure that we send the (emulated) tag's answer at the correct time according to ISO14443-3 @@ -303,7 +296,6 @@ begin end end - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PM3 -> Reader, internal timing: // a timer for the 1172 cycles fdt (Frame Delay Time). Start the timer with a rising edge of the reader's signal. @@ -366,7 +358,6 @@ begin if(fdt_counter == `FDT_INDICATOR_COUNT) fdt_indicator <= 1'b1; end - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PM3 -> Reader or Tag // assign a modulation signal to the antenna. This signal is either a delayed signal (to achieve fdt when sending to a reader) @@ -395,7 +386,6 @@ begin end end - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PM3 -> Reader // determine the required delay in the mod_sig_buf (set mod_sig_ptr). @@ -438,7 +428,6 @@ begin end end - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FPGA -> ARM communication: // buffer 8 bits data to be sent to ARM. Shift them out bit by bit. @@ -482,10 +471,8 @@ begin to_arm[7:1] <= to_arm[6:0]; end end - end - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FPGA <-> ARM communication: // generate a ssp clock and ssp frame signal for the synchronous transfer from/to the ARM @@ -520,7 +507,6 @@ begin end end - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FPGA -> ARM communication: // select the data to be sent to ARM @@ -565,7 +551,6 @@ assign sub_carrier = ~sub_carrier_cnt[3]; // in FPGA_HF_ISO14443A_READER_LISTEN: carrier always on; in other modes: carrier always off assign pwr_hi = (ck_1356meg & (((mod_type == `FPGA_HF_ISO14443A_READER_MOD) & ~mod_sig_coil) || (mod_type == `FPGA_HF_ISO14443A_READER_LISTEN))); - // Enable HF antenna drivers: assign pwr_oe1 = 1'b0; assign pwr_oe3 = 1'b0; diff --git a/fpga/hi_simulate.v b/fpga/hi_simulate.v index 2d8ff2771..77b9a44ed 100644 --- a/fpga/hi_simulate.v +++ b/fpga/hi_simulate.v @@ -88,7 +88,6 @@ begin end end - // Divide 13.56 MHz to produce various frequencies for SSP_CLK // and modulation. reg [8:0] ssp_clk_divider; @@ -99,17 +98,16 @@ always @(negedge adc_clk) always @(negedge adc_clk) begin if (mod_type == `FPGA_HF_SIMULATOR_MODULATE_424K_8BIT) - // Get bit every at 53KHz (every 8th carrier bit of 424kHz) - ssp_clk <= ~ssp_clk_divider[7]; + // Get bit every at 53KHz (every 8th carrier bit of 424kHz) + ssp_clk <= ~ssp_clk_divider[7]; else if (mod_type == `FPGA_HF_SIMULATOR_MODULATE_212K) - // Get next bit at 212kHz - ssp_clk <= ~ssp_clk_divider[5]; + // Get next bit at 212kHz + ssp_clk <= ~ssp_clk_divider[5]; else - // Get next bit at 424kHz - ssp_clk <= ~ssp_clk_divider[4]; + // Get next bit at 424kHz + ssp_clk <= ~ssp_clk_divider[4]; end - // Produce the byte framing signal; the phase of this signal // is arbitrary, because it's just a bit stream in this module. always @(negedge adc_clk) @@ -130,7 +128,6 @@ begin end end - // Synchronize up the after-hysteresis signal, to produce DIN. always @(posedge ssp_clk) ssp_din = after_hysteresis; @@ -147,9 +144,7 @@ always @(*) else if(mod_type == `FPGA_HF_SIMULATOR_MODULATE_424K || mod_type == `FPGA_HF_SIMULATOR_MODULATE_424K_8BIT) modulating_carrier <= ssp_dout & ssp_clk_divider[4]; // switch 424kHz modulation on/off else - modulating_carrier <= 1'b0; // yet unused - - + modulating_carrier <= 1'b0; // yet unused // Load modulation. Toggle only one of these, since we are already producing much deeper // modulation than a real tag would. diff --git a/fpga/lf_edge_detect.v b/fpga/lf_edge_detect.v index 1e4cd0cce..27d7f6901 100644 --- a/fpga/lf_edge_detect.v +++ b/fpga/lf_edge_detect.v @@ -1,4 +1,3 @@ - //----------------------------------------------------------------------------- // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. // @@ -30,73 +29,74 @@ module lf_edge_detect( output edge_toggle ); - min_max_tracker tracker( - .clk (clk), - .adc_d (adc_d), - .threshold (lf_ed_threshold), - .min (min), - .max (max) +min_max_tracker tracker( + .clk (clk), + .adc_d (adc_d), + .threshold (lf_ed_threshold), + .min (min), + .max (max) ); - // auto-tune - assign high_threshold = (max + min) / 2 + (max - min) / 4; - assign highz_threshold = (max + min) / 2 + (max - min) / 8; - assign lowz_threshold = (max + min) / 2 - (max - min) / 8; - assign low_threshold = (max + min) / 2 - (max - min) / 4; +// auto-tune +assign high_threshold = (max + min) / 2 + (max - min) / 4; +assign highz_threshold = (max + min) / 2 + (max - min) / 8; +assign lowz_threshold = (max + min) / 2 - (max - min) / 8; +assign low_threshold = (max + min) / 2 - (max - min) / 4; - // heuristic to see if it makes sense to try to detect an edge - wire enabled = - (high_threshold > highz_threshold) - & (highz_threshold > lowz_threshold) - & (lowz_threshold > low_threshold) - & ((high_threshold - highz_threshold) > 8) - & ((highz_threshold - lowz_threshold) > 16) - & ((lowz_threshold - low_threshold) > 8); +// heuristic to see if it makes sense to try to detect an edge +wire enabled = + (high_threshold > highz_threshold) + & (highz_threshold > lowz_threshold) + & (lowz_threshold > low_threshold) + & ((high_threshold - highz_threshold) > 8) + & ((highz_threshold - lowz_threshold) > 16) + & ((lowz_threshold - low_threshold) > 8); - // Toggle the output with hysteresis - // Set to high if the ADC value is above the threshold - // Set to low if the ADC value is below the threshold - reg is_high = 0; - reg is_low = 0; - reg is_zero = 0; - reg trigger_enabled = 1; - reg output_edge = 0; - reg output_state; +// Toggle the output with hysteresis +// Set to high if the ADC value is above the threshold +// Set to low if the ADC value is below the threshold +reg is_high = 0; +reg is_low = 0; +reg is_zero = 0; +reg trigger_enabled = 1; +reg output_edge = 0; +reg output_state; - always @(posedge clk) +always @(posedge clk) +begin + is_high <= (adc_d >= high_threshold); + is_low <= (adc_d <= low_threshold); + is_zero <= ((adc_d > lowz_threshold) & (adc_d < highz_threshold)); +end + +// all edges detection +always @(posedge clk) +if (enabled) +begin + // To enable detecting two consecutive peaks at the same level + // (low or high) we check whether or not we went back near 0 in-between. + // This extra check is necessary to prevent from noise artifacts + // around the threshold values. + if (trigger_enabled & (is_high | is_low)) begin - is_high <= (adc_d >= high_threshold); - is_low <= (adc_d <= low_threshold); - is_zero <= ((adc_d > lowz_threshold) & (adc_d < highz_threshold)); + output_edge <= ~output_edge; + trigger_enabled <= 0; end + else + trigger_enabled <= trigger_enabled | is_zero; +end - // all edges detection - always @(posedge clk) - if (enabled) - begin - // To enable detecting two consecutive peaks at the same level - // (low or high) we check whether or not we went back near 0 in-between. - // This extra check is necessary to prevent from noise artifacts - // around the threshold values. - if (trigger_enabled & (is_high | is_low)) - begin - output_edge <= ~output_edge; - trigger_enabled <= 0; - end else - trigger_enabled <= trigger_enabled | is_zero; - end +// edge states +always @(posedge clk) +if (enabled) +begin + if (is_high) + output_state <= 1'd1; + else if (is_low) + output_state <= 1'd0; +end - // edge states - always @(posedge clk) - if (enabled) - begin - if (is_high) - output_state <= 1'd1; - else if (is_low) - output_state <= 1'd0; - end - - assign edge_state = output_state; - assign edge_toggle = output_edge; +assign edge_state = output_state; +assign edge_toggle = output_edge; endmodule diff --git a/fpga/lo_edge_detect.v b/fpga/lo_edge_detect.v index 9bf408cc7..c29fdccb3 100644 --- a/fpga/lo_edge_detect.v +++ b/fpga/lo_edge_detect.v @@ -51,8 +51,8 @@ wire tag_modulation = ssp_dout & !lf_field; wire reader_modulation = !ssp_dout & lf_field & pck_divclk; // No logic, straight through. -assign pwr_oe1 = 1'b0; // not used in LF mode -assign pwr_oe3 = 1'b0; // base antenna load = 33 Ohms +assign pwr_oe1 = 1'b0; // not used in LF mode +assign pwr_oe3 = 1'b0; // base antenna load = 33 Ohms // when modulating, add another 33 Ohms and 10k Ohms in parallel: assign pwr_oe2 = tag_modulation; assign pwr_oe4 = tag_modulation; diff --git a/fpga/lo_read.v b/fpga/lo_read.v index 06bd0ae5a..c51857eb4 100644 --- a/fpga/lo_read.v +++ b/fpga/lo_read.v @@ -51,7 +51,7 @@ reg [7:0] to_arm_shiftreg; // we read the ADC value when pck_cnt=7 and shift it out on counts 8..15 always @(posedge pck0) begin - if((pck_cnt == 8'd7) && !pck_divclk) + if ((pck_cnt == 8'd7) && !pck_divclk) to_arm_shiftreg <= adc_d; else begin @@ -73,14 +73,15 @@ end // _ _ _ _ _ _ _ _ _ _ // ssp_clk |_| |_| |_| |_| |_| |_| |_| |_| |_| |_ -// serialized SSP data is gated by ant_lo to suppress unwanted signal +// serialized SSP data is gated by pck_divclk to suppress unwanted signal assign ssp_din = to_arm_shiftreg[7] && !pck_divclk; // SSP clock always runs at 24MHz assign ssp_clk = pck0; -// SSP frame is gated by ant_lo and goes high when pck_divider=8..15 +// SSP frame is gated by pck_divclk and goes high when pck_cnt=8..15 assign ssp_frame = (pck_cnt[7:3] == 5'd1) && !pck_divclk; // unused signals tied low assign pwr_hi = 1'b0; +// always on outputs, unused assign pwr_oe1 = 1'b0; assign pwr_oe2 = 1'b0; assign pwr_oe3 = 1'b0; diff --git a/fpga/min_max_tracker.v b/fpga/min_max_tracker.v index 2f6e06017..2aaab66bb 100644 --- a/fpga/min_max_tracker.v +++ b/fpga/min_max_tracker.v @@ -31,50 +31,50 @@ module min_max_tracker( output [7:0] max ); - reg [7:0] min_val = 255; - reg [7:0] max_val = 0; - reg [7:0] cur_min_val = 255; - reg [7:0] cur_max_val = 0; - reg [1:0] state = 0; +reg [7:0] min_val = 255; +reg [7:0] max_val = 0; +reg [7:0] cur_min_val = 255; +reg [7:0] cur_max_val = 0; +reg [1:0] state = 0; - always @(posedge clk) - begin - case (state) - 0: // initialize - begin - if (cur_max_val >= ({1'b0, adc_d} + threshold)) - state <= 2; - else if (adc_d >= ({1'b0, cur_min_val} + threshold)) - state <= 1; - if (cur_max_val <= adc_d) - cur_max_val <= adc_d; - else if (adc_d <= cur_min_val) - cur_min_val <= adc_d; +always @(posedge clk) +begin + case (state) + 0: // initialize + begin + if (cur_max_val >= ({1'b0, adc_d} + threshold)) + state <= 2; + else if (adc_d >= ({1'b0, cur_min_val} + threshold)) + state <= 1; + if (cur_max_val <= adc_d) + cur_max_val <= adc_d; + else if (adc_d <= cur_min_val) + cur_min_val <= adc_d; + end + 1: // high phase + begin + if (cur_max_val <= adc_d) + cur_max_val <= adc_d; + else if (({1'b0, adc_d} + threshold) <= cur_max_val) begin + state <= 2; + cur_min_val <= adc_d; + max_val <= cur_max_val; end - 1: // high phase - begin - if (cur_max_val <= adc_d) - cur_max_val <= adc_d; - else if (({1'b0, adc_d} + threshold) <= cur_max_val) begin - state <= 2; - cur_min_val <= adc_d; - max_val <= cur_max_val; - end + end + 2: // low phase + begin + if (adc_d <= cur_min_val) + cur_min_val <= adc_d; + else if (adc_d >= ({1'b0, cur_min_val} + threshold)) begin + state <= 1; + cur_max_val <= adc_d; + min_val <= cur_min_val; end - 2: // low phase - begin - if (adc_d <= cur_min_val) - cur_min_val <= adc_d; - else if (adc_d >= ({1'b0, cur_min_val} + threshold)) begin - state <= 1; - cur_max_val <= adc_d; - min_val <= cur_min_val; - end - end - endcase - end + end + endcase +end - assign min = min_val; - assign max = max_val; +assign min = min_val; +assign max = max_val; endmodule From f47e4ed115176d76ee4caaf6246d344300818126 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 24 Aug 2023 18:22:50 +0200 Subject: [PATCH 4/4] Move hardcoded value where it belongs Keep FPGA parameters together in the same place --- client/src/cmdhw.c | 3 ++- common_fpga/fpga.h | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhw.c b/client/src/cmdhw.c index ec3ab4867..1b2cd5459 100644 --- a/client/src/cmdhw.c +++ b/client/src/cmdhw.c @@ -27,6 +27,7 @@ #include "comms.h" #include "usart_defs.h" #include "ui.h" +#include "fpga.h" #include "cmdhw.h" #include "cmddata.h" #include "commonutil.h" @@ -1392,7 +1393,7 @@ void pm3_version(bool verbose, bool oneliner) { } } PrintAndLogEx(NORMAL, payload->versionstr); - if (strstr(payload->versionstr, "2s30vq100") == NULL) { + if (strstr(payload->versionstr, FPGA_TYPE) == NULL) { PrintAndLogEx(NORMAL, " FPGA firmware... %s", _RED_("chip mismatch")); } diff --git a/common_fpga/fpga.h b/common_fpga/fpga.h index b7e017d68..35143ec6f 100644 --- a/common_fpga/fpga.h +++ b/common_fpga/fpga.h @@ -23,9 +23,11 @@ #define FPGA_BITSTREAM_FIXED_HEADER_SIZE sizeof(bitparse_fixed_header) #define FPGA_INTERLEAVE_SIZE 288 #if defined XC3 -#define FPGA_CONFIG_SIZE 72864L // our current fpga_[lh]f.bit files are 72742 bytes. Rounded up to next multiple of FPGA_INTERLEAVE_SIZE +#define FPGA_TYPE "3s100evq100" +#define FPGA_CONFIG_SIZE 72864L // FPGA .bit file rounded up to next multiple of FPGA_INTERLEAVE_SIZE #else -#define FPGA_CONFIG_SIZE 42336L // our current fpga_[lh]f.bit files are 42175 bytes. Rounded up to next multiple of FPGA_INTERLEAVE_SIZE +#define FPGA_TYPE "2s30vq100" +#define FPGA_CONFIG_SIZE 42336L // FPGA .bit file rounded up to next multiple of FPGA_INTERLEAVE_SIZE #endif #define FPGA_RING_BUFFER_BYTES (1024 * 30) #define FPGA_TRACE_SIZE 3072