style of .v files

This commit is contained in:
Philippe Teuwen 2019-07-30 22:47:23 +02:00
commit cb439ef58b
24 changed files with 1257 additions and 1257 deletions

View file

@ -7,19 +7,19 @@
//-----------------------------------------------------------------------------
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_;
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
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

View file

@ -22,14 +22,14 @@
`include "hi_flite.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
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
);
//-----------------------------------------------------------------------------
@ -47,18 +47,18 @@ reg [7:0] conf_word;
// 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
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
if(~ncs)
begin
shift_reg[15:1] <= shift_reg[14:0];
shift_reg[0] <= mosi;
end
end
wire [2:0] major_mode;
@ -87,43 +87,43 @@ wire [2:0] hi_simulate_mod_type = conf_word[2:0];
//-----------------------------------------------------------------------------
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
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
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
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
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
);
hi_sniffer he(
@ -157,17 +157,17 @@ hi_flite hfl(
// 110 -- none
// 111 -- everything off
mux8 mux_ssp_clk (major_mode, ssp_clk, ht_ssp_clk, hrxc_ssp_clk, hs_ssp_clk, hisn_ssp_clk, he_ssp_clk, hfl_ssp_clk, 1'b0, 1'b0);
mux8 mux_ssp_din (major_mode, ssp_din, ht_ssp_din, hrxc_ssp_din, hs_ssp_din, hisn_ssp_din, he_ssp_din, hfl_ssp_din, 1'b0, 1'b0);
mux8 mux_ssp_frame (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, hfl_ssp_frame, 1'b0, 1'b0);
mux8 mux_pwr_oe1 (major_mode, pwr_oe1, ht_pwr_oe1, hrxc_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, he_pwr_oe1, hfl_pwr_oe1, 1'b0, 1'b0);
mux8 mux_pwr_oe2 (major_mode, pwr_oe2, ht_pwr_oe2, hrxc_pwr_oe2, hs_pwr_oe2, hisn_pwr_oe2, he_pwr_oe2, hfl_pwr_oe2, 1'b0, 1'b0);
mux8 mux_pwr_oe3 (major_mode, pwr_oe3, ht_pwr_oe3, hrxc_pwr_oe3, hs_pwr_oe3, hisn_pwr_oe3, he_pwr_oe3, hfl_pwr_oe3, 1'b0, 1'b0);
mux8 mux_pwr_oe4 (major_mode, pwr_oe4, ht_pwr_oe4, hrxc_pwr_oe4, hs_pwr_oe4, hisn_pwr_oe4, he_pwr_oe4, hfl_pwr_oe4, 1'b0, 1'b0);
mux8 mux_pwr_lo (major_mode, pwr_lo, ht_pwr_lo, hrxc_pwr_lo, hs_pwr_lo, hisn_pwr_lo, he_pwr_lo, hfl_pwr_lo, 1'b0, 1'b0);
mux8 mux_pwr_hi (major_mode, pwr_hi, ht_pwr_hi, hrxc_pwr_hi, hs_pwr_hi, hisn_pwr_hi, he_pwr_hi, hfl_pwr_hi, 1'b0, 1'b0);
mux8 mux_adc_clk (major_mode, adc_clk, ht_adc_clk, hrxc_adc_clk, hs_adc_clk, hisn_adc_clk, he_adc_clk, hfl_adc_clk, 1'b0, 1'b0);
mux8 mux_dbg (major_mode, dbg, ht_dbg, hrxc_dbg, hs_dbg, hisn_dbg, he_dbg, hfl_dbg, 1'b0, 1'b0);
mux8 mux_ssp_clk (major_mode, ssp_clk, ht_ssp_clk, hrxc_ssp_clk, hs_ssp_clk, hisn_ssp_clk, he_ssp_clk, hfl_ssp_clk, 1'b0, 1'b0);
mux8 mux_ssp_din (major_mode, ssp_din, ht_ssp_din, hrxc_ssp_din, hs_ssp_din, hisn_ssp_din, he_ssp_din, hfl_ssp_din, 1'b0, 1'b0);
mux8 mux_ssp_frame (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, hfl_ssp_frame, 1'b0, 1'b0);
mux8 mux_pwr_oe1 (major_mode, pwr_oe1, ht_pwr_oe1, hrxc_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, he_pwr_oe1, hfl_pwr_oe1, 1'b0, 1'b0);
mux8 mux_pwr_oe2 (major_mode, pwr_oe2, ht_pwr_oe2, hrxc_pwr_oe2, hs_pwr_oe2, hisn_pwr_oe2, he_pwr_oe2, hfl_pwr_oe2, 1'b0, 1'b0);
mux8 mux_pwr_oe3 (major_mode, pwr_oe3, ht_pwr_oe3, hrxc_pwr_oe3, hs_pwr_oe3, hisn_pwr_oe3, he_pwr_oe3, hfl_pwr_oe3, 1'b0, 1'b0);
mux8 mux_pwr_oe4 (major_mode, pwr_oe4, ht_pwr_oe4, hrxc_pwr_oe4, hs_pwr_oe4, hisn_pwr_oe4, he_pwr_oe4, hfl_pwr_oe4, 1'b0, 1'b0);
mux8 mux_pwr_lo (major_mode, pwr_lo, ht_pwr_lo, hrxc_pwr_lo, hs_pwr_lo, hisn_pwr_lo, he_pwr_lo, hfl_pwr_lo, 1'b0, 1'b0);
mux8 mux_pwr_hi (major_mode, pwr_hi, ht_pwr_hi, hrxc_pwr_hi, hs_pwr_hi, hisn_pwr_hi, he_pwr_hi, hfl_pwr_hi, 1'b0, 1'b0);
mux8 mux_adc_clk (major_mode, adc_clk, ht_adc_clk, hrxc_adc_clk, hs_adc_clk, hisn_adc_clk, he_adc_clk, hfl_adc_clk, 1'b0, 1'b0);
mux8 mux_dbg (major_mode, dbg, ht_dbg, hrxc_dbg, hs_dbg, hisn_dbg, he_dbg, hfl_dbg, 1'b0, 1'b0);
// In all modes, let the ADC's outputs be enabled.
assign adc_noe = 1'b0;

View file

@ -10,14 +10,14 @@
`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
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
);
//-----------------------------------------------------------------------------
@ -34,26 +34,26 @@ reg [7:0] user_byte1;
always @(posedge ncs)
begin
case(shift_reg[15:12])
4'b0001:
begin
conf_word <= shift_reg[7:0];
if (shift_reg[7:0] == 8'b00000001) begin // LF edge detect
user_byte1 <= 127; // default threshold
end
end
4'b0010: divisor <= shift_reg[7:0]; // FPGA_CMD_SET_DIVISOR
4'b0011: user_byte1 <= shift_reg[7:0]; // FPGA_CMD_SET_USER_BYTE1
endcase
case(shift_reg[15:12])
4'b0001:
begin
conf_word <= shift_reg[7:0];
if (shift_reg[7:0] == 8'b00000001) begin // LF edge detect
user_byte1 <= 127; // default threshold
end
end
4'b0010: divisor <= shift_reg[7:0]; // FPGA_CMD_SET_DIVISOR
4'b0011: user_byte1 <= shift_reg[7:0]; // FPGA_CMD_SET_USER_BYTE1
endcase
end
always @(posedge spck)
begin
if(~ncs)
begin
shift_reg[15:1] <= shift_reg[14:0];
shift_reg[0] <= mosi;
end
if(~ncs)
begin
shift_reg[15:1] <= shift_reg[14:0];
shift_reg[0] <= mosi;
end
end
wire [2:0] major_mode = conf_word[7:5];
@ -73,51 +73,51 @@ 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, lf_field
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, lf_field
);
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
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_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,
lf_ed_toggle_mode, lf_ed_threshold
pck0, 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,
lf_ed_toggle_mode, lf_ed_threshold
);
// Major modes:
// 000 -- LF reader (generic)
// 001 -- LF edge detect (generic)
// 010 -- LF passthrough
// 110 -- FPGA_MAJOR_MODE_OFF_LF (rdv40 specific)
// 110 -- FPGA_MAJOR_MODE_OFF_LF (rdv40 specific)
// 111 -- FPGA_MAJOR_MODE_OFF
// 000 001 010 011 100 101 110 111
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, lp_ssp_din, 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'b1, 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);
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, lp_ssp_din, 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'b1, 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;

View file

