FreeCalypso > hg > fc-sim-sniff
diff fpga/sniffer-pps/pps_catcher.v @ 28:0f74428c177c
fpga/sniffer-pps: first version
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 29 Aug 2023 20:05:23 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fpga/sniffer-pps/pps_catcher.v Tue Aug 29 20:05:23 2023 +0000 @@ -0,0 +1,165 @@ +/* + * 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