2 Copyright (c) 2013-2017, IIT Madras
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
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.
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 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
14 * Copyright (c) 2013 Simon W. Moore
15 * All rights reserved.
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.
21 * @BERI_LICENSE_HEADER_START@
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:
30 * http://www.beri-open-systems.org/legal/license-1-0.txt
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.
37 * @BERI_LICENSE_HEADER_END@
39 ******************************************************************************
42 * Simon Moore, July 2013
44 * This Bluespec module implements a 16650 style UART for RS232 serial
47 * The following registers exist at 32-bit boundaries accessible in little
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 ******************************************************************************/
62 //Modifications - The Avalon bus has been removed and AXI-4 Lite Bus support has been added
71 import ClientServer::*;
72 import defined_types::*;
73 import AXI4_Lite_Types::*;
74 import AXI4_Lite_Fabric::*;
76 `include "instance_defines.bsv"
78 // depth of transmit and receive FIFOs
79 typedef 16 Tx_FIFO_depth;
80 typedef 16 Rx_FIFO_depth;
82 // enumerate addresses corresponding to device registers
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,
92 } UART_ADDR_T deriving (Bits, Eq, FShow);
94 // interrupt enable register bits
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);
102 // interrupt identification values
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);
112 // line control register bits
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);
123 // modem control register bits
125 bit uart_MC_LOOPBACK;
130 } UART_MC_T deriving (Bits, Eq, FShow);
132 // line status register bits
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);
144 // modem status register bits
146 bit uart_MS_CDCD; // complement signals
150 bit uart_MS_DDCD; // delta signals
154 } UART_MS_T deriving (Bits, Eq, FShow);
156 // data from receiver
162 } RX_DATA_T deriving (Bits, Eq);
164 // transmitter states
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);
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);
176 (* always_ready, always_enabled *)
177 interface RS232_PHY_Ifc;
178 interface Get#(Bit#(1)) srx_in;
179 interface Get#(Bit#(1)) cts_in;
180 interface Get#(Bit#(1)) dsr_in;
181 interface Get#(Bit#(1)) ri_in;
182 interface Get#(Bit#(1)) dcd_in;
183 interface Put#(Bit#(1)) stx_out;
184 interface Put#(Bit#(1)) rts_out;
185 interface Put#(Bit#(1)) dtr_out;
189 interface Uart16550_AXI4_Lite_Ifc;
190 interface RS232_PHY_Ifc coe_rs232;
191 interface AXI4_Lite_Slave_IFC#(`PADDR,`Reg_width,`USERSPACE) slave_axi_uart;
192 (* always_ready, always_enabled *) method bit irq;
197 reset_prefix = "csi_clockreset_reset_n",
198 clock_prefix = "csi_clockreset_clk" *)
199 module mkUart16550#(Clock core_clock, Reset core_reset)(Uart16550_AXI4_Lite_Ifc);
200 AXI4_Lite_Slave_Xactor_IFC #(`PADDR,`Reg_width,`USERSPACE) s_xactor <- mkAXI4_Lite_Slave_Xactor(clocked_by core_clock, reset_by core_reset);
201 UART_transmitter_ifc uart_tx <- mkUART_transmitter;
202 UART_receiver_ifc uart_rx <- mkUART_receiver;
204 // TODO: FIXME: use Tx_FIFO_depth and Rx_FIFO_depth rather than 16?
205 // TX should only have a 1 element FIFO
206 // FIFOCountIfc#(Bit#(8), 16) tx_fifo <- mkGFIFOCount(True, False, True);
207 FIFOF#(Bit#(8)) tx_fifo <- mkGFIFOF1(True, False);
208 FIFOCountIfc#(RX_DATA_T, 16) rx_fifo <- mkGFIFOCount(True, True, True);
209 PulseWire tx_fifo_clear_pw <- mkPulseWire;
210 PulseWire rx_fifo_clear_pw <- mkPulseWire;
211 // add some bypass wires to hack around scheduling loop
212 Wire#(Bool) rx_fifo_full <- mkBypassWire;
213 Wire#(Bool) rx_fifo_empty <- mkBypassWire;
214 Wire#(Bool) tx_fifo_empty <- mkBypassWire;
215 // provide first item of rx_fifo if there is one, otherwise a default
216 Wire#(RX_DATA_T) rx_fifo_first <- mkBypassWire;
218 PulseWire count_error_up <- mkPulseWire;
219 PulseWire count_error_down <- mkPulseWire;
220 PulseWire count_error_clear <- mkPulseWire;
221 Reg#(UInt#(TAdd#(Rx_FIFO_depth,1)))
222 count_error <- mkReg(0);
224 Reg#(Bit#(2)) fcr <- mkReg(2'b11); // upper 2 bits of FIFO control register (rest not stored)
225 Reg#(UART_IE_T) ier <- mkReg(unpack(0)); // interrupt enable register bits (disable after reset)
226 Reg#(UART_LC_T) lcr <- mkReg(unpack('b00000011)); // line control register (default 8n1 format)
227 Reg#(UART_MC_T) mcr <- mkReg(unpack(0)); // modem control register
228 Wire#(UART_MC_T) mc_bypass <- mkBypassWire;
229 Reg#(UART_LS_T) lsr <- mkReg(unpack(0)); // line status register
230 Reg#(UART_MS_T) msr <- mkReg(unpack(0)); // modem status register
231 Reg#(Bit#(8)) scratch <- mkReg(unpack(0)); // scratch register
233 Wire#(Bool) loopback <- mkBypassWire; // loopback mode (msr[4])
235 Reg#(Bit#(8)) dl1r <- mkReg(0); // divisor 1 register
236 Reg#(Bit#(8)) dl2r <- mkReg(0); // divisor 2 register
237 Reg#(Bit#(16)) dlc <- mkReg(0); // divisor counter
238 Reg#(Bit#(16)) dl <- mkReg(0); // divisor counter bound
239 Reg#(Bool) enable <- mkReg(False);
240 Wire#(Maybe#(Bit#(16)))
241 dl_update <- mkDWire(tagged Invalid);
243 PulseWire interrupt_pw <- mkPulseWireOR;
244 RS_ifc rls_int <- mkRS;
245 RS_ifc rda_int <- mkRS;
246 RS_ifc thre_int <- mkRS;
247 RS_ifc ms_int <- mkRS;
248 RS_ifc ti_int <- mkRS;
250 // synchroniser registers for input pins
251 Reg#(bit) pin_srx_sync <- mkReg(0);
252 Reg#(bit) pin_cts_sync <- mkReg(0);
253 Reg#(bit) pin_dsr_sync <- mkReg(0);
254 Reg#(bit) pin_ri_sync <- mkReg(0);
255 Reg#(bit) pin_dcd_sync <- mkReg(0);
257 // registers for stable input pin values pre loopback check
258 Reg#(bit) pin_srx_c <- mkReg(0);
259 Reg#(bit) pin_cts_c <- mkReg(0);
260 Reg#(bit) pin_dsr_c <- mkReg(0);
261 Reg#(bit) pin_ri_c <- mkReg(0);
262 Reg#(bit) pin_dcd_c <- mkReg(0);
264 // registers for stable input pin values
265 Reg#(bit) pin_srx <- mkReg(0);
266 Reg#(bit) pin_cts <- mkReg(0);
267 Reg#(bit) pin_dsr <- mkReg(0);
268 Reg#(bit) pin_ri <- mkReg(0);
269 Reg#(bit) pin_dcd <- mkReg(0);
271 // previous pin values last read via MSR (modem status register)
272 Reg#(bit) prev_cts <- mkReg(0);
273 Reg#(bit) prev_dsr <- mkReg(0);
274 Reg#(bit) prev_ri <- mkReg(0);
275 Reg#(bit) prev_dcd <- mkReg(0);
276 PulseWire msr_save_pin_state <- mkPulseWire; // trigger condition to save pin state
278 // registered outputs
279 Reg#(bit) pin_stx <- mkReg(0);
280 Reg#(bit) pin_rts <- mkReg(0);
281 Reg#(bit) pin_dtr <- mkReg(0);
283 SyncFIFOIfc#(AXI4_Lite_Rd_Addr #(`PADDR,`USERSPACE)) ff_rd_addr <- mkSyncFIFOToCC(1,core_clock,core_reset);
284 SyncFIFOIfc#(AXI4_Lite_Wr_Addr #(`PADDR, `USERSPACE)) ff_wr_addr <- mkSyncFIFOToCC(1,core_clock,core_reset);
285 SyncFIFOIfc#(AXI4_Lite_Wr_Data #(`Reg_width)) ff_wr_data <- mkSyncFIFOToCC(1,core_clock,core_reset);
287 SyncFIFOIfc#(AXI4_Lite_Rd_Data #(`Reg_width,`USERSPACE)) ff_rd_resp <- mkSyncFIFOFromCC(1,core_clock);
288 SyncFIFOIfc#(AXI4_Lite_Wr_Resp #(`USERSPACE)) ff_wr_resp <- mkSyncFIFOFromCC(1,core_clock);
291 (* no_implicit_conditions *)
292 rule synchronise_input_pins; // N.B. there must be no logic between these registers
293 pin_srx_c <= pin_srx_sync;
294 pin_cts_c <= pin_cts_sync;
295 pin_dsr_c <= pin_dsr_sync;
296 pin_ri_c <= pin_ri_sync;
297 pin_dcd_c <= pin_dcd_sync;
300 rule bypass_mrc_to_avoid_scheduling_loop;
304 (* no_implicit_conditions *)
305 rule handle_loopback_mode;
309 pin_cts <= mc_bypass.uart_MC_RTS;
310 pin_dsr <= mc_bypass.uart_MC_DTR;
311 pin_ri <= mc_bypass.uart_MC_OUT1;
312 pin_dcd <= mc_bypass.uart_MC_OUT2;
316 pin_srx <= pin_srx_c;
317 pin_cts <= pin_cts_c;
318 pin_dsr <= pin_dsr_c;
320 pin_dcd <= pin_dcd_c;
324 // first changes in the pins
325 uart_MS_DCTS: pin_cts ^ prev_cts,
326 uart_MS_DDSR: pin_dsr ^ prev_dsr,
327 uart_MS_TERI: pin_ri ^ prev_ri,
328 uart_MS_DDCD: pin_dcd ^ prev_dcd,
329 // then the actual signals
330 uart_MS_CCTS: pin_cts, // TODO: allow this to be from loopback
331 uart_MS_CDSR: pin_dsr,
333 uart_MS_CDCD: pin_dcd};
335 if(msr_save_pin_state)
344 (* no_implicit_conditions *)
346 pin_rts <= mcr.uart_MC_RTS;
347 pin_dtr <= mcr.uart_MC_DTR;
350 (* no_implicit_conditions *)
351 rule loopback_mode_select;
352 loopback <= mcr.uart_MC_LOOPBACK==1;
355 (* no_implicit_conditions *)
356 rule connect_pins_rx;
357 uart_rx.input_srx(pin_srx);
359 (* no_implicit_conditions *)
360 rule connect_pins_tx;
361 pin_stx <= uart_tx.output_stx;
363 (* no_implicit_conditions *)
364 rule rx_first_item_if_any;
365 rx_fifo_first <= rx_fifo.notEmpty ? rx_fifo.first
370 framing_error: False};
373 (* no_implicit_conditions *)
374 rule interrupt_sources;
375 if(rda_int.state || rls_int.state || thre_int.state || ms_int.state || ti_int.state)
378 // receiver line status interrupt
379 // - note: also reset on read of line status
383 || rx_fifo_first.parity_error
384 || rx_fifo_first.framing_error
385 || rx_fifo_first.break_error)
388 // received data available interrupt
389 UInt#(5) trigger_level;
391 // 2'b00 handled by default case
392 2'b01 : trigger_level = 4;
393 2'b10 : trigger_level = 8;
394 2'b11 : trigger_level = 14;
395 default : trigger_level = 1;
397 // TODO: should this in fact be edge triggered on the trigger level being reached or passed?
398 if(ier.uart_IE_RDA && !rx_fifo_empty && (rx_fifo.count >= trigger_level))
403 // transmitter holding register empty interrupt
404 // if(!ier.uart_IE_THRE)
405 if(!ier.uart_IE_THRE || !tx_fifo_empty)
407 else if(tx_fifo_empty)
408 thre_int.posedge_set;
413 else if(uart_rx.timeout)
416 // modem status interrupt
417 // - note: also reset by reading modem status
420 else if({msr.uart_MS_DCTS, msr.uart_MS_DDSR, msr.uart_MS_TERI, msr.uart_MS_DDCD} != 0)
424 (* no_implicit_conditions *)
425 rule foward_lc_enable;
426 uart_tx.control(lcr, enable);
427 uart_rx.control(lcr, enable);
430 (* no_implicit_conditions *)
431 rule divisor_counter;
432 enable <= (dlc==0) && (dl>0);
433 if(isValid(dl_update))
435 let newdl = fromMaybe(?, dl_update);
438 `ifdef verbose $display("%05t: dl set to %1d", $time, newdl); `endif
441 dlc <= (dlc==0 ? dl : dlc) - 1;
444 (* no_implicit_conditions *)
445 rule forward_tx_clear(tx_fifo_clear_pw);
448 rule forward_tx(!tx_fifo_clear_pw && tx_fifo.notEmpty);
449 uart_tx.tx_char(tx_fifo.first);
456 else if(rx_fifo.notFull)
458 RX_DATA_T rx <- uart_rx.rx_char;
460 if(rx.break_error || rx.parity_error || rx.framing_error)
461 count_error_up.send();
465 (* no_implicit_conditions *)
466 rule count_rx_errors;
467 if(count_error_clear)
471 if(count_error_up && !count_error_down && (count_error<fromInteger(valueOf(Rx_FIFO_depth))))
472 count_error <= count_error+1;
473 if(!count_error_up && count_error_down && (count_error>0))
474 count_error <= count_error-1;
478 (* no_implicit_conditions *)
479 rule fifo_status_bypass_to_avoid_scheduling_loop;
480 rx_fifo_full <= !rx_fifo.notFull;
481 rx_fifo_empty <= !rx_fifo.notEmpty;
482 tx_fifo_empty <= !tx_fifo.notEmpty;
485 rule capture_read_request;
486 let req <- pop_o (s_xactor.o_rd_addr);
489 rule send_read_respone_to_bus;
490 s_xactor.i_rd_data.enq(ff_rd_resp.first);
493 rule capture_write_request;
494 let req <- pop_o (s_xactor.o_wr_addr);
495 let wr_data <- pop_o(s_xactor.o_wr_data);
497 ff_wr_data.enq(wr_data);
499 rule send_write_response;
500 s_xactor.i_wr_resp.enq(ff_wr_resp.first);
505 rule handle_axi4_read(ff_rd_addr.notEmpty);
507 Bool dlab = lcr.uart_LC_DL == 1'b1; // divisor latch enable
508 let req = ff_rd_addr.first;
510 `ifdef verbose $display("RD_ADDR %h", req.araddr); `endif
511 UART_ADDR_T addr = unpack(req.araddr[5:3]);
516 uart_LS_EI: rx_fifo_full || (count_error!=0), // error indicator
517 uart_LS_TW: tx_fifo_empty && uart_tx.tx_buf_empty, // transmitter empty
518 uart_LS_TFE: tx_fifo_empty, // transmitter FIFO empty
519 uart_LS_BI: rx_fifo_first.break_error, // break error
520 uart_LS_FE: rx_fifo_first.framing_error, // framing error
521 uart_LS_PE: rx_fifo_first.parity_error, // parity error
522 uart_LS_OE: rx_fifo_full, // overflow
523 uart_LS_DR: !rx_fifo_empty}; // data ready
528 if(rls_int.state) // highest priority interrupt - receiver line status
530 else if(rda_int.state) // second priority interrupt - received data available
532 else if(ti_int.state) // also second priority - timeout
534 else if(thre_int.state) // third priority - transmitter holding register empty
536 else if(ms_int.state) // fourth - modem status change interrupt
540 `ifdef verbose $display("addr_READ: %d",addr) ; `endif
542 UART_ADDR_DATA : if(dlab) // divisor latch enabled
544 else if(!rx_fifo_empty)
546 RX_DATA_T rx = rx_fifo.first;
548 if(rx.break_error || rx.parity_error || rx.framing_error)
549 count_error_down.send;
555 rtn_valid = False; // TODO: should this be the old value?
556 UART_ADDR_INT_ENABLE : rtn = dlab ? dl2r : zeroExtend(pack(ier));
557 UART_ADDR_INT_ID_FIFO_CTRL : rtn = {4'b1100, pack(ii)};
558 UART_ADDR_LINE_CTRL : rtn = pack(lcr);
559 UART_ADDR_MODEM_CTRL : rtn = zeroExtend(pack(mcr));
560 UART_ADDR_LINE_STATUS : begin
564 UART_ADDR_MODEM_STATUS : begin
567 msr_save_pin_state.send();
569 UART_ADDR_SCRATCH : rtn = scratch;
572 let resp = AXI4_Lite_Rd_Data {rresp : AXI4_LITE_OKAY, rdata : rtn_valid? zeroExtend(rtn) : '1, ruser: 0};
573 ff_rd_resp.enq(resp);
574 // $display ("DATA----------- %b", rtn);
575 `ifdef verbose $display("%05t: --------------------------READ--------------------------------------------",$time); `endif
578 rule handle_axi4_write(ff_wr_addr.notEmpty && ff_wr_data.notEmpty);
579 Bool dlab = lcr.uart_LC_DL == 1'b1; // divisor latch enable
581 uart_LS_EI: rx_fifo_full || (count_error!=0), // error indicator
582 uart_LS_TW: tx_fifo_empty && uart_tx.tx_buf_empty, // transmitter empty
583 uart_LS_TFE: tx_fifo_empty, // transmitter FIFO empty
584 uart_LS_BI: rx_fifo_first.break_error, // break error
585 uart_LS_FE: rx_fifo_first.framing_error, // framing error
586 uart_LS_PE: rx_fifo_first.parity_error, // parity error
587 uart_LS_OE: rx_fifo_full, // overflow
588 uart_LS_DR: !rx_fifo_empty}; // data ready
593 if(rls_int.state) // highest priority interrupt - receiver line status
595 else if(rda_int.state) // second priority interrupt - received data available
597 else if(ti_int.state) // also second priority - timeout
599 else if(thre_int.state) // third priority - transmitter holding register empty
601 else if(ms_int.state) // fourth - modem status change interrupt
606 let wr_addr = ff_wr_addr.first;
607 `ifdef verbose $display("WR_ADDR %h", wr_addr.awaddr); `endif
609 let wr_data = ff_wr_data.first;
611 `ifdef verbose $display("WR_DATA %h", wr_data.wdata); `endif
612 UART_ADDR_T addr = unpack(wr_addr.awaddr[5:3]);
613 Bit#(8) d = truncate(pack(wr_data.wdata));
616 `ifdef verbose $display("addr_WRITE: %d",addr); `endif
618 UART_ADDR_DATA: if(dlab) // divisor latch enabled
621 dl_update <= tagged Valid ({dl2r,d});
623 else if(tx_fifo.notFull)
625 tx_fifo.enq(unpack(d));
628 UART_ADDR_INT_ENABLE: if(dlab)
631 ier <= unpack(truncate(d));
632 UART_ADDR_INT_ID_FIFO_CTRL: begin
636 rx_fifo_clear_pw.send;
637 count_error_clear.send;
640 tx_fifo_clear_pw.send;
642 UART_ADDR_LINE_CTRL : lcr <= unpack(truncate(pack(wr_data.wdata)));
643 UART_ADDR_MODEM_CTRL : mcr <= unpack(truncate(pack(wr_data.wdata)));
644 UART_ADDR_LINE_STATUS : begin /* no write */ end
645 UART_ADDR_MODEM_STATUS : begin /* no write */ end
646 UART_ADDR_SCRATCH : begin scratch <= d; `ifdef verbose $display("scratch : %h",d); `endif end
648 let resp = AXI4_Lite_Wr_Resp {bresp: AXI4_LITE_OKAY, buser: 0};
649 ff_wr_resp.enq(resp);
650 // $display ("DATA WRITE----------- %b", wr_data.wdata);
651 // $display ("DATA Adress----------- %d", addr);
652 `ifdef verbose $display("%05t: ----------------------------WRITE------------------------------------------",$time); `endif
656 $display("%05t: tx bit = %b", $time, pin_stx);
659 interface RS232_PHY_Ifc coe_rs232;
661 interface srx_in = interface Put
662 method Action put(Bit#(1) in);
663 pin_srx_sync <= in; // RX Input
667 interface cts_in = interface Put
668 method Action put(Bit#(1) in);
669 pin_cts_sync <= in; // CTS Input
673 interface dsr_in = interface Put
674 method Action put(Bit#(1) in);
675 pin_dsr_sync <= in; // Data Set Ready indicating that MODEM is ready
676 // to establish the communication
680 interface ri_in = interface Put
681 method Action put(Bit#(1) in);
682 pin_ri_sync <= in; // Ring Indicator indicate that a telephone ringing
683 //signal has been recieved by the MODEM
687 interface dcd_in = interface Put
688 method Action put(Bit#(1) in);
689 pin_dcd_sync <= in; // Data carrier detect
693 interface stx_out = interface Get
694 method ActionValue#(Bit#(1)) get;
695 return pin_stx; // Tx output
699 interface rts_out = interface Get
700 method ActionValue#(Bit#(1)) get;
701 return pin_rts; // RTS output
705 interface dtr_out = interface Get
706 method ActionValue#(Bit#(1)) get;
707 return pin_dtr; // Data Terminal Ready output
713 interface slave_axi_uart = s_xactor.axi_side;
716 return interrupt_pw ? 1'b1 : 1'b0;
724 //////////////////////////////////////////////////////////////////////////////
727 interface UART_transmitter_ifc;
728 method Action tx_char(Bit#(8) c);
729 (* always_ready, always_enabled *)
730 method Bool tx_buf_empty;
731 (* always_ready, always_enabled *)
732 method Action control(UART_LC_T lc_in, Bool enable_in);
733 (* always_ready, always_enabled *)
734 method bit output_stx;
738 module mkUART_transmitter(UART_transmitter_ifc);
740 FIFOF#(Bit#(8)) tx_fifo <- mkLFIFOF;
741 Wire#(Bool) tx_fifo_empty <- mkBypassWire;
742 Reg#(bit) bit_out <- mkReg(0);
743 Reg#(bit) parity_xor <- mkReg(0);
744 Reg#(bit) stx_o_tmp <- mkReg(1); // rename output bit? our use bit_out directly?
745 Reg#(TX_state_T) tstate <- mkReg(STX_idle);
746 Reg#(TX_state_T) last_tstate <- mkReg(STX_idle);
747 Reg#(UInt#(5)) counter <- mkReg(0);
748 Reg#(UInt#(3)) bit_counter <- mkReg(0);
749 Reg#(Bit#(7)) shift_out <- mkReg(0);
750 Wire#(UART_LC_T) lc <- mkBypassWire;
751 Wire#(Bool) enable <- mkBypassWire;
753 rule monitor_state_for_debug(last_tstate != tstate);
755 `ifdef verbose $write("%05t: UART TX state change ", $time); `endif
756 `ifdef verbose $write(fshow(last_tstate)); `endif
757 `ifdef verbose $write(" -> "); `endif
758 `ifdef verbose $display(fshow(tstate)); `endif
760 last_tstate <= tstate;
763 // rule to decouple rule dependency on tx_fifo.notEmpty
764 (* no_implicit_conditions *)
765 rule forward_tx_fifo_empty;
766 tx_fifo_empty <= !tx_fifo.notEmpty;
769 rule idle(enable && (tstate==STX_idle));
770 tstate <= STX_pop_byte; // move directly to pop_byte since it will block if the tx_fifo is empty
774 rule pop_byte(enable && (tstate==STX_pop_byte));
775 case(lc.uart_LC_BITS) // number of bits in a word
778 parity_xor <= ^tx_fifo.first[4:0];
782 parity_xor <= ^tx_fifo.first[5:0];
786 parity_xor <= ^tx_fifo.first[6:0];
790 parity_xor <= ^tx_fifo.first[7:0];
793 shift_out[6:0] <= tx_fifo.first[7:1];
794 bit_out <= tx_fifo.first[0];
795 tstate <= STX_send_start;
798 rule send_start(enable && (tstate==STX_send_start));
805 tstate <= STX_send_byte;
808 counter <= counter-1;
812 rule send_byte(enable && (tstate==STX_send_byte));
819 bit_counter <= bit_counter-1;
820 shift_out <= {1'b0,shift_out[6:1]};
821 bit_out <= shift_out[0];
824 if(lc.uart_LC_PE == 0) // no partity bit
825 tstate <= STX_send_stop;
828 case({lc.uart_LC_EP, lc.uart_LC_SP})
829 2'b00: bit_out <= ~parity_xor;
831 2'b10: bit_out <= parity_xor;
834 tstate <= STX_send_parity;
839 counter <= counter-1;
840 stx_o_tmp <= bit_out;
843 rule send_parity(enable && (tstate==STX_send_parity));
849 tstate <= STX_send_stop;
852 counter <= counter-1;
853 stx_o_tmp <= bit_out;
857 rule send_stop(enable && (tstate==STX_send_stop));
859 counter <= lc.uart_LC_SB==0 ? 5'b01101 : // 1 stop bit
860 lc.uart_LC_BITS==0 ? 5'b10101 : // 1.5 stop bits
861 5'b11101; // 2 stop bits
869 counter <= counter-1;
874 method Action tx_char(Bit#(8) c);
878 method Bool tx_buf_empty = tx_fifo_empty;
880 method Action control(UART_LC_T lc_in, Bool enable_in);
885 method bit output_stx = lc.uart_LC_BC==1 ? 0 : stx_o_tmp; // handle break condition
890 //////////////////////////////////////////////////////////////////////////////
893 interface UART_receiver_ifc;
894 method ActionValue#(RX_DATA_T) rx_char();
895 (* always_ready, always_enabled *)
896 method Bool timeout();
897 (* always_ready, always_enabled *)
898 method Action control(UART_LC_T lc_in, Bool enable_in);
899 (* always_ready, always_enabled *)
900 method Action input_srx(bit rx);
904 module mkUART_receiver(UART_receiver_ifc);
906 FIFOF#(RX_DATA_T) rx_fifo <- mkLFIFOF;
907 Reg#(bit) rx_stable <- mkReg(1);
908 Wire#(UART_LC_T) lc <- mkBypassWire;
909 Wire#(Bool) enable <- mkBypassWire;
910 Reg#(RX_state_T) rstate <- mkReg(SRX_idle);
911 Reg#(RX_state_T) last_rstate <- mkReg(SRX_idle);
912 Reg#(UInt#(4)) rcounter <- mkReg(0);
913 Reg#(UInt#(3)) rbit_counter <- mkReg(0);
914 Reg#(Bit#(8)) rshift <- mkReg(0);
915 Reg#(bit) rparity <- mkReg(0);
916 Reg#(bit) rparity_error <- mkReg(0);
917 Reg#(bit) rframing_error <- mkReg(0);
918 Reg#(bit) rparity_xor <- mkReg(0);
919 Reg#(UInt#(8)) counter_b <- mkReg(159);
920 Reg#(UInt#(10)) counter_t <- mkReg(511);
921 PulseWire counter_t_preset <- mkPulseWireOR;
923 Bool break_error = counter_b==0;
925 rule monitor_state_for_debug(last_rstate != rstate);
927 `ifdef verbose $write("%05t: UART RX state change ", $time); `endif
928 `ifdef verbose $write(fshow(last_rstate)); `endif
929 `ifdef verbose $write(" -> "); `endif
930 `ifdef verbose $display(fshow(rstate)); `endif
932 last_rstate <= rstate;
935 (* no_implicit_conditions *)
936 rule receive_status_counters;
938 case ({lc.uart_LC_PE, lc.uart_LC_SB, lc.uart_LC_BITS})
939 4'b0000: toc_value = 447; // 7 bits
940 4'b0100: toc_value = 479; // 7.5 bits
942 4'b1000: toc_value = 511; // 8 bits
943 4'b1100: toc_value = 543; // 8.5 bits
946 4'b1001: toc_value = 575; // 9 bits
950 4'b1101: toc_value = 639; // 10 bits
953 4'b1110: toc_value = 703; // 11 bits
954 4'b1111: toc_value = 767; // 12 bits
955 default: toc_value = 511; // 8 bits
958 UInt#(8) brc_value = truncate(toc_value>>2); // break counter value
961 counter_b <= brc_value;
962 else if((counter_b!=0) && enable)
963 counter_b <= counter_b-1;
966 counter_t <= toc_value;
967 else if(enable && (counter_t!=0))
968 counter_t <= counter_t - 1;
971 // helper rule to decouple firing dependancies
972 rule couter_t_preset_on_fifo_empty(!rx_fifo.notEmpty);
973 counter_t_preset.send();
976 (* no_implicit_conditions *)
977 rule idle(enable && (rstate==SRX_idle));
979 if((rx_stable==0) && !break_error)
980 rstate <= SRX_rec_start;
983 rule rec_start(enable && (rstate==SRX_rec_start));
985 if(rx_stable==1) // no start bit
988 rstate <= SRX_rec_prepare;
989 rcounter <= rcounter-1;
992 rule rec_prepare(enable && (rstate==SRX_rec_prepare));
993 rbit_counter <= unpack(zeroExtend(lc.uart_LC_BITS) + 4);
996 rstate <= SRX_rec_bit;
1001 rcounter <= rcounter-1;
1004 rule rec_bit(enable && (rstate==SRX_rec_bit));
1006 rstate <= SRX_end_bit;
1007 if(rcounter==7) // read the bit
1008 case(lc.uart_LC_BITS) // number of bits in a word
1009 0: rshift[4:0] <= {rx_stable, rshift[4:1]};
1010 1: rshift[5:0] <= {rx_stable, rshift[5:1]};
1011 2: rshift[6:0] <= {rx_stable, rshift[6:1]};
1012 3: rshift[7:0] <= {rx_stable, rshift[7:1]};
1014 rcounter <= rcounter-1;
1017 rule end_bit(enable && (rstate==SRX_end_bit));
1018 if(rbit_counter==0) // no more bits in the word
1020 rstate <= (lc.uart_LC_PE==1) ? SRX_rec_parity : SRX_rec_stop;
1024 rstate <= SRX_rec_bit;
1025 rbit_counter <= rbit_counter-1;
1026 rcounter <= rcounter-1;
1029 rule rec_parity(enable && (rstate==SRX_rec_parity));
1030 if(rcounter == 7) // read parity
1032 rparity <= rx_stable;
1033 rstate <= SRX_ca_lc_parity;
1035 rcounter <= rcounter-1;
1036 //$display("%05t rx bit = %d", $time, rx_stable);
1040 $display("%05t: rx bit = %d", $time, rx_stable);
1043 rule calc_parity(enable && (rstate==SRX_ca_lc_parity));
1044 rparity_xor <= ^{rshift, rparity};
1045 rstate <= SRX_check_parity;
1046 rcounter <= rcounter-1;
1049 rule check_parity(enable && (rstate==SRX_check_parity));
1050 case({lc.uart_LC_EP, lc.uart_LC_SP})
1051 2'b00: rparity_error <= ~rparity_xor;
1052 2'b01: rparity_error <= ~rparity;
1053 2'b10: rparity_error <= rparity_xor;
1054 2'b11: rparity_error <= rparity;
1056 rcounter <= rcounter-1;
1057 rstate <= SRX_wait1;
1060 rule wait1(enable && (rstate==SRX_wait1));
1063 rcounter <= 4'b1110;
1064 rstate <= SRX_rec_stop;
1067 rcounter <= rcounter-1;
1070 rule rec_stop(enable && (rstate==SRX_rec_stop));
1071 if(rcounter==7) // read the stop bit
1073 rframing_error <= ~rx_stable; // no framing error if stop bit = 1
1076 rcounter <= rcounter-1;
1077 `ifdef verbose $display("%05t: rx bit = %d", $time, rx_stable); `endif
1080 rule push(enable && (rstate==SRX_push));
1081 if((rx_stable==1) || break_error)
1090 framing_error: False
1098 parity_error: rparity_error==1,
1099 framing_error: rframing_error==1
1102 counter_t_preset.send; // preset counter_t on an enq
1103 //$display("%05t: rx bit = %d", $time, rx_stable);
1107 method ActionValue#(RX_DATA_T) rx_char();
1108 counter_t_preset.send; // preset counter_t on a deq
1110 return rx_fifo.first;
1112 method Bool timeout() = counter_t==0;
1113 method Action control(UART_LC_T lc_in, Bool enable_in);
1115 enable <= enable_in;
1117 method Action input_srx(bit rx);
1123 //////////////////////////////////////////////////////////////////////////////
1124 // clocked RS (reset/set) flip-flow with reset dominating and edge triggering set
1127 (* always_ready, always_enabled *)
1130 method Action reset;
1131 method Action enable(Bool en);
1136 module mkRS(RS_ifc);
1137 PulseWire s <- mkPulseWire;
1138 PulseWire r <- mkPulseWireOR;
1139 Wire#(Bool) e <- mkBypassWire;
1140 Wire#(Bool) q_next <- mkBypassWire;
1141 Reg#(Bool) q <- mkReg(False);
1142 Reg#(Bool) s_prev <- mkReg(False);
1144 (* no_implicit_conditions *)
1145 rule handle_state_update;
1146 Bool s_rise = s && !s_prev;
1147 q_next <= e && !r && (s_rise || q);
1152 method Action set; s.send(); endmethod
1153 method Action reset; r.send(); endmethod
1154 method Bool state = q_next;
1155 method Action enable(Bool en);
1163 (* always_ready, always_enabled *)
1166 method Action reset;
1167 method Action posedge_set;
1168 method Action posedge_reset;
1172 module mkRS(RS_ifc);
1173 PulseWire s <- mkPulseWireOR;
1174 PulseWire r <- mkPulseWireOR;
1175 PulseWire edge_s <- mkPulseWireOR;
1176 PulseWire edge_r <- mkPulseWireOR;
1178 Reg#(Bool) q <- mkReg(False);
1179 Reg#(Bool) s_prev <- mkReg(False);
1180 Reg#(Bool) r_prev <- mkReg(False);
1183 (* no_implicit_conditions *)
1184 rule handle_edges_history;
1189 (* no_implicit_conditions *)
1190 rule handle_edges_set;
1191 if(edge_s && !s_prev) s.send;
1192 if(edge_r && !r_prev) r.send;
1195 (* no_implicit_conditions *)
1196 rule handle_state_update;
1197 q <= !r && (q || s);
1200 method Action set; s.send(); endmethod
1201 method Action reset; r.send(); endmethod
1202 method Action posedge_set; edge_s.send(); endmethod
1203 method Action posedge_reset; edge_r.send(); endmethod
1204 method Bool state = q;