add GetPut import
[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 GetPut::*;
73 import defined_types::*;
74 import AXI4_Lite_Types::*;
75 import AXI4_Lite_Fabric::*;
76 import Semi_FIFOF::*;
77 `include "instance_defines.bsv"
78
79 // depth of transmit and receive FIFOs
80 typedef 16 Tx_FIFO_depth;
81 typedef 16 Rx_FIFO_depth;
82
83 // enumerate addresses corresponding to device registers
84 typedef enum {
85 UART_ADDR_DATA=0,
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,
92 UART_ADDR_SCRATCH=7
93 } UART_ADDR_T deriving (Bits, Eq, FShow);
94
95 // interrupt enable register bits
96 typedef struct {
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);
102
103 // interrupt identification values
104 typedef enum {
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);
112
113 // line control register bits
114 typedef struct {
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);
123
124 // modem control register bits
125 typedef struct {
126 bit uart_MC_LOOPBACK;
127 bit uart_MC_OUT2;
128 bit uart_MC_OUT1;
129 bit uart_MC_RTS;
130 bit uart_MC_DTR;
131 } UART_MC_T deriving (Bits, Eq, FShow);
132
133 // line status register bits
134 typedef struct {
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);
144
145 // modem status register bits
146 typedef struct {
147 bit uart_MS_CDCD; // complement signals
148 bit uart_MS_CRI;
149 bit uart_MS_CDSR;
150 bit uart_MS_CCTS;
151 bit uart_MS_DDCD; // delta signals
152 bit uart_MS_TERI;
153 bit uart_MS_DDSR;
154 bit uart_MS_DCTS;
155 } UART_MS_T deriving (Bits, Eq, FShow);
156
157 // data from receiver
158 typedef struct {
159 Bit#(8) data;
160 Bool break_error;
161 Bool parity_error;
162 Bool framing_error;
163 } RX_DATA_T deriving (Bits, Eq);
164
165 // transmitter states
166 typedef enum {
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);
169
170 // receiver states
171 typedef enum {
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);
175
176
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;
187 endinterface
188
189
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;
194 endinterface
195
196
197 (* synthesize,
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;
204
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;
218
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);
224
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
233
234 Wire#(Bool) loopback <- mkBypassWire; // loopback mode (msr[4])
235
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);
243
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;
250
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);
257
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);
264
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);
271
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
278
279 // registered outputs
280 Reg#(bit) pin_stx <- mkReg(0);
281 Reg#(bit) pin_rts <- mkReg(0);
282 Reg#(bit) pin_dtr <- mkReg(0);
283
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);
287
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);
290
291
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;
299 endrule
300
301 rule bypass_mrc_to_avoid_scheduling_loop;
302 mc_bypass <= mcr;
303 endrule
304
305 (* no_implicit_conditions *)
306 rule handle_loopback_mode;
307 if(loopback)
308 begin
309 pin_srx <= pin_stx;
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;
314 end
315 else
316 begin
317 pin_srx <= pin_srx_c;
318 pin_cts <= pin_cts_c;
319 pin_dsr <= pin_dsr_c;
320 pin_ri <= pin_ri_c;
321 pin_dcd <= pin_dcd_c;
322 end
323
324 msr <= UART_MS_T{
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,
333 uart_MS_CRI: pin_ri,
334 uart_MS_CDCD: pin_dcd};
335
336 if(msr_save_pin_state)
337 begin
338 prev_dcd <= pin_dcd;
339 prev_ri <= pin_ri;
340 prev_dsr <= pin_dsr;
341 prev_cts <= pin_cts;
342 end
343 endrule
344
345 (* no_implicit_conditions *)
346 rule output_rts_dtr;
347 pin_rts <= mcr.uart_MC_RTS;
348 pin_dtr <= mcr.uart_MC_DTR;
349 endrule
350
351 (* no_implicit_conditions *)
352 rule loopback_mode_select;
353 loopback <= mcr.uart_MC_LOOPBACK==1;
354 endrule
355
356 (* no_implicit_conditions *)
357 rule connect_pins_rx;
358 uart_rx.input_srx(pin_srx);
359 endrule
360 (* no_implicit_conditions *)
361 rule connect_pins_tx;
362 pin_stx <= uart_tx.output_stx;
363 endrule
364 (* no_implicit_conditions *)
365 rule rx_first_item_if_any;
366 rx_fifo_first <= rx_fifo.notEmpty ? rx_fifo.first
367 : RX_DATA_T{
368 data:0,
369 break_error: False,
370 parity_error: False,
371 framing_error: False};
372 endrule
373
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)
377 interrupt_pw.send;
378
379 // receiver line status interrupt
380 // - note: also reset on read of line status
381 if(!ier.uart_IE_RLS)
382 rls_int.reset;
383 else if(rx_fifo_full
384 || rx_fifo_first.parity_error
385 || rx_fifo_first.framing_error
386 || rx_fifo_first.break_error)
387 rls_int.posedge_set;
388
389 // received data available interrupt
390 UInt#(5) trigger_level;
391 case(fcr)
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;
397 endcase
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))
400 rda_int.set;
401 else
402 rda_int.reset;
403
404 // transmitter holding register empty interrupt
405 // if(!ier.uart_IE_THRE)
406 if(!ier.uart_IE_THRE || !tx_fifo_empty)
407 thre_int.reset;
408 else if(tx_fifo_empty)
409 thre_int.posedge_set;
410
411 // timer interrupt
412 if(!ier.uart_IE_RDA)
413 ti_int.reset;
414 else if(uart_rx.timeout)
415 ti_int.posedge_set;
416
417 // modem status interrupt
418 // - note: also reset by reading modem status
419 if(!ier.uart_IE_MS)
420 ms_int.reset;
421 else if({msr.uart_MS_DCTS, msr.uart_MS_DDSR, msr.uart_MS_TERI, msr.uart_MS_DDCD} != 0)
422 ms_int.posedge_set;
423 endrule
424
425 (* no_implicit_conditions *)
426 rule foward_lc_enable;
427 uart_tx.control(lcr, enable);
428 uart_rx.control(lcr, enable);
429 endrule
430
431 (* no_implicit_conditions *)
432 rule divisor_counter;
433 enable <= (dlc==0) && (dl>0);
434 if(isValid(dl_update))
435 begin
436 let newdl = fromMaybe(?, dl_update);
437 dl <= newdl;
438 dlc <= newdl-1;
439 `ifdef verbose $display("%05t: dl set to %1d", $time, newdl); `endif
440 end
441 else
442 dlc <= (dlc==0 ? dl : dlc) - 1;
443 endrule
444
445 (* no_implicit_conditions *)
446 rule forward_tx_clear(tx_fifo_clear_pw);
447 tx_fifo.clear;
448 endrule
449 rule forward_tx(!tx_fifo_clear_pw && tx_fifo.notEmpty);
450 uart_tx.tx_char(tx_fifo.first);
451 tx_fifo.deq;
452 endrule
453
454 rule forward_rx;
455 if(rx_fifo_clear_pw)
456 rx_fifo.clear;
457 else if(rx_fifo.notFull)
458 begin
459 RX_DATA_T rx <- uart_rx.rx_char;
460 rx_fifo.enq(rx);
461 if(rx.break_error || rx.parity_error || rx.framing_error)
462 count_error_up.send();
463 end
464 endrule
465
466 (* no_implicit_conditions *)
467 rule count_rx_errors;
468 if(count_error_clear)
469 count_error <= 0;
470 else
471 begin
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;
476 end
477 endrule
478
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;
484 endrule
485
486 rule capture_read_request;
487 let req <- pop_o (s_xactor.o_rd_addr);
488 ff_rd_addr.enq(req);
489 endrule
490 rule send_read_respone_to_bus;
491 s_xactor.i_rd_data.enq(ff_rd_resp.first);
492 ff_rd_resp.deq;
493 endrule
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);
497 ff_wr_addr.enq(req);
498 ff_wr_data.enq(wr_data);
499 endrule
500 rule send_write_response;
501 s_xactor.i_wr_resp.enq(ff_wr_resp.first);
502 ff_wr_resp.deq;
503 endrule
504
505
506 rule handle_axi4_read(ff_rd_addr.notEmpty);
507
508 Bool dlab = lcr.uart_LC_DL == 1'b1; // divisor latch enable
509 let req = ff_rd_addr.first;
510 ff_rd_addr.deq;
511 `ifdef verbose $display("RD_ADDR %h", req.araddr); `endif
512 UART_ADDR_T addr = unpack(req.araddr[5:3]);
513 Bool rtn_valid=True;
514 Bit#(8) rtn = 0;
515
516 let ls = UART_LS_T{
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
525
526 lsr <= ls;
527
528 UART_II_T ii;
529 if(rls_int.state) // highest priority interrupt - receiver line status
530 ii = UART_II_RLS;
531 else if(rda_int.state) // second priority interrupt - received data available
532 ii = UART_II_RDA;
533 else if(ti_int.state) // also second priority - timeout
534 ii = UART_II_TI;
535 else if(thre_int.state) // third priority - transmitter holding register empty
536 ii = UART_II_THRE;
537 else if(ms_int.state) // fourth - modem status change interrupt
538 ii = UART_II_MS;
539 else
540 ii = UART_II_NO_INT;
541 `ifdef verbose $display("addr_READ: %d",addr) ; `endif
542 case(addr)
543 UART_ADDR_DATA : if(dlab) // divisor latch enabled
544 rtn = dl1r;
545 else if(!rx_fifo_empty)
546 begin
547 RX_DATA_T rx = rx_fifo.first;
548 rtn = rx.data;
549 if(rx.break_error || rx.parity_error || rx.framing_error)
550 count_error_down.send;
551 rx_fifo.deq;
552 ti_int.reset;
553 rda_int.reset;
554 end
555 else
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
562 rls_int.reset;
563 rtn = pack(ls);
564 end
565 UART_ADDR_MODEM_STATUS : begin
566 ms_int.reset;
567 rtn = pack(msr);
568 msr_save_pin_state.send();
569 end
570 UART_ADDR_SCRATCH : rtn = scratch;
571
572 endcase
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
577 endrule
578
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
581 let ls = UART_LS_T{
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
590
591 lsr <= ls;
592
593 UART_II_T ii;
594 if(rls_int.state) // highest priority interrupt - receiver line status
595 ii = UART_II_RLS;
596 else if(rda_int.state) // second priority interrupt - received data available
597 ii = UART_II_RDA;
598 else if(ti_int.state) // also second priority - timeout
599 ii = UART_II_TI;
600 else if(thre_int.state) // third priority - transmitter holding register empty
601 ii = UART_II_THRE;
602 else if(ms_int.state) // fourth - modem status change interrupt
603 ii = UART_II_MS;
604 else
605 ii = UART_II_NO_INT;
606
607 let wr_addr = ff_wr_addr.first;
608 `ifdef verbose $display("WR_ADDR %h", wr_addr.awaddr); `endif
609 ff_wr_addr.deq;
610 let wr_data = ff_wr_data.first;
611 ff_wr_data.deq;
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));
615 Bit#(8) rtn=0;
616 Bool rtn_valid=True;
617 `ifdef verbose $display("addr_WRITE: %d",addr); `endif
618 case(addr)
619 UART_ADDR_DATA: if(dlab) // divisor latch enabled
620 begin
621 dl1r <= d;
622 dl_update <= tagged Valid ({dl2r,d});
623 end
624 else if(tx_fifo.notFull)
625 begin
626 tx_fifo.enq(unpack(d));
627 thre_int.reset;
628 end
629 UART_ADDR_INT_ENABLE: if(dlab)
630 dl2r <= unpack(d);
631 else
632 ier <= unpack(truncate(d));
633 UART_ADDR_INT_ID_FIFO_CTRL: begin
634 fcr <= d[7:6];
635 if(d[1]==1'b1)
636 begin
637 rx_fifo_clear_pw.send;
638 count_error_clear.send;
639 end
640 if(d[2]==1'b1)
641 tx_fifo_clear_pw.send;
642 end
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
648 endcase
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
654 endrule
655 /*
656 rule trans ;
657 $display("%05t: tx bit = %b", $time, pin_stx);
658 endrule
659 */
660 interface RS232_PHY_Ifc coe_rs232;
661
662 interface srx_in = interface Put
663 method Action put(Bit#(1) in);
664 pin_srx_sync <= in; // RX Input
665 endmethod
666 endinterface;
667
668 interface cts_in = interface Put
669 method Action put(Bit#(1) in);
670 pin_cts_sync <= in; // CTS Input
671 endmethod
672 endinterface;
673
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
678 endmethod
679 endinterface;
680
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
685 endmethod
686 endinterface;
687
688 interface dcd_in = interface Put
689 method Action put(Bit#(1) in);
690 pin_dcd_sync <= in; // Data carrier detect
691 endmethod
692 endinterface;
693
694 interface stx_out = interface Get
695 method ActionValue#(Bit#(1)) get;
696 return pin_stx; // Tx output
697 endmethod
698 endinterface;
699
700 interface rts_out = interface Get
701 method ActionValue#(Bit#(1)) get;
702 return pin_rts; // RTS output
703 endmethod
704 endinterface;
705
706 interface dtr_out = interface Get
707 method ActionValue#(Bit#(1)) get;
708 return pin_dtr; // Data Terminal Ready output
709 endmethod
710 endinterface;
711
712 endinterface
713
714 interface slave_axi_uart = s_xactor.axi_side;
715
716 method bit irq;
717 return interrupt_pw ? 1'b1 : 1'b0;
718 endmethod
719
720 endmodule
721
722
723
724
725 //////////////////////////////////////////////////////////////////////////////
726 // transmitter
727
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;
736 endinterface
737
738
739 module mkUART_transmitter(UART_transmitter_ifc);
740
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;
753
754 rule monitor_state_for_debug(last_tstate != tstate);
755
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
760
761 last_tstate <= tstate;
762 endrule
763
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;
768 endrule
769
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
772 stx_o_tmp <= 1;
773 endrule
774
775 rule pop_byte(enable && (tstate==STX_pop_byte));
776 case(lc.uart_LC_BITS) // number of bits in a word
777 0: begin
778 bit_counter <= 4;
779 parity_xor <= ^tx_fifo.first[4:0];
780 end
781 1: begin
782 bit_counter <= 5;
783 parity_xor <= ^tx_fifo.first[5:0];
784 end
785 2: begin
786 bit_counter <= 6;
787 parity_xor <= ^tx_fifo.first[6:0];
788 end
789 3: begin
790 bit_counter <= 7;
791 parity_xor <= ^tx_fifo.first[7:0];
792 end
793 endcase
794 shift_out[6:0] <= tx_fifo.first[7:1];
795 bit_out <= tx_fifo.first[0];
796 tstate <= STX_send_start;
797 endrule
798
799 rule send_start(enable && (tstate==STX_send_start));
800
801 if(counter==0)
802 counter <= 5'b01111;
803 else if(counter==1)
804 begin
805 counter <= 0;
806 tstate <= STX_send_byte;
807 end
808 else
809 counter <= counter-1;
810 stx_o_tmp <= 0;
811 endrule
812
813 rule send_byte(enable && (tstate==STX_send_byte));
814 if(counter==0)
815 counter <= 5'b01111;
816 else if(counter==1)
817 begin
818 if(bit_counter > 0)
819 begin
820 bit_counter <= bit_counter-1;
821 shift_out <= {1'b0,shift_out[6:1]};
822 bit_out <= shift_out[0];
823 end
824 else // end of byte
825 if(lc.uart_LC_PE == 0) // no partity bit
826 tstate <= STX_send_stop;
827 else
828 begin
829 case({lc.uart_LC_EP, lc.uart_LC_SP})
830 2'b00: bit_out <= ~parity_xor;
831 2'b01: bit_out <= 1;
832 2'b10: bit_out <= parity_xor;
833 2'b11: bit_out <= 0;
834 endcase
835 tstate <= STX_send_parity;
836 end
837 counter <= 0;
838 end
839 else
840 counter <= counter-1;
841 stx_o_tmp <= bit_out;
842 endrule
843
844 rule send_parity(enable && (tstate==STX_send_parity));
845 if(counter==0)
846 counter <= 5'b01111;
847 else if(counter==1)
848 begin
849 counter <= 0;
850 tstate <= STX_send_stop;
851 end
852 else
853 counter <= counter-1;
854 stx_o_tmp <= bit_out;
855
856 endrule
857
858 rule send_stop(enable && (tstate==STX_send_stop));
859 if(counter==0)
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
863 else if(counter==1)
864 begin
865 counter <= 0;
866 tstate <= STX_idle;
867 tx_fifo.deq;
868 end
869 else
870 counter <= counter-1;
871 stx_o_tmp <= 1;
872 endrule
873
874
875 method Action tx_char(Bit#(8) c);
876 tx_fifo.enq(c);
877 endmethod
878
879 method Bool tx_buf_empty = tx_fifo_empty;
880
881 method Action control(UART_LC_T lc_in, Bool enable_in);
882 lc <= lc_in;
883 enable <= enable_in;
884 endmethod
885
886 method bit output_stx = lc.uart_LC_BC==1 ? 0 : stx_o_tmp; // handle break condition
887
888 endmodule
889
890
891 //////////////////////////////////////////////////////////////////////////////
892 // receiver
893
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);
902 endinterface
903
904
905 module mkUART_receiver(UART_receiver_ifc);
906
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;
923
924 Bool break_error = counter_b==0;
925
926 rule monitor_state_for_debug(last_rstate != rstate);
927
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
932
933 last_rstate <= rstate;
934 endrule
935
936 (* no_implicit_conditions *)
937 rule receive_status_counters;
938 UInt#(10) toc_value;
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
942 4'b0001,
943 4'b1000: toc_value = 511; // 8 bits
944 4'b1100: toc_value = 543; // 8.5 bits
945 4'b0010,
946 4'b0101,
947 4'b1001: toc_value = 575; // 9 bits
948 4'b0011,
949 4'b0110,
950 4'b1010,
951 4'b1101: toc_value = 639; // 10 bits
952 4'b0111,
953 4'b1011,
954 4'b1110: toc_value = 703; // 11 bits
955 4'b1111: toc_value = 767; // 12 bits
956 default: toc_value = 511; // 8 bits
957 endcase
958
959 UInt#(8) brc_value = truncate(toc_value>>2); // break counter value
960
961 if(rx_stable==1)
962 counter_b <= brc_value;
963 else if((counter_b!=0) && enable)
964 counter_b <= counter_b-1;
965
966 if(counter_t_preset)
967 counter_t <= toc_value;
968 else if(enable && (counter_t!=0))
969 counter_t <= counter_t - 1;
970 endrule
971
972 // helper rule to decouple firing dependancies
973 rule couter_t_preset_on_fifo_empty(!rx_fifo.notEmpty);
974 counter_t_preset.send();
975 endrule
976
977 (* no_implicit_conditions *)
978 rule idle(enable && (rstate==SRX_idle));
979 rcounter <= 4'b1110;
980 if((rx_stable==0) && !break_error)
981 rstate <= SRX_rec_start;
982 endrule
983
984 rule rec_start(enable && (rstate==SRX_rec_start));
985 if(rcounter==7)
986 if(rx_stable==1) // no start bit
987 rstate <= SRX_idle;
988 else
989 rstate <= SRX_rec_prepare;
990 rcounter <= rcounter-1;
991 endrule
992
993 rule rec_prepare(enable && (rstate==SRX_rec_prepare));
994 rbit_counter <= unpack(zeroExtend(lc.uart_LC_BITS) + 4);
995 if(rcounter==0)
996 begin
997 rstate <= SRX_rec_bit;
998 rcounter <= 4'b1110;
999 rshift <= 0;
1000 end
1001 else
1002 rcounter <= rcounter-1;
1003 endrule
1004
1005 rule rec_bit(enable && (rstate==SRX_rec_bit));
1006 if(rcounter==0)
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]};
1014 endcase
1015 rcounter <= rcounter-1;
1016 endrule
1017
1018 rule end_bit(enable && (rstate==SRX_end_bit));
1019 if(rbit_counter==0) // no more bits in the word
1020 begin
1021 rstate <= (lc.uart_LC_PE==1) ? SRX_rec_parity : SRX_rec_stop;
1022 rparity_error <= 0;
1023 end
1024 else
1025 rstate <= SRX_rec_bit;
1026 rbit_counter <= rbit_counter-1;
1027 rcounter <= rcounter-1;
1028 endrule
1029
1030 rule rec_parity(enable && (rstate==SRX_rec_parity));
1031 if(rcounter == 7) // read parity
1032 begin
1033 rparity <= rx_stable;
1034 rstate <= SRX_ca_lc_parity;
1035 end
1036 rcounter <= rcounter-1;
1037 //$display("%05t rx bit = %d", $time, rx_stable);
1038 endrule
1039 /*
1040 rule recie ;
1041 $display("%05t: rx bit = %d", $time, rx_stable);
1042 endrule
1043 */
1044 rule calc_parity(enable && (rstate==SRX_ca_lc_parity));
1045 rparity_xor <= ^{rshift, rparity};
1046 rstate <= SRX_check_parity;
1047 rcounter <= rcounter-1;
1048 endrule
1049
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;
1056 endcase
1057 rcounter <= rcounter-1;
1058 rstate <= SRX_wait1;
1059 endrule
1060
1061 rule wait1(enable && (rstate==SRX_wait1));
1062 if(rcounter==0)
1063 begin
1064 rcounter <= 4'b1110;
1065 rstate <= SRX_rec_stop;
1066 end
1067 else
1068 rcounter <= rcounter-1;
1069 endrule
1070
1071 rule rec_stop(enable && (rstate==SRX_rec_stop));
1072 if(rcounter==7) // read the stop bit
1073 begin
1074 rframing_error <= ~rx_stable; // no framing error if stop bit = 1
1075 rstate <= SRX_push;
1076 end
1077 rcounter <= rcounter-1;
1078 `ifdef verbose $display("%05t: rx bit = %d", $time, rx_stable); `endif
1079 endrule
1080
1081 rule push(enable && (rstate==SRX_push));
1082 if((rx_stable==1) || break_error)
1083 begin
1084 rstate <= SRX_idle;
1085 if(break_error)
1086 rx_fifo.enq(
1087 RX_DATA_T{
1088 data: 8'b0,
1089 break_error: True,
1090 parity_error: True,
1091 framing_error: False
1092 }
1093 );
1094 else
1095 rx_fifo.enq(
1096 RX_DATA_T{
1097 data: rshift,
1098 break_error: False,
1099 parity_error: rparity_error==1,
1100 framing_error: rframing_error==1
1101 }
1102 );
1103 counter_t_preset.send; // preset counter_t on an enq
1104 //$display("%05t: rx bit = %d", $time, rx_stable);
1105 end
1106 endrule
1107
1108 method ActionValue#(RX_DATA_T) rx_char();
1109 counter_t_preset.send; // preset counter_t on a deq
1110 rx_fifo.deq;
1111 return rx_fifo.first;
1112 endmethod
1113 method Bool timeout() = counter_t==0;
1114 method Action control(UART_LC_T lc_in, Bool enable_in);
1115 lc <= lc_in;
1116 enable <= enable_in;
1117 endmethod
1118 method Action input_srx(bit rx);
1119 rx_stable <= rx;
1120 endmethod
1121 endmodule
1122
1123
1124 //////////////////////////////////////////////////////////////////////////////
1125 // clocked RS (reset/set) flip-flow with reset dominating and edge triggering set
1126
1127 /*
1128 (* always_ready, always_enabled *)
1129 interface RS_ifc;
1130 method Action set;
1131 method Action reset;
1132 method Action enable(Bool en);
1133 method Bool state;
1134 endinterface
1135
1136
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);
1144
1145 (* no_implicit_conditions *)
1146 rule handle_state_update;
1147 Bool s_rise = s && !s_prev;
1148 q_next <= e && !r && (s_rise || q);
1149 q <= q_next;
1150 s_prev <= s;
1151 endrule
1152
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);
1157 e <= en;
1158 endmethod
1159
1160 endmodule
1161 */
1162
1163
1164 (* always_ready, always_enabled *)
1165 interface RS_ifc;
1166 method Action set;
1167 method Action reset;
1168 method Action posedge_set;
1169 method Action posedge_reset;
1170 method Bool state;
1171 endinterface
1172
1173 module mkRS(RS_ifc);
1174 PulseWire s <- mkPulseWireOR;
1175 PulseWire r <- mkPulseWireOR;
1176 PulseWire edge_s <- mkPulseWireOR;
1177 PulseWire edge_r <- mkPulseWireOR;
1178
1179 Reg#(Bool) q <- mkReg(False);
1180 Reg#(Bool) s_prev <- mkReg(False);
1181 Reg#(Bool) r_prev <- mkReg(False);
1182
1183
1184 (* no_implicit_conditions *)
1185 rule handle_edges_history;
1186 s_prev <= s;
1187 r_prev <= r;
1188 endrule
1189
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;
1194 endrule
1195
1196 (* no_implicit_conditions *)
1197 rule handle_state_update;
1198 q <= !r && (q || s);
1199 endrule
1200
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;
1206
1207 endmodule
1208
1209
1210 endpackage