x393  1.0
FPGAcodeforElphelNC393camera
nmea_decoder393.v
Go to the documentation of this file.
1 
39 `timescale 1ns/1ps
40 
42  input mclk, // system clock, posedge
43  input xclk, // half frequency (80 MHz nominal)
44  input we, // registers write enable (@negedge mclk)
45  input [4:0] wa, // registers write address
46  input [7:0] wd, // write data
47  input start, // start of the serail message
48  input rs232_wait_pause,// may be used as reset for decoder
49  input start_char, // serial character start (single pulse)
50  output reg nmea_sent_start, // serial character start (single pulse)
51  input ser_di, // serial data in (LSB first)
52  input ser_stb,// serial data strobe, single-cycle, first cycle after ser_di valid
53  output rdy, // encoded nmea data ready
54  input rd_stb, // encoded nmea data read strobe (increment address)
55  output [15:0] rdata, // encoded data (16 bits)
56  input ser_rst,
57  output [23:0] debug);
58 
59  reg [ 9:0] bitnum;
60  reg gp_exp_bit;
61  reg valid; // so far it is a valid sentence
62  reg [3:0] sentence1hot; // one-hot sentence, matching first 6 bytes ($GPxxx)
63  reg restart; // reset byte number if the first byte was not "$"
64  reg start_d;
65  reg [3:0] stb; // ser_stb delayed
68  reg vfy_gp;
70  reg vfy_first_comma; // first comma after $GPxxx
72  reg last_vfy_gp; // delayed by 1 cycle from bit counters
73  reg last_vfy_sent; // delayed by 1 cycle from bit counters
74  reg lsbs5; // 5 LSBs during reading 3 last letters in $GPxxx
75  reg [3:0] gpxxx_addr;
76  wire [3:1] sentence1hot_pri; // sentence1hot made really one-hot
77  reg [1:0] sentence; // decoded sentence number (0..3)
78  reg [4:0] format_length; // number of fields in the sentence
80  reg [4:0] format_field; // current number of the field in the sentence
82  reg read_format_length; //, read_format_length_d;
87  reg [7:0] format_byte;
88  reg [7:1] last_byte;
89  wire wcomma; // comma
90  wire weof; //asterisk, or cr/lf (<0x10)
91  wire wsep; //any separator
92  reg [3:0] nibble;
93  reg [3:0] nibble_pre;
94  wire [7:0] wbyte;
97  reg [1:0] extra_nibble; // empty byte field - send two 4'hf nibbles
98  reg [6:0] nibble_count;
99  reg [4:0] raddr;
100  wire [3:0] gpxxx_w_one;
101  wire [7:0] format_data;
103  reg [4:0] last_word_written; // number of the last word (4 nibbles) written - used ro deassert rdy (garbage after)
104  reg rdy_r=1'b0;
106  reg [ 7:0] debug0;
107  reg [15:0] debug1;
108  reg [15:0] debug1_or;
109 
110  assign debug[23:0] = {1'b0,
111  proc_fields,
113  vfy_sel_sent,
114  vfy_gp,
115  vfy_dollar,
116  bitnum[9:0],
117  debug0[7:0]};
118 
119  assign sentence1hot_pri[3:1] = {sentence1hot[3]& ~|sentence1hot[2:0],
120  sentence1hot[2]& ~|sentence1hot[1:0],
121  sentence1hot[1]& ~sentence1hot[0]};
122  assign start_format= (vfy_first_comma && (sentence1hot[3:0]!=4'h0) && (stb[3] && msb));
123 
124  assign wbyte[7:0] = {ser_di,last_byte[7:1]}; // valid up to stb[3];
125  assign wcomma = proc_fields && msb && (wbyte[7:0]==8'h2c);
126  assign weof = proc_fields && msb && ((wbyte[7:0]==8'h2a) || (wbyte[7:4]==4'h0)); // 0x2a or 0x0? (<0x10)
127  assign wsep = wcomma || weof;
128  assign w_sentence_over = wsep && (format_field[4:0]==format_length_plus_7[4:0]);
129  assign rdy = rdy_r;
130 
131 //format_length_plus_7
132  always @ (posedge xclk) begin
133  if (ser_rst) debug0 [7:0] <= 8'b0;
134  else debug0 [7:0] <=debug0 [7:0] | {rdy_r,
135  proc_fields,
137  start_format,
139  vfy_sel_sent,
140  vfy_gp,
141  vfy_dollar};
142 
143  if (ser_rst) debug1 [15:0] <= 16'b0;
144  else if (stb[1] && vfy_sel_sent && lsbs5) debug1 [15:0] <= debug1 [15:0] | debug1_or [15:0];
145 
146  case (gpxxx_addr[3:0])
147  4'h0: debug1_or[15:0] <= 16'h0001;
148  4'h1: debug1_or[15:0] <= 16'h0002;
149  4'h2: debug1_or[15:0] <= 16'h0004;
150  4'h3: debug1_or[15:0] <= 16'h0008;
151  4'h4: debug1_or[15:0] <= 16'h0010;
152  4'h5: debug1_or[15:0] <= 16'h0020;
153  4'h6: debug1_or[15:0] <= 16'h0040;
154  4'h7: debug1_or[15:0] <= 16'h0080;
155  4'h8: debug1_or[15:0] <= 16'h0100;
156  4'h9: debug1_or[15:0] <= 16'h0200;
157  4'ha: debug1_or[15:0] <= 16'h0400;
158  4'hb: debug1_or[15:0] <= 16'h0800;
159  4'hc: debug1_or[15:0] <= 16'h1000;
160  4'hd: debug1_or[15:0] <= 16'h2000;
161  4'he: debug1_or[15:0] <= 16'h4000;
162  4'hf: debug1_or[15:0] <= 16'h8000;
163  endcase
164 
165  stb[3:0] <= {stb[2:0], ser_stb};
166  start_d <= start;
167  restart <= start || sentence_over || stb[2] && msb && ((!valid && (vfy_dollar || last_vfy_gp || vfy_first_comma)) || // may abort earlier (use vfy_gp)
168  ((sentence1hot==4'h0) && last_vfy_sent)); // may abort earlier (use vfy_sel_sent)
169 
170  if (start_d) bitnum[2:0] <= 3'h0;
171  else if (stb[3]) bitnum[2:0] <= bitnum[2:0] + 1;
172 
173  if (start_d) msb <= 1'b0;
174  else if (stb[3]) msb <= (bitnum[2:0] ==3'h6);
175 
176  if (start_d) bit3 <= 1'b0;
177  else if (stb[3]) bit3 <= (bitnum[2:0] ==3'h2);
178 
179  if (start_d) bits37 <= 1'b0;
180  else if (stb[3]) bits37 <= (bitnum[1:0] ==2'h2);
181 
182  if (start_d) lsbs5 <= 1'b1;
183  else if (stb[3]) lsbs5 <= !bitnum[2] || (bitnum[2:0] ==3'h7);
184 
185  if (restart) bitnum[9:3] <= 'h0;
186  else if (stb[3] && msb) bitnum[9:3] <= bitnum[9:3] + 1;
187 
188  if (restart || rs232_wait_pause) vfy_dollar <= 1'b1; // byte 0
189  else if (stb[3] && msb) vfy_dollar <= 1'b0;
190 
191  last_vfy_gp <= vfy_gp && !bitnum[3];
192 
193  if (restart) vfy_gp <= 1'b0;
194  else if (stb[3] && msb) vfy_gp <= (valid && vfy_dollar) || (vfy_gp && !last_vfy_gp); // bytes 1-2
195 
196  last_vfy_sent <= vfy_sel_sent && (bitnum[3] && bitnum[5]);
197 
198  if (restart) vfy_sel_sent <= 1'b0;
199  else if (stb[3] && msb) vfy_sel_sent <= (valid && last_vfy_gp) || (vfy_sel_sent && !last_vfy_sent); // bytes 3,4,5
200 
201  if (restart) vfy_first_comma <= 1'b0;
202  else if (stb[3] && msb) vfy_first_comma <= last_vfy_sent;
203 
204  if (restart) valid <= 1'b1; // ready @ stb[2]
205  else if (stb[1] && (ser_di!=gp_exp_bit) &&
206  (vfy_dollar || vfy_gp || vfy_first_comma || (vfy_sel_sent && !lsbs5))) valid <= 1'b0;
207 
208 
209  if (!vfy_sel_sent) gpxxx_addr[3:0] <= 4'h0;
210  else if (lsbs5 &&stb[3]) gpxxx_addr[3:0] <= gpxxx_addr[3:0] + 1;
211 
212  if (vfy_gp) sentence1hot[3:0] <= 4'hf;
213  else if (stb[1] && vfy_sel_sent && lsbs5) sentence1hot[3:0] <= sentence1hot & (ser_di?(gpxxx_w_one[3:0]): (~gpxxx_w_one[3:0]));
214 
216 
217  if (restart || sentence_over) proc_fields <=1'b0;
218  else if (start_format) proc_fields <=1'b1;
219 
220  if (!proc_fields) format_field[4:0] <= 5'h0;
221  else if (read_format_length) format_field[4:0] <= 5'h8;
222  else if (format_over) format_field[4:0] <= format_field[4:0] + 1;
223 
224  format_length_plus_7[4:0] <= format_length[4:0]+7;
225 
226  if (start_format) first_byte_in_field <=1'b1;
227  else if (stb[3] && msb) first_byte_in_field <= format_over;
228 
230 
231  if (read_format_length) format_length[4:0] <= format_data[4:0];
232 
233  read_format_byte <= read_format_length || (format_over && format_field[2:0]==3'h7); // @stb[4]
234 
235  shift_format_byte <= format_over; // @stb[4]
236 
237  if (read_format_byte) format_byte[7:0] <= format_data[7:0];
238  else if (shift_format_byte) format_byte[7:0] <= {1'b0,format_byte[7:1]};
239 
240  // format_byte[0] - current format
241  if (stb[3]) last_byte[7:1] <= {ser_di,last_byte[7:2]};
242 
243  format_over <= stb[2] && wsep;
244 
245  sentence_over <= stb[2] && (weof || w_sentence_over);
246 
247  if (bits37 && stb[3]) nibble_pre[3:0] <= last_byte[4:1]; // always OK
248 
249  if (stb[3] && bit3) nibble[3:0] <= nibble_pre[3:0];
250  else if (stb[3] && msb && wsep && (first_byte_in_field || !format_byte[0])) nibble[3:0] <= 4'hf;
251  else if (stb[3] && msb && format_byte[0]) nibble[3:0] <= {wsep,nibble_pre[2:0]};
252  else if (save_sent_number) nibble[3:0] <= {2'b0,sentence[1:0]};
253 
254  //first_byte_in_field
255 
256  extra_nibble[1:0] <= {extra_nibble[0],
257  msb && wsep && first_byte_in_field & proc_fields & stb[3] & format_byte[0]};// active at stb[4], stb[5]
258 
259  save_sent_number <= start_format; // valid at stb[4]
260 
262  (proc_fields && ((stb[3] && bit3 && !first_byte_in_field) ||
263  (stb[3] && msb && !first_byte_in_field && format_byte[0]) ||
264  (stb[3] && msb && wsep))) || extra_nibble[1]; // extra_nibble[1] will repeat 4'hf
265 
266  if (start_format) nibble_count[6:0] <= 7'h0;
267  else if (nibble_stb) nibble_count[6:0] <= nibble_count[6:0] + 1;
268 
269  if (sentence_over) raddr[4:0] <= 5'h0;
270  else if (rd_stb) raddr[4:0] <= raddr[4:0] + 1;
271 
272  if (nibble_stb) last_word_written[4:0]<=nibble_count[6:2];
273 
274  if (start || vfy_first_comma || (rd_stb && ((raddr[4:0]==5'h1b) ||(raddr[4:0]==last_word_written[4:0])))) rdy_r <= 1'b0;
275  else if (sentence_over) rdy_r <= 1'b1;
276 
278  end
279 // output buffer to hold up to 32 16-bit words. Written 1 nibble at a time
280  // replaced 6 RAM modules with inferred ones
281  reg [3:0] odbuf0_ram[0:31];
282  reg [3:0] odbuf1_ram[0:31];
283  reg [3:0] odbuf2_ram[0:31];
284  reg [3:0] odbuf3_ram[0:31];
285  always @ (posedge xclk) if (nibble_stb && (nibble_count[1:0] == 2'h0)) odbuf0_ram[nibble_count[6:2]] <= nibble[3:0];
286  always @ (posedge xclk) if (nibble_stb && (nibble_count[1:0] == 2'h1)) odbuf1_ram[nibble_count[6:2]] <= nibble[3:0];
287  always @ (posedge xclk) if (nibble_stb && (nibble_count[1:0] == 2'h2)) odbuf2_ram[nibble_count[6:2]] <= nibble[3:0];
288  always @ (posedge xclk) if (nibble_stb && (nibble_count[1:0] == 2'h3)) odbuf3_ram[nibble_count[6:2]] <= nibble[3:0];
289 
290  assign rdata[ 3: 0] = odbuf0_ram[raddr[4:0]];
291  assign rdata[ 7: 4] = odbuf1_ram[raddr[4:0]];
292  assign rdata[11: 8] = odbuf2_ram[raddr[4:0]];
293  assign rdata[15:12] = odbuf3_ram[raddr[4:0]];
294 
295  reg [3:0] gpxxx_ram[0:3];
296  always @ (posedge mclk) if (we & ~wa[4]) gpxxx_ram[wa[3:0]] <= wd[3:0];
297  assign gpxxx_w_one[3:0] = gpxxx_ram[gpxxx_addr[3:0]];
298 // for each of the four sentences first byte - number of field (<=24), next 3 bytes - formats for each nmea filed (LSB first):
299 // 0 - nibble ("-" -> 0xd, "." -> 0xe), terminated with 0xf
300 // 1 - byte (2 nibbles), all bytes but last have MSB clear, last - set.
301 // No padding of nibbles to byte borders, bytes are encoded as 2 nibbles
302  reg [7:0] format_ram[0:3];
303  always @ (posedge mclk) if (we & wa[4]) format_ram[wa[3:0]] <= wd[7:0];
304  assign format_data[7:0] = format_ram[{sentence[1:0],format_field[4:3]}];
305 
306 // ROM to decode "$GP"
307  always @ (posedge xclk) begin
308  if (ser_stb) case ({(bitnum[4] & ~ vfy_sel_sent) | vfy_first_comma, bitnum[3] | vfy_sel_sent | vfy_first_comma, bitnum[2:0]}) // during vfy_sel_sent will point to 1 ('G')
309  5'h00: gp_exp_bit <= 1'b0; //$
310  5'h01: gp_exp_bit <= 1'b0;
311  5'h02: gp_exp_bit <= 1'b1;
312  5'h03: gp_exp_bit <= 1'b0;
313  5'h04: gp_exp_bit <= 1'b0;
314  5'h05: gp_exp_bit <= 1'b1;
315  5'h06: gp_exp_bit <= 1'b0;
316  5'h07: gp_exp_bit <= 1'b0;
317  5'h08: gp_exp_bit <= 1'b1; //G
318  5'h09: gp_exp_bit <= 1'b1;
319  5'h0a: gp_exp_bit <= 1'b1;
320  5'h0b: gp_exp_bit <= 1'b0;
321  5'h0c: gp_exp_bit <= 1'b0;
322  5'h0d: gp_exp_bit <= 1'b0;
323  5'h0e: gp_exp_bit <= 1'b1;
324  5'h0f: gp_exp_bit <= 1'b0;
325  5'h10: gp_exp_bit <= 1'b0; //P
326  5'h11: gp_exp_bit <= 1'b0;
327  5'h12: gp_exp_bit <= 1'b0;
328  5'h13: gp_exp_bit <= 1'b0;
329  5'h14: gp_exp_bit <= 1'b1;
330  5'h15: gp_exp_bit <= 1'b0;
331  5'h16: gp_exp_bit <= 1'b1;
332  5'h17: gp_exp_bit <= 1'b0;
333  5'h18: gp_exp_bit <= 1'b0; //'h2c: "," - will use later - attach first comma to $GPxxx,
334  5'h19: gp_exp_bit <= 1'b0;
335  5'h1a: gp_exp_bit <= 1'b1;
336  5'h1b: gp_exp_bit <= 1'b1;
337  5'h1c: gp_exp_bit <= 1'b0;
338  5'h1d: gp_exp_bit <= 1'b1;
339  5'h1e: gp_exp_bit <= 1'b0;
340  5'h1f: gp_exp_bit <= 1'b0;
341  default:gp_exp_bit <= 1'bX;
342  endcase
343  end
344 endmodule
3789format_length_plus_7reg[4:0]
3807extra_nibblereg[1:0]
3810gpxxx_w_onewire[3:0]
3798last_bytereg[7:1]
3808nibble_countreg[6:0]
3818debug1_orreg[15:0]
[0:31] 3820odbuf1_ramreg[3:0]
3785gpxxx_addrreg[3:0]
[0:3] 3823gpxxx_ramreg[3:0]
[0:31] 3822odbuf3_ramreg[3:0]
[0:3] 3824format_ramreg[7:0]
3790format_fieldreg[4:0]
3803nibble_prereg[3:0]
3786sentence1hot_priwire[3:1]
[0:31] 3819odbuf0_ramreg[3:0]
3787sentencereg[1:0]
3804wbytewire[7:0]
3797format_bytereg[7:0]
3788format_lengthreg[4:0]
3770sentence1hotreg[3:0]
3811format_datawire[7:0]
[0:31] 3821odbuf2_ramreg[3:0]
3813last_word_writtenreg[4:0]