comparison 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
comparison
equal deleted inserted replaced
27:990ecafdddb4 28:0f74428c177c
1 /*
2 * This Verilog module is our PPS catcher. It is a state machine that analyzes
3 * the stream of Rx characters from the primary sniffer and detects the
4 * positions of these two special chars:
5 *
6 * - the PPS1 byte of the card's PPS response;
7 * - the PCK byte concluding that PPS response *if* PPS1 indicated a speed
8 * enhancement mode which we support.
9 */
10
11 module pps_catcher (IntClk, SIM_RST_sync, Rx_strobe, Rx_char,
12 pos_PPS_resp_PPS1, pos_PPS_resp_PCK);
13
14 input IntClk;
15 input SIM_RST_sync;
16 input Rx_strobe;
17 input [7:0] Rx_char;
18
19 output pos_PPS_resp_PPS1, pos_PPS_resp_PCK;
20
21 /* state machine */
22
23 localparam
24 INITIAL = 5'h00,
25 ATR_T0 = 5'h01,
26 ATR_TAn = 5'h02,
27 ATR_TBn = 5'h03,
28 ATR_TCn = 5'h04,
29 ATR_TDn = 5'h05,
30 ATR_HIST = 5'h06,
31 ATR_TCK = 5'h07,
32 READY_FOR_PPS = 5'h08,
33 REQ_PPS0 = 5'h09,
34 REQ_PPS1 = 5'h0A,
35 REQ_PPS2 = 5'h0B,
36 REQ_PPS3 = 5'h0C,
37 REQ_PCK = 5'h0F,
38 READY_FOR_RESP = 5'h10,
39 RESP_PPS0 = 5'h11,
40 RESP_PPS1 = 5'h12,
41 RESP_PPS2 = 5'h13,
42 RESP_PPS3 = 5'h14,
43 RESP_PCK = 5'h17,
44 DONE = 5'h1F
45 ;
46
47 reg [4:0] state;
48 reg [3:0] Y, K;
49 reg have_TCK;
50
51 always @(posedge IntClk)
52 if (!SIM_RST_sync)
53 begin
54 state <= INITIAL;
55 have_TCK <= 1'b0;
56 end
57 else case (state)
58 INITIAL:
59 if (Rx_strobe)
60 begin
61 if (Rx_char == 8'h3B)
62 state <= ATR_T0;
63 else
64 state <= DONE;
65 end
66 ATR_T0:
67 if (Rx_strobe)
68 begin
69 Y <= Rx_char[7:4];
70 K <= Rx_char[3:0];
71 state <= ATR_TAn;
72 end
73 ATR_TAn:
74 if (!Y[0] || Rx_strobe)
75 state <= ATR_TBn;
76 ATR_TBn:
77 if (!Y[1] || Rx_strobe)
78 state <= ATR_TCn;
79 ATR_TCn:
80 if (!Y[2] || Rx_strobe)
81 state <= ATR_TDn;
82 ATR_TDn:
83 if (!Y[3])
84 state <= ATR_HIST;
85 else if (Rx_strobe)
86 begin
87 Y <= Rx_char[7:4];
88 if (Rx_char[3:0] != 4'h0)
89 have_TCK <= 1'b1;
90 state <= ATR_TAn;
91 end
92 ATR_HIST:
93 if (K == 4'd0)
94 state <= ATR_TCK;
95 else if (Rx_strobe)
96 K <= K - 4'd1;
97 ATR_TCK:
98 if (!have_TCK || Rx_strobe)
99 state <= READY_FOR_PPS;
100 READY_FOR_PPS:
101 if (Rx_strobe)
102 begin
103 if (Rx_char == 8'hFF)
104 state <= REQ_PPS0;
105 else
106 state <= DONE;
107 end
108 REQ_PPS0:
109 if (Rx_strobe)
110 begin
111 Y <= Rx_char[7:4];
112 state <= REQ_PPS1;
113 end
114 REQ_PPS1:
115 if (!Y[0] || Rx_strobe)
116 state <= REQ_PPS2;
117 REQ_PPS2:
118 if (!Y[1] || Rx_strobe)
119 state <= REQ_PPS3;
120 REQ_PPS3:
121 if (!Y[2] || Rx_strobe)
122 state <= REQ_PCK;
123 REQ_PCK:
124 if (Rx_strobe)
125 state <= READY_FOR_RESP;
126 READY_FOR_RESP:
127 if (Rx_strobe)
128 begin
129 if (Rx_char == 8'hFF)
130 state <= RESP_PPS0;
131 else
132 state <= DONE;
133 end
134 RESP_PPS0:
135 if (Rx_strobe)
136 begin
137 Y <= Rx_char[7:4];
138 if (Rx_char[4])
139 state <= RESP_PPS1;
140 else
141 state <= DONE;
142 end
143 RESP_PPS1:
144 if (Rx_strobe)
145 begin
146 if (Rx_char[7:2] == 6'b100101)
147 state <= RESP_PPS2;
148 else
149 state <= DONE;
150 end
151 RESP_PPS2:
152 if (!Y[1] || Rx_strobe)
153 state <= RESP_PPS3;
154 RESP_PPS3:
155 if (!Y[2] || Rx_strobe)
156 state <= RESP_PCK;
157 RESP_PCK:
158 if (Rx_strobe)
159 state <= DONE;
160 endcase
161
162 assign pos_PPS_resp_PPS1 = (state == RESP_PPS1);
163 assign pos_PPS_resp_PCK = (state == RESP_PCK);
164
165 endmodule