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::*;
73 import defined_types::*;
74 import AXI4_Lite_Types::*;
75 import AXI4_Lite_Fabric::*;
77 `include "instance_defines.bsv"
79 // depth of transmit and receive FIFOs
80 typedef 16 Tx_FIFO_depth;
81 typedef 16 Rx_FIFO_depth;
83 // enumerate addresses corresponding to device registers
86 UART_ADDR_INT_ENABLE=1,
87 UART_ADDR_INT_ID_FIFO_CTRL=2, // read=INT_ID, write=FIFO_CTRL
88 UART_ADDR_LINE_CTRL=3,
89 UART_ADDR_MODEM_CTRL=4,
90 UART_ADDR_LINE_STATUS=5,
91 UART_ADDR_MODEM_STATUS=6,
93 } UART_ADDR_T deriving (Bits, Eq, FShow);
95 // interrupt enable register bits
97 Bool uart_IE_MS; // Modem status interrupt
98 Bool uart_IE_RLS; // Receiver line status interrupt
99 Bool uart_IE_THRE; // Transmitter holding register empty interrupt
100 Bool uart_IE_RDA; // Recived data available interrupt
101 } UART_IE_T deriving (Bits, Eq, FShow);
103 // interrupt identification values
105 UART_II_MS = 4'b0000, // modem status
106 UART_II_NO_INT = 4'b0001, // no interrupt pending
107 UART_II_THRE = 4'b0010, // transmitter holding register empty
108 UART_II_RDA = 4'b0100, // receiver data available
109 UART_II_RLS = 4'b0110, // receiver line status
110 UART_II_TI = 4'b1100 // timeout indication
111 } UART_II_T deriving (Bits, Eq, FShow);
113 // line control register bits
115 Bit#(1) uart_LC_DL; // divisor latch access bit
116 Bit#(1) uart_LC_BC; // break control
117 Bit#(1) uart_LC_SP; // stick parity
118 Bit#(1) uart_LC_EP; // even parity
119 Bit#(1) uart_LC_PE; // parity enables
120 Bit#(1) uart_LC_SB; // stop bits
121 Bit#(2) uart_LC_BITS; // bits in character
122 } UART_LC_T deriving (Bits, Eq, FShow);
124 // modem control register bits
126 bit uart_MC_LOOPBACK;
131 } UART_MC_T deriving (Bits, Eq, FShow);
133 // line status register bits
135 Bool uart_LS_EI; // error indicator
136 Bool uart_LS_TW; // transmitter empty indicator
137 Bool uart_LS_TFE; // transmitter FIFO is empty
138 Bool uart_LS_BI; // break interrupt
139 Bool uart_LS_FE; // framing error
140 Bool uart_LS_PE; // parity error
141 Bool uart_LS_OE; // overrun error
142 Bool uart_LS_DR; // data ready
143 } UART_LS_T deriving (Bits, Eq, FShow);
145 // modem status register bits
147 bit uart_MS_CDCD; // complement signals
151 bit uart_MS_DDCD; // delta signals
155 } UART_MS_T deriving (Bits, Eq, FShow);
157 // data from receiver
163 } RX_DATA_T deriving (Bits, Eq);
165 // transmitter states
167 STX_idle, STX_pop_byte, STX_send_start, STX_send_byte, STX_send_parity, STX_send_stop
168 } TX_state_T deriving (Bits, Eq, FShow);
172 SRX_idle, SRX_rec_start, SRX_rec_bit, SRX_rec_parity, SRX_rec_stop,
173 SRX_check_parity, SRX_rec_prepare, SRX_end_bit, SRX_wait1,
174 SRX_ca_lc_parity, SRX_push } RX_state_T deriving (Bits, Eq, FShow);
177 (* always_ready, always_enabled *)
178 interface RS232_PHY_Ifc;
179 interface Get#(Bit#(1)) srx_in;
180 interface Get#(Bit#(1)) cts_in;
181 interface Get#(Bit#(1)) dsr_in;
182 interface Get#(Bit#(1)) ri_in;
183 interface Get#(Bit#(1)) dcd_in;
184 interface Put#(Bit#(1)) stx_out;
185 interface Put#(Bit#(1)) rts_out;
186 interface Put#(Bit#(1)) dtr_out;
190 interface Uart16550_AXI4_Lite_Ifc;
191 interface RS232_PHY_Ifc coe_rs232;
192 interface AXI4_Lite_Slave_IFC#(`PADDR,`Reg_width,`USERSPACE) slave_axi_uart;
193 (* always_ready, always_enabled *) method bit irq;
198 reset_prefix = "csi_clockreset_reset_n",
199 clock_prefix = "csi_clockreset_clk" *)
200 module mkUart16550#(Clock core_clock, Reset core_reset)(Uart16550_AXI4_Lite_Ifc);
201 AXI4_Lite_Slave_Xactor_IFC #(`PADDR,`Reg_width,`USERSPACE) s_xactor <- mkAXI4_Lite_Slave_Xactor(clocked_by core_clock, reset_by core_reset);
202 UART_transmitter_ifc uart_tx <- mkUART_transmitter;
203 UART_receiver_ifc uart_rx <- mkUART_receiver;
205 // TODO: FIXME: use Tx_FIFO_depth and Rx_FIFO_depth rather than 16?
206 // TX should only have a 1 element FIFO
207 // FIFOCountIfc#(Bit#(8), 16) tx_fifo <- mkGFIFOCount(True, False, True);
208 FIFOF#(Bit#(8)) tx_fifo <- mkGFIFOF1(True, False);
209 FIFOCountIfc#(RX_DATA_T, 16) rx_fifo <- mkGFIFOCount(True, True, True);
210 PulseWire tx_fifo_clear_pw <- mkPulseWire;
211 PulseWire rx_fifo_clear_pw <- mkPulseWire;
212 // add some bypass wires to hack around scheduling loop
213 Wire#(Bool) rx_fifo_full <- mkBypassWire;
214 Wire#(Bool) rx_fifo_empty <- mkBypassWire;
215 Wire#(Bool) tx_fifo_empty <- mkBypassWire;
216 // provide first item of rx_fifo if there is one, otherwise a default
217 Wire#(RX_DATA_T) rx_fifo_first <- mkBypassWire;
219 PulseWire count_error_up <- mkPulseWire;
220 PulseWire count_error_down <- mkPulseWire;
221 PulseWire count_error_clear <- mkPulseWire;
222 Reg#(UInt#(TAdd#(Rx_FIFO_depth,1)))
223 count_error <- mkReg(0);
225 Reg#(Bit#(2)) fcr <- mkReg(2'b11); // upper 2 bits of FIFO control register (rest not stored)
226 Reg#(UART_IE_T) ier <- mkReg(unpack(0)); // interrupt enable register bits (disable after reset)
227 Reg#(UART_LC_T) lcr <- mkReg(unpack('b00000011)); // line control register (default 8n1 format)
228 Reg#(UART_MC_T) mcr <- mkReg(unpack(0)); // modem control register
229 Wire#(UART_MC_T) mc_bypass <- mkBypassWire;
230 Reg#(UART_LS_T) lsr <- mkReg(unpack(0)); // line status register
231 Reg#(UART_MS_T) msr <- mkReg(unpack(0)); // modem status register
232 Reg#(Bit#(8)) scratch <- mkReg(unpack(0)); // scratch register
234 Wire#(Bool) loopback <- mkBypassWire; // loopback mode (msr[4])
236 Reg#(Bit#(8)) dl1r <- mkReg(0); // divisor 1 register
237 Reg#(Bit#(8)) dl2r <- mkReg(0); // divisor 2 register
238 Reg#(Bit#(16)) dlc <- mkReg(0); // divisor counter
239 Reg#(Bit#(16)) dl <- mkReg(0); // divisor counter bound
240 Reg#(Bool) enable <- mkReg(False);
241 Wire#(Maybe#(Bit#(16)))
242 dl_update <- mkDWire(tagged Invalid);
244 PulseWire interrupt_pw <- mkPulseWireOR;
245 RS_ifc rls_int <- mkRS;
246 RS_ifc rda_int <- mkRS;
247 RS_ifc thre_int <- mkRS;
248 RS_ifc ms_int <- mkRS;
249 RS_ifc ti_int <- mkRS;
251 // synchroniser registers for input pins
252 Reg#(bit) pin_srx_sync <- mkReg(0);
253 Reg#(bit) pin_cts_sync <- mkReg(0);
254 Reg#(bit) pin_dsr_sync <- mkReg(0);
255 Reg#(bit) pin_ri_sync <- mkReg(0);
256 Reg#(bit) pin_dcd_sync <- mkReg(0);
258 // registers for stable input pin values pre loopback check
259 Reg#(bit) pin_srx_c <- mkReg(0);
260 Reg#(bit) pin_cts_c <- mkReg(0);
261 Reg#(bit) pin_dsr_c <- mkReg(0);
262 Reg#(bit) pin_ri_c <- mkReg(0);
263 Reg#(bit) pin_dcd_c <- mkReg(0);
265 // registers for stable input pin values
266 Reg#(bit) pin_srx <- mkReg(0);
267 Reg#(bit) pin_cts <- mkReg(0);
268 Reg#(bit) pin_dsr <- mkReg(0);
269 Reg#(bit) pin_ri <- mkReg(0);
270 Reg#(bit) pin_dcd <- mkReg(0);
272 // previous pin values last read via MSR (modem status register)
273 Reg#(bit) prev_cts <- mkReg(0);
274 Reg#(bit) prev_dsr <- mkReg(0);
275 Reg#(bit) prev_ri <- mkReg(0);
276 Reg#(bit) prev_dcd <- mkReg(0);
277 PulseWire msr_save_pin_state <- mkPulseWire; // trigger condition to save pin state
279 // registered outputs
280 Reg#(bit) pin_stx <- mkReg(0);
281 Reg#(bit) pin_rts <- mkReg(0);
282 Reg#(bit) pin_dtr <- mkReg(0);
284 SyncFIFOIfc#(AXI4_Lite_Rd_Addr #(`PADDR,`USERSPACE)) ff_rd_addr <- mkSyncFIFOToCC(1,core_clock,core_reset);
285 SyncFIFOIfc#(AXI4_Lite_Wr_Addr #(`PADDR, `USERSPACE)) ff_wr_addr <- mkSyncFIFOToCC(1,core_clock,core_reset);
286 SyncFIFOIfc#(AXI4_Lite_Wr_Data #(`Reg_width)) ff_wr_data <- mkSyncFIFOToCC(1,core_clock,core_reset);
288 SyncFIFOIfc#(AXI4_Lite_Rd_Data #(`Reg_width,`USERSPACE)) ff_rd_resp <- mkSyncFIFOFromCC(1,core_clock);
289 SyncFIFOIfc#(AXI4_Lite_Wr_Resp #(`USERSPACE)) ff_wr_resp <- mkSyncFIFOFromCC(1,core_clock);
292 (* no_implicit_conditions *)
293 rule synchronise_input_pins; // N.B. there must be no logic between these registers
294 pin_srx_c <= pin_srx_sync;
295 pin_cts_c <= pin_cts_sync;
296 pin_dsr_c <= pin_dsr_sync;
297 pin_ri_c <= pin_ri_sync;
298 pin_dcd_c <= pin_dcd_sync;
301 rule bypass_mrc_to_avoid_scheduling_loop;
305 (* no_implicit_conditions *)
306 rule handle_loopback_mode;
310 pin_cts <= mc_bypass.uart_MC_RTS;
311 pin_dsr <= mc_bypass.uart_MC_DTR;
312 pin_ri <= mc_bypass.uart_MC_OUT1;
313 pin_dcd <= mc_bypass.uart_MC_OUT2;
317 pin_srx <= pin_srx_c;
318 pin_cts <= pin_cts_c;
319 pin_dsr <= pin_dsr_c;
321 pin_dcd <= pin_dcd_c;
325 // first changes in the pins
326 uart_MS_DCTS: pin_cts ^ prev_cts,
327 uart_MS_DDSR: pin_dsr ^ prev_dsr,
328 uart_MS_TERI: pin_ri ^ prev_ri,
329 uart_MS_DDCD: pin_dcd ^ prev_dcd,
330 // then the actual signals
331 uart_MS_CCTS: pin_cts, // TODO: allow this to be from loopback
332 uart_MS_CDSR: pin_dsr,
334 uart_MS_CDCD: pin_dcd};
336 if(msr_save_pin_state)
345 (* no_implicit_conditions *)
347 pin_rts <= mcr.uart_MC_RTS;
348 pin_dtr <= mcr.uart_MC_DTR;
351 (* no_implicit_conditions *)
352 rule loopback_mode_select;
353 loopback <= mcr.uart_MC_LOOPBACK==1;
356 (* no_implicit_conditions *)
357 rule connect_pins_rx;
358 uart_rx.input_srx(pin_srx);
360 (* no_implicit_conditions *)
361 rule connect_pins_tx;
362 pin_stx <= uart_tx.output_stx;
364 (* no_implicit_conditions *)
365 rule rx_first_item_if_any;
366 rx_fifo_first <= rx_fifo.notEmpty ? rx_fifo.first
371 framing_error: False};
374 (* no_implicit_conditions *)
375 rule interrupt_sources;
376 if(rda_int.state || rls_int.state || thre_int.state || ms_int.state || ti_int.state)
379 // receiver line status interrupt
380 // - note: also reset on read of line status
384 || rx_fifo_first.parity_error
385 || rx_fifo_first.framing_error
386 || rx_fifo_first.break_error)
389 // received data available interrupt
390 UInt#(5) trigger_level;
392 // 2'b00 handled by default case
393 2'b01 : trigger_level = 4;
394 2'b10 : trigger_level = 8;
395 2'b11 : trigger_level = 14;
396 default : trigger_level = 1;
398 // TODO: should this in fact be edge triggered on the trigger level being reached or passed?
399 if(ier.uart_IE_RDA && !rx_fifo_empty && (rx_fifo.count >= trigger_level))
404 // transmitter holding register empty interrupt
405 // if(!ier.uart_IE_THRE)
406 if(!ier.uart_IE_THRE || !tx_fifo_empty)
408 else if(tx_fifo_empty)
409 thre_int.posedge_set;
414 else if(uart_rx.timeout)
417 // modem status interrupt
418 // - note: also reset by reading modem status
421 else if({msr.uart_MS_DCTS, msr.uart_MS_DDSR, msr.uart_MS_TERI, msr.uart_MS_DDCD} != 0)
425 (* no_implicit_conditions *)
426 rule foward_lc_enable;
427 uart_tx.control(lcr, enable);
428 uart_rx.control(lcr, enable);
431 (* no_implicit_conditions *)
432 rule divisor_counter;
433 enable <= (dlc==0) && (dl>0);
434 if(isValid(dl_update))
436 let newdl = fromMaybe(?, dl_update);
439 `ifdef verbose $display("%05t: dl set to %1d", $time, newdl); `endif
442 dlc <= (dlc==0 ? dl : dlc) - 1;
445 (* no_implicit_conditions *)
446 rule forward_tx_clear(tx_fifo_clear_pw);
449 rule forward_tx(!tx_fifo_clear_pw && tx_fifo.notEmpty);
450 uart_tx.tx_char(tx_fifo.first);
457 else if(rx_fifo.notFull)
459 RX_DATA_T rx <- uart_rx.rx_char;
461 if(rx.break_error || rx.parity_error || rx.framing_error)
462 count_error_up.send();
466 (* no_implicit_conditions *)
467 rule count_rx_errors;
468 if(count_error_clear)
472 if(count_error_up && !count_error_down && (count_error<fromInteger(valueOf(Rx_FIFO_depth))))
473 count_error <= count_error+1;
474 if(!count_error_up && count_error_down && (count_error>0))
475 count_error <= count_error-1;
479 (* no_implicit_conditions *)
480 rule fifo_status_bypass_to_avoid_scheduling_loop;
481 rx_fifo_full <= !rx_fifo.notFull;
482 rx_fifo_empty <= !rx_fifo.notEmpty;
483 tx_fifo_empty <= !tx_fifo.notEmpty;
486 rule capture_read_request;
487 let req <- pop_o (s_xactor.o_rd_addr);
490 rule send_read_respone_to_bus;
491 s_xactor.i_rd_data.enq(ff_rd_resp.first);
494 rule capture_write_request;
495 let req <- pop_o (s_xactor.o_wr_addr);
496 let wr_data <- pop_o(s_xactor.o_wr_data);
498 ff_wr_data.enq(wr_data);
500 rule send_write_response;
501 s_xactor.i_wr_resp.enq(ff_wr_resp.first);
506 rule handle_axi4_read(ff_rd_addr.notEmpty);
508 Bool dlab = lcr.uart_LC_DL == 1'b1; // divisor latch enable
509 let req = ff_rd_addr.first;
511 `ifdef verbose $display("RD_ADDR %h", req.araddr); `endif
512 UART_ADDR_T addr = unpack(req.araddr[5:3]);
517 uart_LS_EI: rx_fifo_full || (count_error!=0), // error indicator
518 uart_LS_TW: tx_fifo_empty && uart_tx.tx_buf_empty, // transmitter empty
519 uart_LS_TFE: tx_fifo_empty, // transmitter FIFO empty
520 uart_LS_BI: rx_fifo_first.break_error, // break error
521 uart_LS_FE: rx_fifo_first.framing_error, // framing error
522 uart_LS_PE: rx_fifo_first.parity_error, // parity error
523 uart_LS_OE: rx_fifo_full, // overflow
524 uart_LS_DR: !rx_fifo_empty}; // data ready
529 if(rls_int.state) // highest priority interrupt - receiver line status
531 else if(rda_int.state) // second priority interrupt - received data available
533 else if(ti_int.state) // also second priority - timeout
535 else if(thre_int.state) // third priority - transmitter holding register empty
537 else if(ms_int.state) // fourth - modem status change interrupt
541 `ifdef verbose $display("addr_READ: %d",addr) ; `endif
543 UART_ADDR_DATA : if(dlab) // divisor latch enabled
545 else if(!rx_fifo_empty)
547 RX_DATA_T rx = rx_fifo.first;
549 if(rx.break_error || rx.parity_error || rx.framing_error)
550 count_error_down.send;
556 rtn_valid = False; // TODO: should this be the old value?
557 UART_ADDR_INT_ENABLE : rtn = dlab ? dl2r : zeroExtend(pack(ier));
558 UART_ADDR_INT_ID_FIFO_CTRL : rtn = {4'b1100, pack(ii)};
559 UART_ADDR_LINE_CTRL : rtn = pack(lcr);
560 UART_ADDR_MODEM_CTRL : rtn = zeroExtend(pack(mcr));
561 UART_ADDR_LINE_STATUS : begin
565 UART_ADDR_MODEM_STATUS : begin
568 msr_save_pin_state.send();
570 UART_ADDR_SCRATCH : rtn = scratch;
573 let resp = AXI4_Lite_Rd_Data {rresp : AXI4_LITE_OKAY, rdata : rtn_valid? zeroExtend(rtn) : '1, ruser: 0};
574 ff_rd_resp.enq(resp);
575 // $display ("DATA----------- %b", rtn);
576 `ifdef verbose $display("%05t: --------------------------READ--------------------------------------------",$time); `endif
579 rule handle_axi4_write(ff_wr_addr.notEmpty && ff_wr_data.notEmpty);
580 Bool dlab = lcr.uart_LC_DL == 1'b1; // divisor latch enable
582 uart_LS_EI: rx_fifo_full || (count_error!=0), // error indicator
583 uart_LS_TW: tx_fifo_empty && uart_tx.tx_buf_empty, // transmitter empty
584 uart_LS_TFE: tx_fifo_empty, // transmitter FIFO empty
585 uart_LS_BI: rx_fifo_first.break_error, // break error
586 uart_LS_FE: rx_fifo_first.framing_error, // framing error
587 uart_LS_PE: rx_fifo_first.parity_error, // parity error
588 uart_LS_OE: rx_fifo_full, // overflow
589 uart_LS_DR: !rx_fifo_empty}; // data ready
594 if(rls_int.state) // highest priority interrupt - receiver line status
596 else if(rda_int.state) // second priority interrupt - received data available
598 else if(ti_int.state) // also second priority - timeout
600 else if(thre_int.state) // third priority - transmitter holding register empty
602 else if(ms_int.state) // fourth - modem status change interrupt
607 let wr_addr = ff_wr_addr.first;
608 `ifdef verbose $display("WR_ADDR %h", wr_addr.awaddr); `endif
610 let wr_data = ff_wr_data.first;
612 `ifdef verbose $display("WR_DATA %h", wr_data.wdata); `endif
613 UART_ADDR_T addr = unpack(wr_addr.awaddr[5:3]);
614 Bit#(8) d = truncate(pack(wr_data.wdata));
617 `ifdef verbose $display("addr_WRITE: %d",addr); `endif
619 UART_ADDR_DATA: if(dlab) // divisor latch enabled
622 dl_update <= tagged Valid ({dl2r,d});
624 else if(tx_fifo.notFull)
626 tx_fifo.enq(unpack(d));
629 UART_ADDR_INT_ENABLE: if(dlab)
632 ier <= unpack(truncate(d));
633 UART_ADDR_INT_ID_FIFO_CTRL: begin
637 rx_fifo_clear_pw.send;
638 count_error_clear.send;
641 tx_fifo_clear_pw.send;
643 UART_ADDR_LINE_CTRL : lcr <= unpack(truncate(pack(wr_data.wdata)));
644 UART_ADDR_MODEM_CTRL : mcr <= unpack(truncate(pack(wr_data.wdata)));
645 UART_ADDR_LINE_STATUS : begin /* no write */ end
646 UART_ADDR_MODEM_STATUS : begin /* no write */ end
647 UART_ADDR_SCRATCH : begin scratch <= d; `ifdef verbose $display("scratch : %h",d); `endif end
649 let resp = AXI4_Lite_Wr_Resp {bresp: AXI4_LITE_OKAY, buser: 0};
650 ff_wr_resp.enq(resp);
651 // $display ("DATA WRITE----------- %b", wr_data.wdata);
652 // $display ("DATA Adress----------- %d", addr);
653 `ifdef verbose $display("%05t: ----------------------------WRITE------------------------------------------",$time); `endif
657 $display("%05t: tx bit = %b", $time, pin_stx);
660 interface RS232_PHY_Ifc coe_rs232;
662 interface srx_in = interface Put
663 method Action put(Bit#(1) in);
664 pin_srx_sync <= in; // RX Input
668 interface cts_in = interface Put
669 method Action put(Bit#(1) in);
670 pin_cts_sync <= in; // CTS Input
674 interface dsr_in = interface Put
675 method Action put(Bit#(1) in);
676 pin_dsr_sync <= in; // Data Set Ready indicating that MODEM is ready
677 // to establish the communication
681 interface ri_in = interface Put
682 method Action put(Bit#(1) in);
683 pin_ri_sync <= in; // Ring Indicator indicate that a telephone ringing
684 //signal has been recieved by the MODEM
688 interface dcd_in = interface Put
689 method Action put(Bit#(1) in);
690 pin_dcd_sync <= in; // Data carrier detect
694 interface stx_out = interface Get
695 method ActionValue#(Bit#(1)) get;
696 return pin_stx; // Tx output
700 interface rts_out = interface Get
701 method ActionValue#(Bit#(1)) get;
702 return pin_rts; // RTS output
706 interface dtr_out = interface Get
707 method ActionValue#(Bit#(1)) get;
708 return pin_dtr; // Data Terminal Ready output
714 interface slave_axi_uart = s_xactor.axi_side;
717 return interrupt_pw ? 1'b1 : 1'b0;
725 //////////////////////////////////////////////////////////////////////////////
728 interface UART_transmitter_ifc;
729 method Action tx_char(Bit#(8) c);
730 (* always_ready, always_enabled *)
731 method Bool tx_buf_empty;
732 (* always_ready, always_enabled *)
733 method Action control(UART_LC_T lc_in, Bool enable_in);
734 (* always_ready, always_enabled *)
735 method bit output_stx;
739 module mkUART_transmitter(UART_transmitter_ifc);
741 FIFOF#(Bit#(8)) tx_fifo <- mkLFIFOF;
742 Wire#(Bool) tx_fifo_empty <- mkBypassWire;
743 Reg#(bit) bit_out <- mkReg(0);
744 Reg#(bit) parity_xor <- mkReg(0);
745 Reg#(bit) stx_o_tmp <- mkReg(1); // rename output bit? our use bit_out directly?
746 Reg#(TX_state_T) tstate <- mkReg(STX_idle);
747 Reg#(TX_state_T) last_tstate <- mkReg(STX_idle);
748 Reg#(UInt#(5)) counter <- mkReg(0);
749 Reg#(UInt#(3)) bit_counter <- mkReg(0);
750 Reg#(Bit#(7)) shift_out <- mkReg(0);
751 Wire#(UART_LC_T) lc <- mkBypassWire;
752 Wire#(Bool) enable <- mkBypassWire;
754 rule monitor_state_for_debug(last_tstate != tstate);
756 `ifdef verbose $write("%05t: UART TX state change ", $time); `endif
757 `ifdef verbose $write(fshow(last_tstate)); `endif
758 `ifdef verbose $write(" -> "); `endif
759 `ifdef verbose $display(fshow(tstate)); `endif
761 last_tstate <= tstate;
764 // rule to decouple rule dependency on tx_fifo.notEmpty
765 (* no_implicit_conditions *)
766 rule forward_tx_fifo_empty;
767 tx_fifo_empty <= !tx_fifo.notEmpty;
770 rule idle(enable && (tstate==STX_idle));
771 tstate <= STX_pop_byte; // move directly to pop_byte since it will block if the tx_fifo is empty
775 rule pop_byte(enable && (tstate==STX_pop_byte));
776 case(lc.uart_LC_BITS) // number of bits in a word
779 parity_xor <= ^tx_fifo.first[4:0];
783 parity_xor <= ^tx_fifo.first[5:0];
787 parity_xor <= ^tx_fifo.first[6:0];
791 parity_xor <= ^tx_fifo.first[7:0];
794 shift_out[6:0] <= tx_fifo.first[7:1];
795 bit_out <= tx_fifo.first[0];
796 tstate <= STX_send_start;
799 rule send_start(enable && (tstate==STX_send_start));
806 tstate <= STX_send_byte;
809 counter <= counter-1;
813 rule send_byte(enable && (tstate==STX_send_byte));
820 bit_counter <= bit_counter-1;
821 shift_out <= {1'b0,shift_out[6:1]};
822 bit_out <= shift_out[0];
825 if(lc.uart_LC_PE == 0) // no partity bit
826 tstate <= STX_send_stop;
829 case({lc.uart_LC_EP, lc.uart_LC_SP})
830 2'b00: bit_out <= ~parity_xor;
832 2'b10: bit_out <= parity_xor;
835 tstate <= STX_send_parity;
840 counter <= counter-1;
841 stx_o_tmp <= bit_out;
844 rule send_parity(enable && (tstate==STX_send_parity));
850 tstate <= STX_send_stop;
853 counter <= counter-1;
854 stx_o_tmp <= bit_out;
858 rule send_stop(enable && (tstate==STX_send_stop));
860 counter <= lc.uart_LC_SB==0 ? 5'b01101 : // 1 stop bit
861 lc.uart_LC_BITS==0 ? 5'b10101 : // 1.5 stop bits
862 5'b11101; // 2 stop bits
870 counter <= counter-1;
875 method Action tx_char(Bit#(8) c);
879 method Bool tx_buf_empty = tx_fifo_empty;
881 method Action control(UART_LC_T lc_in, Bool enable_in);
886 method bit output_stx = lc.uart_LC_BC==1 ? 0 : stx_o_tmp; // handle break condition
891 //////////////////////////////////////////////////////////////////////////////
894 interface UART_receiver_ifc;
895 method ActionValue#(RX_DATA_T) rx_char();
896 (* always_ready, always_enabled *)
897 method Bool timeout();
898 (* always_ready, always_enabled *)
899 method Action control(UART_LC_T lc_in, Bool enable_in);
900 (* always_ready, always_enabled *)
901 method Action input_srx(bit rx);
905 module mkUART_receiver(UART_receiver_ifc);
907 FIFOF#(RX_DATA_T) rx_fifo <- mkLFIFOF;
908 Reg#(bit) rx_stable <- mkReg(1);
909 Wire#(UART_LC_T) lc <- mkBypassWire;
910 Wire#(Bool) enable <- mkBypassWire;
911 Reg#(RX_state_T) rstate <- mkReg(SRX_idle);
912 Reg#(RX_state_T) last_rstate <- mkReg(SRX_idle);
913 Reg#(UInt#(4)) rcounter <- mkReg(0);
914 Reg#(UInt#(3)) rbit_counter <- mkReg(0);
915 Reg#(Bit#(8)) rshift <- mkReg(0);
916 Reg#(bit) rparity <- mkReg(0);
917 Reg#(bit) rparity_error <- mkReg(0);
918 Reg#(bit) rframing_error <- mkReg(0);
919 Reg#(bit) rparity_xor <- mkReg(0);
920 Reg#(UInt#(8)) counter_b <- mkReg(159);
921 Reg#(UInt#(10)) counter_t <- mkReg(511);
922 PulseWire counter_t_preset <- mkPulseWireOR;
924 Bool break_error = counter_b==0;
926 rule monitor_state_for_debug(last_rstate != rstate);
928 `ifdef verbose $write("%05t: UART RX state change ", $time); `endif
929 `ifdef verbose $write(fshow(last_rstate)); `endif
930 `ifdef verbose $write(" -> "); `endif
931 `ifdef verbose $display(fshow(rstate)); `endif
933 last_rstate <= rstate;
936 (* no_implicit_conditions *)
937 rule receive_status_counters;
939 case ({lc.uart_LC_PE, lc.uart_LC_SB, lc.uart_LC_BITS})
940 4'b0000: toc_value = 447; // 7 bits
941 4'b0100: toc_value = 479; // 7.5 bits
943 4'b1000: toc_value = 511; // 8 bits
944 4'b1100: toc_value = 543; // 8.5 bits
947 4'b1001: toc_value = 575; // 9 bits
951 4'b1101: toc_value = 639; // 10 bits
954 4'b1110: toc_value = 703; // 11 bits
955 4'b1111: toc_value = 767; // 12 bits
956 default: toc_value = 511; // 8 bits
959 UInt#(8) brc_value = truncate(toc_value>>2); // break counter value
962 counter_b <= brc_value;
963 else if((counter_b!=0) && enable)
964 counter_b <= counter_b-1;
967 counter_t <= toc_value;
968 else if(enable && (counter_t!=0))
969 counter_t <= counter_t - 1;
972 // helper rule to decouple firing dependancies
973 rule couter_t_preset_on_fifo_empty(!rx_fifo.notEmpty);
974 counter_t_preset.send();
977 (* no_implicit_conditions *)
978 rule idle(enable && (rstate==SRX_idle));
980 if((rx_stable==0) && !break_error)
981 rstate <= SRX_rec_start;
984 rule rec_start(enable && (rstate==SRX_rec_start));
986 if(rx_stable==1) // no start bit
989 rstate <= SRX_rec_prepare;
990 rcounter <= rcounter-1;
993 rule rec_prepare(enable && (rstate==SRX_rec_prepare));
994 rbit_counter <= unpack(zeroExtend(lc.uart_LC_BITS) + 4);
997 rstate <= SRX_rec_bit;
1002 rcounter <= rcounter-1;
1005 rule rec_bit(enable && (rstate==SRX_rec_bit));
1007 rstate <= SRX_end_bit;
1008 if(rcounter==7) // read the bit
1009 case(lc.uart_LC_BITS) // number of bits in a word
1010 0: rshift[4:0] <= {rx_stable, rshift[4:1]};
1011 1: rshift[5:0] <= {rx_stable, rshift[5:1]};
1012 2: rshift[6:0] <= {rx_stable, rshift[6:1]};
1013 3: rshift[7:0] <= {rx_stable, rshift[7:1]};
1015 rcounter <= rcounter-1;
1018 rule end_bit(enable && (rstate==SRX_end_bit));
1019 if(rbit_counter==0) // no more bits in the word
1021 rstate <= (lc.uart_LC_PE==1) ? SRX_rec_parity : SRX_rec_stop;
1025 rstate <= SRX_rec_bit;
1026 rbit_counter <= rbit_counter-1;
1027 rcounter <= rcounter-1;
1030 rule rec_parity(enable && (rstate==SRX_rec_parity));
1031 if(rcounter == 7) // read parity
1033 rparity <= rx_stable;
1034 rstate <= SRX_ca_lc_parity;
1036 rcounter <= rcounter-1;
1037 //$display("%05t rx bit = %d", $time, rx_stable);
1041 $display("%05t: rx bit = %d", $time, rx_stable);
1044 rule calc_parity(enable && (rstate==SRX_ca_lc_parity));
1045 rparity_xor <= ^{rshift, rparity};
1046 rstate <= SRX_check_parity;
1047 rcounter <= rcounter-1;
1050 rule check_parity(enable && (rstate==SRX_check_parity));
1051 case({lc.uart_LC_EP, lc.uart_LC_SP})
1052 2'b00: rparity_error <= ~rparity_xor;
1053 2'b01: rparity_error <= ~rparity;
1054 2'b10: rparity_error <= rparity_xor;
1055 2'b11: rparity_error <= rparity;
1057 rcounter <= rcounter-1;
1058 rstate <= SRX_wait1;
1061 rule wait1(enable && (rstate==SRX_wait1));
1064 rcounter <= 4'b1110;
1065 rstate <= SRX_rec_stop;
1068 rcounter <= rcounter-1;
1071 rule rec_stop(enable && (rstate==SRX_rec_stop));
1072 if(rcounter==7) // read the stop bit
1074 rframing_error <= ~rx_stable; // no framing error if stop bit = 1
1077 rcounter <= rcounter-1;
1078 `ifdef verbose $display("%05t: rx bit = %d", $time, rx_stable); `endif
1081 rule push(enable && (rstate==SRX_push));
1082 if((rx_stable==1) || break_error)
1091 framing_error: False
1099 parity_error: rparity_error==1,
1100 framing_error: rframing_error==1
1103 counter_t_preset.send; // preset counter_t on an enq
1104 //$display("%05t: rx bit = %d", $time, rx_stable);
1108 method ActionValue#(RX_DATA_T) rx_char();
1109 counter_t_preset.send; // preset counter_t on a deq
1111 return rx_fifo.first;
1113 method Bool timeout() = counter_t==0;
1114 method Action control(UART_LC_T lc_in, Bool enable_in);
1116 enable <= enable_in;
1118 method Action input_srx(bit rx);
1124 //////////////////////////////////////////////////////////////////////////////
1125 // clocked RS (reset/set) flip-flow with reset dominating and edge triggering set
1128 (* always_ready, always_enabled *)
1131 method Action reset;
1132 method Action enable(Bool en);
1137 module mkRS(RS_ifc);
1138 PulseWire s <- mkPulseWire;
1139 PulseWire r <- mkPulseWireOR;
1140 Wire#(Bool) e <- mkBypassWire;
1141 Wire#(Bool) q_next <- mkBypassWire;
1142 Reg#(Bool) q <- mkReg(False);
1143 Reg#(Bool) s_prev <- mkReg(False);
1145 (* no_implicit_conditions *)
1146 rule handle_state_update;
1147 Bool s_rise = s && !s_prev;
1148 q_next <= e && !r && (s_rise || q);
1153 method Action set; s.send(); endmethod
1154 method Action reset; r.send(); endmethod
1155 method Bool state = q_next;
1156 method Action enable(Bool en);
1164 (* always_ready, always_enabled *)
1167 method Action reset;
1168 method Action posedge_set;
1169 method Action posedge_reset;
1173 module mkRS(RS_ifc);
1174 PulseWire s <- mkPulseWireOR;
1175 PulseWire r <- mkPulseWireOR;
1176 PulseWire edge_s <- mkPulseWireOR;
1177 PulseWire edge_r <- mkPulseWireOR;
1179 Reg#(Bool) q <- mkReg(False);
1180 Reg#(Bool) s_prev <- mkReg(False);
1181 Reg#(Bool) r_prev <- mkReg(False);
1184 (* no_implicit_conditions *)
1185 rule handle_edges_history;
1190 (* no_implicit_conditions *)
1191 rule handle_edges_set;
1192 if(edge_s && !s_prev) s.send;
1193 if(edge_r && !r_prev) r.send;
1196 (* no_implicit_conditions *)
1197 rule handle_state_update;
1198 q <= !r && (q || s);
1201 method Action set; s.send(); endmethod
1202 method Action reset; r.send(); endmethod
1203 method Action posedge_set; edge_s.send(); endmethod
1204 method Action posedge_reset; edge_r.send(); endmethod
1205 method Bool state = q;