mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-07-16 02:03:00 -07:00
THIS REQUIRES A BOOTROM UPDATE!! To save FPGA area, split the LF and HF bitstreams and load them on-demand.
This commit is contained in:
parent
d51b2eda8f
commit
7cc204bff8
32 changed files with 771 additions and 661 deletions
|
@ -1,31 +1,33 @@
|
|||
include ../common/Makefile.common
|
||||
|
||||
all: fpga.ngc fpga.ngd fpga.ncd fpga-placed.ncd fpga.bit
|
||||
all: fpga_lf.bit fpga_hf.bit
|
||||
clean:
|
||||
$(DELETE) fpga.bgn fpga.drc fpga.ncd fpga.ngd fpga_par.xrpt fpga-placed.pad fpga-placed.par fpga-placed.xpi fpga_usage.xml xlnx_auto_0.ise xst.srp
|
||||
$(DELETE) fpga.map fpga.ngc fpga_ngdbuild.xrpt fpga.pcf fpga-placed_pad.csv fpga-placed.ptwx fpga.rbt xlnx_auto_0_xdb
|
||||
$(DELETE) fpga.bld fpga.mrp fpga.ngc_xst.xrpt fpga.ngm fpga-placed.ncd fpga-placed_pad.txt fpga-placed.unroutes fpga_summary.xml netlist.lst xst
|
||||
$(DELETE) *.bgn *.drc *.ncd *.ngd *_par.xrpt *-placed.* *-placed_pad.* *_usage.xml xst_hf.srp xst_lf.srp
|
||||
$(DELETE) *.map *.ngc *.xrpt *.pcf *.rbt *_auto_* *.bld *.mrp *.ngm *.unroutes *_summary.xml netlist.lst xst
|
||||
|
||||
fpga.ngc: fpga.v fpga.ucf xst.scr util.v lo_edge_detect.v lo_read.v lo_passthru.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v
|
||||
$(DELETE) fpga.ngc
|
||||
$(XILINX_TOOLS_PREFIX)xst -ifn xst.scr
|
||||
fpga_hf.ngc: fpga_hf.v fpga.ucf xst_hf.scr util.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v
|
||||
$(DELETE) $@
|
||||
$(XILINX_TOOLS_PREFIX)xst -ifn xst_hf.scr
|
||||
|
||||
fpga.ngd: fpga.ngc
|
||||
$(DELETE) fpga.ngd
|
||||
$(XILINX_TOOLS_PREFIX)ngdbuild -aul -p xc2s30-5-vq100 -nt timestamp -uc fpga.ucf fpga.ngc fpga.ngd
|
||||
fpga_lf.ngc: fpga_lf.v fpga.ucf xst_lf.scr util.v clk_divider.v lo_edge_detect.v lo_read.v lo_passthru.v
|
||||
$(DELETE) $@
|
||||
$(XILINX_TOOLS_PREFIX)xst -ifn xst_lf.scr
|
||||
|
||||
fpga.ncd: fpga.ngd
|
||||
$(DELETE) fpga.ncd
|
||||
$(XILINX_TOOLS_PREFIX)map -p xc2s30-5-vq100 fpga.ngd
|
||||
%.ngd: %.ngc
|
||||
$(DELETE) $@
|
||||
$(XILINX_TOOLS_PREFIX)ngdbuild -aul -p xc2s30-5-vq100 -nt timestamp -uc fpga.ucf $< $@
|
||||
|
||||
fpga-placed.ncd: fpga.ncd
|
||||
$(DELETE) fpga-placed.ncd
|
||||
$(XILINX_TOOLS_PREFIX)par fpga.ncd fpga-placed.ncd
|
||||
%.ncd: %.ngd
|
||||
$(DELETE) $@
|
||||
$(XILINX_TOOLS_PREFIX)map -p xc2s30-5-vq100 $<
|
||||
|
||||
fpga.bit: fpga-placed.ncd
|
||||
$(DELETE) fpga.bit fpga.drc fpga.rbt
|
||||
$(XILINX_TOOLS_PREFIX)bitgen fpga-placed.ncd fpga.bit
|
||||
%-placed.ncd: %.ncd
|
||||
$(DELETE) $@
|
||||
$(XILINX_TOOLS_PREFIX)par $< $@
|
||||
|
||||
%.bit: %-placed.ncd
|
||||
$(DELETE) $@ $*.drc $*.rbt
|
||||
$(XILINX_TOOLS_PREFIX)bitgen $< $@
|
||||
|
||||
.PHONY: all clean help
|
||||
help:
|
||||
|
|
25
fpga/clk_divider.v
Normal file
25
fpga/clk_divider.v
Normal file
|
@ -0,0 +1,25 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2014 iZsh <izsh at fail0verflow.com>
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
module clk_divider(input clk, input [7:0] divisor, output [7:0] div_cnt, output div_clk);
|
||||
|
||||
reg [7:0] div_cnt_ = 0;
|
||||
reg div_clk_;
|
||||
assign div_cnt = div_cnt_;
|
||||
assign div_clk = div_clk_;
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if(div_cnt == divisor) begin
|
||||
div_cnt_ <= 8'd0;
|
||||
div_clk_ = !div_clk_;
|
||||
end else
|
||||
div_cnt_ <= div_cnt_ + 1;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
BIN
fpga/fpga.bit
BIN
fpga/fpga.bit
Binary file not shown.
220
fpga/fpga.v
220
fpga/fpga.v
|
@ -1,220 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//
|
||||
// I am not really an FPGA/ASIC designer, so I am sure that a lot of this
|
||||
// could be improved.
|
||||
//
|
||||
// Jonathan Westhues, March 2006
|
||||
// Added ISO14443-A support by Gerhard de Koning Gans, April 2008
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
`include "lo_read.v"
|
||||
`include "lo_passthru.v"
|
||||
`include "lo_edge_detect.v"
|
||||
`include "hi_read_tx.v"
|
||||
`include "hi_read_rx_xcorr.v"
|
||||
`include "hi_simulate.v"
|
||||
`include "hi_iso14443a.v"
|
||||
`include "util.v"
|
||||
|
||||
module fpga(
|
||||
spck, miso, mosi, ncs,
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4,
|
||||
adc_d, adc_clk, adc_noe,
|
||||
ssp_frame, ssp_din, ssp_dout, ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
dbg
|
||||
);
|
||||
input spck, mosi, ncs;
|
||||
output miso;
|
||||
input pck0, ck_1356meg, ck_1356megb;
|
||||
output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
|
||||
input [7:0] adc_d;
|
||||
output adc_clk, adc_noe;
|
||||
input ssp_dout;
|
||||
output ssp_frame, ssp_din, ssp_clk;
|
||||
input cross_hi, cross_lo;
|
||||
output dbg;
|
||||
|
||||
//assign pck0 = pck0i;
|
||||
// IBUFG #(.IOSTANDARD("DEFAULT") ) pck0b(
|
||||
// .O(pck0),
|
||||
// .I(pck0i)
|
||||
// );
|
||||
//assign spck = spcki;
|
||||
// IBUFG #(.IOSTANDARD("DEFAULT") ) spckb(
|
||||
// .O(spck),
|
||||
// .I(spcki)
|
||||
// );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
reg [15:0] shift_reg;
|
||||
reg [7:0] divisor;
|
||||
reg [7:0] conf_word;
|
||||
|
||||
// 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
|
||||
case(shift_reg[15:12])
|
||||
4'b0001: conf_word <= shift_reg[7:0]; // FPGA_CMD_SET_CONFREG
|
||||
4'b0010: divisor <= shift_reg[7:0]; // FPGA_CMD_SET_DIVISOR
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge spck)
|
||||
begin
|
||||
if(~ncs)
|
||||
begin
|
||||
shift_reg[15:1] <= shift_reg[14:0];
|
||||
shift_reg[0] <= mosi;
|
||||
end
|
||||
end
|
||||
|
||||
wire [2:0] major_mode;
|
||||
assign major_mode = conf_word[7:5];
|
||||
|
||||
// For the low-frequency configuration:
|
||||
wire lo_is_125khz;
|
||||
assign lo_is_125khz = conf_word[3];
|
||||
|
||||
// For the high-frequency transmit configuration: modulation depth, either
|
||||
// 100% (just quite driving antenna, steady LOW), or shallower (tri-state
|
||||
// some fraction of the buffers)
|
||||
wire hi_read_tx_shallow_modulation;
|
||||
assign hi_read_tx_shallow_modulation = conf_word[0];
|
||||
|
||||
// For the high-frequency receive correlator: frequency against which to
|
||||
// correlate.
|
||||
wire hi_read_rx_xcorr_848;
|
||||
assign hi_read_rx_xcorr_848 = conf_word[0];
|
||||
// and whether to drive the coil (reader) or just short it (snooper)
|
||||
wire hi_read_rx_xcorr_snoop;
|
||||
assign hi_read_rx_xcorr_snoop = conf_word[1];
|
||||
|
||||
// Divide the expected subcarrier frequency for hi_read_rx_xcorr by 4
|
||||
wire hi_read_rx_xcorr_quarter;
|
||||
assign hi_read_rx_xcorr_quarter = conf_word[2];
|
||||
|
||||
// For the high-frequency simulated tag: what kind of modulation to use.
|
||||
wire [2:0] hi_simulate_mod_type;
|
||||
assign hi_simulate_mod_type = conf_word[2:0];
|
||||
|
||||
// For the high-frequency simulated tag: what kind of modulation to use.
|
||||
wire lf_field;
|
||||
assign lf_field = conf_word[0];
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
lo_read lr(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
lr_pwr_lo, lr_pwr_hi, lr_pwr_oe1, lr_pwr_oe2, lr_pwr_oe3, lr_pwr_oe4,
|
||||
adc_d, lr_adc_clk,
|
||||
lr_ssp_frame, lr_ssp_din, ssp_dout, lr_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
lr_dbg,
|
||||
lo_is_125khz, divisor
|
||||
);
|
||||
|
||||
lo_passthru lp(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
lp_pwr_lo, lp_pwr_hi, lp_pwr_oe1, lp_pwr_oe2, lp_pwr_oe3, lp_pwr_oe4,
|
||||
adc_d, lp_adc_clk,
|
||||
lp_ssp_frame, lp_ssp_din, ssp_dout, lp_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
lp_dbg, divisor
|
||||
);
|
||||
|
||||
lo_edge_detect ls(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
ls_pwr_lo, ls_pwr_hi, ls_pwr_oe1, ls_pwr_oe2, ls_pwr_oe3, ls_pwr_oe4,
|
||||
adc_d, ls_adc_clk,
|
||||
ls_ssp_frame, ls_ssp_din, ssp_dout, ls_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
ls_dbg, divisor,
|
||||
lf_field
|
||||
);
|
||||
|
||||
hi_read_tx ht(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
ht_pwr_lo, ht_pwr_hi, ht_pwr_oe1, ht_pwr_oe2, ht_pwr_oe3, ht_pwr_oe4,
|
||||
adc_d, ht_adc_clk,
|
||||
ht_ssp_frame, ht_ssp_din, ssp_dout, ht_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
ht_dbg,
|
||||
hi_read_tx_shallow_modulation
|
||||
);
|
||||
|
||||
hi_read_rx_xcorr hrxc(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
hrxc_pwr_lo, hrxc_pwr_hi, hrxc_pwr_oe1, hrxc_pwr_oe2, hrxc_pwr_oe3, hrxc_pwr_oe4,
|
||||
adc_d, hrxc_adc_clk,
|
||||
hrxc_ssp_frame, hrxc_ssp_din, ssp_dout, hrxc_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
hrxc_dbg,
|
||||
hi_read_rx_xcorr_848, hi_read_rx_xcorr_snoop, hi_read_rx_xcorr_quarter
|
||||
);
|
||||
|
||||
hi_simulate hs(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
hs_pwr_lo, hs_pwr_hi, hs_pwr_oe1, hs_pwr_oe2, hs_pwr_oe3, hs_pwr_oe4,
|
||||
adc_d, hs_adc_clk,
|
||||
hs_ssp_frame, hs_ssp_din, ssp_dout, hs_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
hs_dbg,
|
||||
hi_simulate_mod_type
|
||||
);
|
||||
|
||||
hi_iso14443a hisn(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
hisn_pwr_lo, hisn_pwr_hi, hisn_pwr_oe1, hisn_pwr_oe2, hisn_pwr_oe3, hisn_pwr_oe4,
|
||||
adc_d, hisn_adc_clk,
|
||||
hisn_ssp_frame, hisn_ssp_din, ssp_dout, hisn_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
hisn_dbg,
|
||||
hi_simulate_mod_type
|
||||
);
|
||||
|
||||
// Major modes:
|
||||
// 000 -- LF reader (generic)
|
||||
// 001 -- LF simulated tag (generic)
|
||||
// 010 -- HF reader, transmitting to tag; modulation depth selectable
|
||||
// 011 -- HF reader, receiving from tag, correlating as it goes; frequency selectable
|
||||
// 100 -- HF simulated tag
|
||||
// 101 -- HF ISO14443-A
|
||||
// 110 -- LF passthrough
|
||||
// 111 -- everything off
|
||||
|
||||
mux8 mux_ssp_clk (major_mode, ssp_clk, lr_ssp_clk, ls_ssp_clk, ht_ssp_clk, hrxc_ssp_clk, hs_ssp_clk, hisn_ssp_clk, lp_ssp_clk, 1'b0);
|
||||
mux8 mux_ssp_din (major_mode, ssp_din, lr_ssp_din, ls_ssp_din, ht_ssp_din, hrxc_ssp_din, hs_ssp_din, hisn_ssp_din, lp_ssp_din, 1'b0);
|
||||
mux8 mux_ssp_frame (major_mode, ssp_frame, lr_ssp_frame, ls_ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, lp_ssp_frame, 1'b0);
|
||||
mux8 mux_pwr_oe1 (major_mode, pwr_oe1, lr_pwr_oe1, ls_pwr_oe1, ht_pwr_oe1, hrxc_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, lp_pwr_oe1, 1'b0);
|
||||
mux8 mux_pwr_oe2 (major_mode, pwr_oe2, lr_pwr_oe2, ls_pwr_oe2, ht_pwr_oe2, hrxc_pwr_oe2, hs_pwr_oe2, hisn_pwr_oe2, lp_pwr_oe2, 1'b0);
|
||||
mux8 mux_pwr_oe3 (major_mode, pwr_oe3, lr_pwr_oe3, ls_pwr_oe3, ht_pwr_oe3, hrxc_pwr_oe3, hs_pwr_oe3, hisn_pwr_oe3, lp_pwr_oe3, 1'b0);
|
||||
mux8 mux_pwr_oe4 (major_mode, pwr_oe4, lr_pwr_oe4, ls_pwr_oe4, ht_pwr_oe4, hrxc_pwr_oe4, hs_pwr_oe4, hisn_pwr_oe4, lp_pwr_oe4, 1'b0);
|
||||
mux8 mux_pwr_lo (major_mode, pwr_lo, lr_pwr_lo, ls_pwr_lo, ht_pwr_lo, hrxc_pwr_lo, hs_pwr_lo, hisn_pwr_lo, lp_pwr_lo, 1'b0);
|
||||
mux8 mux_pwr_hi (major_mode, pwr_hi, lr_pwr_hi, ls_pwr_hi, ht_pwr_hi, hrxc_pwr_hi, hs_pwr_hi, hisn_pwr_hi, lp_pwr_hi, 1'b0);
|
||||
mux8 mux_adc_clk (major_mode, adc_clk, lr_adc_clk, ls_adc_clk, ht_adc_clk, hrxc_adc_clk, hs_adc_clk, hisn_adc_clk, lp_adc_clk, 1'b0);
|
||||
mux8 mux_dbg (major_mode, dbg, lr_dbg, ls_dbg, ht_dbg, hrxc_dbg, hs_dbg, hisn_dbg, lp_dbg, 1'b0);
|
||||
|
||||
// In all modes, let the ADC's outputs be enabled.
|
||||
assign adc_noe = 1'b0;
|
||||
|
||||
endmodule
|
BIN
fpga/fpga_hf.bit
Normal file
BIN
fpga/fpga_hf.bit
Normal file
Binary file not shown.
150
fpga/fpga_hf.v
Normal file
150
fpga/fpga_hf.v
Normal file
|
@ -0,0 +1,150 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//
|
||||
// I am not really an FPGA/ASIC designer, so I am sure that a lot of this
|
||||
// could be improved.
|
||||
//
|
||||
// Jonathan Westhues, March 2006
|
||||
// Added ISO14443-A support by Gerhard de Koning Gans, April 2008
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
`include "hi_read_tx.v"
|
||||
`include "hi_read_rx_xcorr.v"
|
||||
`include "hi_simulate.v"
|
||||
`include "hi_iso14443a.v"
|
||||
`include "util.v"
|
||||
|
||||
module fpga_hf(
|
||||
input spck, output miso, input mosi, input ncs,
|
||||
input pck0, input ck_1356meg, input ck_1356megb,
|
||||
output pwr_lo, output pwr_hi,
|
||||
output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4,
|
||||
input [7:0] adc_d, output adc_clk, output adc_noe,
|
||||
output ssp_frame, output ssp_din, input ssp_dout, output ssp_clk,
|
||||
input cross_hi, input cross_lo,
|
||||
output dbg
|
||||
);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
reg [15:0] shift_reg;
|
||||
reg [7:0] conf_word;
|
||||
|
||||
// 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
|
||||
case(shift_reg[15:12])
|
||||
4'b0001: conf_word <= shift_reg[7:0]; // FPGA_CMD_SET_CONFREG
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge spck)
|
||||
begin
|
||||
if(~ncs)
|
||||
begin
|
||||
shift_reg[15:1] <= shift_reg[14:0];
|
||||
shift_reg[0] <= mosi;
|
||||
end
|
||||
end
|
||||
|
||||
wire [2:0] major_mode;
|
||||
assign major_mode = conf_word[7:5];
|
||||
|
||||
// For the high-frequency transmit configuration: modulation depth, either
|
||||
// 100% (just quite driving antenna, steady LOW), or shallower (tri-state
|
||||
// some fraction of the buffers)
|
||||
wire hi_read_tx_shallow_modulation = conf_word[0];
|
||||
|
||||
// For the high-frequency receive correlator: frequency against which to
|
||||
// correlate.
|
||||
wire hi_read_rx_xcorr_848 = conf_word[0];
|
||||
// and whether to drive the coil (reader) or just short it (snooper)
|
||||
wire hi_read_rx_xcorr_snoop = conf_word[1];
|
||||
|
||||
// Divide the expected subcarrier frequency for hi_read_rx_xcorr by 4
|
||||
wire hi_read_rx_xcorr_quarter = conf_word[2];
|
||||
|
||||
// For the high-frequency simulated tag: what kind of modulation to use.
|
||||
wire [2:0] hi_simulate_mod_type = conf_word[2:0];
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
hi_read_tx ht(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
ht_pwr_lo, ht_pwr_hi, ht_pwr_oe1, ht_pwr_oe2, ht_pwr_oe3, ht_pwr_oe4,
|
||||
adc_d, ht_adc_clk,
|
||||
ht_ssp_frame, ht_ssp_din, ssp_dout, ht_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
ht_dbg,
|
||||
hi_read_tx_shallow_modulation
|
||||
);
|
||||
|
||||
hi_read_rx_xcorr hrxc(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
hrxc_pwr_lo, hrxc_pwr_hi, hrxc_pwr_oe1, hrxc_pwr_oe2, hrxc_pwr_oe3, hrxc_pwr_oe4,
|
||||
adc_d, hrxc_adc_clk,
|
||||
hrxc_ssp_frame, hrxc_ssp_din, ssp_dout, hrxc_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
hrxc_dbg,
|
||||
hi_read_rx_xcorr_848, hi_read_rx_xcorr_snoop, hi_read_rx_xcorr_quarter
|
||||
);
|
||||
|
||||
hi_simulate hs(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
hs_pwr_lo, hs_pwr_hi, hs_pwr_oe1, hs_pwr_oe2, hs_pwr_oe3, hs_pwr_oe4,
|
||||
adc_d, hs_adc_clk,
|
||||
hs_ssp_frame, hs_ssp_din, ssp_dout, hs_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
hs_dbg,
|
||||
hi_simulate_mod_type
|
||||
);
|
||||
|
||||
hi_iso14443a hisn(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
hisn_pwr_lo, hisn_pwr_hi, hisn_pwr_oe1, hisn_pwr_oe2, hisn_pwr_oe3, hisn_pwr_oe4,
|
||||
adc_d, hisn_adc_clk,
|
||||
hisn_ssp_frame, hisn_ssp_din, ssp_dout, hisn_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
hisn_dbg,
|
||||
hi_simulate_mod_type
|
||||
);
|
||||
|
||||
// Major modes:
|
||||
|
||||
// 000 -- HF reader, transmitting to tag; modulation depth selectable
|
||||
// 001 -- HF reader, receiving from tag, correlating as it goes; frequency selectable
|
||||
// 010 -- HF simulated tag
|
||||
// 011 -- HF ISO14443-A
|
||||
// 111 -- everything off
|
||||
|
||||
mux8 mux_ssp_clk (major_mode, ssp_clk, ht_ssp_clk, hrxc_ssp_clk, hs_ssp_clk, hisn_ssp_clk, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_ssp_din (major_mode, ssp_din, ht_ssp_din, hrxc_ssp_din, hs_ssp_din, hisn_ssp_din, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_ssp_frame (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe1 (major_mode, pwr_oe1, ht_pwr_oe1, hrxc_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe2 (major_mode, pwr_oe2, ht_pwr_oe2, hrxc_pwr_oe2, hs_pwr_oe2, hisn_pwr_oe2, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe3 (major_mode, pwr_oe3, ht_pwr_oe3, hrxc_pwr_oe3, hs_pwr_oe3, hisn_pwr_oe3, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe4 (major_mode, pwr_oe4, ht_pwr_oe4, hrxc_pwr_oe4, hs_pwr_oe4, hisn_pwr_oe4, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_lo (major_mode, pwr_lo, ht_pwr_lo, hrxc_pwr_lo, hs_pwr_lo, hisn_pwr_lo, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_hi (major_mode, pwr_hi, ht_pwr_hi, hrxc_pwr_hi, hs_pwr_hi, hisn_pwr_hi, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_adc_clk (major_mode, adc_clk, ht_adc_clk, hrxc_adc_clk, hs_adc_clk, hisn_adc_clk, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_dbg (major_mode, dbg, ht_dbg, hrxc_dbg, hs_dbg, hisn_dbg, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
|
||||
// In all modes, let the ADC's outputs be enabled.
|
||||
assign adc_noe = 1'b0;
|
||||
|
||||
endmodule
|
BIN
fpga/fpga_lf.bit
Normal file
BIN
fpga/fpga_lf.bit
Normal file
Binary file not shown.
125
fpga/fpga_lf.v
Normal file
125
fpga/fpga_lf.v
Normal file
|
@ -0,0 +1,125 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//
|
||||
// I am not really an FPGA/ASIC designer, so I am sure that a lot of this
|
||||
// could be improved.
|
||||
//
|
||||
// Jonathan Westhues, March 2006
|
||||
// Added ISO14443-A support by Gerhard de Koning Gans, April 2008
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
`include "lo_read.v"
|
||||
`include "lo_passthru.v"
|
||||
`include "lo_edge_detect.v"
|
||||
`include "util.v"
|
||||
`include "clk_divider.v"
|
||||
|
||||
module fpga_lf(
|
||||
input spck, output miso, input mosi, input ncs,
|
||||
input pck0, input ck_1356meg, input ck_1356megb,
|
||||
output pwr_lo, output pwr_hi,
|
||||
output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4,
|
||||
input [7:0] adc_d, output adc_clk, output adc_noe,
|
||||
output ssp_frame, output ssp_din, input ssp_dout, output ssp_clk,
|
||||
input cross_hi, input cross_lo,
|
||||
output dbg
|
||||
);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
reg [15:0] shift_reg;
|
||||
reg [7:0] divisor;
|
||||
reg [7:0] conf_word;
|
||||
|
||||
// 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
|
||||
case(shift_reg[15:12])
|
||||
4'b0001: conf_word <= shift_reg[7:0]; // FPGA_CMD_SET_CONFREG
|
||||
4'b0010: divisor <= shift_reg[7:0]; // FPGA_CMD_SET_DIVISOR
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge spck)
|
||||
begin
|
||||
if(~ncs)
|
||||
begin
|
||||
shift_reg[15:1] <= shift_reg[14:0];
|
||||
shift_reg[0] <= mosi;
|
||||
end
|
||||
end
|
||||
|
||||
wire [2:0] major_mode;
|
||||
assign major_mode = conf_word[7:5];
|
||||
|
||||
// For the low-frequency configuration:
|
||||
wire lf_field = conf_word[0];
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
wire [7:0] pck_cnt;
|
||||
wire pck_divclk;
|
||||
clk_divider div_clk(pck0, divisor, pck_cnt, pck_divclk);
|
||||
|
||||
lo_read lr(
|
||||
pck0, pck_cnt, pck_divclk,
|
||||
lr_pwr_lo, lr_pwr_hi, lr_pwr_oe1, lr_pwr_oe2, lr_pwr_oe3, lr_pwr_oe4,
|
||||
adc_d, lr_adc_clk,
|
||||
lr_ssp_frame, lr_ssp_din, lr_ssp_clk,
|
||||
lr_dbg
|
||||
);
|
||||
|
||||
lo_passthru lp(
|
||||
pck_divclk,
|
||||
lp_pwr_lo, lp_pwr_hi, lp_pwr_oe1, lp_pwr_oe2, lp_pwr_oe3, lp_pwr_oe4,
|
||||
lp_adc_clk,
|
||||
lp_ssp_din, ssp_dout,
|
||||
cross_lo,
|
||||
lp_dbg
|
||||
);
|
||||
|
||||
lo_edge_detect le(
|
||||
pck0, pck_cnt, pck_divclk,
|
||||
le_pwr_lo, le_pwr_hi, le_pwr_oe1, le_pwr_oe2, le_pwr_oe3, le_pwr_oe4,
|
||||
adc_d, le_adc_clk,
|
||||
le_ssp_frame, ssp_dout, le_ssp_clk,
|
||||
cross_lo,
|
||||
le_dbg,
|
||||
lf_field
|
||||
);
|
||||
|
||||
// Major modes:
|
||||
// 000 -- LF reader (generic)
|
||||
// 001 -- LF edge detect (generic)
|
||||
// 010 -- LF passthrough
|
||||
|
||||
mux8 mux_ssp_clk (major_mode, ssp_clk, lr_ssp_clk, le_ssp_clk, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_ssp_din (major_mode, ssp_din, lr_ssp_din, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_ssp_frame (major_mode, ssp_frame, lr_ssp_frame, le_ssp_frame, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe1 (major_mode, pwr_oe1, lr_pwr_oe1, le_pwr_oe1, lp_pwr_oe1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe2 (major_mode, pwr_oe2, lr_pwr_oe2, le_pwr_oe2, lp_pwr_oe2, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe3 (major_mode, pwr_oe3, lr_pwr_oe3, le_pwr_oe3, lp_pwr_oe3, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe4 (major_mode, pwr_oe4, lr_pwr_oe4, le_pwr_oe4, lp_pwr_oe4, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_lo (major_mode, pwr_lo, lr_pwr_lo, le_pwr_lo, lp_pwr_lo, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_hi (major_mode, pwr_hi, lr_pwr_hi, le_pwr_hi, lp_pwr_hi, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_adc_clk (major_mode, adc_clk, lr_adc_clk, le_adc_clk, lp_adc_clk, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_dbg (major_mode, dbg, lr_dbg, le_dbg, lp_dbg, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
|
||||
// In all modes, let the ADC's outputs be enabled.
|
||||
assign adc_noe = 1'b0;
|
||||
|
||||
endmodule
|
52
fpga/go.bat
52
fpga/go.bat
|
@ -2,37 +2,67 @@
|
|||
|
||||
rmdir/s/q xst
|
||||
|
||||
del fpga.ngc
|
||||
xst -ifn xst.scr
|
||||
del fpga_lf.ngc
|
||||
xst -ifn xst_lf.scr
|
||||
if errorlevel 0 goto ok1
|
||||
goto done
|
||||
:ok1
|
||||
|
||||
del fpga.ngd
|
||||
ngdbuild -aul -p xc2s30-6vq100 -nt timestamp -uc fpga.ucf fpga.ngc fpga.ngd
|
||||
del fpga_lf.ngd
|
||||
ngdbuild -aul -p xc2s30-6vq100 -nt timestamp -uc fpga.ucf fpga_lf.ngc fpga_lf.ngd
|
||||
if errorlevel 0 goto ok2
|
||||
goto done
|
||||
:ok2
|
||||
|
||||
del fpga.ncd
|
||||
map -p xc2s30-6vq100 fpga.ngd
|
||||
del fpga_lf.ncd
|
||||
map -p xc2s30-6vq100 fpga_lf.ngd
|
||||
if errorlevel 0 goto ok3
|
||||
goto done
|
||||
:ok3
|
||||
|
||||
del fpga-placed.ncd
|
||||
par fpga.ncd fpga-placed.ncd
|
||||
del fpga_lf-placed.ncd
|
||||
par fpga_lf.ncd fpga_lf-placed.ncd
|
||||
if errorlevel 0 goto ok4
|
||||
goto done
|
||||
:ok4
|
||||
|
||||
del fpga.bit fpga.drc fpga.rbt
|
||||
bitgen -b fpga-placed.ncd fpga.bit
|
||||
del fpga_lf.bit fpga_lf.drc fpga_lf.rbt
|
||||
bitgen -b fpga_lf-placed.ncd fpga_lf.bit
|
||||
if errorlevel 0 goto ok5
|
||||
goto done
|
||||
:ok5
|
||||
|
||||
del fpga_hf.ngc
|
||||
xst -ifn xst_hf.scr
|
||||
if errorlevel 0 goto ok6
|
||||
goto done
|
||||
:ok6
|
||||
|
||||
del fpga_hf.ngd
|
||||
ngdbuild -aul -p xc2s30-6vq100 -nt timestamp -uc fpga.ucf fpga_hf.ngc fpga_hf.ngd
|
||||
if errorlevel 0 goto ok7
|
||||
goto done
|
||||
:ok7
|
||||
|
||||
del fpga_hf.ncd
|
||||
map -p xc2s30-6vq100 fpga_hf.ngd
|
||||
if errorlevel 0 goto ok8
|
||||
goto done
|
||||
:ok8
|
||||
|
||||
del fpga_hf-placed.ncd
|
||||
par fpga_hf.ncd fpga_hf-placed.ncd
|
||||
if errorlevel 0 goto ok9
|
||||
goto done
|
||||
:ok9
|
||||
|
||||
del fpga_hf.bit fpga_hf.drc fpga_hf.rbt
|
||||
bitgen -b fpga_hf-placed.ncd fpga_hf.bit
|
||||
if errorlevel 0 goto ok10
|
||||
goto done
|
||||
:ok10
|
||||
|
||||
echo okay
|
||||
perl ..\tools\rbt2c.pl fpga.rbt > ..\armsrc\fpgaimg.c
|
||||
perl ..\tools\rbt2c.pl fpga_lf.rbt > ..\armsrc\fpgaimg.c
|
||||
|
||||
:done
|
||||
|
|
|
@ -7,34 +7,18 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
module lo_edge_detect(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4,
|
||||
adc_d, adc_clk,
|
||||
ssp_frame, ssp_din, ssp_dout, ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
dbg,
|
||||
divisor,
|
||||
lf_field
|
||||
input pck0, input [7:0] pck_cnt, input pck_divclk,
|
||||
output pwr_lo, output pwr_hi,
|
||||
output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4,
|
||||
input [7:0] adc_d, output adc_clk,
|
||||
output ssp_frame, input ssp_dout, output ssp_clk,
|
||||
input cross_lo,
|
||||
output dbg,
|
||||
input lf_field
|
||||
);
|
||||
input pck0, ck_1356meg, ck_1356megb;
|
||||
output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
|
||||
input [7:0] adc_d;
|
||||
output adc_clk;
|
||||
input ssp_dout;
|
||||
output ssp_frame, ssp_din, ssp_clk;
|
||||
input cross_hi, cross_lo;
|
||||
output dbg;
|
||||
input [7:0] divisor;
|
||||
input lf_field;
|
||||
|
||||
// Divide the clock to be used for the ADC
|
||||
reg [7:0] pck_divider;
|
||||
reg clk_state;
|
||||
|
||||
wire tag_modulation;
|
||||
assign tag_modulation = ssp_dout & !lf_field;
|
||||
wire reader_modulation;
|
||||
assign reader_modulation = !ssp_dout & lf_field & clk_state;
|
||||
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
|
||||
|
@ -46,20 +30,7 @@ assign pwr_lo = reader_modulation;
|
|||
assign pwr_hi = 1'b0;
|
||||
assign dbg = ssp_frame;
|
||||
|
||||
always @(posedge pck0)
|
||||
begin
|
||||
if(pck_divider == divisor[7:0])
|
||||
begin
|
||||
pck_divider <= 8'd0;
|
||||
clk_state = !clk_state;
|
||||
end
|
||||
else
|
||||
begin
|
||||
pck_divider <= pck_divider + 1;
|
||||
end
|
||||
end
|
||||
|
||||
assign adc_clk = ~clk_state;
|
||||
assign adc_clk = ~pck_divclk;
|
||||
|
||||
// Toggle the output with hysteresis
|
||||
// Set to high if the ADC value is above 200
|
||||
|
@ -70,7 +41,7 @@ reg output_state;
|
|||
|
||||
always @(posedge pck0)
|
||||
begin
|
||||
if((pck_divider == 8'd7) && !clk_state) begin
|
||||
if((pck_cnt == 8'd7) && !pck_divclk) begin
|
||||
is_high = (adc_d >= 8'd190);
|
||||
is_low = (adc_d <= 8'd70);
|
||||
end
|
||||
|
|
|
@ -4,42 +4,14 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
module lo_passthru(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4,
|
||||
adc_d, adc_clk,
|
||||
ssp_frame, ssp_din, ssp_dout, ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
dbg, divisor
|
||||
input pck_divclk,
|
||||
output pwr_lo, output pwr_hi,
|
||||
output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4,
|
||||
output adc_clk,
|
||||
output ssp_din, input ssp_dout,
|
||||
input cross_lo,
|
||||
output dbg
|
||||
);
|
||||
input pck0, ck_1356meg, ck_1356megb;
|
||||
output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
|
||||
input [7:0] adc_d;
|
||||
output adc_clk;
|
||||
input ssp_dout;
|
||||
output ssp_frame, ssp_din, ssp_clk;
|
||||
input cross_hi, cross_lo;
|
||||
output dbg;
|
||||
input [7:0] divisor;
|
||||
|
||||
reg [7:0] pck_divider;
|
||||
reg ant_lo;
|
||||
|
||||
// this task runs on the rising egde of pck0 clock (24Mhz) and creates ant_lo
|
||||
// which is high for (divisor+1) pck0 cycles and low for the same duration
|
||||
// ant_lo is therefore a 50% duty cycle clock signal with a frequency of
|
||||
// 12Mhz/(divisor+1) which drives the antenna as well as the ADC clock adc_clk
|
||||
always @(posedge pck0)
|
||||
begin
|
||||
if(pck_divider == divisor[7:0])
|
||||
begin
|
||||
pck_divider <= 8'd0;
|
||||
ant_lo = !ant_lo;
|
||||
end
|
||||
else
|
||||
begin
|
||||
pck_divider <= pck_divider + 1;
|
||||
end
|
||||
end
|
||||
|
||||
// the antenna is modulated when ssp_dout = 1, when 0 the
|
||||
// antenna drivers stop modulating and go into listen mode
|
||||
|
@ -47,7 +19,7 @@ assign pwr_oe3 = 1'b0;
|
|||
assign pwr_oe1 = ssp_dout;
|
||||
assign pwr_oe2 = ssp_dout;
|
||||
assign pwr_oe4 = ssp_dout;
|
||||
assign pwr_lo = ant_lo && ssp_dout;
|
||||
assign pwr_lo = pck_divclk && ssp_dout;
|
||||
assign pwr_hi = 1'b0;
|
||||
assign adc_clk = 1'b0;
|
||||
assign ssp_din = cross_lo;
|
||||
|
|
|
@ -7,65 +7,34 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
module lo_read(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4,
|
||||
adc_d, adc_clk,
|
||||
ssp_frame, ssp_din, ssp_dout, ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
dbg,
|
||||
lo_is_125khz, divisor
|
||||
input pck0, input [7:0] pck_cnt, input pck_divclk,
|
||||
output pwr_lo, output pwr_hi,
|
||||
output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4,
|
||||
input [7:0] adc_d, output adc_clk,
|
||||
output ssp_frame, output ssp_din, output ssp_clk,
|
||||
output dbg
|
||||
);
|
||||
input pck0, ck_1356meg, ck_1356megb;
|
||||
output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
|
||||
input [7:0] adc_d;
|
||||
output adc_clk;
|
||||
input ssp_dout;
|
||||
output ssp_frame, ssp_din, ssp_clk;
|
||||
input cross_hi, cross_lo;
|
||||
output dbg;
|
||||
input lo_is_125khz; // redundant signal, no longer used anywhere
|
||||
input [7:0] divisor;
|
||||
|
||||
reg [7:0] to_arm_shiftreg;
|
||||
reg [7:0] pck_divider;
|
||||
reg ant_lo;
|
||||
|
||||
// this task runs on the rising egde of pck0 clock (24Mhz) and creates ant_lo
|
||||
// which is high for (divisor+1) pck0 cycles and low for the same duration
|
||||
// ant_lo is therefore a 50% duty cycle clock signal with a frequency of
|
||||
// 12Mhz/(divisor+1) which drives the antenna as well as the ADC clock adc_clk
|
||||
always @(posedge pck0)
|
||||
begin
|
||||
if(pck_divider == divisor[7:0])
|
||||
begin
|
||||
pck_divider <= 8'd0;
|
||||
ant_lo = !ant_lo;
|
||||
end
|
||||
else
|
||||
begin
|
||||
pck_divider <= pck_divider + 1;
|
||||
end
|
||||
end
|
||||
|
||||
// this task also runs at pck0 frequency (24Mhz) and is used to serialize
|
||||
// the ADC output which is then clocked into the ARM SSP.
|
||||
|
||||
// because ant_lo always transitions when pck_divider = 0 we use the
|
||||
// pck_divider counter to sync our other signals off it
|
||||
// we read the ADC value when pck_divider=7 and shift it out on counts 8..15
|
||||
// because pck_divclk always transitions when pck_cnt = 0 we use the
|
||||
// pck_div counter to sync our other signals off it
|
||||
// we read the ADC value when pck_cnt=7 and shift it out on counts 8..15
|
||||
always @(posedge pck0)
|
||||
begin
|
||||
if((pck_divider == 8'd7) && !ant_lo)
|
||||
to_arm_shiftreg <= adc_d;
|
||||
else
|
||||
begin
|
||||
to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0];
|
||||
if((pck_cnt == 8'd7) && !pck_divclk)
|
||||
to_arm_shiftreg <= adc_d;
|
||||
else begin
|
||||
to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0];
|
||||
// simulation showed a glitch occuring due to the LSB of the shifter
|
||||
// not being set as we shift bits out
|
||||
// this ensures the ssp_din remains low after a transfer and suppresses
|
||||
// the glitch that would occur when the last data shifted out ended in
|
||||
// a 1 bit and the next data shifted out started with a 0 bit
|
||||
to_arm_shiftreg[0] <= 1'b0;
|
||||
to_arm_shiftreg[0] <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -83,11 +52,11 @@ end
|
|||
// ssp_clk |_| |_| |_| |_| |_| |_| |_| |_| |_| |_
|
||||
|
||||
// serialized SSP data is gated by ant_lo to suppress unwanted signal
|
||||
assign ssp_din = to_arm_shiftreg[7] && !ant_lo;
|
||||
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
|
||||
assign ssp_frame = (pck_divider[7:3] == 5'd1) && !ant_lo;
|
||||
assign ssp_frame = (pck_cnt[7:3] == 5'd1) && !pck_divclk;
|
||||
// unused signals tied low
|
||||
assign pwr_hi = 1'b0;
|
||||
assign pwr_oe1 = 1'b0;
|
||||
|
@ -95,9 +64,9 @@ assign pwr_oe2 = 1'b0;
|
|||
assign pwr_oe3 = 1'b0;
|
||||
assign pwr_oe4 = 1'b0;
|
||||
// this is the antenna driver signal
|
||||
assign pwr_lo = ant_lo;
|
||||
assign pwr_lo = pck_divclk;
|
||||
// ADC clock out of phase with antenna driver
|
||||
assign adc_clk = ~ant_lo;
|
||||
assign adc_clk = ~pck_divclk;
|
||||
// ADC clock also routed to debug pin
|
||||
assign dbg = adc_clk;
|
||||
endmodule
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
run -ifn fpga.v -ifmt Verilog -ofn fpga.ngc -ofmt NGC -p xc2s30-5-vq100 -opt_mode Speed -opt_level 1 -ent fpga
|
1
fpga/xst_hf.scr
Normal file
1
fpga/xst_hf.scr
Normal file
|
@ -0,0 +1 @@
|
|||
run -ifn fpga_hf.v -ifmt Verilog -ofn fpga_hf.ngc -ofmt NGC -p xc2s30-5-vq100 -top fpga_hf -opt_mode area -opt_level 2 -resource_sharing yes -fsm_style bram -fsm_encoding compact
|
1
fpga/xst_lf.scr
Normal file
1
fpga/xst_lf.scr
Normal file
|
@ -0,0 +1 @@
|
|||
run -ifn fpga_lf.v -ifmt Verilog -ofn fpga_lf.ngc -ofmt NGC -p xc2s30-5-vq100 -top fpga_lf -opt_mode area -opt_level 2 -resource_sharing yes -fsm_style bram -fsm_encoding compact
|
Loading…
Add table
Add a link
Reference in a new issue