ae97d23b109b51dbd92a7eb129acf41f3114af72
[shakti-peripherals.git] / src / peripherals / uart / Uart16550.bsv
1 /*
2 Copyright (c) 2013-2017, IIT Madras
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6
7 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9 * Neither the name of IIT Madras nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10
11 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
13 /*-
14 * Copyright (c) 2013 Simon W. Moore
15 * All rights reserved.
16 *
17 * This software was developed by SRI International and the University of
18 * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
19 * ("CTSRD"), as part of the DARPA CRASH research programme.
20 *
21 * @BERI_LICENSE_HEADER_START@
22 *
23 * Licensed to BERI Open Systems C.I.C. (BERI) under one or more contributor
24 * license agreements. See the NOTICE file distributed with this work for
25 * additional information regarding copyright ownership. BERI licenses this
26 * file to you under the BERI Hardware-Software License, Version 1.0 (the
27 * "License"); you may not use this file except in compliance with the
28 * License. You may obtain a copy of the License at:
29 *
30 * http://www.beri-open-systems.org/legal/license-1-0.txt
31 *
32 * Unless required by applicable law or agreed to in writing, Work distributed
33 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
34 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
35 * specific language governing permissions and limitations under the License.
36 *
37 * @BERI_LICENSE_HEADER_END@
38 *
39 ******************************************************************************
40 * UART16550
41 * =========
42 * Simon Moore, July 2013
43 *
44 * This Bluespec module implements a 16650 style UART for RS232 serial
45 * communication.
46 *
47 * The following registers exist at 32-bit boundaries accessible in little
48 * endian byte order:
49 *
50 * Offset Name Read/Write Description
51 * 0 UART_DATA RW write to transmit, read to receive
52 * 1 UART_INT_ENABLE RW interrupt enable
53 * 2 UART_INT_ID R interrupt identification
54 * 2 UART_FIFO_CTRL W FIFO control
55 * 3 UART_LINE_CTRL RW line control
56 * 4 UART_MODEM_CTRL W modem control
57 * 5 UART_LINE_STATUS R line status
58 * 6 UART_MODEM_STATUS R modem status
59 * 7 UART_SCRATCH RW scratch register
60 ******************************************************************************/
61
62 //Modifications - The Avalon bus has been removed and AXI-4 Lite Bus support has been added
63
64
65 package Uart16550;
66
67 import FIFO::*;
68 import FIFOF::*;
69 import FIFOLevel::*;
70 import Clocks::*;
71 import ClientServer::*;
72 import defined_types::*;
73 import AXI4_Lite_Types::*;
74 import AXI4_Lite_Fabric::*;
75 import Semi_FIFOF::*;
76 `include "instance_defines.bsv"
77
78 // depth of transmit and receive FIFOs
79 typedef 16 Tx_FIFO_depth;
80 typedef 16 Rx_FIFO_depth;
81
82 // enumerate addresses corresponding to device registers
83 typedef enum {
84 UART_ADDR_DATA=0,
85 UART_ADDR_INT_ENABLE=1,
86 UART_ADDR_INT_ID_FIFO_CTRL=2, // read=INT_ID, write=FIFO_CTRL
87 UART_ADDR_LINE_CTRL=3,
88 UART_ADDR_MODEM_CTRL=4,
89 UART_ADDR_LINE_STATUS=5,
90 UART_ADDR_MODEM_STATUS=6,
91 UART_ADDR_SCRATCH=7
92 } UART_ADDR_T deriving (Bits, Eq, FShow);
93
94 // interrupt enable register bits
95 typedef struct {
96 Bool uart_IE_MS; // Modem status interrupt
97 Bool uart_IE_RLS; // Receiver line status interrupt
98 Bool uart_IE_THRE; // Transmitter holding register empty interrupt
99 Bool uart_IE_RDA; // Recived data available interrupt
100 } UART_IE_T deriving (Bits, Eq, FShow);
101
102 // interrupt identification values
103 typedef enum {
104 UART_II_MS = 4'b0000, // modem status
105 UART_II_NO_INT = 4'b0001, // no interrupt pending
106 UART_II_THRE = 4'b0010, // transmitter holding register empty
107 UART_II_RDA = 4'b0100, // receiver data available
108 UART_II_RLS = 4'b0110, // receiver line status
109 UART_II_TI = 4'b1100 // timeout indication
110 } UART_II_T deriving (Bits, Eq, FShow);
111
112 // line control register bits
113 typedef struct {
114 Bit#(1) uart_LC_DL; // divisor latch access bit
115 Bit#(1) uart_LC_BC; // break control
116 Bit#(1) uart_LC_SP; // stick parity
117 Bit#(1) uart_LC_EP; // even parity
118 Bit#(1) uart_LC_PE; // parity enables
119 Bit#(1) uart_LC_SB; // stop bits
120 Bit#(2) uart_LC_BITS; // bits in character
121 } UART_LC_T deriving (Bits, Eq, FShow);
122
123 // modem control register bits
124 typedef struct {
125 bit uart_MC_LOOPBACK;
126 bit uart_MC_OUT2;
127 bit uart_MC_OUT1;
128 bit uart_MC_RTS;
129 bit uart_MC_DTR;
130 } UART_MC_T deriving (Bits, Eq, FShow);
131
132 // line status register bits
133 typedef struct {
134 Bool uart_LS_EI; // error indicator
135 Bool uart_LS_TW; // transmitter empty indicator
136 Bool uart_LS_TFE; // transmitter FIFO is empty
137 Bool uart_LS_BI; // break interrupt
138 Bool uart_LS_FE; // framing error
139 Bool uart_LS_PE; // parity error
140 Bool uart_LS_OE; // overrun error
141 Bool uart_LS_DR; // data ready
142 } UART_LS_T deriving (Bits, Eq, FShow);
143
144 // modem status register bits
145 typedef struct {
146 bit uart_MS_CDCD; // complement signals
147 bit uart_MS_CRI;
148 bit uart_MS_CDSR;
149 bit uart_MS_CCTS;
150 bit uart_MS_DDCD; // delta signals
151 bit uart_MS_TERI;
152 bit uart_MS_DDSR;
153 bit uart_MS_DCTS;
154 } UART_MS_T deriving (Bits, Eq, FShow);
155
156 // data from receiver
157 typedef struct {
158 Bit#(8) data;
159 Bool break_error;
160 Bool parity_error;
161 Bool framing_error;
162 } RX_DATA_T deriving (Bits, Eq);
163
164 // transmitter states
165 typedef enum {
166 STX_idle, STX_pop_byte, STX_send_start, STX_send_byte, STX_send_parity, STX_send_stop
167 } TX_state_T deriving (Bits, Eq, FShow);
168
169 // receiver states
170 typedef enum {
171 SRX_idle, SRX_rec_start, SRX_rec_bit, SRX_rec_parity, SRX_rec_stop,
172 SRX_check_parity, SRX_rec_prepare, SRX_end_bit, SRX_wait1,
173 SRX_ca_lc_parity, SRX_push } RX_state_T deriving (Bits, Eq, FShow);
174
175
176 (* always_ready, always_enabled *)
177 interface RS232_PHY_Ifc;
178 (* always_ready, always_enabled *) method Action modem_input(bit srx, bit cts, bit dsr, bit ri, bit dcd);
179 method bit modem_output_stx;
180 method bit modem_output_rts;
181 method bit modem_output_dtr;
182 endinterface
183
184
185 interface Uart16550_AXI4_Lite_Ifc;
186 interface RS232_PHY_Ifc coe_rs232;
187 interface AXI4_Lite_Slave_IFC#(`PADDR,`Reg_width,`USERSPACE) slave_axi_uart;
188 (* always_ready, always_enabled *) method bit irq;
189 endinterface
190
191
192 (* synthesize,
193 reset_prefix = "csi_clockreset_reset_n",
194 clock_prefix = "csi_clockreset_clk" *)
195 module mkUart16550#(Clock core_clock, Reset core_reset)(Uart16550_AXI4_Lite_Ifc);
196 AXI4_Lite_Slave_Xactor_IFC #(`PADDR,`Reg_width,`USERSPACE) s_xactor <- mkAXI4_Lite_Slave_Xactor(clocked_by core_clock, reset_by core_reset);
197 UART_transmitter_ifc uart_tx <- mkUART_transmitter;
198 UART_receiver_ifc uart_rx <- mkUART_receiver;
199
200 // TODO: FIXME: use Tx_FIFO_depth and Rx_FIFO_depth rather than 16?
201 // TX should only have a 1 element FIFO
202 // FIFOCountIfc#(Bit#(8), 16) tx_fifo <- mkGFIFOCount(True, False, True);
203 FIFOF#(Bit#(8)) tx_fifo <- mkGFIFOF1(True, False);
204 FIFOCountIfc#(RX_DATA_T, 16) rx_fifo <- mkGFIFOCount(True, True, True);
205 PulseWire tx_fifo_clear_pw <- mkPulseWire;
206 PulseWire rx_fifo_clear_pw <- mkPulseWire;
207 // add some bypass wires to hack around scheduling loop
208 Wire#(Bool) rx_fifo_full <- mkBypassWire;
209 Wire#(Bool) rx_fifo_empty <- mkBypassWire;
210 Wire#(Bool) tx_fifo_empty <- mkBypassWire;
211 // provide first item of rx_fifo if there is one, otherwise a default
212 Wire#(RX_DATA_T) rx_fifo_first <- mkBypassWire;
213
214 PulseWire count_error_up <- mkPulseWire;
215 PulseWire count_error_down <- mkPulseWire;
216 PulseWire count_error_clear <- mkPulseWire;
217 Reg#(UInt#(TAdd#(Rx_FIFO_depth,1)))
218 count_error <- mkReg(0);
219
220 Reg#(Bit#(2)) fcr <- mkReg(2'b11); // upper 2 bits of FIFO control register (rest not stored)
221 Reg#(UART_IE_T) ier <- mkReg(unpack(0)); // interrupt enable register bits (disable after reset)
222 Reg#(UART_LC_T) lcr <- mkReg(unpack('b00000011)); // line control register (default 8n1 format)
223 Reg#(UART_MC_T) mcr <- mkReg(unpack(0)); // modem control register
224 Wire#(UART_MC_T) mc_bypass <- mkBypassWire;
225 Reg#(UART_LS_T) lsr <- mkReg(unpack(0)); // line status register
226 Reg#(UART_MS_T) msr <- mkReg(unpack(0)); // modem status register
227 Reg#(Bit#(8)) scratch <- mkReg(unpack(0)); // scratch register
228
229 Wire#(Bool) loopback <- mkBypassWire; // loopback mode (msr[4])
230
231 Reg#(Bit#(8)) dl1r <- mkReg(0); // divisor 1 register
232 Reg#(Bit#(8)) dl2r <- mkReg(0); // divisor 2 register
233 Reg#(Bit#(16)) dlc <- mkReg(0); // divisor counter
234 Reg#(Bit#(16)) dl <- mkReg(0); // divisor counter bound
235 Reg#(Bool) enable <- mkReg(False);
236 Wire#(Maybe#(Bit#(16)))
237 dl_update <- mkDWire(tagged Invalid);
238
239 PulseWire interrupt_pw <- mkPulseWireOR;
240 RS_ifc rls_int <- mkRS;
241 RS_ifc rda_int <- mkRS;
242 RS_ifc thre_int <- mkRS;
243 RS_ifc ms_int <- mkRS;
244 RS_ifc ti_int <- mkRS;
245
246 // synchroniser registers for input pins
247 Reg#(bit) pin_srx_sync <- mkReg(0);
248 Reg#(bit) pin_cts_sync <- mkReg(0);
249 Reg#(bit) pin_dsr_sync <- mkReg(0);
250 Reg#(bit) pin_ri_sync <- mkReg(0);
251 Reg#(bit) pin_dcd_sync <- mkReg(0);
252
253 // registers for stable input pin values pre loopback check
254 Reg#(bit) pin_srx_c <- mkReg(0);
255 Reg#(bit) pin_cts_c <- mkReg(0);
256 Reg#(bit) pin_dsr_c <- mkReg(0);
257 Reg#(bit) pin_ri_c <- mkReg(0);
258 Reg#(bit) pin_dcd_c <- mkReg(0);
259
260 // registers for stable input pin values
261 Reg#(bit) pin_srx <- mkReg(0);
262 Reg#(bit) pin_cts <- mkReg(0);
263 Reg#(bit) pin_dsr <- mkReg(0);
264 Reg#(bit) pin_ri <- mkReg(0);
265 Reg#(bit) pin_dcd <- mkReg(0);
266
267 // previous pin values last read via MSR (modem status register)
268 Reg#(bit) prev_cts <- mkReg(0);
269 Reg#(bit) prev_dsr <- mkReg(0);
270 Reg#(bit) prev_ri <- mkReg(0);
271 Reg#(bit) prev_dcd <- mkReg(0);
272 PulseWire msr_save_pin_state <- mkPulseWire; // trigger condition to save pin state
273
274 // registered outputs
275 Reg#(bit) pin_stx <- mkReg(0);
276 Reg#(bit) pin_rts <- mkReg(0);
277 Reg#(bit) pin_dtr <- mkReg(0);
278
279 SyncFIFOIfc#(AXI4_Lite_Rd_Addr #(`PADDR,`USERSPACE)) ff_rd_addr <- mkSyncFIFOToCC(1,core_clock,core_reset);
280 SyncFIFOIfc#(AXI4_Lite_Wr_Addr #(`PADDR, `USERSPACE)) ff_wr_addr <- mkSyncFIFOToCC(1,core_clock,core_reset);
281 SyncFIFOIfc#(AXI4_Lite_Wr_Data #(`Reg_width)) ff_wr_data <- mkSyncFIFOToCC(1,core_clock,core_reset);
282
283 SyncFIFOIfc#(AXI4_Lite_Rd_Data #(`Reg_width,`USERSPACE)) ff_rd_resp <- mkSyncFIFOFromCC(1,core_clock);
284 SyncFIFOIfc#(AXI4_Lite_Wr_Resp #(`USERSPACE)) ff_wr_resp <- mkSyncFIFOFromCC(1,core_clock);
285
286
287 (* no_implicit_conditions *)
288 rule synchronise_input_pins; // N.B. there must be no logic between these registers
289 pin_srx_c <= pin_srx_sync;
290 pin_cts_c <= pin_cts_sync;
291 pin_dsr_c <= pin_dsr_sync;
292 pin_ri_c <= pin_ri_sync;
293 pin_dcd_c <= pin_dcd_sync;
294 endrule
295
296 rule bypass_mrc_to_avoid_scheduling_loop;
297 mc_bypass <= mcr;
298 endrule
299
300 (* no_implicit_conditions *)
301 rule handle_loopback_mode;
302 if(loopback)
303 begin
304 pin_srx <= pin_stx;
305 pin_cts <= mc_bypass.uart_MC_RTS;
306 pin_dsr <= mc_bypass.uart_MC_DTR;
307 pin_ri <= mc_bypass.uart_MC_OUT1;
308 pin_dcd <= mc_bypass.uart_MC_OUT2;
309 end
310 else
311 begin
312 pin_srx <= pin_srx_c;
313 pin_cts <= pin_cts_c;
314 pin_dsr <= pin_dsr_c;
315 pin_ri <= pin_ri_c;
316 pin_dcd <= pin_dcd_c;
317 end
318
319 msr <= UART_MS_T{
320 // first changes in the pins
321 uart_MS_DCTS: pin_cts ^ prev_cts,
322 uart_MS_DDSR: pin_dsr ^ prev_dsr,
323 uart_MS_TERI: pin_ri ^ prev_ri,
324 uart_MS_DDCD: pin_dcd ^ prev_dcd,
325 // then the actual signals
326 uart_MS_CCTS: pin_cts, // TODO: allow this to be from loopback
327 uart_MS_CDSR: pin_dsr,
328 uart_MS_CRI: pin_ri,
329 uart_MS_CDCD: pin_dcd};
330
331 if(msr_save_pin_state)
332 begin
333 prev_dcd <= pin_dcd;
334 prev_ri <= pin_ri;
335 prev_dsr <= pin_dsr;
336 prev_cts <= pin_cts;
337 end
338 endrule
339
340 (* no_implicit_conditions *)
341 rule output_rts_dtr;
342 pin_rts <= mcr.uart_MC_RTS;
343 pin_dtr <= mcr.uart_MC_DTR;
344 endrule
345
346 (* no_implicit_conditions *)
347 rule loopback_mode_select;
348 loopback <= mcr.uart_MC_LOOPBACK==1;
349 endrule
350
351 (* no_implicit_conditions *)
352 rule connect_pins_rx;
353 uart_rx.input_srx(pin_srx);
354 endrule
355 (* no_implicit_conditions *)
356 rule connect_pins_tx;
357 pin_stx <= uart_tx.output_stx;
358 endrule
359 (* no_implicit_conditions *)
360 rule rx_first_item_if_any;
361 rx_fifo_first <= rx_fifo.notEmpty ? rx_fifo.first
362 : RX_DATA_T{
363 data:0,
364 break_error: False,
365 parity_error: False,
366 framing_error: False};
367 endrule
368
369 (* no_implicit_conditions *)
370 rule interrupt_sources;
371 if(rda_int.state || rls_int.state || thre_int.state || ms_int.state || ti_int.state)
372 interrupt_pw.send;
373
374 // receiver line status interrupt
375 // - note: also reset on read of line status
376 if(!ier.uart_IE_RLS)
377 rls_int.reset;
378 else if(rx_fifo_full
379 || rx_fifo_first.parity_error
380 || rx_fifo_first.framing_error
381 || rx_fifo_first.break_error)
382 rls_int.posedge_set;
383
384 // received data available interrupt
385 UInt#(5) trigger_level;
386 case(fcr)
387 // 2'b00 handled by default case
388 2'b01 : trigger_level = 4;
389 2'b10 : trigger_level = 8;
390 2'b11 : trigger_level = 14;
391 default : trigger_level = 1;
392 endcase
393 // TODO: should this in fact be edge triggered on the trigger level being reached or passed?
394 if(ier.uart_IE_RDA && !rx_fifo_empty && (rx_fifo.count >= trigger_level))
395 rda_int.set;
396 else
397 rda_int.reset;
398
399 // transmitter holding register empty interrupt
400 // if(!ier.uart_IE_THRE)
401 if(!ier.uart_IE_THRE || !tx_fifo_empty)
402 thre_int.reset;
403 else if(tx_fifo_empty)
404 thre_int.posedge_set;
405
406 // timer interrupt
407 if(!ier.uart_IE_RDA)
408 ti_int.reset;
409 else if(uart_rx.timeout)
410 ti_int.posedge_set;
411
412 // modem status interrupt
413 // - note: also reset by reading modem status
414 if(!ier.uart_IE_MS)
415 ms_int.reset;
416 else if({msr.uart_MS_DCTS, msr.uart_MS_DDSR, msr.uart_MS_TERI, msr.uart_MS_DDCD} != 0)
417 ms_int.posedge_set;
418 endrule
419
420 (* no_implicit_conditions *)
421 rule foward_lc_enable;
422 uart_tx.control(lcr, enable);
423 uart_rx.control(lcr, enable);
424 endrule
425
426 (* no_implicit_conditions *)
427 rule divisor_counter;
428 enable <= (dlc==0) && (dl>0);
429 if(isValid(dl_update))
430 begin
431 let newdl = fromMaybe(?, dl_update);
432 dl <= newdl;
433 dlc <= newdl-1;
434 `ifdef verbose $display("%05t: dl set to %1d", $time, newdl); `endif
435 end
436 else
437 dlc <= (dlc==0 ? dl : dlc) - 1;
438 endrule
439
440 (* no_implicit_conditions *)
441 rule forward_tx_clear(tx_fifo_clear_pw);
442 tx_fifo.clear;
443 endrule
444 rule forward_tx(!tx_fifo_clear_pw && tx_fifo.notEmpty);
445 uart_tx.tx_char(tx_fifo.first);
446 tx_fifo.deq;
447 endrule
448
449 rule forward_rx;
450 if(rx_fifo_clear_pw)
451 rx_fifo.clear;
452 else if(rx_fifo.notFull)
453 begin
454 RX_DATA_T rx <- uart_rx.rx_char;
455 rx_fifo.enq(rx);
456 if(rx.break_error || rx.parity_error || rx.framing_error)
457 count_error_up.send();
458 end
459 endrule
460
461 (* no_implicit_conditions *)
462 rule count_rx_errors;
463 if(count_error_clear)
464 count_error <= 0;
465 else
466 begin
467 if(count_error_up && !count_error_down && (count_error<fromInteger(valueOf(Rx_FIFO_depth))))
468 count_error <= count_error+1;
469 if(!count_error_up && count_error_down && (count_error>0))
470 count_error <= count_error-1;
471 end
472 endrule
473
474 (* no_implicit_conditions *)
475 rule fifo_status_bypass_to_avoid_scheduling_loop;
476 rx_fifo_full <= !rx_fifo.notFull;
477 rx_fifo_empty <= !rx_fifo.notEmpty;
478 tx_fifo_empty <= !tx_fifo.notEmpty;
479 endrule
480
481 rule capture_read_request;
482 let req <- pop_o (s_xactor.o_rd_addr);
483 ff_rd_addr.enq(req);
484 endrule
485 rule send_read_respone_to_bus;
486 s_xactor.i_rd_data.enq(ff_rd_resp.first);
487 ff_rd_resp.deq;
488 endrule
489 rule capture_write_request;
490 let req <- pop_o (s_xactor.o_wr_addr);
491 let wr_data <- pop_o(s_xactor.o_wr_data);
492 ff_wr_addr.enq(req);
493 ff_wr_data.enq(wr_data);
494 endrule
495 rule send_write_response;
496 s_xactor.i_wr_resp.enq(ff_wr_resp.first);
497 ff_wr_resp.deq;
498 endrule
499
500
501 rule handle_axi4_read(ff_rd_addr.notEmpty);
502
503 Bool dlab = lcr.uart_LC_DL == 1'b1; // divisor latch enable
504 let req = ff_rd_addr.first;
505 ff_rd_addr.deq;
506 `ifdef verbose $display("RD_ADDR %h", req.araddr); `endif
507 UART_ADDR_T addr = unpack(req.araddr[5:3]);
508 Bool rtn_valid=True;
509 Bit#(8) rtn = 0;
510
511 let ls = UART_LS_T{
512 uart_LS_EI: rx_fifo_full || (count_error!=0), // error indicator
513 uart_LS_TW: tx_fifo_empty && uart_tx.tx_buf_empty, // transmitter empty
514 uart_LS_TFE: tx_fifo_empty, // transmitter FIFO empty
515 uart_LS_BI: rx_fifo_first.break_error, // break error
516 uart_LS_FE: rx_fifo_first.framing_error, // framing error
517 uart_LS_PE: rx_fifo_first.parity_error, // parity error
518 uart_LS_OE: rx_fifo_full, // overflow
519 uart_LS_DR: !rx_fifo_empty}; // data ready
520
521 lsr <= ls;
522
523 UART_II_T ii;
524 if(rls_int.state) // highest priority interrupt - receiver line status
525 ii = UART_II_RLS;
526 else if(rda_int.state) // second priority interrupt - received data available
527 ii = UART_II_RDA;
528 else if(ti_int.state) // also second priority - timeout
529 ii = UART_II_TI;
530 else if(thre_int.state) // third priority - transmitter holding register empty
531 ii = UART_II_THRE;
532 else if(ms_int.state) // fourth - modem status change interrupt
533 ii = UART_II_MS;
534 else
535 ii = UART_II_NO_INT;
536 `ifdef verbose $display("addr_READ: %d",addr) ; `endif
537 case(addr)
538 UART_ADDR_DATA : if(dlab) // divisor latch enabled
539 rtn = dl1r;
540 else if(!rx_fifo_empty)
541 begin
542 RX_DATA_T rx = rx_fifo.first;
543 rtn = rx.data;
544 if(rx.break_error || rx.parity_error || rx.framing_error)
545 count_error_down.send;
546 rx_fifo.deq;
547 ti_int.reset;
548 rda_int.reset;
549 end
550 else
551 rtn_valid = False; // TODO: should this be the old value?
552 UART_ADDR_INT_ENABLE : rtn = dlab ? dl2r : zeroExtend(pack(ier));
553 UART_ADDR_INT_ID_FIFO_CTRL : rtn = {4'b1100, pack(ii)};
554 UART_ADDR_LINE_CTRL : rtn = pack(lcr);
555 UART_ADDR_MODEM_CTRL : rtn = zeroExtend(pack(mcr));
556 UART_ADDR_LINE_STATUS : begin
557 rls_int.reset;
558 rtn = pack(ls);
559 end
560 UART_ADDR_MODEM_STATUS : begin
561 ms_int.reset;
562 rtn = pack(msr);
563 msr_save_pin_state.send();
564 end
565 UART_ADDR_SCRATCH : rtn = scratch;
566
567 endcase
568 let resp = AXI4_Lite_Rd_Data {rresp : AXI4_LITE_OKAY, rdata : rtn_valid? zeroExtend(rtn) : '1, ruser: 0};
569 ff_rd_resp.enq(resp);
570 // $display ("DATA----------- %b", rtn);
571 `ifdef verbose $display("%05t: --------------------------READ--------------------------------------------",$time); `endif
572 endrule
573
574 rule handle_axi4_write(ff_wr_addr.notEmpty && ff_wr_data.notEmpty);
575 Bool dlab = lcr.uart_LC_DL == 1'b1; // divisor latch enable
576 let ls = UART_LS_T{
577 uart_LS_EI: rx_fifo_full || (count_error!=0), // error indicator
578 uart_LS_TW: tx_fifo_empty && uart_tx.tx_buf_empty, // transmitter empty
579 uart_LS_TFE: tx_fifo_empty, // transmitter FIFO empty
580 uart_LS_BI: rx_fifo_first.break_error, // break error
581 uart_LS_FE: rx_fifo_first.framing_error, // framing error
582 uart_LS_PE: rx_fifo_first.parity_error, // parity error
583 uart_LS_OE: rx_fifo_full, // overflow
584 uart_LS_DR: !rx_fifo_empty}; // data ready
585
586 lsr <= ls;
587
588 UART_II_T ii;
589 if(rls_int.state) // highest priority interrupt - receiver line status
590 ii = UART_II_RLS;
591 else if(rda_int.state) // second priority interrupt - received data available
592 ii = UART_II_RDA;
593 else if(ti_int.state) // also second priority - timeout
594 ii = UART_II_TI;
595 else if(thre_int.state) // third priority - transmitter holding register empty
596 ii = UART_II_THRE;
597 else if(ms_int.state) // fourth - modem status change interrupt
598 ii = UART_II_MS;
599 else
600 ii = UART_II_NO_INT;
601
602 let wr_addr = ff_wr_addr.first;
603 `ifdef verbose $display("WR_ADDR %h", wr_addr.awaddr); `endif
604 ff_wr_addr.deq;
605 let wr_data = ff_wr_data.first;
606 ff_wr_data.deq;
607 `ifdef verbose $display("WR_DATA %h", wr_data.wdata); `endif
608 UART_ADDR_T addr = unpack(wr_addr.awaddr[5:3]);
609 Bit#(8) d = truncate(pack(wr_data.wdata));
610 Bit#(8) rtn=0;
611 Bool rtn_valid=True;
612 `ifdef verbose $display("addr_WRITE: %d",addr); `endif
613 case(addr)
614 UART_ADDR_DATA: if(dlab) // divisor latch enabled
615 begin
616 dl1r <= d;
617 dl_update <= tagged Valid ({dl2r,d});
618 end
619 else if(tx_fifo.notFull)
620 begin
621 tx_fifo.enq(unpack(d));
622 thre_int.reset;
623 end
624 UART_ADDR_INT_ENABLE: if(dlab)
625 dl2r <= unpack(d);
626 else
627 ier <= unpack(truncate(d));
628 UART_ADDR_INT_ID_FIFO_CTRL: begin
629 fcr <= d[7:6];
630 if(d[1]==1'b1)
631 begin
632 rx_fifo_clear_pw.send;
633 count_error_clear.send;
634 end
635 if(d[2]==1'b1)
636 tx_fifo_clear_pw.send;
637 end
638 UART_ADDR_LINE_CTRL : lcr <= unpack(truncate(pack(wr_data.wdata)));
639 UART_ADDR_MODEM_CTRL : mcr <= unpack(truncate(pack(wr_data.wdata)));
640 UART_ADDR_LINE_STATUS : begin /* no write */ end
641 UART_ADDR_MODEM_STATUS : begin /* no write */ end
642 UART_ADDR_SCRATCH : begin scratch <= d; `ifdef verbose $display("scratch : %h",d); `endif end
643 endcase
644 let resp = AXI4_Lite_Wr_Resp {bresp: AXI4_LITE_OKAY, buser: 0};
645 ff_wr_resp.enq(resp);
646 // $display ("DATA WRITE----------- %b", wr_data.wdata);
647 // $display ("DATA Adress----------- %d", addr);
648 `ifdef verbose $display("%05t: ----------------------------WRITE------------------------------------------",$time); `endif
649 endrule
650 /*
651 rule trans ;
652 $display("%05t: tx bit = %b", $time, pin_stx);
653 endrule
654 */
655 interface RS232_PHY_Ifc coe_rs232;
656 method Action modem_input(bit srx, bit cts, bit dsr, bit ri, bit dcd);
657 pin_srx_sync <= srx; // RX Input
658 pin_cts_sync <= cts; // CTS Input
659 pin_dsr_sync <= dsr; // Data Set Ready indicating that MODEM is ready to establish the communication
660 pin_ri_sync <= ri; // Ring Indicator indicate that a telephone ringing signal has been recieved by the MODEM
661 pin_dcd_sync <= dcd; // Data carrier detect
662 endmethod
663 method bit modem_output_stx = pin_stx; // Tx output
664 method bit modem_output_rts = pin_rts; // RTS output
665 method bit modem_output_dtr = pin_dtr; // Data Terminal Ready output
666 endinterface
667
668 interface slave_axi_uart = s_xactor.axi_side;
669
670 method bit irq;
671 return interrupt_pw ? 1'b1 : 1'b0;
672 endmethod
673
674 endmodule
675
676
677
678
679 //////////////////////////////////////////////////////////////////////////////
680 // transmitter
681
682 interface UART_transmitter_ifc;
683 method Action tx_char(Bit#(8) c);
684 (* always_ready, always_enabled *)
685 method Bool tx_buf_empty;
686 (* always_ready, always_enabled *)
687 method Action control(UART_LC_T lc_in, Bool enable_in);
688 (* always_ready, always_enabled *)
689 method bit output_stx;
690 endinterface
691
692
693 module mkUART_transmitter(UART_transmitter_ifc);
694
695 FIFOF#(Bit#(8)) tx_fifo <- mkLFIFOF;
696 Wire#(Bool) tx_fifo_empty <- mkBypassWire;
697 Reg#(bit) bit_out <- mkReg(0);
698 Reg#(bit) parity_xor <- mkReg(0);
699 Reg#(bit) stx_o_tmp <- mkReg(1); // rename output bit? our use bit_out directly?
700 Reg#(TX_state_T) tstate <- mkReg(STX_idle);
701 Reg#(TX_state_T) last_tstate <- mkReg(STX_idle);
702 Reg#(UInt#(5)) counter <- mkReg(0);
703 Reg#(UInt#(3)) bit_counter <- mkReg(0);
704 Reg#(Bit#(7)) shift_out <- mkReg(0);
705 Wire#(UART_LC_T) lc <- mkBypassWire;
706 Wire#(Bool) enable <- mkBypassWire;
707
708 rule monitor_state_for_debug(last_tstate != tstate);
709
710 `ifdef verbose $write("%05t: UART TX state change ", $time); `endif
711 `ifdef verbose $write(fshow(last_tstate)); `endif
712 `ifdef verbose $write(" -> "); `endif
713 `ifdef verbose $display(fshow(tstate)); `endif
714
715 last_tstate <= tstate;
716 endrule
717
718 // rule to decouple rule dependency on tx_fifo.notEmpty
719 (* no_implicit_conditions *)
720 rule forward_tx_fifo_empty;
721 tx_fifo_empty <= !tx_fifo.notEmpty;
722 endrule
723
724 rule idle(enable && (tstate==STX_idle));
725 tstate <= STX_pop_byte; // move directly to pop_byte since it will block if the tx_fifo is empty
726 stx_o_tmp <= 1;
727 endrule
728
729 rule pop_byte(enable && (tstate==STX_pop_byte));
730 case(lc.uart_LC_BITS) // number of bits in a word
731 0: begin
732 bit_counter <= 4;
733 parity_xor <= ^tx_fifo.first[4:0];
734 end
735 1: begin
736 bit_counter <= 5;
737 parity_xor <= ^tx_fifo.first[5:0];
738 end
739 2: begin
740 bit_counter <= 6;
741 parity_xor <= ^tx_fifo.first[6:0];
742 end
743 3: begin
744 bit_counter <= 7;
745 parity_xor <= ^tx_fifo.first[7:0];
746 end
747 endcase
748 shift_out[6:0] <= tx_fifo.first[7:1];
749 bit_out <= tx_fifo.first[0];
750 tstate <= STX_send_start;
751 endrule
752
753 rule send_start(enable && (tstate==STX_send_start));
754
755 if(counter==0)
756 counter <= 5'b01111;
757 else if(counter==1)
758 begin
759 counter <= 0;
760 tstate <= STX_send_byte;
761 end
762 else
763 counter <= counter-1;
764 stx_o_tmp <= 0;
765 endrule
766
767 rule send_byte(enable && (tstate==STX_send_byte));
768 if(counter==0)
769 counter <= 5'b01111;
770 else if(counter==1)
771 begin
772 if(bit_counter > 0)
773 begin
774 bit_counter <= bit_counter-1;
775 shift_out <= {1'b0,shift_out[6:1]};
776 bit_out <= shift_out[0];
777 end
778 else // end of byte
779 if(lc.uart_LC_PE == 0) // no partity bit
780 tstate <= STX_send_stop;
781 else
782 begin
783 case({lc.uart_LC_EP, lc.uart_LC_SP})
784 2'b00: bit_out <= ~parity_xor;
785 2'b01: bit_out <= 1;
786 2'b10: bit_out <= parity_xor;
787 2'b11: bit_out <= 0;
788 endcase
789 tstate <= STX_send_parity;
790 end
791 counter <= 0;
792 end
793 else
794 counter <= counter-1;
795 stx_o_tmp <= bit_out;
796 endrule
797
798 rule send_parity(enable && (tstate==STX_send_parity));
799 if(counter==0)
800 counter <= 5'b01111;
801 else if(counter==1)
802 begin
803 counter <= 0;
804 tstate <= STX_send_stop;
805 end
806 else
807 counter <= counter-1;
808 stx_o_tmp <= bit_out;
809
810 endrule
811
812 rule send_stop(enable && (tstate==STX_send_stop));
813 if(counter==0)
814 counter <= lc.uart_LC_SB==0 ? 5'b01101 : // 1 stop bit
815 lc.uart_LC_BITS==0 ? 5'b10101 : // 1.5 stop bits
816 5'b11101; // 2 stop bits
817 else if(counter==1)
818 begin
819 counter <= 0;
820 tstate <= STX_idle;
821 tx_fifo.deq;
822 end
823 else
824 counter <= counter-1;
825 stx_o_tmp <= 1;
826 endrule
827
828
829 method Action tx_char(Bit#(8) c);
830 tx_fifo.enq(c);
831 endmethod
832
833 method Bool tx_buf_empty = tx_fifo_empty;
834
835 method Action control(UART_LC_T lc_in, Bool enable_in);
836 lc <= lc_in;
837 enable <= enable_in;
838 endmethod
839
840 method bit output_stx = lc.uart_LC_BC==1 ? 0 : stx_o_tmp; // handle break condition
841
842 endmodule
843
844
845 //////////////////////////////////////////////////////////////////////////////
846 // receiver
847
848 interface UART_receiver_ifc;
849 method ActionValue#(RX_DATA_T) rx_char();
850 (* always_ready, always_enabled *)
851 method Bool timeout();
852 (* always_ready, always_enabled *)
853 method Action control(UART_LC_T lc_in, Bool enable_in);
854 (* always_ready, always_enabled *)
855 method Action input_srx(bit rx);
856 endinterface
857
858
859 module mkUART_receiver(UART_receiver_ifc);
860
861 FIFOF#(RX_DATA_T) rx_fifo <- mkLFIFOF;
862 Reg#(bit) rx_stable <- mkReg(1);
863 Wire#(UART_LC_T) lc <- mkBypassWire;
864 Wire#(Bool) enable <- mkBypassWire;
865 Reg#(RX_state_T) rstate <- mkReg(SRX_idle);
866 Reg#(RX_state_T) last_rstate <- mkReg(SRX_idle);
867 Reg#(UInt#(4)) rcounter <- mkReg(0);
868 Reg#(UInt#(3)) rbit_counter <- mkReg(0);
869 Reg#(Bit#(8)) rshift <- mkReg(0);
870 Reg#(bit) rparity <- mkReg(0);
871 Reg#(bit) rparity_error <- mkReg(0);
872 Reg#(bit) rframing_error <- mkReg(0);
873 Reg#(bit) rparity_xor <- mkReg(0);
874 Reg#(UInt#(8)) counter_b <- mkReg(159);
875 Reg#(UInt#(10)) counter_t <- mkReg(511);
876 PulseWire counter_t_preset <- mkPulseWireOR;
877
878 Bool break_error = counter_b==0;
879
880 rule monitor_state_for_debug(last_rstate != rstate);
881
882 `ifdef verbose $write("%05t: UART RX state change ", $time); `endif
883 `ifdef verbose $write(fshow(last_rstate)); `endif
884 `ifdef verbose $write(" -> "); `endif
885 `ifdef verbose $display(fshow(rstate)); `endif
886
887 last_rstate <= rstate;
888 endrule
889
890 (* no_implicit_conditions *)
891 rule receive_status_counters;
892 UInt#(10) toc_value;
893 case ({lc.uart_LC_PE, lc.uart_LC_SB, lc.uart_LC_BITS})
894 4'b0000: toc_value = 447; // 7 bits
895 4'b0100: toc_value = 479; // 7.5 bits
896 4'b0001,
897 4'b1000: toc_value = 511; // 8 bits
898 4'b1100: toc_value = 543; // 8.5 bits
899 4'b0010,
900 4'b0101,
901 4'b1001: toc_value = 575; // 9 bits
902 4'b0011,
903 4'b0110,
904 4'b1010,
905 4'b1101: toc_value = 639; // 10 bits
906 4'b0111,
907 4'b1011,
908 4'b1110: toc_value = 703; // 11 bits
909 4'b1111: toc_value = 767; // 12 bits
910 default: toc_value = 511; // 8 bits
911 endcase
912
913 UInt#(8) brc_value = truncate(toc_value>>2); // break counter value
914
915 if(rx_stable==1)
916 counter_b <= brc_value;
917 else if((counter_b!=0) && enable)
918 counter_b <= counter_b-1;
919
920 if(counter_t_preset)
921 counter_t <= toc_value;
922 else if(enable && (counter_t!=0))
923 counter_t <= counter_t - 1;
924 endrule
925
926 // helper rule to decouple firing dependancies
927 rule couter_t_preset_on_fifo_empty(!rx_fifo.notEmpty);
928 counter_t_preset.send();
929 endrule
930
931 (* no_implicit_conditions *)
932 rule idle(enable && (rstate==SRX_idle));
933 rcounter <= 4'b1110;
934 if((rx_stable==0) && !break_error)
935 rstate <= SRX_rec_start;
936 endrule
937
938 rule rec_start(enable && (rstate==SRX_rec_start));
939 if(rcounter==7)
940 if(rx_stable==1) // no start bit
941 rstate <= SRX_idle;
942 else
943 rstate <= SRX_rec_prepare;
944 rcounter <= rcounter-1;
945 endrule
946
947 rule rec_prepare(enable && (rstate==SRX_rec_prepare));
948 rbit_counter <= unpack(zeroExtend(lc.uart_LC_BITS) + 4);
949 if(rcounter==0)
950 begin
951 rstate <= SRX_rec_bit;
952 rcounter <= 4'b1110;
953 rshift <= 0;
954 end
955 else
956 rcounter <= rcounter-1;
957 endrule
958
959 rule rec_bit(enable && (rstate==SRX_rec_bit));
960 if(rcounter==0)
961 rstate <= SRX_end_bit;
962 if(rcounter==7) // read the bit
963 case(lc.uart_LC_BITS) // number of bits in a word
964 0: rshift[4:0] <= {rx_stable, rshift[4:1]};
965 1: rshift[5:0] <= {rx_stable, rshift[5:1]};
966 2: rshift[6:0] <= {rx_stable, rshift[6:1]};
967 3: rshift[7:0] <= {rx_stable, rshift[7:1]};
968 endcase
969 rcounter <= rcounter-1;
970 endrule
971
972 rule end_bit(enable && (rstate==SRX_end_bit));
973 if(rbit_counter==0) // no more bits in the word
974 begin
975 rstate <= (lc.uart_LC_PE==1) ? SRX_rec_parity : SRX_rec_stop;
976 rparity_error <= 0;
977 end
978 else
979 rstate <= SRX_rec_bit;
980 rbit_counter <= rbit_counter-1;
981 rcounter <= rcounter-1;
982 endrule
983
984 rule rec_parity(enable && (rstate==SRX_rec_parity));
985 if(rcounter == 7) // read parity
986 begin
987 rparity <= rx_stable;
988 rstate <= SRX_ca_lc_parity;
989 end
990 rcounter <= rcounter-1;
991 //$display("%05t rx bit = %d", $time, rx_stable);
992 endrule
993 /*
994 rule recie ;
995 $display("%05t: rx bit = %d", $time, rx_stable);
996 endrule
997 */
998 rule calc_parity(enable && (rstate==SRX_ca_lc_parity));
999 rparity_xor <= ^{rshift, rparity};
1000 rstate <= SRX_check_parity;
1001 rcounter <= rcounter-1;
1002 endrule
1003
1004 rule check_parity(enable && (rstate==SRX_check_parity));
1005 case({lc.uart_LC_EP, lc.uart_LC_SP})
1006 2'b00: rparity_error <= ~rparity_xor;
1007 2'b01: rparity_error <= ~rparity;
1008 2'b10: rparity_error <= rparity_xor;
1009 2'b11: rparity_error <= rparity;
1010 endcase
1011 rcounter <= rcounter-1;
1012 rstate <= SRX_wait1;
1013 endrule
1014
1015 rule wait1(enable && (rstate==SRX_wait1));
1016 if(rcounter==0)
1017 begin
1018 rcounter <= 4'b1110;
1019 rstate <= SRX_rec_stop;
1020 end
1021 else
1022 rcounter <= rcounter-1;
1023 endrule
1024
1025 rule rec_stop(enable && (rstate==SRX_rec_stop));
1026 if(rcounter==7) // read the stop bit
1027 begin
1028 rframing_error <= ~rx_stable; // no framing error if stop bit = 1
1029 rstate <= SRX_push;
1030 end
1031 rcounter <= rcounter-1;
1032 `ifdef verbose $display("%05t: rx bit = %d", $time, rx_stable); `endif
1033 endrule
1034
1035 rule push(enable && (rstate==SRX_push));
1036 if((rx_stable==1) || break_error)
1037 begin
1038 rstate <= SRX_idle;
1039 if(break_error)
1040 rx_fifo.enq(
1041 RX_DATA_T{
1042 data: 8'b0,
1043 break_error: True,
1044 parity_error: True,
1045 framing_error: False
1046 }
1047 );
1048 else
1049 rx_fifo.enq(
1050 RX_DATA_T{
1051 data: rshift,
1052 break_error: False,
1053 parity_error: rparity_error==1,
1054 framing_error: rframing_error==1
1055 }
1056 );
1057 counter_t_preset.send; // preset counter_t on an enq
1058 //$display("%05t: rx bit = %d", $time, rx_stable);
1059 end
1060 endrule
1061
1062 method ActionValue#(RX_DATA_T) rx_char();
1063 counter_t_preset.send; // preset counter_t on a deq
1064 rx_fifo.deq;
1065 return rx_fifo.first;
1066 endmethod
1067 method Bool timeout() = counter_t==0;
1068 method Action control(UART_LC_T lc_in, Bool enable_in);
1069 lc <= lc_in;
1070 enable <= enable_in;
1071 endmethod
1072 method Action input_srx(bit rx);
1073 rx_stable <= rx;
1074 endmethod
1075 endmodule
1076
1077
1078 //////////////////////////////////////////////////////////////////////////////
1079 // clocked RS (reset/set) flip-flow with reset dominating and edge triggering set
1080
1081 /*
1082 (* always_ready, always_enabled *)
1083 interface RS_ifc;
1084 method Action set;
1085 method Action reset;
1086 method Action enable(Bool en);
1087 method Bool state;
1088 endinterface
1089
1090
1091 module mkRS(RS_ifc);
1092 PulseWire s <- mkPulseWire;
1093 PulseWire r <- mkPulseWireOR;
1094 Wire#(Bool) e <- mkBypassWire;
1095 Wire#(Bool) q_next <- mkBypassWire;
1096 Reg#(Bool) q <- mkReg(False);
1097 Reg#(Bool) s_prev <- mkReg(False);
1098
1099 (* no_implicit_conditions *)
1100 rule handle_state_update;
1101 Bool s_rise = s && !s_prev;
1102 q_next <= e && !r && (s_rise || q);
1103 q <= q_next;
1104 s_prev <= s;
1105 endrule
1106
1107 method Action set; s.send(); endmethod
1108 method Action reset; r.send(); endmethod
1109 method Bool state = q_next;
1110 method Action enable(Bool en);
1111 e <= en;
1112 endmethod
1113
1114 endmodule
1115 */
1116
1117
1118 (* always_ready, always_enabled *)
1119 interface RS_ifc;
1120 method Action set;
1121 method Action reset;
1122 method Action posedge_set;
1123 method Action posedge_reset;
1124 method Bool state;
1125 endinterface
1126
1127 module mkRS(RS_ifc);
1128 PulseWire s <- mkPulseWireOR;
1129 PulseWire r <- mkPulseWireOR;
1130 PulseWire edge_s <- mkPulseWireOR;
1131 PulseWire edge_r <- mkPulseWireOR;
1132
1133 Reg#(Bool) q <- mkReg(False);
1134 Reg#(Bool) s_prev <- mkReg(False);
1135 Reg#(Bool) r_prev <- mkReg(False);
1136
1137
1138 (* no_implicit_conditions *)
1139 rule handle_edges_history;
1140 s_prev <= s;
1141 r_prev <= r;
1142 endrule
1143
1144 (* no_implicit_conditions *)
1145 rule handle_edges_set;
1146 if(edge_s && !s_prev) s.send;
1147 if(edge_r && !r_prev) r.send;
1148 endrule
1149
1150 (* no_implicit_conditions *)
1151 rule handle_state_update;
1152 q <= !r && (q || s);
1153 endrule
1154
1155 method Action set; s.send(); endmethod
1156 method Action reset; r.send(); endmethod
1157 method Action posedge_set; edge_s.send(); endmethod
1158 method Action posedge_reset; edge_r.send(); endmethod
1159 method Bool state = q;
1160
1161 endmodule
1162
1163
1164 endpackage