mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-12-27 10:34:08 +08:00
168 lines
4.4 KiB
Verilog
168 lines
4.4 KiB
Verilog
//-----------------------------------------------------------------------------
|
|
// 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.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
module hi_get_trace(
|
|
input ck_1356megb,
|
|
input [7:0] adc_d,
|
|
input trace_enable,
|
|
input [2:0] major_mode,
|
|
|
|
output ssp_din,
|
|
output reg ssp_frame,
|
|
output reg ssp_clk
|
|
);
|
|
|
|
// clock divider
|
|
reg [6:0] clock_cnt;
|
|
always @(negedge ck_1356megb)
|
|
begin
|
|
clock_cnt <= clock_cnt + 1;
|
|
end
|
|
|
|
// sample at 13,56MHz / 8. The highest signal frequency (subcarrier) is 848,5kHz, i.e. in this case we oversample by a factor of 2
|
|
reg [2:0] sample_clock;
|
|
always @(negedge ck_1356megb)
|
|
begin
|
|
if (sample_clock == 3'd7)
|
|
sample_clock <= 3'd0;
|
|
else
|
|
sample_clock <= sample_clock + 1;
|
|
end
|
|
|
|
|
|
reg [11:0] addr;
|
|
reg [11:0] start_addr;
|
|
reg [2:0] previous_major_mode;
|
|
reg write_enable1;
|
|
reg write_enable2;
|
|
always @(negedge ck_1356megb)
|
|
begin
|
|
previous_major_mode <= major_mode;
|
|
if (major_mode == `FPGA_MAJOR_MODE_HF_GET_TRACE)
|
|
begin
|
|
write_enable1 <= 1'b0;
|
|
write_enable2 <= 1'b0;
|
|
if (previous_major_mode != `FPGA_MAJOR_MODE_HF_GET_TRACE) // just switched into GET_TRACE mode
|
|
addr <= start_addr;
|
|
if (clock_cnt == 7'd0)
|
|
begin
|
|
if (addr == 12'd3071)
|
|
addr <= 12'd0;
|
|
else
|
|
addr <= addr + 1;
|
|
end
|
|
end
|
|
else if (major_mode != `FPGA_MAJOR_MODE_OFF)
|
|
begin
|
|
if (trace_enable)
|
|
begin
|
|
if (addr[11] == 1'b0)
|
|
begin
|
|
write_enable1 <= 1'b1;
|
|
write_enable2 <= 1'b0;
|
|
end
|
|
else
|
|
begin
|
|
write_enable1 <= 1'b0;
|
|
write_enable2 <= 1'b1;
|
|
end
|
|
if (sample_clock == 3'b000)
|
|
begin
|
|
if (addr == 12'd3071)
|
|
begin
|
|
addr <= 12'd0;
|
|
write_enable1 <= 1'b1;
|
|
write_enable2 <= 1'b0;
|
|
end
|
|
else
|
|
begin
|
|
addr <= addr + 1;
|
|
end
|
|
end
|
|
end
|
|
else
|
|
begin
|
|
write_enable1 <= 1'b0;
|
|
write_enable2 <= 1'b0;
|
|
start_addr <= addr;
|
|
end
|
|
end
|
|
else // major_mode == `FPGA_MAJOR_MODE_OFF
|
|
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
|
|
start_addr <= addr;
|
|
end
|
|
end
|
|
end
|
|
|
|
// (2+1)k RAM
|
|
reg [7:0] D_out1, D_out2;
|
|
reg [7:0] ram1 [2047:0]; // 2048 u8
|
|
reg [7:0] ram2 [1023:0]; // 1024 u8
|
|
|
|
always @(negedge ck_1356megb)
|
|
begin
|
|
if (write_enable1)
|
|
begin
|
|
ram1[addr[10:0]] <= adc_d;
|
|
D_out1 <= adc_d;
|
|
end
|
|
else
|
|
D_out1 <= ram1[addr[10:0]];
|
|
if (write_enable2)
|
|
begin
|
|
ram2[addr[9:0]] <= adc_d;
|
|
D_out2 <= adc_d;
|
|
end
|
|
else
|
|
D_out2 <= ram2[addr[9:0]];
|
|
end
|
|
|
|
reg [7:0] shift_out;
|
|
|
|
always @(negedge ck_1356megb)
|
|
begin
|
|
if (clock_cnt[3:0] == 4'd0) // update shift register every 16 clock cycles
|
|
begin
|
|
if (clock_cnt[6:4] == 3'd0) // either load new value
|
|
begin
|
|
if (addr[11] == 1'b0)
|
|
shift_out <= D_out1;
|
|
else
|
|
shift_out <= D_out2;
|
|
end
|
|
else
|
|
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
|
|
|
|
if (clock_cnt[6:4] == 3'b000) // set ssp_frame for 0...31
|
|
ssp_frame <= 1'b1;
|
|
else
|
|
ssp_frame <= 1'b0;
|
|
|
|
end
|
|
|
|
assign ssp_din = shift_out[7];
|
|
|
|
endmodule
|