From: bushing Date: Mon, 22 Feb 2010 19:29:05 +0000 (+0000) Subject: setting svn:eol-style=native on files, part 3 X-Git-Tag: v1.0.0~330 X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/ba06a4b694da23045ed75d18ccf77a9befac65c0 setting svn:eol-style=native on files, part 3 (should be done now, sorry) --- diff --git a/fpga/fpga.ucf b/fpga/fpga.ucf index bf0d40bc..35f38e73 100644 --- a/fpga/fpga.ucf +++ b/fpga/fpga.ucf @@ -1,41 +1,41 @@ -# See the schematic for the pin assignment. - -NET "adc_d<0>" LOC = "P62" ; -NET "adc_d<1>" LOC = "P60" ; -NET "adc_d<2>" LOC = "P58" ; -NET "adc_d<3>" LOC = "P57" ; -NET "adc_d<4>" LOC = "P56" ; -NET "adc_d<5>" LOC = "P55" ; -NET "adc_d<6>" LOC = "P54" ; -NET "adc_d<7>" LOC = "P53" ; -#NET "cross_hi" LOC = "P88" ; -#NET "miso" LOC = "P40" ; -#PACE: Start of Constraints generated by PACE - -#PACE: Start of PACE I/O Pin Assignments -NET "adc_clk" LOC = "P46" ; -NET "adc_noe" LOC = "P47" ; -NET "ck_1356meg" LOC = "P91" ; -NET "ck_1356megb" LOC = "P93" ; -NET "cross_lo" LOC = "P87" ; -NET "dbg" LOC = "P22" ; -NET "mosi" LOC = "P43" ; -NET "ncs" LOC = "P44" ; -NET "pck0" LOC = "P36" ; -NET "pwr_hi" LOC = "P80" ; -NET "pwr_lo" LOC = "P81" ; -NET "pwr_oe1" LOC = "P82" ; -NET "pwr_oe2" LOC = "P83" ; -NET "pwr_oe3" LOC = "P84" ; -NET "pwr_oe4" LOC = "P86" ; -NET "spck" LOC = "P39" ; -NET "ssp_clk" LOC = "P71" ; -NET "ssp_din" LOC = "P32" ; -NET "ssp_dout" LOC = "P34" ; -NET "ssp_frame" LOC = "P31" ; - -#PACE: Start of PACE Area Constraints - -#PACE: Start of PACE Prohibit Constraints - -#PACE: End of Constraints generated by PACE +# See the schematic for the pin assignment. + +NET "adc_d<0>" LOC = "P62" ; +NET "adc_d<1>" LOC = "P60" ; +NET "adc_d<2>" LOC = "P58" ; +NET "adc_d<3>" LOC = "P57" ; +NET "adc_d<4>" LOC = "P56" ; +NET "adc_d<5>" LOC = "P55" ; +NET "adc_d<6>" LOC = "P54" ; +NET "adc_d<7>" LOC = "P53" ; +#NET "cross_hi" LOC = "P88" ; +#NET "miso" LOC = "P40" ; +#PACE: Start of Constraints generated by PACE + +#PACE: Start of PACE I/O Pin Assignments +NET "adc_clk" LOC = "P46" ; +NET "adc_noe" LOC = "P47" ; +NET "ck_1356meg" LOC = "P91" ; +NET "ck_1356megb" LOC = "P93" ; +NET "cross_lo" LOC = "P87" ; +NET "dbg" LOC = "P22" ; +NET "mosi" LOC = "P43" ; +NET "ncs" LOC = "P44" ; +NET "pck0" LOC = "P36" ; +NET "pwr_hi" LOC = "P80" ; +NET "pwr_lo" LOC = "P81" ; +NET "pwr_oe1" LOC = "P82" ; +NET "pwr_oe2" LOC = "P83" ; +NET "pwr_oe3" LOC = "P84" ; +NET "pwr_oe4" LOC = "P86" ; +NET "spck" LOC = "P39" ; +NET "ssp_clk" LOC = "P71" ; +NET "ssp_din" LOC = "P32" ; +NET "ssp_dout" LOC = "P34" ; +NET "ssp_frame" LOC = "P31" ; + +#PACE: Start of PACE Area Constraints + +#PACE: Start of PACE Prohibit Constraints + +#PACE: End of Constraints generated by PACE diff --git a/fpga/fpga.v b/fpga/fpga.v index c39109f9..4002945b 100644 --- a/fpga/fpga.v +++ b/fpga/fpga.v @@ -1,213 +1,213 @@ -//----------------------------------------------------------------------------- -// 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_simulate.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( - spcki, miso, mosi, ncs, - pck0i, 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 spcki, mosi, ncs; - output miso; - input pck0i, 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]; - 4'b0010: divisor <= shift_reg[7:0]; - 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]; - -//----------------------------------------------------------------------------- -// 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_simulate 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 -); - -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 +//----------------------------------------------------------------------------- +// 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_simulate.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( + spcki, miso, mosi, ncs, + pck0i, 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 spcki, mosi, ncs; + output miso; + input pck0i, 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]; + 4'b0010: divisor <= shift_reg[7:0]; + 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]; + +//----------------------------------------------------------------------------- +// 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_simulate 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 +); + +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 diff --git a/fpga/hi_read_rx_xcorr.v b/fpga/hi_read_rx_xcorr.v index 9d012f42..dece2db3 100644 --- a/fpga/hi_read_rx_xcorr.v +++ b/fpga/hi_read_rx_xcorr.v @@ -1,185 +1,185 @@ -//----------------------------------------------------------------------------- -// -// Jonathan Westhues, April 2006 -//----------------------------------------------------------------------------- - -module hi_read_rx_xcorr( - 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, - xcorr_is_848, snoop, xcorr_quarter_freq -); - 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 xcorr_is_848, snoop, xcorr_quarter_freq; - -// Carrier is steady on through this, unless we're snooping. -assign pwr_hi = ck_1356megb & (~snoop); -assign pwr_oe1 = 1'b0; -assign pwr_oe2 = 1'b0; -assign pwr_oe3 = 1'b0; -assign pwr_oe4 = 1'b0; - -reg ssp_clk; -reg ssp_frame; - -reg fc_div_2; -always @(posedge ck_1356meg) - fc_div_2 = ~fc_div_2; - -reg fc_div_4; -always @(posedge fc_div_2) - fc_div_4 = ~fc_div_4; - -reg fc_div_8; -always @(posedge fc_div_4) - fc_div_8 = ~fc_div_8; - -reg adc_clk; - -always @(xcorr_is_848 or xcorr_quarter_freq or ck_1356meg) - if(~xcorr_quarter_freq) - begin - if(xcorr_is_848) - // The subcarrier frequency is fc/16; we will sample at fc, so that - // means the subcarrier is 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 ... - adc_clk <= ck_1356meg; - else - // The subcarrier frequency is fc/32; we will sample at fc/2, and - // the subcarrier will look identical. - adc_clk <= fc_div_2; - end - else - begin - if(xcorr_is_848) - // The subcarrier frequency is fc/64 - adc_clk <= fc_div_4; - else - // The subcarrier frequency is fc/128 - adc_clk <= fc_div_8; - end - -// 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; -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 <= 7'b0; - 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 4 subcarrier cycles, or 4*16 samples, -// so we need a 6-bit counter. -reg [5:0] corr_i_cnt; -reg [5:0] corr_q_cnt; -// And a couple of registers in which to accumulate the correlations. -reg signed [15:0] corr_i_accum; -reg signed [15:0] corr_q_accum; -reg signed [7:0] corr_i_out; -reg signed [7:0] corr_q_out; - -// 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) result to - // send out later over the SSP. - if(corr_i_cnt == 7'd63) - begin - if(snoop) - begin - corr_i_out <= {corr_i_accum[12:6], after_hysteresis_prev}; - corr_q_out <= {corr_q_accum[12:6], after_hysteresis}; - end - else - begin - // Only correlations need to be delivered. - corr_i_out <= corr_i_accum[13:6]; - corr_q_out <= corr_q_accum[13:6]; - end - - corr_i_accum <= adc_d; - corr_q_accum <= adc_d; - corr_q_cnt <= 4; - corr_i_cnt <= 0; - end - else - begin - if(corr_i_cnt[3]) - corr_i_accum <= corr_i_accum - adc_d; - else - corr_i_accum <= corr_i_accum + adc_d; - - if(corr_q_cnt[3]) - corr_q_accum <= corr_q_accum - adc_d; - else - corr_q_accum <= corr_q_accum + adc_d; - - corr_i_cnt <= corr_i_cnt + 1; - corr_q_cnt <= corr_q_cnt + 1; - end - - // The logic in hi_simulate.v reports 4 samples per bit. We report two - // (I, Q) pairs per bit, so we should do 2 samples per pair. - if(corr_i_cnt == 6'd31) - 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. - - if(corr_i_cnt[1:0] == 2'b10) - ssp_clk <= 1'b0; - - if(corr_i_cnt[1:0] == 2'b00) - begin - ssp_clk <= 1'b1; - // Don't shift if we just loaded new data, obviously. - if(corr_i_cnt != 7'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 - - if(corr_i_cnt[5:2] == 4'b000 || corr_i_cnt[5:2] == 4'b1000) - ssp_frame = 1'b1; - else - ssp_frame = 1'b0; - -end - -assign ssp_din = corr_i_out[7]; - -assign dbg = corr_i_cnt[3]; - -// Unused. -assign pwr_lo = 1'b0; - -endmodule +//----------------------------------------------------------------------------- +// +// Jonathan Westhues, April 2006 +//----------------------------------------------------------------------------- + +module hi_read_rx_xcorr( + 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, + xcorr_is_848, snoop, xcorr_quarter_freq +); + 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 xcorr_is_848, snoop, xcorr_quarter_freq; + +// Carrier is steady on through this, unless we're snooping. +assign pwr_hi = ck_1356megb & (~snoop); +assign pwr_oe1 = 1'b0; +assign pwr_oe2 = 1'b0; +assign pwr_oe3 = 1'b0; +assign pwr_oe4 = 1'b0; + +reg ssp_clk; +reg ssp_frame; + +reg fc_div_2; +always @(posedge ck_1356meg) + fc_div_2 = ~fc_div_2; + +reg fc_div_4; +always @(posedge fc_div_2) + fc_div_4 = ~fc_div_4; + +reg fc_div_8; +always @(posedge fc_div_4) + fc_div_8 = ~fc_div_8; + +reg adc_clk; + +always @(xcorr_is_848 or xcorr_quarter_freq or ck_1356meg) + if(~xcorr_quarter_freq) + begin + if(xcorr_is_848) + // The subcarrier frequency is fc/16; we will sample at fc, so that + // means the subcarrier is 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 ... + adc_clk <= ck_1356meg; + else + // The subcarrier frequency is fc/32; we will sample at fc/2, and + // the subcarrier will look identical. + adc_clk <= fc_div_2; + end + else + begin + if(xcorr_is_848) + // The subcarrier frequency is fc/64 + adc_clk <= fc_div_4; + else + // The subcarrier frequency is fc/128 + adc_clk <= fc_div_8; + end + +// 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; +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 <= 7'b0; + 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 4 subcarrier cycles, or 4*16 samples, +// so we need a 6-bit counter. +reg [5:0] corr_i_cnt; +reg [5:0] corr_q_cnt; +// And a couple of registers in which to accumulate the correlations. +reg signed [15:0] corr_i_accum; +reg signed [15:0] corr_q_accum; +reg signed [7:0] corr_i_out; +reg signed [7:0] corr_q_out; + +// 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) result to + // send out later over the SSP. + if(corr_i_cnt == 7'd63) + begin + if(snoop) + begin + corr_i_out <= {corr_i_accum[12:6], after_hysteresis_prev}; + corr_q_out <= {corr_q_accum[12:6], after_hysteresis}; + end + else + begin + // Only correlations need to be delivered. + corr_i_out <= corr_i_accum[13:6]; + corr_q_out <= corr_q_accum[13:6]; + end + + corr_i_accum <= adc_d; + corr_q_accum <= adc_d; + corr_q_cnt <= 4; + corr_i_cnt <= 0; + end + else + begin + if(corr_i_cnt[3]) + corr_i_accum <= corr_i_accum - adc_d; + else + corr_i_accum <= corr_i_accum + adc_d; + + if(corr_q_cnt[3]) + corr_q_accum <= corr_q_accum - adc_d; + else + corr_q_accum <= corr_q_accum + adc_d; + + corr_i_cnt <= corr_i_cnt + 1; + corr_q_cnt <= corr_q_cnt + 1; + end + + // The logic in hi_simulate.v reports 4 samples per bit. We report two + // (I, Q) pairs per bit, so we should do 2 samples per pair. + if(corr_i_cnt == 6'd31) + 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. + + if(corr_i_cnt[1:0] == 2'b10) + ssp_clk <= 1'b0; + + if(corr_i_cnt[1:0] == 2'b00) + begin + ssp_clk <= 1'b1; + // Don't shift if we just loaded new data, obviously. + if(corr_i_cnt != 7'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 + + if(corr_i_cnt[5:2] == 4'b000 || corr_i_cnt[5:2] == 4'b1000) + ssp_frame = 1'b1; + else + ssp_frame = 1'b0; + +end + +assign ssp_din = corr_i_out[7]; + +assign dbg = corr_i_cnt[3]; + +// Unused. +assign pwr_lo = 1'b0; + +endmodule diff --git a/fpga/hi_read_tx.v b/fpga/hi_read_tx.v index 5ddc974d..f12e64eb 100644 --- a/fpga/hi_read_tx.v +++ b/fpga/hi_read_tx.v @@ -1,89 +1,89 @@ -//----------------------------------------------------------------------------- -// The way that we connect things when transmitting a command to an ISO -// 15693 tag, using 100% modulation only for now. -// -// Jonathan Westhues, April 2006 -//----------------------------------------------------------------------------- - -module hi_read_tx( - 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, - shallow_modulation -); - 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 shallow_modulation; - -// The high-frequency stuff. For now, for testing, just bring out the carrier, -// and allow the ARM to modulate it over the SSP. -reg pwr_hi; -reg pwr_oe1; -reg pwr_oe2; -reg pwr_oe3; -reg pwr_oe4; -always @(ck_1356megb or ssp_dout or shallow_modulation) -begin - if(shallow_modulation) - begin - pwr_hi <= ck_1356megb; - pwr_oe1 <= ~ssp_dout; - pwr_oe2 <= ~ssp_dout; - pwr_oe3 <= ~ssp_dout; - pwr_oe4 <= 1'b0; - end - else - begin - pwr_hi <= ck_1356megb & ssp_dout; - pwr_oe1 <= 1'b0; - pwr_oe2 <= 1'b0; - pwr_oe3 <= 1'b0; - pwr_oe4 <= 1'b0; - end -end - -// Then just divide the 13.56 MHz clock down to produce appropriate clocks -// for the synchronous serial port. - -reg [6:0] hi_div_by_128; - -always @(posedge ck_1356meg) - hi_div_by_128 <= hi_div_by_128 + 1; - -assign ssp_clk = hi_div_by_128[6]; - -reg [2:0] hi_byte_div; - -always @(negedge ssp_clk) - hi_byte_div <= hi_byte_div + 1; - -assign ssp_frame = (hi_byte_div == 3'b000); - -// Implement a hysteresis to give out the received signal on -// ssp_din. Sample at fc. -assign adc_clk = ck_1356meg; - -// ADC data appears on the rising edge, so sample it on the falling edge -reg after_hysteresis; -always @(negedge adc_clk) -begin - if(& adc_d[7:0]) after_hysteresis <= 1'b1; - else if(~(| adc_d[7:0])) after_hysteresis <= 1'b0; -end - - -assign ssp_din = after_hysteresis; - -assign pwr_lo = 1'b0; -assign dbg = ssp_din; - -endmodule +//----------------------------------------------------------------------------- +// The way that we connect things when transmitting a command to an ISO +// 15693 tag, using 100% modulation only for now. +// +// Jonathan Westhues, April 2006 +//----------------------------------------------------------------------------- + +module hi_read_tx( + 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, + shallow_modulation +); + 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 shallow_modulation; + +// The high-frequency stuff. For now, for testing, just bring out the carrier, +// and allow the ARM to modulate it over the SSP. +reg pwr_hi; +reg pwr_oe1; +reg pwr_oe2; +reg pwr_oe3; +reg pwr_oe4; +always @(ck_1356megb or ssp_dout or shallow_modulation) +begin + if(shallow_modulation) + begin + pwr_hi <= ck_1356megb; + pwr_oe1 <= ~ssp_dout; + pwr_oe2 <= ~ssp_dout; + pwr_oe3 <= ~ssp_dout; + pwr_oe4 <= 1'b0; + end + else + begin + pwr_hi <= ck_1356megb & ssp_dout; + pwr_oe1 <= 1'b0; + pwr_oe2 <= 1'b0; + pwr_oe3 <= 1'b0; + pwr_oe4 <= 1'b0; + end +end + +// Then just divide the 13.56 MHz clock down to produce appropriate clocks +// for the synchronous serial port. + +reg [6:0] hi_div_by_128; + +always @(posedge ck_1356meg) + hi_div_by_128 <= hi_div_by_128 + 1; + +assign ssp_clk = hi_div_by_128[6]; + +reg [2:0] hi_byte_div; + +always @(negedge ssp_clk) + hi_byte_div <= hi_byte_div + 1; + +assign ssp_frame = (hi_byte_div == 3'b000); + +// Implement a hysteresis to give out the received signal on +// ssp_din. Sample at fc. +assign adc_clk = ck_1356meg; + +// ADC data appears on the rising edge, so sample it on the falling edge +reg after_hysteresis; +always @(negedge adc_clk) +begin + if(& adc_d[7:0]) after_hysteresis <= 1'b1; + else if(~(| adc_d[7:0])) after_hysteresis <= 1'b0; +end + + +assign ssp_din = after_hysteresis; + +assign pwr_lo = 1'b0; +assign dbg = ssp_din; + +endmodule diff --git a/fpga/hi_simulate.v b/fpga/hi_simulate.v index 05662e53..efaf452f 100644 --- a/fpga/hi_simulate.v +++ b/fpga/hi_simulate.v @@ -1,109 +1,109 @@ -//----------------------------------------------------------------------------- -// Pretend to be an ISO 14443 tag. We will do this by alternately short- -// circuiting and open-circuiting the antenna coil, with the tri-state -// pins. -// -// We communicate over the SSP, as a bitstream (i.e., might as well be -// unframed, though we still generate the word sync signal). The output -// (ARM -> FPGA) tells us whether to modulate or not. The input (FPGA -// -> ARM) is us using the A/D as a fancy comparator; this is with -// (software-added) hysteresis, to undo the high-pass filter. -// -// At this point only Type A is implemented. This means that we are using a -// bit rate of 106 kbit/s, or fc/128. Oversample by 4, which ought to make -// things practical for the ARM (fc/32, 423.8 kbits/s, ~50 kbytes/s) -// -// Jonathan Westhues, October 2006 -//----------------------------------------------------------------------------- - -module hi_simulate( - 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, - mod_type -); - 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 [2:0] mod_type; - -// Power amp goes between LOW and tri-state, so pwr_hi (and pwr_lo) can -// always be low. -assign pwr_hi = 1'b0; -assign pwr_lo = 1'b0; - -// The comparator with hysteresis on the output from the peak detector. -reg after_hysteresis; -assign adc_clk = ck_1356meg; - -always @(negedge adc_clk) -begin - if(& adc_d[7:5]) after_hysteresis = 1'b1; - else if(~(| adc_d[7:5])) after_hysteresis = 1'b0; -end - -// Divide 13.56 MHz by 32 to produce the SSP_CLK -// The register is bigger to allow higher division factors of up to /128 -reg [6:0] ssp_clk_divider; -always @(posedge adc_clk) - ssp_clk_divider <= (ssp_clk_divider + 1); -assign ssp_clk = ssp_clk_divider[4]; - -// Divide SSP_CLK by 8 to produce the byte framing signal; the phase of -// this is arbitrary, because it's just a bitstream. -// One nasty issue, though: I can't make it work with both rx and tx at -// once. The phase wrt ssp_clk must be changed. TODO to find out why -// that is and make a better fix. -reg [2:0] ssp_frame_divider_to_arm; -always @(posedge ssp_clk) - ssp_frame_divider_to_arm <= (ssp_frame_divider_to_arm + 1); -reg [2:0] ssp_frame_divider_from_arm; -always @(negedge ssp_clk) - ssp_frame_divider_from_arm <= (ssp_frame_divider_from_arm + 1); - -reg ssp_frame; -always @(ssp_frame_divider_to_arm or ssp_frame_divider_from_arm or mod_type) - if(mod_type == 3'b000) // not modulating, so listening, to ARM - ssp_frame = (ssp_frame_divider_to_arm == 3'b000); - else - ssp_frame = (ssp_frame_divider_from_arm == 3'b000); - -// Synchronize up the after-hysteresis signal, to produce DIN. -reg ssp_din; -always @(posedge ssp_clk) - ssp_din = after_hysteresis; - -// Modulating carrier frequency is fc/16, reuse ssp_clk divider for that -reg modulating_carrier; -always @(mod_type or ssp_clk or ssp_dout) - if(mod_type == 3'b000) - modulating_carrier <= 1'b0; // no modulation - else if(mod_type == 3'b001) - modulating_carrier <= ssp_dout ^ ssp_clk_divider[3]; // XOR means BPSK - else if(mod_type == 3'b010) - modulating_carrier <= ssp_dout & ssp_clk_divider[5]; // switch 212kHz subcarrier on/off - else - modulating_carrier <= 1'b0; // yet unused - -// This one is all LF, so doesn't matter -assign pwr_oe2 = modulating_carrier; - -// Toggle only one of these, since we are already producing much deeper -// modulation than a real tag would. -assign pwr_oe1 = modulating_carrier; -assign pwr_oe4 = modulating_carrier; - -// This one is always on, so that we can watch the carrier. -assign pwr_oe3 = 1'b0; - -assign dbg = after_hysteresis; - -endmodule +//----------------------------------------------------------------------------- +// Pretend to be an ISO 14443 tag. We will do this by alternately short- +// circuiting and open-circuiting the antenna coil, with the tri-state +// pins. +// +// We communicate over the SSP, as a bitstream (i.e., might as well be +// unframed, though we still generate the word sync signal). The output +// (ARM -> FPGA) tells us whether to modulate or not. The input (FPGA +// -> ARM) is us using the A/D as a fancy comparator; this is with +// (software-added) hysteresis, to undo the high-pass filter. +// +// At this point only Type A is implemented. This means that we are using a +// bit rate of 106 kbit/s, or fc/128. Oversample by 4, which ought to make +// things practical for the ARM (fc/32, 423.8 kbits/s, ~50 kbytes/s) +// +// Jonathan Westhues, October 2006 +//----------------------------------------------------------------------------- + +module hi_simulate( + 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, + mod_type +); + 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 [2:0] mod_type; + +// Power amp goes between LOW and tri-state, so pwr_hi (and pwr_lo) can +// always be low. +assign pwr_hi = 1'b0; +assign pwr_lo = 1'b0; + +// The comparator with hysteresis on the output from the peak detector. +reg after_hysteresis; +assign adc_clk = ck_1356meg; + +always @(negedge adc_clk) +begin + if(& adc_d[7:5]) after_hysteresis = 1'b1; + else if(~(| adc_d[7:5])) after_hysteresis = 1'b0; +end + +// Divide 13.56 MHz by 32 to produce the SSP_CLK +// The register is bigger to allow higher division factors of up to /128 +reg [6:0] ssp_clk_divider; +always @(posedge adc_clk) + ssp_clk_divider <= (ssp_clk_divider + 1); +assign ssp_clk = ssp_clk_divider[4]; + +// Divide SSP_CLK by 8 to produce the byte framing signal; the phase of +// this is arbitrary, because it's just a bitstream. +// One nasty issue, though: I can't make it work with both rx and tx at +// once. The phase wrt ssp_clk must be changed. TODO to find out why +// that is and make a better fix. +reg [2:0] ssp_frame_divider_to_arm; +always @(posedge ssp_clk) + ssp_frame_divider_to_arm <= (ssp_frame_divider_to_arm + 1); +reg [2:0] ssp_frame_divider_from_arm; +always @(negedge ssp_clk) + ssp_frame_divider_from_arm <= (ssp_frame_divider_from_arm + 1); + +reg ssp_frame; +always @(ssp_frame_divider_to_arm or ssp_frame_divider_from_arm or mod_type) + if(mod_type == 3'b000) // not modulating, so listening, to ARM + ssp_frame = (ssp_frame_divider_to_arm == 3'b000); + else + ssp_frame = (ssp_frame_divider_from_arm == 3'b000); + +// Synchronize up the after-hysteresis signal, to produce DIN. +reg ssp_din; +always @(posedge ssp_clk) + ssp_din = after_hysteresis; + +// Modulating carrier frequency is fc/16, reuse ssp_clk divider for that +reg modulating_carrier; +always @(mod_type or ssp_clk or ssp_dout) + if(mod_type == 3'b000) + modulating_carrier <= 1'b0; // no modulation + else if(mod_type == 3'b001) + modulating_carrier <= ssp_dout ^ ssp_clk_divider[3]; // XOR means BPSK + else if(mod_type == 3'b010) + modulating_carrier <= ssp_dout & ssp_clk_divider[5]; // switch 212kHz subcarrier on/off + else + modulating_carrier <= 1'b0; // yet unused + +// This one is all LF, so doesn't matter +assign pwr_oe2 = modulating_carrier; + +// Toggle only one of these, since we are already producing much deeper +// modulation than a real tag would. +assign pwr_oe1 = modulating_carrier; +assign pwr_oe4 = modulating_carrier; + +// This one is always on, so that we can watch the carrier. +assign pwr_oe3 = 1'b0; + +assign dbg = after_hysteresis; + +endmodule diff --git a/fpga/lo_passthru.v b/fpga/lo_passthru.v index e1cb2ef2..5c59d11c 100644 --- a/fpga/lo_passthru.v +++ b/fpga/lo_passthru.v @@ -1,56 +1,56 @@ -//----------------------------------------------------------------------------- -// For reading TI tags, we need to place the FPGA in pass through mode -// and pass everything through to the ARM -//----------------------------------------------------------------------------- - -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 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 -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_hi = 1'b0; -assign adc_clk = 1'b0; -assign ssp_din = cross_lo; -assign dbg = cross_lo; - -endmodule +//----------------------------------------------------------------------------- +// For reading TI tags, we need to place the FPGA in pass through mode +// and pass everything through to the ARM +//----------------------------------------------------------------------------- + +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 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 +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_hi = 1'b0; +assign adc_clk = 1'b0; +assign ssp_din = cross_lo; +assign dbg = cross_lo; + +endmodule diff --git a/fpga/lo_read.v b/fpga/lo_read.v index 8dce4dda..e6f245ca 100644 --- a/fpga/lo_read.v +++ b/fpga/lo_read.v @@ -1,103 +1,103 @@ -//----------------------------------------------------------------------------- -// The way that we connect things in low-frequency read mode. In this case -// we are generating the unmodulated low frequency carrier. -// The A/D samples at that same rate and the result is serialized. -// -// Jonathan Westhues, April 2006 -//----------------------------------------------------------------------------- - -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, 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 -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]; - // 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; - end -end - -// ADC samples on falling edge of adc_clk, data available on the rising edge - -// example of ssp transfer of binary value 1100101 -// start of transfer is indicated by the rise of the ssp_frame signal -// ssp_din changes on the rising edge of the ssp_clk clock and is clocked into -// the ARM by the falling edge of ssp_clk -// _______________________________ -// ssp_frame__| |__ -// _______ ___ ___ -// ssp_din __| |_______| |___| |______ -// _ _ _ _ _ _ _ _ _ _ -// ssp_clk |_| |_| |_| |_| |_| |_| |_| |_| |_| |_ - -// serialized SSP data is gated by ant_lo to suppress unwanted signal -assign ssp_din = to_arm_shiftreg[7] && !ant_lo; -// 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; -// unused signals tied low -assign pwr_hi = 1'b0; -assign pwr_oe1 = 1'b0; -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; -// ADC clock out of phase with antenna driver -assign adc_clk = ~ant_lo; -// ADC clock also routed to debug pin -assign dbg = adc_clk; -endmodule +//----------------------------------------------------------------------------- +// The way that we connect things in low-frequency read mode. In this case +// we are generating the unmodulated low frequency carrier. +// The A/D samples at that same rate and the result is serialized. +// +// Jonathan Westhues, April 2006 +//----------------------------------------------------------------------------- + +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, 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 +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]; + // 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; + end +end + +// ADC samples on falling edge of adc_clk, data available on the rising edge + +// example of ssp transfer of binary value 1100101 +// start of transfer is indicated by the rise of the ssp_frame signal +// ssp_din changes on the rising edge of the ssp_clk clock and is clocked into +// the ARM by the falling edge of ssp_clk +// _______________________________ +// ssp_frame__| |__ +// _______ ___ ___ +// ssp_din __| |_______| |___| |______ +// _ _ _ _ _ _ _ _ _ _ +// ssp_clk |_| |_| |_| |_| |_| |_| |_| |_| |_| |_ + +// serialized SSP data is gated by ant_lo to suppress unwanted signal +assign ssp_din = to_arm_shiftreg[7] && !ant_lo; +// 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; +// unused signals tied low +assign pwr_hi = 1'b0; +assign pwr_oe1 = 1'b0; +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; +// ADC clock out of phase with antenna driver +assign adc_clk = ~ant_lo; +// ADC clock also routed to debug pin +assign dbg = adc_clk; +endmodule diff --git a/fpga/lo_simulate.v b/fpga/lo_simulate.v index 9e3cd50a..57e602a2 100644 --- a/fpga/lo_simulate.v +++ b/fpga/lo_simulate.v @@ -1,56 +1,56 @@ -//----------------------------------------------------------------------------- -// The way that we connect things in low-frequency simulation mode. In this -// case just pass everything through to the ARM, which can bit-bang this -// (because it is so slow). -// -// Jonathan Westhues, April 2006 -//----------------------------------------------------------------------------- - -module lo_simulate( - 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, +//----------------------------------------------------------------------------- +// The way that we connect things in low-frequency simulation mode. In this +// case just pass everything through to the ARM, which can bit-bang this +// (because it is so slow). +// +// Jonathan Westhues, April 2006 +//----------------------------------------------------------------------------- + +module lo_simulate( + 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 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; + divisor +); + 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; - -// No logic, straight through. -assign pwr_oe3 = 1'b0; -assign pwr_oe1 = ssp_dout; -assign pwr_oe2 = ssp_dout; -assign pwr_oe4 = ssp_dout; -assign ssp_clk = cross_lo; -assign pwr_lo = 1'b0; -assign pwr_hi = 1'b0; -assign dbg = ssp_frame; + input [7:0] divisor; + +// No logic, straight through. +assign pwr_oe3 = 1'b0; +assign pwr_oe1 = ssp_dout; +assign pwr_oe2 = ssp_dout; +assign pwr_oe4 = ssp_dout; +assign ssp_clk = cross_lo; +assign pwr_lo = 1'b0; +assign pwr_hi = 1'b0; +assign dbg = ssp_frame; // Divide the clock to be used for the ADC reg [7:0] pck_divider; reg clk_state; - -always @(posedge pck0) -begin - if(pck_divider == divisor[7:0]) - begin + +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 + clk_state = !clk_state; + end + else + begin + pck_divider <= pck_divider + 1; + end +end assign adc_clk = ~clk_state; @@ -61,8 +61,8 @@ reg is_high; reg is_low; reg output_state; -always @(posedge pck0) -begin +always @(posedge pck0) +begin if((pck_divider == 8'd7) && !clk_state) begin is_high = (adc_d >= 8'd200); is_low = (adc_d <= 8'd64); @@ -78,5 +78,6 @@ begin end assign ssp_frame = output_state; - -endmodule + +endmodule + diff --git a/fpga/sim.tcl b/fpga/sim.tcl index 477acd1d..0ee8c0c3 100644 --- a/fpga/sim.tcl +++ b/fpga/sim.tcl @@ -1,27 +1,27 @@ -#------------------------------------------------------------------------------ -# Run the simulation testbench in ModelSim: recompile both Verilog source -# files, then start the simulation, add a lot of signals to the waveform -# viewer, and run. I should (TODO) fix the absolute paths at some point. -# -# Jonathan Westhues, Mar 2006 -#------------------------------------------------------------------------------ - -vlog -work work -O0 C:/depot/proximity/mark3/fpga/fpga.v -vlog -work work -O0 C:/depot/proximity/mark3/fpga/fpga_tb.v - -vsim work.fpga_tb - -add wave sim:/fpga_tb/adc_clk -add wave sim:/fpga_tb/adc_d -add wave sim:/fpga_tb/pwr_lo -add wave sim:/fpga_tb/ssp_clk -add wave sim:/fpga_tb/ssp_frame -add wave sim:/fpga_tb/ssp_din -add wave sim:/fpga_tb/ssp_dout - -add wave sim:/fpga_tb/dut/clk_lo -add wave sim:/fpga_tb/dut/pck_divider -add wave sim:/fpga_tb/dut/carrier_divider_lo -add wave sim:/fpga_tb/dut/conf_word - -run 30000 +#------------------------------------------------------------------------------ +# Run the simulation testbench in ModelSim: recompile both Verilog source +# files, then start the simulation, add a lot of signals to the waveform +# viewer, and run. I should (TODO) fix the absolute paths at some point. +# +# Jonathan Westhues, Mar 2006 +#------------------------------------------------------------------------------ + +vlog -work work -O0 C:/depot/proximity/mark3/fpga/fpga.v +vlog -work work -O0 C:/depot/proximity/mark3/fpga/fpga_tb.v + +vsim work.fpga_tb + +add wave sim:/fpga_tb/adc_clk +add wave sim:/fpga_tb/adc_d +add wave sim:/fpga_tb/pwr_lo +add wave sim:/fpga_tb/ssp_clk +add wave sim:/fpga_tb/ssp_frame +add wave sim:/fpga_tb/ssp_din +add wave sim:/fpga_tb/ssp_dout + +add wave sim:/fpga_tb/dut/clk_lo +add wave sim:/fpga_tb/dut/pck_divider +add wave sim:/fpga_tb/dut/carrier_divider_lo +add wave sim:/fpga_tb/dut/conf_word + +run 30000 diff --git a/fpga/testbed_fpga.v b/fpga/testbed_fpga.v index 3ef2766a..f62255db 100644 --- a/fpga/testbed_fpga.v +++ b/fpga/testbed_fpga.v @@ -1,50 +1,50 @@ -`include "fpga.v" - -module testbed_fpga; - reg spck, mosi, ncs; - wire miso; - reg pck0i, ck_1356meg, ck_1356megb; - wire pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4; - reg [7:0] adc_d; - wire adc_clk, adc_noe; - reg ssp_dout; - wire ssp_frame, ssp_din, ssp_clk; - - fpga dut( - spck, miso, mosi, ncs, - pck0i, 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 - ); - - integer i; - - initial begin - - // init inputs - #5 ncs=1; - #5 spck = 1; - #5 mosi = 1; - - #50 ncs=0; - for (i = 0 ; i < 8 ; i = i + 1) begin - #5 mosi = $random; - #5 spck = 0; - #5 spck = 1; - end - #5 ncs=1; - - #50 ncs=0; - for (i = 0 ; i < 8 ; i = i + 1) begin - #5 mosi = $random; - #5 spck = 0; - #5 spck = 1; - end - #5 ncs=1; - - #50 mosi=1; - $finish; - end - -endmodule // main +`include "fpga.v" + +module testbed_fpga; + reg spck, mosi, ncs; + wire miso; + reg pck0i, ck_1356meg, ck_1356megb; + wire pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4; + reg [7:0] adc_d; + wire adc_clk, adc_noe; + reg ssp_dout; + wire ssp_frame, ssp_din, ssp_clk; + + fpga dut( + spck, miso, mosi, ncs, + pck0i, 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 + ); + + integer i; + + initial begin + + // init inputs + #5 ncs=1; + #5 spck = 1; + #5 mosi = 1; + + #50 ncs=0; + for (i = 0 ; i < 8 ; i = i + 1) begin + #5 mosi = $random; + #5 spck = 0; + #5 spck = 1; + end + #5 ncs=1; + + #50 ncs=0; + for (i = 0 ; i < 8 ; i = i + 1) begin + #5 mosi = $random; + #5 spck = 0; + #5 spck = 1; + end + #5 ncs=1; + + #50 mosi=1; + $finish; + end + +endmodule // main diff --git a/fpga/testbed_hi_read_tx.v b/fpga/testbed_hi_read_tx.v index 0d600a1f..bd4f5b40 100644 --- a/fpga/testbed_hi_read_tx.v +++ b/fpga/testbed_hi_read_tx.v @@ -1,109 +1,109 @@ -`include "hi_read_tx.v" - -/* - pck0 - input main 24Mhz clock (PLL / 4) - [7:0] adc_d - input data from A/D converter - shallow_modulation - modulation type - - pwr_lo - output to coil drivers (ssp_clk / 8) - adc_clk - output A/D clock signal - ssp_frame - output SSS frame indicator (goes high while the 8 bits are shifted) - ssp_din - output SSP data to ARM (shifts 8 bit A/D value serially to ARM MSB first) - ssp_clk - output SSP clock signal - - ck_1356meg - input unused - ck_1356megb - input unused - ssp_dout - input unused - cross_hi - input unused - cross_lo - input unused - - pwr_hi - output unused, tied low - pwr_oe1 - output unused, undefined - pwr_oe2 - output unused, undefined - pwr_oe3 - output unused, undefined - pwr_oe4 - output unused, undefined - dbg - output alias for adc_clk -*/ - -module testbed_hi_read_tx; - reg pck0; - reg [7:0] adc_d; - reg shallow_modulation; - - wire pwr_lo; - wire adc_clk; - reg ck_1356meg; - reg ck_1356megb; - wire ssp_frame; - wire ssp_din; - wire ssp_clk; - reg ssp_dout; - wire pwr_hi; - wire pwr_oe1; - wire pwr_oe2; - wire pwr_oe3; - wire pwr_oe4; - wire cross_lo; - wire cross_hi; - wire dbg; - - hi_read_tx #(5,200) dut( - .pck0(pck0), - .ck_1356meg(ck_1356meg), - .ck_1356megb(ck_1356megb), - .pwr_lo(pwr_lo), - .pwr_hi(pwr_hi), - .pwr_oe1(pwr_oe1), - .pwr_oe2(pwr_oe2), - .pwr_oe3(pwr_oe3), - .pwr_oe4(pwr_oe4), - .adc_d(adc_d), - .adc_clk(adc_clk), - .ssp_frame(ssp_frame), - .ssp_din(ssp_din), - .ssp_dout(ssp_dout), - .ssp_clk(ssp_clk), - .cross_hi(cross_hi), - .cross_lo(cross_lo), - .dbg(dbg), - .shallow_modulation(shallow_modulation) - ); - - integer idx, i; - - // main clock - always #5 begin - ck_1356megb = !ck_1356megb; - ck_1356meg = ck_1356megb; - end - - //crank DUT - task crank_dut; - begin - @(posedge ssp_clk) ; - ssp_dout = $random; - end - endtask - - initial begin - - // init inputs - ck_1356megb = 0; - adc_d = 0; - ssp_dout=0; - - // shallow modulation off - shallow_modulation=0; - for (i = 0 ; i < 16 ; i = i + 1) begin - crank_dut; - end - - // shallow modulation on - shallow_modulation=1; - for (i = 0 ; i < 16 ; i = i + 1) begin - crank_dut; - end - $finish; - end - -endmodule // main +`include "hi_read_tx.v" + +/* + pck0 - input main 24Mhz clock (PLL / 4) + [7:0] adc_d - input data from A/D converter + shallow_modulation - modulation type + + pwr_lo - output to coil drivers (ssp_clk / 8) + adc_clk - output A/D clock signal + ssp_frame - output SSS frame indicator (goes high while the 8 bits are shifted) + ssp_din - output SSP data to ARM (shifts 8 bit A/D value serially to ARM MSB first) + ssp_clk - output SSP clock signal + + ck_1356meg - input unused + ck_1356megb - input unused + ssp_dout - input unused + cross_hi - input unused + cross_lo - input unused + + pwr_hi - output unused, tied low + pwr_oe1 - output unused, undefined + pwr_oe2 - output unused, undefined + pwr_oe3 - output unused, undefined + pwr_oe4 - output unused, undefined + dbg - output alias for adc_clk +*/ + +module testbed_hi_read_tx; + reg pck0; + reg [7:0] adc_d; + reg shallow_modulation; + + wire pwr_lo; + wire adc_clk; + reg ck_1356meg; + reg ck_1356megb; + wire ssp_frame; + wire ssp_din; + wire ssp_clk; + reg ssp_dout; + wire pwr_hi; + wire pwr_oe1; + wire pwr_oe2; + wire pwr_oe3; + wire pwr_oe4; + wire cross_lo; + wire cross_hi; + wire dbg; + + hi_read_tx #(5,200) dut( + .pck0(pck0), + .ck_1356meg(ck_1356meg), + .ck_1356megb(ck_1356megb), + .pwr_lo(pwr_lo), + .pwr_hi(pwr_hi), + .pwr_oe1(pwr_oe1), + .pwr_oe2(pwr_oe2), + .pwr_oe3(pwr_oe3), + .pwr_oe4(pwr_oe4), + .adc_d(adc_d), + .adc_clk(adc_clk), + .ssp_frame(ssp_frame), + .ssp_din(ssp_din), + .ssp_dout(ssp_dout), + .ssp_clk(ssp_clk), + .cross_hi(cross_hi), + .cross_lo(cross_lo), + .dbg(dbg), + .shallow_modulation(shallow_modulation) + ); + + integer idx, i; + + // main clock + always #5 begin + ck_1356megb = !ck_1356megb; + ck_1356meg = ck_1356megb; + end + + //crank DUT + task crank_dut; + begin + @(posedge ssp_clk) ; + ssp_dout = $random; + end + endtask + + initial begin + + // init inputs + ck_1356megb = 0; + adc_d = 0; + ssp_dout=0; + + // shallow modulation off + shallow_modulation=0; + for (i = 0 ; i < 16 ; i = i + 1) begin + crank_dut; + end + + // shallow modulation on + shallow_modulation=1; + for (i = 0 ; i < 16 ; i = i + 1) begin + crank_dut; + end + $finish; + end + +endmodule // main diff --git a/fpga/testbed_hi_simulate.v b/fpga/testbed_hi_simulate.v index 6dc30f0b..b0672016 100644 --- a/fpga/testbed_hi_simulate.v +++ b/fpga/testbed_hi_simulate.v @@ -1,116 +1,116 @@ -`include "hi_simulate.v" - -/* - pck0 - input main 24Mhz clock (PLL / 4) - [7:0] adc_d - input data from A/D converter - mod_type - modulation type - - pwr_lo - output to coil drivers (ssp_clk / 8) - adc_clk - output A/D clock signal - ssp_frame - output SSS frame indicator (goes high while the 8 bits are shifted) - ssp_din - output SSP data to ARM (shifts 8 bit A/D value serially to ARM MSB first) - ssp_clk - output SSP clock signal - - ck_1356meg - input unused - ck_1356megb - input unused - ssp_dout - input unused - cross_hi - input unused - cross_lo - input unused - - pwr_hi - output unused, tied low - pwr_oe1 - output unused, undefined - pwr_oe2 - output unused, undefined - pwr_oe3 - output unused, undefined - pwr_oe4 - output unused, undefined - dbg - output alias for adc_clk -*/ - -module testbed_hi_simulate; - reg pck0; - reg [7:0] adc_d; - reg mod_type; - - wire pwr_lo; - wire adc_clk; - reg ck_1356meg; - reg ck_1356megb; - wire ssp_frame; - wire ssp_din; - wire ssp_clk; - reg ssp_dout; - wire pwr_hi; - wire pwr_oe1; - wire pwr_oe2; - wire pwr_oe3; - wire pwr_oe4; - wire cross_lo; - wire cross_hi; - wire dbg; - - hi_simulate #(5,200) dut( - .pck0(pck0), - .ck_1356meg(ck_1356meg), - .ck_1356megb(ck_1356megb), - .pwr_lo(pwr_lo), - .pwr_hi(pwr_hi), - .pwr_oe1(pwr_oe1), - .pwr_oe2(pwr_oe2), - .pwr_oe3(pwr_oe3), - .pwr_oe4(pwr_oe4), - .adc_d(adc_d), - .adc_clk(adc_clk), - .ssp_frame(ssp_frame), - .ssp_din(ssp_din), - .ssp_dout(ssp_dout), - .ssp_clk(ssp_clk), - .cross_hi(cross_hi), - .cross_lo(cross_lo), - .dbg(dbg), - .mod_type(mod_type) - ); - - integer idx, i; - - // main clock - always #5 begin - ck_1356megb = !ck_1356megb; - ck_1356meg = ck_1356megb; - end - - always begin - @(negedge adc_clk) ; - adc_d = $random; - end - - //crank DUT - task crank_dut; - begin - @(negedge ssp_clk) ; - ssp_dout = $random; - end - endtask - - initial begin - - // init inputs - ck_1356megb = 0; - // random values - adc_d = 0; - ssp_dout=1; - - // shallow modulation off - mod_type=0; - for (i = 0 ; i < 16 ; i = i + 1) begin - crank_dut; - end - - // shallow modulation on - mod_type=1; - for (i = 0 ; i < 16 ; i = i + 1) begin - crank_dut; - end - $finish; - end - -endmodule // main - +`include "hi_simulate.v" + +/* + pck0 - input main 24Mhz clock (PLL / 4) + [7:0] adc_d - input data from A/D converter + mod_type - modulation type + + pwr_lo - output to coil drivers (ssp_clk / 8) + adc_clk - output A/D clock signal + ssp_frame - output SSS frame indicator (goes high while the 8 bits are shifted) + ssp_din - output SSP data to ARM (shifts 8 bit A/D value serially to ARM MSB first) + ssp_clk - output SSP clock signal + + ck_1356meg - input unused + ck_1356megb - input unused + ssp_dout - input unused + cross_hi - input unused + cross_lo - input unused + + pwr_hi - output unused, tied low + pwr_oe1 - output unused, undefined + pwr_oe2 - output unused, undefined + pwr_oe3 - output unused, undefined + pwr_oe4 - output unused, undefined + dbg - output alias for adc_clk +*/ + +module testbed_hi_simulate; + reg pck0; + reg [7:0] adc_d; + reg mod_type; + + wire pwr_lo; + wire adc_clk; + reg ck_1356meg; + reg ck_1356megb; + wire ssp_frame; + wire ssp_din; + wire ssp_clk; + reg ssp_dout; + wire pwr_hi; + wire pwr_oe1; + wire pwr_oe2; + wire pwr_oe3; + wire pwr_oe4; + wire cross_lo; + wire cross_hi; + wire dbg; + + hi_simulate #(5,200) dut( + .pck0(pck0), + .ck_1356meg(ck_1356meg), + .ck_1356megb(ck_1356megb), + .pwr_lo(pwr_lo), + .pwr_hi(pwr_hi), + .pwr_oe1(pwr_oe1), + .pwr_oe2(pwr_oe2), + .pwr_oe3(pwr_oe3), + .pwr_oe4(pwr_oe4), + .adc_d(adc_d), + .adc_clk(adc_clk), + .ssp_frame(ssp_frame), + .ssp_din(ssp_din), + .ssp_dout(ssp_dout), + .ssp_clk(ssp_clk), + .cross_hi(cross_hi), + .cross_lo(cross_lo), + .dbg(dbg), + .mod_type(mod_type) + ); + + integer idx, i; + + // main clock + always #5 begin + ck_1356megb = !ck_1356megb; + ck_1356meg = ck_1356megb; + end + + always begin + @(negedge adc_clk) ; + adc_d = $random; + end + + //crank DUT + task crank_dut; + begin + @(negedge ssp_clk) ; + ssp_dout = $random; + end + endtask + + initial begin + + // init inputs + ck_1356megb = 0; + // random values + adc_d = 0; + ssp_dout=1; + + // shallow modulation off + mod_type=0; + for (i = 0 ; i < 16 ; i = i + 1) begin + crank_dut; + end + + // shallow modulation on + mod_type=1; + for (i = 0 ; i < 16 ; i = i + 1) begin + crank_dut; + end + $finish; + end + +endmodule // main + diff --git a/fpga/testbed_lo_read.v b/fpga/testbed_lo_read.v index cb0f119c..370ed389 100644 --- a/fpga/testbed_lo_read.v +++ b/fpga/testbed_lo_read.v @@ -1,101 +1,101 @@ -`include "lo_read.v" -/* - pck0 - input main 24Mhz clock (PLL / 4) - [7:0] adc_d - input data from A/D converter - lo_is_125khz - input freq selector (1=125Khz, 0=136Khz) - - pwr_lo - output to coil drivers (ssp_clk / 8) - adc_clk - output A/D clock signal - ssp_frame - output SSS frame indicator (goes high while the 8 bits are shifted) - ssp_din - output SSP data to ARM (shifts 8 bit A/D value serially to ARM MSB first) - ssp_clk - output SSP clock signal 1Mhz/1.09Mhz (pck0 / 2*(11+lo_is_125khz) ) - - ck_1356meg - input unused - ck_1356megb - input unused - ssp_dout - input unused - cross_hi - input unused - cross_lo - input unused - - pwr_hi - output unused, tied low - pwr_oe1 - output unused, undefined - pwr_oe2 - output unused, undefined - pwr_oe3 - output unused, undefined - pwr_oe4 - output unused, undefined - dbg - output alias for adc_clk -*/ - -module testbed_lo_read; - reg pck0; - reg [7:0] adc_d; - reg lo_is_125khz; - reg [15:0] divisor; - - wire pwr_lo; - wire adc_clk; - wire ck_1356meg; - wire ck_1356megb; - wire ssp_frame; - wire ssp_din; - wire ssp_clk; - reg ssp_dout; - wire pwr_hi; - wire pwr_oe1; - wire pwr_oe2; - wire pwr_oe3; - wire pwr_oe4; - wire cross_lo; - wire cross_hi; - wire dbg; - - lo_read #(5,10) dut( - .pck0(pck0), - .ck_1356meg(ck_1356meg), - .ck_1356megb(ck_1356megb), - .pwr_lo(pwr_lo), - .pwr_hi(pwr_hi), - .pwr_oe1(pwr_oe1), - .pwr_oe2(pwr_oe2), - .pwr_oe3(pwr_oe3), - .pwr_oe4(pwr_oe4), - .adc_d(adc_d), - .adc_clk(adc_clk), - .ssp_frame(ssp_frame), - .ssp_din(ssp_din), - .ssp_dout(ssp_dout), - .ssp_clk(ssp_clk), - .cross_hi(cross_hi), - .cross_lo(cross_lo), - .dbg(dbg), - .lo_is_125khz(lo_is_125khz), - .divisor(divisor) - ); - - integer idx, i, adc_val=8; - - // main clock - always #5 pck0 = !pck0; - - task crank_dut; - begin - @(posedge adc_clk) ; - adc_d = adc_val; - adc_val = (adc_val *2) + 53; - end - endtask - - initial begin - - // init inputs - pck0 = 0; - adc_d = 0; - ssp_dout = 0; - lo_is_125khz = 1; - divisor = 255; //min 16, 95=125Khz, max 255 - - // simulate 4 A/D cycles at 125Khz - for (i = 0 ; i < 8 ; i = i + 1) begin - crank_dut; - end - $finish; - end -endmodule // main +`include "lo_read.v" +/* + pck0 - input main 24Mhz clock (PLL / 4) + [7:0] adc_d - input data from A/D converter + lo_is_125khz - input freq selector (1=125Khz, 0=136Khz) + + pwr_lo - output to coil drivers (ssp_clk / 8) + adc_clk - output A/D clock signal + ssp_frame - output SSS frame indicator (goes high while the 8 bits are shifted) + ssp_din - output SSP data to ARM (shifts 8 bit A/D value serially to ARM MSB first) + ssp_clk - output SSP clock signal 1Mhz/1.09Mhz (pck0 / 2*(11+lo_is_125khz) ) + + ck_1356meg - input unused + ck_1356megb - input unused + ssp_dout - input unused + cross_hi - input unused + cross_lo - input unused + + pwr_hi - output unused, tied low + pwr_oe1 - output unused, undefined + pwr_oe2 - output unused, undefined + pwr_oe3 - output unused, undefined + pwr_oe4 - output unused, undefined + dbg - output alias for adc_clk +*/ + +module testbed_lo_read; + reg pck0; + reg [7:0] adc_d; + reg lo_is_125khz; + reg [15:0] divisor; + + wire pwr_lo; + wire adc_clk; + wire ck_1356meg; + wire ck_1356megb; + wire ssp_frame; + wire ssp_din; + wire ssp_clk; + reg ssp_dout; + wire pwr_hi; + wire pwr_oe1; + wire pwr_oe2; + wire pwr_oe3; + wire pwr_oe4; + wire cross_lo; + wire cross_hi; + wire dbg; + + lo_read #(5,10) dut( + .pck0(pck0), + .ck_1356meg(ck_1356meg), + .ck_1356megb(ck_1356megb), + .pwr_lo(pwr_lo), + .pwr_hi(pwr_hi), + .pwr_oe1(pwr_oe1), + .pwr_oe2(pwr_oe2), + .pwr_oe3(pwr_oe3), + .pwr_oe4(pwr_oe4), + .adc_d(adc_d), + .adc_clk(adc_clk), + .ssp_frame(ssp_frame), + .ssp_din(ssp_din), + .ssp_dout(ssp_dout), + .ssp_clk(ssp_clk), + .cross_hi(cross_hi), + .cross_lo(cross_lo), + .dbg(dbg), + .lo_is_125khz(lo_is_125khz), + .divisor(divisor) + ); + + integer idx, i, adc_val=8; + + // main clock + always #5 pck0 = !pck0; + + task crank_dut; + begin + @(posedge adc_clk) ; + adc_d = adc_val; + adc_val = (adc_val *2) + 53; + end + endtask + + initial begin + + // init inputs + pck0 = 0; + adc_d = 0; + ssp_dout = 0; + lo_is_125khz = 1; + divisor = 255; //min 16, 95=125Khz, max 255 + + // simulate 4 A/D cycles at 125Khz + for (i = 0 ; i < 8 ; i = i + 1) begin + crank_dut; + end + $finish; + end +endmodule // main diff --git a/fpga/testbed_lo_simulate.v b/fpga/testbed_lo_simulate.v index d30f822d..70b6331f 100644 --- a/fpga/testbed_lo_simulate.v +++ b/fpga/testbed_lo_simulate.v @@ -1,101 +1,101 @@ -`include "lo_simulate.v" - -/* - pck0 - input main 24Mhz clock (PLL / 4) - [7:0] adc_d - input data from A/D converter - - - pwr_lo - output to coil drivers (ssp_clk / 8) - adc_clk - output A/D clock signal - ssp_frame - output SSS frame indicator (goes high while the 8 bits are shifted) - ssp_din - output SSP data to ARM (shifts 8 bit A/D value serially to ARM MSB first) - ssp_clk - output SSP clock signal - - ck_1356meg - input unused - ck_1356megb - input unused - ssp_dout - input unused - cross_hi - input unused - cross_lo - input unused - - pwr_hi - output unused, tied low - pwr_oe1 - output unused, undefined - pwr_oe2 - output unused, undefined - pwr_oe3 - output unused, undefined - pwr_oe4 - output unused, undefined - dbg - output alias for adc_clk -*/ - -module testbed_lo_simulate; - reg pck0; - reg [7:0] adc_d; - - - wire pwr_lo; - wire adc_clk; - wire ck_1356meg; - wire ck_1356megb; - wire ssp_frame; - wire ssp_din; - wire ssp_clk; - reg ssp_dout; - wire pwr_hi; - wire pwr_oe1; - wire pwr_oe2; - wire pwr_oe3; - wire pwr_oe4; - reg cross_lo; - wire cross_hi; - wire dbg; - - lo_simulate #(5,200) dut( - .pck0(pck0), - .ck_1356meg(ck_1356meg), - .ck_1356megb(ck_1356megb), - .pwr_lo(pwr_lo), - .pwr_hi(pwr_hi), - .pwr_oe1(pwr_oe1), - .pwr_oe2(pwr_oe2), - .pwr_oe3(pwr_oe3), - .pwr_oe4(pwr_oe4), - .adc_d(adc_d), - .adc_clk(adc_clk), - .ssp_frame(ssp_frame), - .ssp_din(ssp_din), - .ssp_dout(ssp_dout), - .ssp_clk(ssp_clk), - .cross_hi(cross_hi), - .cross_lo(cross_lo), - .dbg(dbg) - ); - - - integer i, counter=0; - - // main clock - always #5 pck0 = !pck0; - - //cross_lo is not really synced to pck0 but it's roughly pck0/192 (24Mhz/192=125Khz) - task crank_dut; - begin - @(posedge pck0) ; - counter = counter + 1; - if (counter == 192) begin - counter = 0; - ssp_dout = $random; - cross_lo = 1; - end else begin - cross_lo = 0; - end - - end - endtask - - initial begin - pck0 = 0; - for (i = 0 ; i < 4096 ; i = i + 1) begin - crank_dut; - end - $finish; - end - -endmodule // main +`include "lo_simulate.v" + +/* + pck0 - input main 24Mhz clock (PLL / 4) + [7:0] adc_d - input data from A/D converter + + + pwr_lo - output to coil drivers (ssp_clk / 8) + adc_clk - output A/D clock signal + ssp_frame - output SSS frame indicator (goes high while the 8 bits are shifted) + ssp_din - output SSP data to ARM (shifts 8 bit A/D value serially to ARM MSB first) + ssp_clk - output SSP clock signal + + ck_1356meg - input unused + ck_1356megb - input unused + ssp_dout - input unused + cross_hi - input unused + cross_lo - input unused + + pwr_hi - output unused, tied low + pwr_oe1 - output unused, undefined + pwr_oe2 - output unused, undefined + pwr_oe3 - output unused, undefined + pwr_oe4 - output unused, undefined + dbg - output alias for adc_clk +*/ + +module testbed_lo_simulate; + reg pck0; + reg [7:0] adc_d; + + + wire pwr_lo; + wire adc_clk; + wire ck_1356meg; + wire ck_1356megb; + wire ssp_frame; + wire ssp_din; + wire ssp_clk; + reg ssp_dout; + wire pwr_hi; + wire pwr_oe1; + wire pwr_oe2; + wire pwr_oe3; + wire pwr_oe4; + reg cross_lo; + wire cross_hi; + wire dbg; + + lo_simulate #(5,200) dut( + .pck0(pck0), + .ck_1356meg(ck_1356meg), + .ck_1356megb(ck_1356megb), + .pwr_lo(pwr_lo), + .pwr_hi(pwr_hi), + .pwr_oe1(pwr_oe1), + .pwr_oe2(pwr_oe2), + .pwr_oe3(pwr_oe3), + .pwr_oe4(pwr_oe4), + .adc_d(adc_d), + .adc_clk(adc_clk), + .ssp_frame(ssp_frame), + .ssp_din(ssp_din), + .ssp_dout(ssp_dout), + .ssp_clk(ssp_clk), + .cross_hi(cross_hi), + .cross_lo(cross_lo), + .dbg(dbg) + ); + + + integer i, counter=0; + + // main clock + always #5 pck0 = !pck0; + + //cross_lo is not really synced to pck0 but it's roughly pck0/192 (24Mhz/192=125Khz) + task crank_dut; + begin + @(posedge pck0) ; + counter = counter + 1; + if (counter == 192) begin + counter = 0; + ssp_dout = $random; + cross_lo = 1; + end else begin + cross_lo = 0; + end + + end + endtask + + initial begin + pck0 = 0; + for (i = 0 ; i < 4096 ; i = i + 1) begin + crank_dut; + end + $finish; + end + +endmodule // main diff --git a/fpga/util.v b/fpga/util.v index c500edb4..0842ac64 100644 --- a/fpga/util.v +++ b/fpga/util.v @@ -1,27 +1,27 @@ -//----------------------------------------------------------------------------- -// General-purpose miscellany. -// -// Jonathan Westhues, April 2006. -//----------------------------------------------------------------------------- - -module mux8(sel, y, x0, x1, x2, x3, x4, x5, x6, x7); - input [2:0] sel; - input x0, x1, x2, x3, x4, x5, x6, x7; - output y; - reg y; - -always @(x0 or x1 or x2 or x3 or x4 or x5 or x6 or x7 or sel) -begin - case (sel) - 3'b000: y = x0; - 3'b001: y = x1; - 3'b010: y = x2; - 3'b011: y = x3; - 3'b100: y = x4; - 3'b101: y = x5; - 3'b110: y = x6; - 3'b111: y = x7; - endcase -end - -endmodule +//----------------------------------------------------------------------------- +// General-purpose miscellany. +// +// Jonathan Westhues, April 2006. +//----------------------------------------------------------------------------- + +module mux8(sel, y, x0, x1, x2, x3, x4, x5, x6, x7); + input [2:0] sel; + input x0, x1, x2, x3, x4, x5, x6, x7; + output y; + reg y; + +always @(x0 or x1 or x2 or x3 or x4 or x5 or x6 or x7 or sel) +begin + case (sel) + 3'b000: y = x0; + 3'b001: y = x1; + 3'b010: y = x2; + 3'b011: y = x3; + 3'b100: y = x4; + 3'b101: y = x5; + 3'b110: y = x6; + 3'b111: y = x7; + endcase +end + +endmodule diff --git a/fpga/xst.scr b/fpga/xst.scr index 365db39a..60d24c64 100644 --- a/fpga/xst.scr +++ b/fpga/xst.scr @@ -1 +1 @@ -run -ifn fpga.v -ifmt Verilog -ofn fpga.ngc -ofmt NGC -p xc2s30-6vq100 -opt_mode Speed -opt_level 1 -ent fpga +run -ifn fpga.v -ifmt Verilog -ofn fpga.ngc -ofmt NGC -p xc2s30-6vq100 -opt_mode Speed -opt_level 1 -ent fpga diff --git a/tools/at91sam7s256-armusbocd-flash-program.cfg b/tools/at91sam7s256-armusbocd-flash-program.cfg index 2dce014f..1884407a 100644 --- a/tools/at91sam7s256-armusbocd-flash-program.cfg +++ b/tools/at91sam7s256-armusbocd-flash-program.cfg @@ -1,39 +1,39 @@ -#define our ports -telnet_port 4444 -gdb_port 3333 - -#commands specific to the Olimex ARM-USB-OCD Dongle -interface ft2232 -ft2232_device_desc "Olimex OpenOCD JTAG" -ft2232_layout "olimex-jtag" -ft2232_vid_pid 0x15BA 0x0003 -jtag_speed 2 -jtag_nsrst_delay 200 -jtag_ntrst_delay 200 - -#reset_config [combination] [trst_type] [srst_type] -reset_config srst_only srst_pulls_trst - -#jtag_device -jtag_device 4 0x1 0xf 0xe - -#daemon_startup <'attach'|'reset'> -daemon_startup reset - -#target [variant] -target arm7tdmi little run_and_init 0 arm7tdmi_r4 - -#run_and_halt_time -run_and_halt_time 0 30 - -# commands below are specific to AT91sam7 Flash Programming -# --------------------------------------------------------- - -#target_script specifies the flash programming script file -target_script 0 reset script.ocd - -#working_area
<'backup'|'nobackup'> -working_area 0 0x40000000 0x4000 nobackup - -#flash bank at91sam7 0 0 0 0 -flash bank at91sam7 0 0 0 0 0 +#define our ports +telnet_port 4444 +gdb_port 3333 + +#commands specific to the Olimex ARM-USB-OCD Dongle +interface ft2232 +ft2232_device_desc "Olimex OpenOCD JTAG" +ft2232_layout "olimex-jtag" +ft2232_vid_pid 0x15BA 0x0003 +jtag_speed 2 +jtag_nsrst_delay 200 +jtag_ntrst_delay 200 + +#reset_config [combination] [trst_type] [srst_type] +reset_config srst_only srst_pulls_trst + +#jtag_device +jtag_device 4 0x1 0xf 0xe + +#daemon_startup <'attach'|'reset'> +daemon_startup reset + +#target [variant] +target arm7tdmi little run_and_init 0 arm7tdmi_r4 + +#run_and_halt_time +run_and_halt_time 0 30 + +# commands below are specific to AT91sam7 Flash Programming +# --------------------------------------------------------- + +#target_script specifies the flash programming script file +target_script 0 reset script.ocd + +#working_area
<'backup'|'nobackup'> +working_area 0 0x40000000 0x4000 nobackup + +#flash bank at91sam7 0 0 0 0 +flash bank at91sam7 0 0 0 0 0 diff --git a/tools/at91sam7s256-jtagkey.cfg b/tools/at91sam7s256-jtagkey.cfg index 5b56608c..2c32b795 100644 --- a/tools/at91sam7s256-jtagkey.cfg +++ b/tools/at91sam7s256-jtagkey.cfg @@ -1,24 +1,24 @@ -#define our ports -telnet_port 4444 -gdb_port 3333 - -#commands specific to the Amontec JTAGKey -interface ft2232 -ft2232_device_desc "Amontec JTAGkey A" -ft2232_layout jtagkey -ft2232_vid_pid 0x0403 0xcff8 -jtag_khz 200 -jtag_nsrst_delay 200 -jtag_ntrst_delay 200 - -#reset_config [combination] [trst_type] [srst_type] -reset_config srst_only srst_pulls_trst - -jtag newtap sam7x256 cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x3f0f0f0f - -target create sam7x256.cpu arm7tdmi -endian little -chain-position sam7x256.cpu -variant arm7tdmi - -gdb_memory_map enable - -sam7x256.cpu configure -work-area-virt 0 -work-area-phys 0x00200000 -work-area-size 0x10000 -work-area-backup 0 -flash bank at91sam7 0x100000 0x40000 0 4 sam7x256.cpu +#define our ports +telnet_port 4444 +gdb_port 3333 + +#commands specific to the Amontec JTAGKey +interface ft2232 +ft2232_device_desc "Amontec JTAGkey A" +ft2232_layout jtagkey +ft2232_vid_pid 0x0403 0xcff8 +jtag_khz 200 +jtag_nsrst_delay 200 +jtag_ntrst_delay 200 + +#reset_config [combination] [trst_type] [srst_type] +reset_config srst_only srst_pulls_trst + +jtag newtap sam7x256 cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x3f0f0f0f + +target create sam7x256.cpu arm7tdmi -endian little -chain-position sam7x256.cpu -variant arm7tdmi + +gdb_memory_map enable + +sam7x256.cpu configure -work-area-virt 0 -work-area-phys 0x00200000 -work-area-size 0x10000 -work-area-backup 0 +flash bank at91sam7 0x100000 0x40000 0 4 sam7x256.cpu diff --git a/tools/at91sam7s256-wiggler.cfg b/tools/at91sam7s256-wiggler.cfg index 83156fe5..83180dc9 100644 --- a/tools/at91sam7s256-wiggler.cfg +++ b/tools/at91sam7s256-wiggler.cfg @@ -1,39 +1,39 @@ -telnet_port 4444 -gdb_port 3333 - -interface parport -parport_port 0x378 -parport_cable wiggler -jtag_speed 0 -jtag_nsrst_delay 200 -jtag_ntrst_delay 200 - -reset_config srst_only srst_pulls_trst - -jtag newtap sam7x256 cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x3f0f0f0f -#jtag newtap xilinx tap -irlen 6 -ircapture 0x1 -irmask 0xf -expected-id 0x1c1a093 - -target create sam7x256.cpu arm7tdmi -endian little -chain-position sam7x256.cpu -variant arm7tdmi -sam7x256.cpu configure -event reset-init { - # disable watchdog - mww 0xfffffd44 0x00008000 - # enable user reset - mww 0xfffffd08 0xa5000001 - # CKGR_MOR : enable the main oscillator - mww 0xfffffc20 0x00000601 - sleep 10 - # CKGR_PLLR: 16 MHz * (5+1) /1 = 96Mhz - mww 0xfffffc2c 0x00051c01 - sleep 10 - # PMC_MCKR : MCK = PLL / 2 = 48 MHz - mww 0xfffffc30 0x00000007 - sleep 10 - # MC_FMR: flash mode (FWS=1,FMCN=60) - mww 0xffffff60 0x003c0100 - sleep 100 -} - -gdb_memory_map enable - -sam7x256.cpu configure -work-area-virt 0 -work-area-phys 0x00200000 -work-area-size 0x10000 -work-area-backup 0 -flash bank at91sam7 0 0 0 0 0 +telnet_port 4444 +gdb_port 3333 + +interface parport +parport_port 0x378 +parport_cable wiggler +jtag_speed 0 +jtag_nsrst_delay 200 +jtag_ntrst_delay 200 + +reset_config srst_only srst_pulls_trst + +jtag newtap sam7x256 cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x3f0f0f0f +#jtag newtap xilinx tap -irlen 6 -ircapture 0x1 -irmask 0xf -expected-id 0x1c1a093 + +target create sam7x256.cpu arm7tdmi -endian little -chain-position sam7x256.cpu -variant arm7tdmi +sam7x256.cpu configure -event reset-init { + # disable watchdog + mww 0xfffffd44 0x00008000 + # enable user reset + mww 0xfffffd08 0xa5000001 + # CKGR_MOR : enable the main oscillator + mww 0xfffffc20 0x00000601 + sleep 10 + # CKGR_PLLR: 16 MHz * (5+1) /1 = 96Mhz + mww 0xfffffc2c 0x00051c01 + sleep 10 + # PMC_MCKR : MCK = PLL / 2 = 48 MHz + mww 0xfffffc30 0x00000007 + sleep 10 + # MC_FMR: flash mode (FWS=1,FMCN=60) + mww 0xffffff60 0x003c0100 + sleep 100 +} + +gdb_memory_map enable + +sam7x256.cpu configure -work-area-virt 0 -work-area-phys 0x00200000 -work-area-size 0x10000 -work-area-backup 0 +flash bank at91sam7 0 0 0 0 0