@ -1,9 +1,9 @@
//this code demodulates and modulates signal as described in ISO/IEC 18092. That includes packets used for Felica, NFC Tag 3, etc. (which do overlap)
//simple envelope following algorithm is used (modification of fail0verflow LF one) is used to combat some nasty aliasing effect with testing phone (envelope looked like sine wave)
//simple envelope following algorithm is used (modification of fail0verflow LF one) is used to combat some nasty aliasing effect with testing phone (envelope looked like sine wave)
// only 212 kbps (fc/64) for now 414 is relatively straightforward... though for reader, the selection has to come from ARM
// modulation waits for
//market sprocket -doesn't really mean anything ;)
// modulation waits for
//market sprocket -doesn't really mean anything ;)
//redefining mod_type: bits 210: bit 2 - reader drive/power on/off, bit 1 - speed bit, 0:212, 1 -424 bit 0: listen or modulate
@ -15,7 +15,7 @@ module hi_flite(
cross_hi, cross_lo,
dbg,
mod_type // used
);
input pck0, ck_1356meg, ck_1356megb;
output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
@ -33,7 +33,7 @@ wire speed= mod_type[1];
wire disabl= mod_type[0];
// Most off, oe4 for modulation;
// Trying reader emulation (would presumably just require switching power on, but I am not sure)
// Trying reader emulation (would presumably just require switching power on, but I am not sure)
//;// 1'b0;
assign pwr_lo = 1'b0;
@ -55,7 +55,7 @@ assign adc_clk = ck_1356meg;
//minimum values and corresponding thresholds
reg [8:0] curmin=`imin;
reg [8:0] curminthres=`ithrmin;
reg [8:0] curminthres=`ithrmin;
reg [8:0] curmaxthres=`ithrmax;
reg [8:0] curmax=`imax;
@ -103,37 +103,37 @@ always @(posedge adc_clk)
ssp_cnt <= (ssp_cnt + 1);
//maybe change it so that ARM sends preamble as well.
//then: ready bits sent to ARM, 8 bits sent from ARM (all ones), then preamble (all zeros, presumably) - which starts modulation
//then: ready bits sent to ARM, 8 bits sent from ARM (all ones), then preamble (all zeros, presumably) - which starts modulation
always @(negedge adc_clk)
begin
//count fc/64 - transfer bits to ARM at the rate they are received
if( ((~speed) && (ssp_cnt[5:0] == 6'b000000)) || (speed &&(ssp_cnt[4:0] == 5'b00000)))
begin
ssp_clk <= 1'b1;
ssp_clk <= 1'b1;
// if(mod_type[2])
// begin
// ssp_din<=outp[0];//after_hysteresis;
//outp<={1'b0,outp[7:1]};
//outp<={1'b0,outp[7:1]};
// end
// else
ssp_din <= curbit;
ssp_din <= curbit;
//sample ssp_dout
end
if( ( (~speed) && (ssp_cnt[5:0] == 6'b100000)) ||(speed && ssp_cnt[4:0] == 5'b10000))
ssp_clk <= 1'b0;
if( ( (~speed) && (ssp_cnt[5:0] == 6'b100000)) ||(speed && ssp_cnt[4:0] == 5'b10000))
ssp_clk <= 1'b0;
//create frame pulses. TBH, I still don't know what they do exactly, but they are crucial for ARM->FPGA transfer. If the frame is in the beginning of the byte, transfer slows to a crawl for some reason
// took me a day to figure THAT out.
// took me a day to figure THAT out.
if(( (~speed) && (ssp_cnt[8:0] == 9'd31))||(speed && ssp_cnt[7:0] == 8'd15))
begin
ssp_frame <= 1'b1;
ssp_frame <= 1'b1;
end
if(( (~speed) && (ssp_cnt[8:0] == 9'b1011111))||(speed &&ssp_cnt[7:0] == 8'b101111) )
begin
ssp_frame <= 1'b0;
ssp_frame <= 1'b0;
end
end
@ -141,23 +141,23 @@ end
//send current bit (detected in SNIFF mode or the one being modulated in MOD mode, 0 otherwise)
reg ssp_din;//= outp[0];
reg ssp_din;//= outp[0];
//previous signal value, mostly to detect SYNC
reg prv =1'b1;
reg[7:0] mid=8'd128; //for simple error correction in mod/demod detection, use maximum of modded/demodded in given interval. Maybe 1 bit is extra? but better safe than sorry.
reg[7:0] mid=8'd128; //for simple error correction in mod/demod detection, use maximum of modded/demodded in given interval. Maybe 1 bit is extra? but better safe than sorry.
// set TAGSIM__MODULATE on ARM if we want to write... (frame would get lost if done mid-frame...)
// start sending over 1s on ssp->arm when we start sending preamble
reg counting_desync=1'b0; // are we counting bits since last frame?
reg sending=1'b0; // are we actively modulating?
reg [11:0] bit_counts=12'd0;///for timeslots... only support ts=0 for now, at 212 speed -512 fullbits from end of frame. One hopes. might remove those?
reg counting_desync=1'b0; // are we counting bits since last frame?
reg sending=1'b0; // are we actively modulating?
reg [11:0] bit_counts=12'd0;///for timeslots... only support ts=0 for now, at 212 speed -512 fullbits from end of frame. One hopes. might remove those?
//reg [2:0]old_mod;
@ -166,19 +166,19 @@ reg [11:0] bit_counts=12'd0;///for timeslots... only support ts=0 for now, at 21
//begin
//if (mod_type[2]==1&&old_mod[2]==0)
// bit_counts=0;
//old_mod=mod_type;
//old_mod=mod_type;
//end
//we need some way to flush bit_counts triggers on mod_type changes don't compile
reg dlay;
always @(negedge adc_clk) //every data ping?
always @(negedge adc_clk) //every data ping?
begin
//envelope follow code...
////////////
//envelope follow code...
////////////
//move the counter to the outside...
// if (adc_d>=curminthres||try_sync)
// if (adc_d>=curminthres||try_sync)
if(fccount==bitmlen)
begin
begin
if((~try_sync)&&(adc_d<curminthres)&&disabl )
begin
fccount<=1;
@ -186,12 +186,12 @@ begin
else
begin
fccount<=0;
end
end
// if (counting_desync)
// begin
dlay<=ssp_dout;
if(bit_counts>768) // should be over ts0 now, without ARM interference... stop counting...
begin
begin
bit_counts<=0;
// counting_desync<=0;
end
@ -199,11 +199,11 @@ begin
if((power))
bit_counts<=0;
else
bit_counts<=bit_counts+1;
// end
bit_counts<=bit_counts+1;
// end
end
else
begin
begin
if((~try_sync)&&(adc_d<curminthres) &&disabl)
begin
fccount<=1;
@ -211,9 +211,9 @@ begin
else
begin
fccount<=fccount+1;
end
end
end
if (adc_d>curmaxthres) //rising edge
begin
case (state)
@ -230,38 +230,38 @@ begin
2: begin
if (adc_d>curmax)
curmax <= adc_d;
end
end
default:
begin
end
end
endcase
after_hysteresis <=1'b1;
if(try_sync)
tsinceedge<=0;
end
else if (adc_d<curminthres) //falling edge
begin
begin
case (state)
0: begin
curmin <=adc_d<`imin? adc_d :`imin;
curmin <=adc_d<`imin? adc_d :`imin;
state <=1;
end
1: begin
if (adc_d<curmin)
curmin <= adc_d;
curmin <= adc_d;
end
2: begin
curminthres <= ( (curmin>>1)+(curmin>>2)+(curmin>>4)+(curmax>>3)+(curmax>>4));
curmaxthres <= ( (curmax>>1)+(curmax>>2)+(curmax>>4)+(curmin>>3)+(curmin>>4));
curmin <=adc_d<`imin? adc_d :`imin;
state <=1;
end
state <=1;
end
default:
begin
end
endcase
end
endcase
after_hysteresis <=0;
if (~try_sync ) //begin modulation, lower edge...
if (~try_sync ) //begin modulation, lower edge...
begin
try_sync <=1;
//counting_desync<=1'b0;
@ -271,7 +271,7 @@ begin
mid <=8'd127;
tsinceedge<=0;
prv <=1;
end
end
else
begin
tsinceedge<=0;
@ -282,12 +282,12 @@ begin
curminthres <= ( (curmin>>1)+(curmin>>2)+(curmin>>4)+(curmax>>3)+(curmax>>4));
curmaxthres <= ( (curmax>>1)+(curmax>>2)+(curmax>>4)+(curmin>>3)+(curmin>>4));
state <=0;
if (try_sync )
begin
if (tsinceedge>=(128))
begin
//we might need to start counting... assuming ARM wants to reply to the frame.
//we might need to start counting... assuming ARM wants to reply to the frame.
// counting_desync<=1'b1;
bit_counts<=1;// i think? 128 is about 2 bits passed... but 1 also works
try_sync<=0;
@ -295,7 +295,7 @@ begin
curmin <=`imin; //reset envelope
curmax <=`imax;
curminthres <=`ithrmin;
curmaxthres <=`ithrmax;
curmaxthres <=`ithrmax;
prv <=1;
tsinceedge <=0;
after_hysteresis <=1'b1;
@ -305,33 +305,33 @@ begin
else
tsinceedge<=(tsinceedge+1);
end
end
end
if (try_sync && tsinceedge<128)
begin
//detect bits in their middle ssp sampling is in sync, so it would sample all bits in order
if (fccount==bithalf)
begin
if ((~did_sync) && ((prv==1&&(mid>128))||(prv==0&&(mid<=128))))
begin
begin
//sync the Zero, and set curbit roperly
did_sync <=1'b1;
zero <= ~prv;// 1-prv
curbit <=1;
end
else
end
else
curbit <= (mid>128) ? (~zero):zero;
prv <=(mid>128) ?1:0;
if(adc_d>curmaxthres)
prv <=(mid>128) ?1:0;
if(adc_d>curmaxthres)
mid <=8'd129;
else if (adc_d<curminthres)
else if (adc_d<curminthres)
mid <=8'd127;
else
else
begin
if (after_hysteresis)
begin
@ -342,24 +342,24 @@ begin
mid<=8'd127;
end
end
end
else
begin
else
begin
if (fccount==bitmlen)
begin
// fccount <=0;
prv <=(mid>128)?1:0;
prv <=(mid>128)?1:0;
mid <=128;
end
else
begin
// minimum-maximum calc
if(adc_d>curmaxthres)
if(adc_d>curmaxthres)
mid <=mid+1;
else if (adc_d<curminthres)
else if (adc_d<curminthres)
mid <=mid-1;
else
else
begin
if (after_hysteresis)
begin
@ -369,14 +369,14 @@ begin
begin
mid<=mid-1;
end
end
end
end
end
end
end
end
else
begin
end
sending <=0;
end
sending <=0;
end
//put modulation here to maintain the correct clock. Seems that some readers are sensitive to that
reg pwr_hi;
@ -398,7 +398,7 @@ if (power)
pwr_oe4 <= mod;//1'b0;
end
else
begin
begin
pwr_hi <= 1'b0;
pwr_oe1 <= 1'b0;
pwr_oe2 <= 1'b0;

View file

