FreeCalypso > hg > fc-sim-sniff
view fpga/sniffer-pps/pps_catcher.v @ 36:f1c3dd2173d3
doc/Sniffing-hw-setup: document written
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 30 Aug 2023 02:22:44 +0000 |
parents | 0f74428c177c |
children |
line wrap: on
line source
/* * This Verilog module is our PPS catcher. It is a state machine that analyzes * the stream of Rx characters from the primary sniffer and detects the * positions of these two special chars: * * - the PPS1 byte of the card's PPS response; * - the PCK byte concluding that PPS response *if* PPS1 indicated a speed * enhancement mode which we support. */ module pps_catcher (IntClk, SIM_RST_sync, Rx_strobe, Rx_char, pos_PPS_resp_PPS1, pos_PPS_resp_PCK); input IntClk; input SIM_RST_sync; input Rx_strobe; input [7:0] Rx_char; output pos_PPS_resp_PPS1, pos_PPS_resp_PCK; /* state machine */ localparam INITIAL = 5'h00, ATR_T0 = 5'h01, ATR_TAn = 5'h02, ATR_TBn = 5'h03, ATR_TCn = 5'h04, ATR_TDn = 5'h05, ATR_HIST = 5'h06, ATR_TCK = 5'h07, READY_FOR_PPS = 5'h08, REQ_PPS0 = 5'h09, REQ_PPS1 = 5'h0A, REQ_PPS2 = 5'h0B, REQ_PPS3 = 5'h0C, REQ_PCK = 5'h0F, READY_FOR_RESP = 5'h10, RESP_PPS0 = 5'h11, RESP_PPS1 = 5'h12, RESP_PPS2 = 5'h13, RESP_PPS3 = 5'h14, RESP_PCK = 5'h17, DONE = 5'h1F ; reg [4:0] state; reg [3:0] Y, K; reg have_TCK; always @(posedge IntClk) if (!SIM_RST_sync) begin state <= INITIAL; have_TCK <= 1'b0; end else case (state) INITIAL: if (Rx_strobe) begin if (Rx_char == 8'h3B) state <= ATR_T0; else state <= DONE; end ATR_T0: if (Rx_strobe) begin Y <= Rx_char[7:4]; K <= Rx_char[3:0]; state <= ATR_TAn; end ATR_TAn: if (!Y[0] || Rx_strobe) state <= ATR_TBn; ATR_TBn: if (!Y[1] || Rx_strobe) state <= ATR_TCn; ATR_TCn: if (!Y[2] || Rx_strobe) state <= ATR_TDn; ATR_TDn: if (!Y[3]) state <= ATR_HIST; else if (Rx_strobe) begin Y <= Rx_char[7:4]; if (Rx_char[3:0] != 4'h0) have_TCK <= 1'b1; state <= ATR_TAn; end ATR_HIST: if (K == 4'd0) state <= ATR_TCK; else if (Rx_strobe) K <= K - 4'd1; ATR_TCK: if (!have_TCK || Rx_strobe) state <= READY_FOR_PPS; READY_FOR_PPS: if (Rx_strobe) begin if (Rx_char == 8'hFF) state <= REQ_PPS0; else state <= DONE; end REQ_PPS0: if (Rx_strobe) begin Y <= Rx_char[7:4]; state <= REQ_PPS1; end REQ_PPS1: if (!Y[0] || Rx_strobe) state <= REQ_PPS2; REQ_PPS2: if (!Y[1] || Rx_strobe) state <= REQ_PPS3; REQ_PPS3: if (!Y[2] || Rx_strobe) state <= REQ_PCK; REQ_PCK: if (Rx_strobe) state <= READY_FOR_RESP; READY_FOR_RESP: if (Rx_strobe) begin if (Rx_char == 8'hFF) state <= RESP_PPS0; else state <= DONE; end RESP_PPS0: if (Rx_strobe) begin Y <= Rx_char[7:4]; if (Rx_char[4]) state <= RESP_PPS1; else state <= DONE; end RESP_PPS1: if (Rx_strobe) begin if (Rx_char[7:2] == 6'b100101) state <= RESP_PPS2; else state <= DONE; end RESP_PPS2: if (!Y[1] || Rx_strobe) state <= RESP_PPS3; RESP_PPS3: if (!Y[2] || Rx_strobe) state <= RESP_PCK; RESP_PCK: if (Rx_strobe) state <= DONE; endcase assign pos_PPS_resp_PPS1 = (state == RESP_PPS1); assign pos_PPS_resp_PCK = (state == RESP_PCK); endmodule