@ -4,11 +4,11 @@
//-----------------------------------------------------------------------------
// constants for the different modes:
`define SNIFFER 3'b000
`define TAGSIM_LISTEN 3'b001
`define TAGSIM_MOD 3'b010
`define READER_LISTEN 3'b011
`define READER_MOD 3'b100
`define SNIFFER 3'b000
`define TAGSIM_LISTEN 3'b001
`define TAGSIM_MOD 3'b010
`define READER_LISTEN 3'b011
`define READER_MOD 3'b100
module hi_iso14443a(
pck0, ck_1356meg, ck_1356megb,
@ -36,24 +36,24 @@ wire adc_clk = ck_1356meg;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Reader -> PM3:
// detecting and shaping the reader's signal. Reader will modulate the carrier by 100% (signal is either on or off). Use a
// detecting and shaping the reader's signal. Reader will modulate the carrier by 100% (signal is either on or off). Use a
// hysteresis (Schmitt Trigger) to avoid false triggers during slowly increasing or decreasing carrier amplitudes
reg after_hysteresis;
reg [11:0] has_been_low_for;
always @(negedge adc_clk)
begin
if(adc_d >= 16) after_hysteresis <= 1'b1; // U >= 1,14V -> after_hysteresis = 1
else if(adc_d < 8) after_hysteresis <= 1'b0; // U < 1,04V -> after_hysteresis = 0
// Note: was >= 3,53V and <= 1,19V. The new trigger values allow more reliable detection of the first bit
// (it might not reach 3,53V due to the high time constant of the high pass filter in the analogue RF part).
// In addition, the new values are more in line with ISO14443-2: "The PICC shall detect the ”End of Pause” after the field exceeds
// 5% of H_INITIAL and before it exceeds 60% of H_INITIAL." Depending on the signal strength, 60% might well be less than 3,53V.
// detecting a loss of reader's field (adc_d < 192 for 4096 clock cycles). If this is the case,
// set the detected reader signal (after_hysteresis) to '1' (unmodulated)
if(adc_d >= 192)
if(adc_d >= 16) after_hysteresis <= 1'b1; // U >= 1,14V -> after_hysteresis = 1
else if(adc_d < 8) after_hysteresis <= 1'b0; // U < 1,04V -> after_hysteresis = 0
// Note: was >= 3,53V and <= 1,19V. The new trigger values allow more reliable detection of the first bit
// (it might not reach 3,53V due to the high time constant of the high pass filter in the analogue RF part).
// In addition, the new values are more in line with ISO14443-2: "The PICC shall detect the ”End of Pause” after the field exceeds
// 5% of H_INITIAL and before it exceeds 60% of H_INITIAL." Depending on the signal strength, 60% might well be less than 3,53V.
// detecting a loss of reader's field (adc_d < 192 for 4096 clock cycles). If this is the case,
// set the detected reader signal (after_hysteresis) to '1' (unmodulated)
if(adc_d >= 192)
begin
has_been_low_for <= 12'd0;
end
@ -65,43 +65,43 @@ begin
after_hysteresis <= 1'b1;
end
else
begin
begin
has_been_low_for <= has_been_low_for + 1;
end
end
end
end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Reader -> PM3
// detect when a reader is active (modulating). We assume that the reader is active, if we see the carrier off for at least 8
// carrier cycles. We assume that the reader is inactive, if the carrier stayed high for at least 256 carrier cycles.
// detect when a reader is active (modulating). We assume that the reader is active, if we see the carrier off for at least 8
// carrier cycles. We assume that the reader is inactive, if the carrier stayed high for at least 256 carrier cycles.
reg deep_modulation;
reg [2:0] deep_counter;
reg [8:0] saw_deep_modulation;
always @(negedge adc_clk)
begin
if(~(| adc_d[7:0])) // if adc_d == 0 (U <= 0,94V)
begin
if(deep_counter == 3'd7) // adc_d == 0 for 8 adc_clk ticks -> deep_modulation (by reader)
begin
deep_modulation <= 1'b1;
saw_deep_modulation <= 8'd0;
end
else
deep_counter <= deep_counter + 1;
end
else
begin
deep_counter <= 3'd0;
if(saw_deep_modulation == 8'd255) // adc_d != 0 for 256 adc_clk ticks -> deep_modulation is over, probably waiting for tag's response
deep_modulation <= 1'b0;
else
saw_deep_modulation <= saw_deep_modulation + 1;
end
if(~(| adc_d[7:0])) // if adc_d == 0 (U <= 0,94V)
begin
if(deep_counter == 3'd7) // adc_d == 0 for 8 adc_clk ticks -> deep_modulation (by reader)
begin
deep_modulation <= 1'b1;
saw_deep_modulation <= 8'd0;
end
else
deep_counter <= deep_counter + 1;
end
else
begin
deep_counter <= 3'd0;
if(saw_deep_modulation == 8'd255) // adc_d != 0 for 256 adc_clk ticks -> deep_modulation is over, probably waiting for tag's response
deep_modulation <= 1'b0;
else
saw_deep_modulation <= saw_deep_modulation + 1;
end
end
@ -115,16 +115,16 @@ reg [7:0] input_prev_4, input_prev_3, input_prev_2, input_prev_1;
always @(negedge adc_clk)
begin
input_prev_4 <= input_prev_3;
input_prev_3 <= input_prev_2;
input_prev_2 <= input_prev_1;
input_prev_1 <= adc_d;
end
input_prev_4 <= input_prev_3;
input_prev_3 <= input_prev_2;
input_prev_2 <= input_prev_1;
input_prev_1 <= adc_d;
end
// adc_d_filtered = 2*input_prev4 + 1*input_prev3 + 0*input_prev2 - 1*input_prev1 - 2*input
// = (2*input_prev4 + input_prev3) - (2*input + input_prev1)
// = (2*input_prev4 + input_prev3) - (2*input + input_prev1)
wire [8:0] input_prev_4_times_2 = input_prev_4 << 1;
wire [8:0] adc_d_times_2 = adc_d << 1;
wire [8:0] adc_d_times_2 = adc_d << 1;
wire [9:0] tmp1 = input_prev_4_times_2 + input_prev_3;
wire [9:0] tmp2 = adc_d_times_2 + input_prev_1;
@ -133,49 +133,49 @@ wire [9:0] tmp2 = adc_d_times_2 + input_prev_1;
wire signed [10:0] adc_d_filtered = {1'b0, tmp1} - {1'b0, tmp2};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// internal FPGA timing. Maximum required period is 128 carrier clock cycles for a full 8 Bit transfer to ARM. (i.e. we need a
// internal FPGA timing. Maximum required period is 128 carrier clock cycles for a full 8 Bit transfer to ARM. (i.e. we need a
// 7 bit counter). Adjust its frequency to external reader's clock when simulating a tag or sniffing.
reg pre_after_hysteresis;
reg pre_after_hysteresis;
reg [3:0] reader_falling_edge_time;
reg [6:0] negedge_cnt;
always @(negedge adc_clk)
begin
// detect a reader signal's falling edge and remember its timing:
pre_after_hysteresis <= after_hysteresis;
if (pre_after_hysteresis && ~after_hysteresis)
begin
reader_falling_edge_time[3:0] <= negedge_cnt[3:0];
end
// detect a reader signal's falling edge and remember its timing:
pre_after_hysteresis <= after_hysteresis;
if (pre_after_hysteresis && ~after_hysteresis)
begin
reader_falling_edge_time[3:0] <= negedge_cnt[3:0];
end
// adjust internal timer counter if necessary:
if (negedge_cnt[3:0] == 4'd13 && (mod_type == `SNIFFER || mod_type == `TAGSIM_LISTEN) && deep_modulation)
begin
if (reader_falling_edge_time == 4'd1) // reader signal changes right after sampling. Better sample earlier next time.
begin
negedge_cnt <= negedge_cnt + 2; // time warp
end
else if (reader_falling_edge_time == 4'd0) // reader signal changes right before sampling. Better sample later next time.
begin
negedge_cnt <= negedge_cnt; // freeze time
end
else
begin
negedge_cnt <= negedge_cnt + 1; // Continue as usual
end
reader_falling_edge_time[3:0] <= 4'd8; // adjust only once per detected edge
end
else if (negedge_cnt == 7'd127) // normal operation: count from 0 to 127
begin
negedge_cnt <= 0;
end
else
begin
negedge_cnt <= negedge_cnt + 1;
end
end
// adjust internal timer counter if necessary:
if (negedge_cnt[3:0] == 4'd13 && (mod_type == `SNIFFER || mod_type == `TAGSIM_LISTEN) && deep_modulation)
begin
if (reader_falling_edge_time == 4'd1) // reader signal changes right after sampling. Better sample earlier next time.
begin
negedge_cnt <= negedge_cnt + 2; // time warp
end
else if (reader_falling_edge_time == 4'd0) // reader signal changes right before sampling. Better sample later next time.
begin
negedge_cnt <= negedge_cnt; // freeze time
end
else
begin
negedge_cnt <= negedge_cnt + 1; // Continue as usual
end
reader_falling_edge_time[3:0] <= 4'd8; // adjust only once per detected edge
end
else if (negedge_cnt == 7'd127) // normal operation: count from 0 to 127
begin
negedge_cnt <= 0;
end
else
begin
negedge_cnt <= negedge_cnt + 1;
end
end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -185,28 +185,28 @@ reg [3:0] mod_detect_reset_time;
always @(negedge adc_clk)
begin
if (mod_type == `READER_LISTEN)
// (our) reader signal changes at negedge_cnt[3:0]=9, tag response expected to start n*16+4 ticks later, further delayed by
// 3 ticks ADC conversion. The maximum filter output (edge detected) will be detected after subcarrier zero crossing (+7 ticks).
// To allow some timing variances, we want to have the maximum filter outputs well within the detection window, i.e.
// at mod_detect_reset_time+4 and mod_detect_reset_time+12 (-4 ticks).
// 9 + 4 + 3 + 7 - 4 = 19. 19 mod 16 = 3
begin
mod_detect_reset_time <= 4'd4;
end
else
if (mod_type == `SNIFFER)
begin
// detect a rising edge of reader's signal and sync modulation detector to the tag's answer:
if (~pre_after_hysteresis && after_hysteresis && deep_modulation)
// reader signal rising edge detected at negedge_cnt[3:0]. This signal had been delayed
// 9 ticks by the RF part + 3 ticks by the A/D converter + 1 tick to assign to after_hysteresis.
// Then the same as above.
// - 9 - 3 - 1 + 4 + 3 + 7 - 4 = -3
begin
mod_detect_reset_time <= negedge_cnt[3:0] - 4'd3;
end
end
if (mod_type == `READER_LISTEN)
// (our) reader signal changes at negedge_cnt[3:0]=9, tag response expected to start n*16+4 ticks later, further delayed by
// 3 ticks ADC conversion. The maximum filter output (edge detected) will be detected after subcarrier zero crossing (+7 ticks).
// To allow some timing variances, we want to have the maximum filter outputs well within the detection window, i.e.
// at mod_detect_reset_time+4 and mod_detect_reset_time+12 (-4 ticks).
// 9 + 4 + 3 + 7 - 4 = 19. 19 mod 16 = 3
begin
mod_detect_reset_time <= 4'd4;
end
else
if (mod_type == `SNIFFER)
begin
// detect a rising edge of reader's signal and sync modulation detector to the tag's answer:
if (~pre_after_hysteresis && after_hysteresis && deep_modulation)
// reader signal rising edge detected at negedge_cnt[3:0]. This signal had been delayed
// 9 ticks by the RF part + 3 ticks by the A/D converter + 1 tick to assign to after_hysteresis.
// Then the same as above.
// - 9 - 3 - 1 + 4 + 3 + 7 - 4 = -3
begin
mod_detect_reset_time <= negedge_cnt[3:0] - 4'd3;
end
end
end
@ -218,34 +218,34 @@ reg signed [10:0] rx_mod_falling_edge_max;
reg signed [10:0] rx_mod_rising_edge_max;
reg curbit;
`define EDGE_DETECT_THRESHOLD 5
`define EDGE_DETECT_THRESHOLD 5
always @(negedge adc_clk)
begin
if(negedge_cnt[3:0] == mod_detect_reset_time)
begin
// detect modulation signal: if modulating, there must have been a falling AND a rising edge
if ((rx_mod_falling_edge_max > `EDGE_DETECT_THRESHOLD) && (rx_mod_rising_edge_max < -`EDGE_DETECT_THRESHOLD))
curbit <= 1'b1; // modulation
else
curbit <= 1'b0; // no modulation
// reset modulation detector
rx_mod_rising_edge_max <= 0;
rx_mod_falling_edge_max <= 0;
end
else // look for steepest edges (slopes)
begin
if (adc_d_filtered > 0)
begin
if (adc_d_filtered > rx_mod_falling_edge_max)
rx_mod_falling_edge_max <= adc_d_filtered;
end
else
begin
if (adc_d_filtered < rx_mod_rising_edge_max)
rx_mod_rising_edge_max <= adc_d_filtered;
end
end
if(negedge_cnt[3:0] == mod_detect_reset_time)
begin
// detect modulation signal: if modulating, there must have been a falling AND a rising edge
if ((rx_mod_falling_edge_max > `EDGE_DETECT_THRESHOLD) && (rx_mod_rising_edge_max < -`EDGE_DETECT_THRESHOLD))
curbit <= 1'b1; // modulation
else
curbit <= 1'b0; // no modulation
// reset modulation detector
rx_mod_rising_edge_max <= 0;
rx_mod_falling_edge_max <= 0;
end
else // look for steepest edges (slopes)
begin
if (adc_d_filtered > 0)
begin
if (adc_d_filtered > rx_mod_falling_edge_max)
rx_mod_falling_edge_max <= adc_d_filtered;
end
else
begin
if (adc_d_filtered < rx_mod_rising_edge_max)
rx_mod_rising_edge_max <= adc_d_filtered;
end
end
end
@ -260,11 +260,11 @@ reg [3:0] tag_data;
always @(negedge adc_clk)
begin
if(negedge_cnt[3:0] == 4'd0)
begin
begin
reader_data[3:0] <= {reader_data[2:0], after_hysteresis};
tag_data[3:0] <= {tag_data[2:0], curbit};
end
end
tag_data[3:0] <= {tag_data[2:0], curbit};
end
end
@ -277,17 +277,17 @@ reg mod_sig;
always @(negedge adc_clk)
begin
if(negedge_cnt[3:0] == 4'd0) // sample data at rising edge of ssp_clk - ssp_dout changes at the falling edge.
begin
mod_sig_buf[31:2] <= mod_sig_buf[30:1]; // shift
if (~ssp_dout && ~mod_sig_buf[1])
mod_sig_buf[1] <= 1'b0; // delete the correction bit (a single 1 preceded and succeeded by 0)
else
mod_sig_buf[1] <= mod_sig_buf[0];
mod_sig_buf[0] <= ssp_dout; // add new data to the delay line
if(negedge_cnt[3:0] == 4'd0) // sample data at rising edge of ssp_clk - ssp_dout changes at the falling edge.
begin
mod_sig_buf[31:2] <= mod_sig_buf[30:1]; // shift
if (~ssp_dout && ~mod_sig_buf[1])
mod_sig_buf[1] <= 1'b0; // delete the correction bit (a single 1 preceded and succeeded by 0)
else
mod_sig_buf[1] <= mod_sig_buf[0];
mod_sig_buf[0] <= ssp_dout; // add new data to the delay line
mod_sig = mod_sig_buf[mod_sig_ptr]; // the delayed signal.
end
mod_sig = mod_sig_buf[mod_sig_ptr]; // the delayed signal.
end
end
@ -297,7 +297,7 @@ end
// a timer for the 1172 cycles fdt (Frame Delay Time). Start the timer with a rising edge of the reader's signal.
// set fdt_elapsed when we no longer need to delay data. Set fdt_indicator when we can start sending data.
// Note: the FPGA only takes care for the 1172 delay. To achieve an additional 1236-1172=64 ticks delay, the ARM must send
// a correction bit (before the start bit). The correction bit will be coded as 00010000, i.e. it adds 4 bits to the
// a correction bit (before the start bit). The correction bit will be coded as 00010000, i.e. it adds 4 bits to the
// transmission stream, causing the required additional delay.
reg [10:0] fdt_counter;
reg fdt_indicator, fdt_elapsed;
@ -317,41 +317,41 @@ reg [3:0] sub_carrier_cnt;
`define FDT_INDICATOR_COUNT 11'd647
// Note: worst case, assignment to sendbit takes 15 ticks more, and transfer to ARM needs 7*16 = 112 ticks more.
// When the ARM's response then appears, the fdt_count is already 647 + 15 + 112 = 774, which still allows the ARM a possible
// response window of 1128 - 774 = 354 ticks.
// response window of 1128 - 774 = 354 ticks.
// reset on a pause in listen mode. I.e. the counter starts when the pause is over:
assign fdt_reset = ~after_hysteresis && mod_type == `TAGSIM_LISTEN;
always @(negedge adc_clk)
begin
if (fdt_reset)
begin
fdt_counter <= 11'd0;
fdt_elapsed <= 1'b0;
fdt_indicator <= 1'b0;
end
else
begin
if(fdt_counter == `FDT_COUNT)
begin
if(~fdt_elapsed) // just reached fdt.
begin
mod_sig_flip <= negedge_cnt[3:0]; // start modulation at this time
sub_carrier_cnt <= 4'd0; // subcarrier phase in sync with start of modulation
fdt_elapsed <= 1'b1;
end
else
begin
sub_carrier_cnt <= sub_carrier_cnt + 1;
end
end
else
begin
fdt_counter <= fdt_counter + 1;
end
end
if(fdt_counter == `FDT_INDICATOR_COUNT) fdt_indicator <= 1'b1;
if (fdt_reset)
begin
fdt_counter <= 11'd0;
fdt_elapsed <= 1'b0;
fdt_indicator <= 1'b0;
end
else
begin
if(fdt_counter == `FDT_COUNT)
begin
if(~fdt_elapsed) // just reached fdt.
begin
mod_sig_flip <= negedge_cnt[3:0]; // start modulation at this time
sub_carrier_cnt <= 4'd0; // subcarrier phase in sync with start of modulation
fdt_elapsed <= 1'b1;
end
else
begin
sub_carrier_cnt <= sub_carrier_cnt + 1;
end
end
else
begin
fdt_counter <= fdt_counter + 1;
end
end
if(fdt_counter == `FDT_INDICATOR_COUNT) fdt_indicator <= 1'b1;
end
@ -363,24 +363,24 @@ reg mod_sig_coil;
always @(negedge adc_clk)
begin
if (mod_type == `TAGSIM_MOD) // need to take care of proper fdt timing
begin
if(fdt_counter == `FDT_COUNT)
begin
if(fdt_elapsed)
begin
if(negedge_cnt[3:0] == mod_sig_flip) mod_sig_coil <= mod_sig;
end
else
begin
mod_sig_coil <= mod_sig; // just reached fdt. Immediately assign signal to coil
end
end
end
else // other modes: don't delay
begin
mod_sig_coil <= ssp_dout;
end
if (mod_type == `TAGSIM_MOD) // need to take care of proper fdt timing
begin
if(fdt_counter == `FDT_COUNT)
begin
if(fdt_elapsed)
begin
if(negedge_cnt[3:0] == mod_sig_flip) mod_sig_coil <= mod_sig;
end
else
begin
mod_sig_coil <= mod_sig; // just reached fdt. Immediately assign signal to coil
end
end
end
else // other modes: don't delay
begin
mod_sig_coil <= ssp_dout;
end
end
@ -392,39 +392,39 @@ reg temp_buffer_reset;
always @(negedge adc_clk)
begin
if(fdt_reset)
begin
mod_sig_ptr <= 5'd0;
temp_buffer_reset = 1'b0;
end
else
begin
if(fdt_counter == `FDT_COUNT && ~fdt_elapsed) // if we just reached fdt
if(~(| mod_sig_ptr[4:0]))
mod_sig_ptr <= 5'd8; // ... but didn't buffer a 1 yet, delay next 1 by n*128 ticks.
else
temp_buffer_reset = 1'b1; // else no need for further delays.
if(fdt_reset)
begin
mod_sig_ptr <= 5'd0;
temp_buffer_reset = 1'b0;
end
else
begin
if(fdt_counter == `FDT_COUNT && ~fdt_elapsed) // if we just reached fdt
if(~(| mod_sig_ptr[4:0]))
mod_sig_ptr <= 5'd8; // ... but didn't buffer a 1 yet, delay next 1 by n*128 ticks.
else
temp_buffer_reset = 1'b1; // else no need for further delays.
if(negedge_cnt[3:0] == 4'd0) // at rising edge of ssp_clk - ssp_dout changes at the falling edge.
begin
if((ssp_dout || (| mod_sig_ptr[4:0])) && ~fdt_elapsed) // buffer a 1 (and all subsequent data) until fdt is reached.
if (mod_sig_ptr == 5'd31)
mod_sig_ptr <= 5'd0; // buffer overflow - data loss.
else
mod_sig_ptr <= mod_sig_ptr + 1; // increase buffer (= increase delay by 16 adc_clk ticks). mod_sig_ptr always points ahead of first 1.
else if(fdt_elapsed && ~temp_buffer_reset)
begin
// wait for the next 1 after fdt_elapsed before fixing the delay and starting modulation. This ensures that the response can only happen
// at intervals of 8 * 16 = 128 adc_clk ticks (as defined in ISO14443-3)
if(ssp_dout)
temp_buffer_reset = 1'b1;
if(mod_sig_ptr == 5'd1)
mod_sig_ptr <= 5'd8; // still nothing received, need to go for the next interval
else
mod_sig_ptr <= mod_sig_ptr - 1; // decrease buffer.
end
end
end
if(negedge_cnt[3:0] == 4'd0) // at rising edge of ssp_clk - ssp_dout changes at the falling edge.
begin
if((ssp_dout || (| mod_sig_ptr[4:0])) && ~fdt_elapsed) // buffer a 1 (and all subsequent data) until fdt is reached.
if (mod_sig_ptr == 5'd31)
mod_sig_ptr <= 5'd0; // buffer overflow - data loss.
else
mod_sig_ptr <= mod_sig_ptr + 1; // increase buffer (= increase delay by 16 adc_clk ticks). mod_sig_ptr always points ahead of first 1.
else if(fdt_elapsed && ~temp_buffer_reset)
begin
// wait for the next 1 after fdt_elapsed before fixing the delay and starting modulation. This ensures that the response can only happen
// at intervals of 8 * 16 = 128 adc_clk ticks (as defined in ISO14443-3)
if(ssp_dout)
temp_buffer_reset = 1'b1;
if(mod_sig_ptr == 5'd1)
mod_sig_ptr <= 5'd8; // still nothing received, need to go for the next interval
else
mod_sig_ptr <= mod_sig_ptr - 1; // decrease buffer.
end
end
end
end
@ -436,43 +436,43 @@ reg [7:0] to_arm;
always @(negedge adc_clk)
begin
if (negedge_cnt[5:0] == 6'd63) // fill the buffer
begin
if (mod_type == `SNIFFER)
begin
if(deep_modulation) // a reader is sending (or there's no field at all)
begin
to_arm <= {reader_data[3:0], 4'b0000}; // don't send tag data
end
else
begin
to_arm <= {reader_data[3:0], tag_data[3:0]};
end
end
else
begin
to_arm[7:0] <= {mod_sig_ptr[4:0], mod_sig_flip[3:1]}; // feedback timing information
end
end
if (negedge_cnt[5:0] == 6'd63) // fill the buffer
begin
if (mod_type == `SNIFFER)
begin
if(deep_modulation) // a reader is sending (or there's no field at all)
begin
to_arm <= {reader_data[3:0], 4'b0000}; // don't send tag data
end
else
begin
to_arm <= {reader_data[3:0], tag_data[3:0]};
end
end
else
begin
to_arm[7:0] <= {mod_sig_ptr[4:0], mod_sig_flip[3:1]}; // feedback timing information
end
end
if(negedge_cnt[2:0] == 3'b000 && mod_type == `SNIFFER) // shift at double speed
begin
// Don't shift if we just loaded new data, obviously.
if(negedge_cnt[5:0] != 6'd0)
begin
to_arm[7:1] <= to_arm[6:0];
end
end
if(negedge_cnt[2:0] == 3'b000 && mod_type == `SNIFFER) // shift at double speed
begin
// Don't shift if we just loaded new data, obviously.
if(negedge_cnt[5:0] != 6'd0)
begin
to_arm[7:1] <= to_arm[6:0];
end
end
if(negedge_cnt[3:0] == 4'b0000 && mod_type != `SNIFFER)
begin
// Don't shift if we just loaded new data, obviously.
if(negedge_cnt[6:0] != 7'd0)
begin
to_arm[7:1] <= to_arm[6:0];
end
end
if(negedge_cnt[3:0] == 4'b0000 && mod_type != `SNIFFER)
begin
// Don't shift if we just loaded new data, obviously.
if(negedge_cnt[6:0] != 7'd0)
begin
to_arm[7:1] <= to_arm[6:0];
end
end
end
@ -484,32 +484,32 @@ reg ssp_frame;
always @(negedge adc_clk)
begin
if(mod_type == `SNIFFER)
// SNIFFER mode (ssp_clk = adc_clk / 8, ssp_frame clock = adc_clk / 64)):
begin
if(negedge_cnt[2:0] == 3'd0)
ssp_clk <= 1'b1;
if(negedge_cnt[2:0] == 3'd4)
ssp_clk <= 1'b0;
if(mod_type == `SNIFFER)
// SNIFFER mode (ssp_clk = adc_clk / 8, ssp_frame clock = adc_clk / 64)):
begin
if(negedge_cnt[2:0] == 3'd0)
ssp_clk <= 1'b1;
if(negedge_cnt[2:0] == 3'd4)
ssp_clk <= 1'b0;
if(negedge_cnt[5:0] == 6'd0) // ssp_frame rising edge indicates start of frame
ssp_frame <= 1'b1;
if(negedge_cnt[5:0] == 6'd8)
ssp_frame <= 1'b0;
end
else
// all other modes (ssp_clk = adc_clk / 16, ssp_frame clock = adc_clk / 128):
begin
if(negedge_cnt[3:0] == 4'd0)
ssp_clk <= 1'b1;
if(negedge_cnt[3:0] == 4'd8)
ssp_clk <= 1'b0;
if(negedge_cnt[5:0] == 6'd0) // ssp_frame rising edge indicates start of frame
ssp_frame <= 1'b1;
if(negedge_cnt[5:0] == 6'd8)
ssp_frame <= 1'b0;
end
else
// all other modes (ssp_clk = adc_clk / 16, ssp_frame clock = adc_clk / 128):
begin
if(negedge_cnt[3:0] == 4'd0)
ssp_clk <= 1'b1;
if(negedge_cnt[3:0] == 4'd8)
ssp_clk <= 1'b0;
if(negedge_cnt[6:0] == 7'd7) // ssp_frame rising edge indicates start of frame
ssp_frame <= 1'b1;
if(negedge_cnt[6:0] == 7'd23)
ssp_frame <= 1'b0;
end
if(negedge_cnt[6:0] == 7'd7) // ssp_frame rising edge indicates start of frame
ssp_frame <= 1'b1;
if(negedge_cnt[6:0] == 7'd23)
ssp_frame <= 1'b0;
end
end
@ -522,31 +522,31 @@ reg sendbit;
always @(negedge adc_clk)
begin
if(negedge_cnt[3:0] == 4'd0)
begin
// What do we communicate to the ARM
if(mod_type == `TAGSIM_LISTEN)
sendbit = after_hysteresis;
else if(mod_type == `TAGSIM_MOD)
/* if(fdt_counter > 11'd772) sendbit = mod_sig_coil; // huh?
else */
sendbit = fdt_indicator;
else if (mod_type == `READER_LISTEN)
sendbit = curbit;
else
sendbit = 1'b0;
end
if(negedge_cnt[3:0] == 4'd0)
begin
// What do we communicate to the ARM
if(mod_type == `TAGSIM_LISTEN)
sendbit = after_hysteresis;
else if(mod_type == `TAGSIM_MOD)
/* if(fdt_counter > 11'd772) sendbit = mod_sig_coil; // huh?
else */
sendbit = fdt_indicator;
else if (mod_type == `READER_LISTEN)
sendbit = curbit;
else
sendbit = 1'b0;
end
if(mod_type == `SNIFFER)
// send sampled reader and tag data:
bit_to_arm = to_arm[7];
else if (mod_type == `TAGSIM_MOD && fdt_elapsed && temp_buffer_reset)
// send timing information:
bit_to_arm = to_arm[7];
else
// send data or fdt_indicator
bit_to_arm = sendbit;
if(mod_type == `SNIFFER)
// send sampled reader and tag data:
bit_to_arm = to_arm[7];
else if (mod_type == `TAGSIM_MOD && fdt_elapsed && temp_buffer_reset)
// send timing information:
bit_to_arm = to_arm[7];
else
// send data or fdt_indicator
bit_to_arm = sendbit;
end
@ -559,7 +559,7 @@ wire sub_carrier;
assign sub_carrier = ~sub_carrier_cnt[3];
// in READER_MOD: drop carrier for mod_sig_coil==1 (pause); in READER_LISTEN: carrier always on; in other modes: carrier always off
assign pwr_hi = (ck_1356megb & (((mod_type == `READER_MOD) & ~mod_sig_coil) || (mod_type == `READER_LISTEN)));
assign pwr_hi = (ck_1356megb & (((mod_type == `READER_MOD) & ~mod_sig_coil) || (mod_type == `READER_LISTEN)));
// Enable HF antenna drivers:
@ -567,8 +567,8 @@ assign pwr_oe1 = 1'b0;
assign pwr_oe3 = 1'b0;
// TAGSIM_MOD: short circuit antenna with different resistances (modulated by sub_carrier modulated by mod_sig_coil)
// for pwr_oe4 = 1 (tristate): antenna load = 10k || 33 = 32,9 Ohms
// for pwr_oe4 = 0 (active): antenna load = 10k || 33 || 33 = 16,5 Ohms
// for pwr_oe4 = 1 (tristate): antenna load = 10k || 33 = 32,9 Ohms
// for pwr_oe4 = 0 (active): antenna load = 10k || 33 || 33 = 16,5 Ohms
assign pwr_oe4 = mod_sig_coil & sub_carrier & (mod_type == `TAGSIM_MOD);
// This is all LF, so doesn't matter.

View file

@ -32,16 +32,16 @@ reg [2:0] fc_div;
always @(negedge ck_1356megb)
fc_div <= fc_div + 1;
(* clock_signal = "yes" *) reg adc_clk; // sample frequency, always 16 * fc
(* clock_signal = "yes" *) reg adc_clk; // sample frequency, always 16 * fc
always @(ck_1356megb, xcorr_is_848, xcorr_quarter_freq, fc_div)
if (xcorr_is_848 & ~xcorr_quarter_freq) // fc = 847.5 kHz, standard ISO14443B
adc_clk <= ck_1356megb;
else if (~xcorr_is_848 & ~xcorr_quarter_freq) // fc = 423.75 kHz
adc_clk <= fc_div[0];
else if (xcorr_is_848 & xcorr_quarter_freq) // fc = 211.875 kHz
adc_clk <= fc_div[1];
else // fc = 105.9375 kHz
adc_clk <= fc_div[2];
if (xcorr_is_848 & ~xcorr_quarter_freq) // fc = 847.5 kHz, standard ISO14443B
adc_clk <= ck_1356megb;
else if (~xcorr_is_848 & ~xcorr_quarter_freq) // fc = 423.75 kHz
adc_clk <= fc_div[0];
else if (xcorr_is_848 & xcorr_quarter_freq) // fc = 211.875 kHz
adc_clk <= fc_div[1];
else // fc = 105.9375 kHz
adc_clk <= fc_div[2];
// 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,
@ -94,9 +94,9 @@ reg ssp_frame;
always @(negedge adc_clk)
begin
corr_i_cnt <= corr_i_cnt + 1;
end
corr_i_cnt <= corr_i_cnt + 1;
end
// ADC data appears on the rising edge, so sample it on the falling edge
always @(negedge adc_clk)
@ -147,7 +147,7 @@ begin
else
corr_i_accum <= corr_i_accum + adc_d;
if(corr_i_cnt[3] == corr_i_cnt[2]) // phase shifted by pi/2
if(corr_i_cnt[3] == corr_i_cnt[2]) // phase shifted by pi/2
corr_q_accum <= corr_q_accum + adc_d;
else
corr_q_accum <= corr_q_accum - adc_d;
@ -177,8 +177,8 @@ begin
end
end
// set ssp_frame signal for corr_i_cnt = 0..3 and corr_i_cnt = 32..35
// (send two frames with 8 Bits each)
// set ssp_frame signal for corr_i_cnt = 0..3 and corr_i_cnt = 32..35
// (send two frames with 8 Bits each)
if(corr_i_cnt[5:2] == 4'b0000 || corr_i_cnt[5:2] == 4'b1000)
ssp_frame = 1'b1;
else

View file

@ -27,7 +27,7 @@ module hi_read_tx(
// low frequency outputs, not relevant
assign pwr_lo = 1'b0;
assign pwr_oe2 = 1'b0;
// 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;
@ -75,4 +75,4 @@ assign ssp_din = 1'b0;
assign dbg = ssp_frame;
endmodule
endmodule

View file

@ -1,7 +1,7 @@
//-----------------------------------------------------------------------------
// 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.
// 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

View file

@ -9,69 +9,69 @@
`include "min_max_tracker.v"
module lf_edge_detect(input clk, input [7:0] adc_d, input [7:0] lf_ed_threshold,
output [7:0] max, output [7:0] min,
output [7:0] high_threshold, output [7:0] highz_threshold,
output [7:0] lowz_threshold, output [7:0] low_threshold,
output edge_state, output edge_toggle);
output [7:0] max, output [7:0] min,
output [7:0] high_threshold, output [7:0] highz_threshold,
output [7:0] lowz_threshold, output [7:0] low_threshold,
output edge_state, output edge_toggle);
min_max_tracker tracker(clk, adc_d, lf_ed_threshold, min, max);
min_max_tracker tracker(clk, adc_d, lf_ed_threshold, min, max);
// auto-tune
assign high_threshold = (max + min) / 2 + (max - min) / 4;
assign highz_threshold = (max + min) / 2 + (max - min) / 8;
assign lowz_threshold = (max + min) / 2 - (max - min) / 8;
assign low_threshold = (max + min) / 2 - (max - min) / 4;
// auto-tune
assign high_threshold = (max + min) / 2 + (max - min) / 4;
assign highz_threshold = (max + min) / 2 + (max - min) / 8;
assign lowz_threshold = (max + min) / 2 - (max - min) / 8;
assign low_threshold = (max + min) / 2 - (max - min) / 4;
// heuristic to see if it makes sense to try to detect an edge
wire enabled =
(high_threshold > highz_threshold)
& (highz_threshold > lowz_threshold)
& (lowz_threshold > low_threshold)
& ((high_threshold - highz_threshold) > 8)
& ((highz_threshold - lowz_threshold) > 16)
& ((lowz_threshold - low_threshold) > 8);
// heuristic to see if it makes sense to try to detect an edge
wire enabled =
(high_threshold > highz_threshold)
& (highz_threshold > lowz_threshold)
& (lowz_threshold > low_threshold)
& ((high_threshold - highz_threshold) > 8)
& ((highz_threshold - lowz_threshold) > 16)
& ((lowz_threshold - low_threshold) > 8);
// Toggle the output with hysteresis
// Set to high if the ADC value is above the threshold
// Set to low if the ADC value is below the threshold
reg is_high = 0;
reg is_low = 0;
reg is_zero = 0;
reg trigger_enabled = 1;
reg output_edge = 0;
reg output_state;
// Toggle the output with hysteresis
// Set to high if the ADC value is above the threshold
// Set to low if the ADC value is below the threshold
reg is_high = 0;
reg is_low = 0;
reg is_zero = 0;
reg trigger_enabled = 1;
reg output_edge = 0;
reg output_state;
always @(posedge clk)
begin
is_high <= (adc_d >= high_threshold);
is_low <= (adc_d <= low_threshold);
is_zero <= ((adc_d > lowz_threshold) & (adc_d < highz_threshold));
end
always @(posedge clk)
begin
is_high <= (adc_d >= high_threshold);
is_low <= (adc_d <= low_threshold);
is_zero <= ((adc_d > lowz_threshold) & (adc_d < highz_threshold));
end
// all edges detection
always @(posedge clk)
if (enabled) begin
// To enable detecting two consecutive peaks at the same level
// (low or high) we check whether or not we went back near 0 in-between.
// This extra check is necessary to prevent from noise artifacts
// around the threshold values.
if (trigger_enabled & (is_high | is_low)) begin
output_edge <= ~output_edge;
trigger_enabled <= 0;
end else
trigger_enabled <= trigger_enabled | is_zero;
end
// all edges detection
always @(posedge clk)
if (enabled) begin
// To enable detecting two consecutive peaks at the same level
// (low or high) we check whether or not we went back near 0 in-between.
// This extra check is necessary to prevent from noise artifacts
// around the threshold values.
if (trigger_enabled & (is_high | is_low)) begin
output_edge <= ~output_edge;
trigger_enabled <= 0;
end else
trigger_enabled <= trigger_enabled | is_zero;
end
// edge states
always @(posedge clk)
if (enabled) begin
if (is_high)
output_state <= 1'd1;
else if (is_low)
output_state <= 1'd0;
end
// edge states
always @(posedge clk)
if (enabled) begin
if (is_high)
output_state <= 1'd1;
else if (is_low)
output_state <= 1'd0;
end
assign edge_state = output_state;
assign edge_toggle = output_edge;
assign edge_state = output_state;
assign edge_toggle = output_edge;
endmodule

View file

@ -35,11 +35,11 @@ wire tag_modulation = ssp_dout & !lf_field;
wire reader_modulation = !ssp_dout & lf_field & pck_divclk;
// No logic, straight through.
assign pwr_oe1 = 1'b0; // not used in LF mode
assign pwr_oe3 = 1'b0; // base antenna load = 33 Ohms
assign pwr_oe1 = 1'b0; // not used in LF mode
assign pwr_oe3 = 1'b0; // base antenna load = 33 Ohms
// when modulating, add another 33 Ohms and 10k Ohms in parallel:
assign pwr_oe2 = tag_modulation;
assign pwr_oe4 = tag_modulation;
assign pwr_oe4 = tag_modulation;
assign ssp_clk = cross_lo;
assign pwr_lo = reader_modulation;
@ -56,9 +56,9 @@ wire [7:0] high_threshold, highz_threshold, lowz_threshold, low_threshold;
wire [7:0] max, min;
wire edge_state, edge_toggle;
lf_edge_detect lf_ed(pck0, adc_filtered, lf_ed_threshold,
max, min,
high_threshold, highz_threshold, lowz_threshold, low_threshold,
edge_state, edge_toggle);
max, min,
high_threshold, highz_threshold, lowz_threshold, low_threshold,
edge_state, edge_toggle);
assign dbg = lf_ed_toggle_mode ? edge_toggle : edge_state;

View file

@ -5,13 +5,13 @@
// iZsh <izsh at fail0verflow.com>, June 2014
module lo_passthru(
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 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
);
// the antenna is modulated when ssp_dout = 1, when 0 the

View file

@ -8,13 +8,13 @@
//-----------------------------------------------------------------------------
module lo_read(
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 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, output ssp_din, output ssp_clk,
output dbg,
input lf_field
);
reg [7:0] to_arm_shiftreg;
@ -27,17 +27,17 @@ reg [7:0] to_arm_shiftreg;
// we read the ADC value when pck_cnt=7 and shift it out on counts 8..15
always @(posedge pck0)
begin
if((pck_cnt == 8'd7) && !pck_divclk)
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
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;
end
end
// ADC samples on falling edge of adc_clk, data available on the rising edge

View file

@ -13,7 +13,7 @@ module lo_simulate(
ssp_frame, ssp_din, ssp_dout, ssp_clk,
cross_hi, cross_lo,
dbg,
divisor
divisor
);
input pck0, ck_1356meg, ck_1356megb;
output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
@ -23,7 +23,7 @@ module lo_simulate(
output ssp_frame, ssp_din, ssp_clk;
input cross_hi, cross_lo;
output dbg;
input [7:0] divisor;
input [7:0] divisor;
// No logic, straight through.
assign pwr_oe3 = 1'b0;
@ -41,15 +41,15 @@ reg clk_state;
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
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;
@ -63,18 +63,18 @@ reg output_state;
always @(posedge pck0)
begin
if((pck_divider == 8'd7) && !clk_state) begin
is_high = (adc_d >= 8'd191);
is_low = (adc_d <= 8'd64);
end
if((pck_divider == 8'd7) && !clk_state) begin
is_high = (adc_d >= 8'd191);
is_low = (adc_d <= 8'd64);
end
end
always @(posedge is_high or posedge is_low)
begin
if(is_high)
output_state <= 1'd1;
else if(is_low)
output_state <= 1'd0;
if(is_high)
output_state <= 1'd1;
else if(is_low)
output_state <= 1'd0;
end
assign ssp_frame = output_state;

View file

@ -28,54 +28,54 @@
// https://fail0verflow.com/blog/2014/proxmark3-fpga-iir-filter.html
module lp20khz_1MSa_iir_filter(input clk, input [7:0] adc_d, output rdy, output [7:0] out);
// clk is 24Mhz, the IIR filter is designed for 1MS/s
// hence we need to divide it by 24
// using a shift register takes less area than a counter
reg [23:0] cnt = 1;
assign rdy = cnt[0];
always @(posedge clk)
cnt <= {cnt[22:0], cnt[23]};
// clk is 24Mhz, the IIR filter is designed for 1MS/s
// hence we need to divide it by 24
// using a shift register takes less area than a counter
reg [23:0] cnt = 1;
assign rdy = cnt[0];
always @(posedge clk)
cnt <= {cnt[22:0], cnt[23]};
reg [7:0] x0 = 0;
reg [7:0] x1 = 0;
reg [16:0] y0 = 0;
reg [16:0] y1 = 0;
reg [7:0] x0 = 0;
reg [7:0] x1 = 0;
reg [16:0] y0 = 0;
reg [16:0] y1 = 0;
always @(posedge clk)
begin
if (rdy)
begin
x0 <= x1;
x1 <= adc_d;
y0 <= y1;
y1 <=
// center the signal:
// input range is [0; 255]
// We want "128" to be at the center of the 17bit register
// (128+z)*gain = 17bit center
// z = (1<<16)/gain - 128 = 109
// We could use 9bit x registers for that, but that would be
// a waste, let's just add the constant during the computation
// (x0+109) + 2*(x1+109) + (x2+109) = x0 + 2*x1 + x2 + 436
x0 + {x1, 1'b0} + adc_d + 436
// we want "- y0 * 0xd6 / 0x100" using only shift and add
// 0xd6 == 0b11010110
// so *0xd6/0x100 is equivalent to
// ((x << 1) + (x << 2) + (x << 4) + (x << 6) + (x << 7)) >> 8
// which is also equivalent to
// (x >> 7) + (x >> 6) + (x >> 4) + (x >> 2) + (x >> 1)
- ((y0 >> 7) + (y0 >> 6) + (y0 >> 4) + (y0 >> 2) + (y0 >> 1)) // - y0 * 0xd6 / 0x100
// we want "+ y1 * 0x1d3 / 0x100"
// 0x1d3 == 0b111010011
// so this is equivalent to
// ((x << 0) + (x << 1) + (x << 4) + (x << 6) + (x << 7) + (x << 8)) >> 8
// which is also equivalent to
// (x >> 8) + (x >> 7) + (x >> 4) + (x >> 2) + (x >> 1) + (x >> 0)
+ ((y1 >> 8) + (y1 >> 7) + (y1 >> 4) + (y1 >> 2) + (y1 >> 1) + y1);
end
end
always @(posedge clk)
begin
if (rdy)
begin
x0 <= x1;
x1 <= adc_d;
y0 <= y1;
y1 <=
// center the signal:
// input range is [0; 255]
// We want "128" to be at the center of the 17bit register
// (128+z)*gain = 17bit center
// z = (1<<16)/gain - 128 = 109
// We could use 9bit x registers for that, but that would be
// a waste, let's just add the constant during the computation
// (x0+109) + 2*(x1+109) + (x2+109) = x0 + 2*x1 + x2 + 436
x0 + {x1, 1'b0} + adc_d + 436
// we want "- y0 * 0xd6 / 0x100" using only shift and add
// 0xd6 == 0b11010110
// so *0xd6/0x100 is equivalent to
// ((x << 1) + (x << 2) + (x << 4) + (x << 6) + (x << 7)) >> 8
// which is also equivalent to
// (x >> 7) + (x >> 6) + (x >> 4) + (x >> 2) + (x >> 1)
- ((y0 >> 7) + (y0 >> 6) + (y0 >> 4) + (y0 >> 2) + (y0 >> 1)) // - y0 * 0xd6 / 0x100
// we want "+ y1 * 0x1d3 / 0x100"
// 0x1d3 == 0b111010011
// so this is equivalent to
// ((x << 0) + (x << 1) + (x << 4) + (x << 6) + (x << 7) + (x << 8)) >> 8
// which is also equivalent to
// (x >> 8) + (x >> 7) + (x >> 4) + (x >> 2) + (x >> 1) + (x >> 0)
+ ((y1 >> 8) + (y1 >> 7) + (y1 >> 4) + (y1 >> 2) + (y1 >> 1) + y1);
end
end
// output: reduce to 8bit
assign out = y1[16:9];
// output: reduce to 8bit
assign out = y1[16:9];
endmodule

View file

@ -14,52 +14,52 @@
// This algorithm therefore can't be used directly for realtime peak detections,
// but it can be used as a simple envelope follower.
module min_max_tracker(input clk, input [7:0] adc_d, input [7:0] threshold,
output [7:0] min, output [7:0] max);
output [7:0] min, output [7:0] max);
reg [7:0] min_val = 255;
reg [7:0] max_val = 0;
reg [7:0] cur_min_val = 255;
reg [7:0] cur_max_val = 0;
reg [1:0] state = 0;
reg [7:0] min_val = 255;
reg [7:0] max_val = 0;
reg [7:0] cur_min_val = 255;
reg [7:0] cur_max_val = 0;
reg [1:0] state = 0;
always @(posedge clk)
begin
case (state)
0:
begin
if (cur_max_val >= ({1'b0, adc_d} + threshold))
state <= 2;
else if (adc_d >= ({1'b0, cur_min_val} + threshold))
state <= 1;
if (cur_max_val <= adc_d)
cur_max_val <= adc_d;
else if (adc_d <= cur_min_val)
cur_min_val <= adc_d;
end
1:
begin
if (cur_max_val <= adc_d)
cur_max_val <= adc_d;
else if (({1'b0, adc_d} + threshold) <= cur_max_val) begin
state <= 2;
cur_min_val <= adc_d;
max_val <= cur_max_val;
end
end
2:
begin
if (adc_d <= cur_min_val)
cur_min_val <= adc_d;
else if (adc_d >= ({1'b0, cur_min_val} + threshold)) begin
state <= 1;
cur_max_val <= adc_d;
min_val <= cur_min_val;
end
end
endcase
end
always @(posedge clk)
begin
case (state)
0:
begin
if (cur_max_val >= ({1'b0, adc_d} + threshold))
state <= 2;
else if (adc_d >= ({1'b0, cur_min_val} + threshold))
state <= 1;
if (cur_max_val <= adc_d)
cur_max_val <= adc_d;
else if (adc_d <= cur_min_val)
cur_min_val <= adc_d;
end
1:
begin
if (cur_max_val <= adc_d)
cur_max_val <= adc_d;
else if (({1'b0, adc_d} + threshold) <= cur_max_val) begin
state <= 2;
cur_min_val <= adc_d;
max_val <= cur_max_val;
end
end
2:
begin
if (adc_d <= cur_min_val)
cur_min_val <= adc_d;
else if (adc_d >= ({1'b0, cur_min_val} + threshold)) begin
state <= 1;
cur_max_val <= adc_d;
min_val <= cur_min_val;
end
end
endcase
end
assign min = min_val;
assign max = max_val;
assign min = min_val;
assign max = max_val;
endmodule

View file

@ -18,33 +18,33 @@ module testbed_fpga;
ssp_frame, ssp_din, ssp_dout, ssp_clk
);
integer i;
integer i;
initial begin
initial begin
// init inputs
#5 ncs=1;
#5 spck = 1;
#5 mosi = 1;
// 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 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
#50 mosi=1;
$finish;
end
endmodule // main

View file

@ -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
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
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
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
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;
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;
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)
);
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;
integer idx, i;
// main clock
always #5 begin
ck_1356megb = !ck_1356megb;
ck_1356meg = ck_1356megb;
end
// 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
//crank DUT
task crank_dut;
begin
@(posedge ssp_clk) ;
ssp_dout = $random;
end
endtask
initial begin
initial begin
// init inputs
ck_1356megb = 0;
adc_d = 0;
ssp_dout=0;
// 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 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
// shallow modulation on
shallow_modulation=1;
for (i = 0 ; i < 16 ; i = i + 1) begin
crank_dut;
end
$finish;
end
endmodule // main

View file

@ -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
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
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
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
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;
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;
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)
);
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;
integer idx, i;
// main clock
always #5 begin
ck_1356megb = !ck_1356megb;
ck_1356meg = ck_1356megb;
end
// main clock
always #5 begin
ck_1356megb = !ck_1356megb;
ck_1356meg = ck_1356megb;
end
always begin
@(negedge adc_clk) ;
adc_d = $random;
end
always begin
@(negedge adc_clk) ;
adc_d = $random;
end
//crank DUT
task crank_dut;
begin
@(negedge ssp_clk) ;
ssp_dout = $random;
end
endtask
//crank DUT
task crank_dut;
begin
@(negedge ssp_clk) ;
ssp_dout = $random;
end
endtask
initial begin
initial begin
// init inputs
ck_1356megb = 0;
// random values
adc_d = 0;
ssp_dout=1;
// 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 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
// shallow modulation on
mod_type=1;
for (i = 0 ; i < 16 ; i = i + 1) begin
crank_dut;
end
$finish;
end
endmodule // main

View file

@ -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)
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) )
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
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
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;
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;
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)
);
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;
integer idx, i, adc_val=8;
// main clock
always #5 pck0 = !pck0;
// 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
task crank_dut;
begin
@(posedge adc_clk) ;
adc_d = adc_val;
adc_val = (adc_val *2) + 53;
end
endtask
initial begin
initial begin
// init inputs
pck0 = 0;
adc_d = 0;
ssp_dout = 0;
lo_is_125khz = 1;
divisor = 255; //min 16, 95=125Khz, max 255
// 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
// simulate 4 A/D cycles at 125Khz
for (i = 0 ; i < 8 ; i = i + 1) begin
crank_dut;
end
$finish;
end
endmodule // main

View file

@ -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
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
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
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
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;
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;
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)
);
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;
integer i, counter=0;
// main clock
always #5 pck0 = !pck0;
// 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
//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
initial begin
pck0 = 0;
for (i = 0 ; i < 4096 ; i = i + 1) begin
crank_dut;
end
$finish;
end
end
endtask
initial begin
pck0 = 0;
for (i = 0 ; i < 4096 ; i = i + 1) begin
crank_dut;
end
$finish;
end
endmodule // main

View file

@ -20,16 +20,16 @@
module lf_edge_detect_tb;
integer fin, fout_state, fout_toggle;
integer fout_high, fout_highz, fout_lowz, fout_low, fout_min, fout_max;
integer r;
integer fin, fout_state, fout_toggle;
integer fout_high, fout_highz, fout_lowz, fout_low, fout_min, fout_max;
integer r;
reg clk = 0;
reg [7:0] adc_d;
wire adc_clk;
wire data_rdy;
wire edge_state;
wire edge_toggle;
reg clk = 0;
reg [7:0] adc_d;
wire adc_clk;
wire data_rdy;
wire edge_state;
wire edge_toggle;
wire [7:0] high_threshold;
wire [7:0] highz_threshold;
@ -38,74 +38,74 @@ module lf_edge_detect_tb;
wire [7:0] max;
wire [7:0] min;
initial
begin
clk = 0;
fin = $fopen(`FIN, "r");
if (!fin) begin
$display("ERROR: can't open the data file");
$finish;
end
fout_min = $fopen(`FOUT_MIN, "w+");
fout_max = $fopen(`FOUT_MAX, "w+");
fout_state = $fopen(`FOUT_STATE, "w+");
fout_toggle = $fopen(`FOUT_TOGGLE, "w+");
fout_high = $fopen(`FOUT_HIGH, "w+");
fout_highz = $fopen(`FOUT_HIGHZ, "w+");
fout_lowz = $fopen(`FOUT_LOWZ, "w+");
fout_low = $fopen(`FOUT_LOW, "w+");
if (!$feof(fin))
adc_d = $fgetc(fin); // read the first value
end
initial
begin
clk = 0;
fin = $fopen(`FIN, "r");
if (!fin) begin
$display("ERROR: can't open the data file");
$finish;
end
fout_min = $fopen(`FOUT_MIN, "w+");
fout_max = $fopen(`FOUT_MAX, "w+");
fout_state = $fopen(`FOUT_STATE, "w+");
fout_toggle = $fopen(`FOUT_TOGGLE, "w+");
fout_high = $fopen(`FOUT_HIGH, "w+");
fout_highz = $fopen(`FOUT_HIGHZ, "w+");
fout_lowz = $fopen(`FOUT_LOWZ, "w+");
fout_low = $fopen(`FOUT_LOW, "w+");
if (!$feof(fin))
adc_d = $fgetc(fin); // read the first value
end
always
# 1 clk = !clk;
always
# 1 clk = !clk;
// input
initial
begin
while (!$feof(fin)) begin
@(negedge clk) adc_d <= $fgetc(fin);
end
// input
initial
begin
while (!$feof(fin)) begin
@(negedge clk) adc_d <= $fgetc(fin);
end
if ($feof(fin))
begin
# 3 $fclose(fin);
$fclose(fout_state);
$fclose(fout_toggle);
$fclose(fout_high);
$fclose(fout_highz);
$fclose(fout_lowz);
$fclose(fout_low);
$fclose(fout_min);
$fclose(fout_max);
$finish;
end
end
if ($feof(fin))
begin
# 3 $fclose(fin);
$fclose(fout_state);
$fclose(fout_toggle);
$fclose(fout_high);
$fclose(fout_highz);
$fclose(fout_lowz);
$fclose(fout_low);
$fclose(fout_min);
$fclose(fout_max);
$finish;
end
end
initial
begin
// $monitor("%d\t S: %b, E: %b", $time, edge_state, edge_toggle);
end
initial
begin
// $monitor("%d\t S: %b, E: %b", $time, edge_state, edge_toggle);
end
// output
always @(negedge clk)
if ($time > 2) begin
r = $fputc(min, fout_min);
r = $fputc(max, fout_max);
r = $fputc(edge_state, fout_state);
r = $fputc(edge_toggle, fout_toggle);
r = $fputc(high_threshold, fout_high);
r = $fputc(highz_threshold, fout_highz);
r = $fputc(lowz_threshold, fout_lowz);
r = $fputc(low_threshold, fout_low);
end
// output
always @(negedge clk)
if ($time > 2) begin
r = $fputc(min, fout_min);
r = $fputc(max, fout_max);
r = $fputc(edge_state, fout_state);
r = $fputc(edge_toggle, fout_toggle);
r = $fputc(high_threshold, fout_high);
r = $fputc(highz_threshold, fout_highz);
r = $fputc(lowz_threshold, fout_lowz);
r = $fputc(low_threshold, fout_low);
end
// module to test
lf_edge_detect detect(clk, adc_d, 8'd127,
max, min,
high_threshold, highz_threshold,
lowz_threshold, low_threshold,
edge_state, edge_toggle);
// module to test
lf_edge_detect detect(clk, adc_d, 8'd127,
max, min,
high_threshold, highz_threshold,
lowz_threshold, low_threshold,
edge_state, edge_toggle);
endmodule
endmodule

View file

@ -13,43 +13,43 @@
module lp20khz_1MSa_iir_filter_tb;
integer fin, fout, r;
integer fin, fout, r;
reg clk;
reg [7:0] adc_d;
wire data_rdy;
wire [7:0] adc_filtered;
reg clk;
reg [7:0] adc_d;
wire data_rdy;
wire [7:0] adc_filtered;
initial
begin
clk = 0;
fin = $fopen(`FIN, "r");
if (!fin) begin
$display("ERROR: can't open the data file");
$finish;
end
fout = $fopen(`FOUT, "w+");
if (!$feof(fin))
adc_d = $fgetc(fin); // read the first value
end
initial
begin
clk = 0;
fin = $fopen(`FIN, "r");
if (!fin) begin
$display("ERROR: can't open the data file");
$finish;
end
fout = $fopen(`FOUT, "w+");
if (!$feof(fin))
adc_d = $fgetc(fin); // read the first value
end
always
# 1 clk = !clk;
always
# 1 clk = !clk;
always @(posedge clk)
if (data_rdy) begin
if ($time > 1)
r = $fputc(adc_filtered, fout);
if (!$feof(fin))
adc_d <= $fgetc(fin);
else begin
$fclose(fin);
$fclose(fout);
$finish;
end
end
always @(posedge clk)
if (data_rdy) begin
if ($time > 1)
r = $fputc(adc_filtered, fout);
if (!$feof(fin))
adc_d <= $fgetc(fin);
else begin
$fclose(fin);
$fclose(fout);
$finish;
end
end
// module to test
lp20khz_1MSa_iir_filter filter(clk, adc_d, data_rdy, adc_filtered);
// module to test
lp20khz_1MSa_iir_filter filter(clk, adc_d, data_rdy, adc_filtered);
endmodule

View file

@ -14,61 +14,61 @@
module min_max_tracker_tb;
integer fin;
integer fout_min, fout_max;
integer r;
integer fin;
integer fout_min, fout_max;
integer r;
reg clk;
reg [7:0] adc_d;
wire [7:0] min;
wire [7:0] max;
reg clk;
reg [7:0] adc_d;
wire [7:0] min;
wire [7:0] max;
initial
begin
clk = 0;
fin = $fopen(`FIN, "r");
if (!fin) begin
$display("ERROR: can't open the data file");
$finish;
end
fout_min = $fopen(`FOUT_MIN, "w+");
fout_max = $fopen(`FOUT_MAX, "w+");
if (!$feof(fin))
adc_d = $fgetc(fin); // read the first value
end
initial
begin
clk = 0;
fin = $fopen(`FIN, "r");
if (!fin) begin
$display("ERROR: can't open the data file");
$finish;
end
fout_min = $fopen(`FOUT_MIN, "w+");
fout_max = $fopen(`FOUT_MAX, "w+");
if (!$feof(fin))
adc_d = $fgetc(fin); // read the first value
end
always
# 1 clk = !clk;
always
# 1 clk = !clk;
// input
initial
begin
while (!$feof(fin)) begin
@(negedge clk) adc_d <= $fgetc(fin);
end
// input
initial
begin
while (!$feof(fin)) begin
@(negedge clk) adc_d <= $fgetc(fin);
end
if ($feof(fin))
begin
# 3 $fclose(fin);
$fclose(fout_min);
$fclose(fout_max);
$finish;
end
end
if ($feof(fin))
begin
# 3 $fclose(fin);
$fclose(fout_min);
$fclose(fout_max);
$finish;
end
end
initial
begin
// $monitor("%d\t min: %x, max: %x", $time, min, max);
end
initial
begin
// $monitor("%d\t min: %x, max: %x", $time, min, max);
end
// output
always @(negedge clk)
if ($time > 2) begin
r = $fputc(min, fout_min);
r = $fputc(max, fout_max);
end
// output
always @(negedge clk)
if ($time > 2) begin
r = $fputc(min, fout_min);
r = $fputc(max, fout_max);
end
// module to test
min_max_tracker tracker(clk, adc_d, 8'd127, min, max);
// module to test
min_max_tracker tracker(clk, adc_d, 8'd127, min, max);
endmodule
endmodule