convert uart16550 to get/put
[shakti-peripherals.git] / src / peripherals / uart / Uart16550.bsv
1 /*
2 Copyright (c) 2013-2017, IIT Madras
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6
7 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9 * Neither the name of IIT Madras nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10
11 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
13 /*-
14 * Copyright (c) 2013 Simon W. Moore
15 * All rights reserved.
16 *
17 * This software was developed by SRI International and the University of
18 * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
19 * ("CTSRD"), as part of the DARPA CRASH research programme.
20 *
21 * @BERI_LICENSE_HEADER_START@
22 *
23 * Licensed to BERI Open Systems C.I.C. (BERI) under one or more contributor
24 * license agreements. See the NOTICE file distributed with this work for
25 * additional information regarding copyright ownership. BERI licenses this
26 * file to you under the BERI Hardware-Software License, Version 1.0 (the
27 * "License"); you may not use this file except in compliance with the
28 * License. You may obtain a copy of the License at:
29 *
30 * http://www.beri-open-systems.org/legal/license-1-0.txt
31 *
32 * Unless required by applicable law or agreed to in writing, Work distributed
33 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
34 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
35 * specific language governing permissions and limitations under the License.
36 *
37 * @BERI_LICENSE_HEADER_END@
38 *
39 ******************************************************************************
40 * UART16550
41 * =========
42 * Simon Moore, July 2013
43 *
44 * This Bluespec module implements a 16650 style UART for RS232 serial
45 * communication.
46 *
47 * The following registers exist at 32-bit boundaries accessible in little
48 * endian byte order:
49 *
50 * Offset Name Read/Write Description
51 * 0 UART_DATA RW write to transmit, read to receive
52 * 1 UART_INT_ENABLE RW interrupt enable
53 * 2 UART_INT_ID R interrupt identification
54 * 2 UART_FIFO_CTRL W FIFO control
55 * 3 UART_LINE_CTRL RW line control
56 * 4 UART_MODEM_CTRL W modem control
57 * 5 UART_LINE_STATUS R line status
58 * 6 UART_MODEM_STATUS R modem status
59 * 7 UART_SCRATCH RW scratch register
60 ******************************************************************************/
61
62 //Modifications - The Avalon bus has been removed and AXI-4 Lite Bus support has been added
63
64
65 package Uart16550;
66
67 import FIFO::*;
68 import FIFOF::*;
69 import FIFOLevel::*;
70 import Clocks::*;
71 import ClientServer::*;
72 import defined_types::*;
73 import AXI4_Lite_Types::*;
74 import AXI4_Lite_Fabric::*;
75 import Semi_FIFOF::*;
76 `include "instance_defines.bsv"
77
78 // depth of transmit and receive FIFOs
79 typedef 16 Tx_FIFO_depth;
80 typedef 16 Rx_FIFO_depth;
81
82 // enumerate addresses corresponding to device registers
83 typedef enum {
84 UART_ADDR_DATA=0,
85 UART_ADDR_INT_ENABLE=1,
86 UART_ADDR_INT_ID_FIFO_CTRL=2, // read=INT_ID, write=FIFO_CTRL
87 UART_ADDR_LINE_CTRL=3,
88 UART_ADDR_MODEM_CTRL=4,
89 UART_ADDR_LINE_STATUS=5,
90 UART_ADDR_MODEM_STATUS=6,
91 UART_ADDR_SCRATCH=7
92 } UART_ADDR_T deriving (Bits, Eq, FShow);
93
94 // interrupt enable register bits
95 typedef struct {
96 Bool uart_IE_MS; // Modem status interrupt
97 Bool uart_IE_RLS; // Receiver line status interrupt
98 Bool uart_IE_THRE; // Transmitter holding register empty interrupt
99 Bool uart_IE_RDA; // Recived data available interrupt
100 } UART_IE_T deriving (Bits, Eq, FShow);
101
102 // interrupt identification values
103 typedef enum {
104 UART_II_MS = 4'b0000, // modem status
105 UART_II_NO_INT = 4'b0001, // no interrupt pending
106 UART_II_THRE = 4'b0010, // transmitter holding register empty
107 UART_II_RDA = 4'b0100, // receiver data available
108 UART_II_RLS = 4'b0110, // receiver line status
109 UART_II_TI = 4'b1100 // timeout indication
110 } UART_II_T deriving (Bits, Eq, FShow);
111
112 // line control register bits
113 typedef struct {
114 Bit#(1) uart_LC_DL; // divisor latch access bit
115 Bit#(1) uart_LC_BC; // break control
116 Bit#(1) uart_LC_SP; // stick parity
117 Bit#(1) uart_LC_EP; // even parity
118 Bit#(1) uart_LC_PE; // parity enables
119 Bit#(1) uart_LC_SB; // stop bits
120 Bit#(2) uart_LC_BITS; // bits in character
121 } UART_LC_T deriving (Bits, Eq, FShow);
122
123 // modem control register bits
124 typedef struct {
125 bit uart_MC_LOOPBACK;
126 bit uart_MC_OUT2;
127 bit uart_MC_OUT1;
128 bit uart_MC_RTS;
129 bit uart_MC_DTR;
130 } UART_MC_T deriving (Bits, Eq, FShow);
131
132 // line status register bits
133 typedef struct {
134 Bool uart_LS_EI; // error indicator
135 Bool uart_LS_TW; // transmitter empty indicator
136 Bool uart_LS_TFE; // transmitter FIFO is empty
137 Bool uart_LS_BI; // break interrupt
138 Bool uart_LS_FE; // framing error
139 Bool uart_LS_PE; // parity error
140 Bool uart_LS_OE; // overrun error
141 Bool uart_LS_DR; // data ready
142 } UART_LS_T deriving (Bits, Eq, FShow);
143
144 // modem status register bits
145 typedef struct {
146 bit uart_MS_CDCD; // complement signals
147 bit uart_MS_CRI;
148 bit uart_MS_CDSR;
149 bit uart_MS_CCTS;
150 bit uart_MS_DDCD; // delta signals
151 bit uart_MS_TERI;
152 bit uart_MS_DDSR;
153 bit uart_MS_DCTS;
154 } UART_MS_T deriving (Bits, Eq, FShow);
155
156 // data from receiver
157 typedef struct {
158 Bit#(8) data;
159 Bool break_error;
160 Bool parity_error;
161 Bool framing_error;
162 } RX_DATA_T deriving (Bits, Eq);
163
164 // transmitter states
165 typedef enum {
166 STX_idle, STX_pop_byte, STX_send_start, STX_send_byte, STX_send_parity, STX_send_stop
167 } TX_state_T deriving (Bits, Eq, FShow);
168
169 // receiver states
170 typedef enum {
171 SRX_idle, SRX_rec_start, SRX_rec_bit, SRX_rec_parity, SRX_rec_stop,
172 SRX_check_parity, SRX_rec_prepare, SRX_end_bit, SRX_wait1,
173 SRX_ca_lc_parity, SRX_push } RX_state_T deriving (Bits, Eq, FShow);
174
175
176 (* always_ready, always_enabled *)
177 interface RS232_PHY_Ifc;
178 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;
186 endinterface
187
188
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;
193 endinterface
194
195
196 (* synthesize,
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;
203
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;
217
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);
223
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
232
233 Wire#(Bool) loopback <- mkBypassWire; // loopback mode (msr[4])
234
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);
242
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;
249
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);
256
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);
263
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);
270
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
277
278 // registered outputs
279 Reg#(bit) pin_stx <- mkReg(0);
280 Reg#(bit) pin_rts <- mkReg(0);
281 Reg#(bit) pin_dtr <- mkReg(0);
282
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);
286
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);
289
290
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;
298 endrule
299
300 rule bypass_mrc_to_avoid_scheduling_loop;
301 mc_bypass <= mcr;
302 endrule
303
304 (* no_implicit_conditions *)
305 rule handle_loopback_mode;
306 if(loopback)
307 begin
308 pin_srx <= pin_stx;
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;
313 end
314 else
315 begin
316 pin_srx <= pin_srx_c;
317 pin_cts <= pin_cts_c;
318 pin_dsr <= pin_dsr_c;
319 pin_ri <= pin_ri_c;
320 pin_dcd <= pin_dcd_c;
321 end
322
323 msr <= UART_MS_T{
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,
332 uart_MS_CRI: pin_ri,
333 uart_MS_CDCD: pin_dcd};
334
335 if(msr_save_pin_state)
336 begin
337 prev_dcd <= pin_dcd;
338 prev_ri <= pin_ri;
339 prev_dsr <= pin_dsr;
340 prev_cts <= pin_cts;
341 end
342 endrule
343
344 (* no_implicit_conditions *)
345 rule output_rts_dtr;
346 pin_rts <= mcr.uart_MC_RTS;
347 pin_dtr <= mcr.uart_MC_DTR;
348 endrule
349
350 (* no_implicit_conditions *)
351 rule loopback_mode_select;
352 loopback <= mcr.uart_MC_LOOPBACK==1;
353 endrule
354
355 (* no_implicit_conditions *)
356 rule connect_pins_rx;
357 uart_rx.input_srx(pin_srx);
358 endrule
359 (* no_implicit_conditions *)
360 rule connect_pins_tx;
361 pin_stx <= uart_tx.output_stx;
362 endrule
363 (* no_implicit_conditions *)
364 rule rx_first_item_if_any;
365 rx_fifo_first <= rx_fifo.notEmpty ? rx_fifo.first
366 : RX_DATA_T{
367 data:0,
368 break_error: False,
369 parity_error: False,
370 framing_error: False};
371 endrule
372
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)
376 interrupt_pw.send;
377
378 // receiver line status interrupt
379 // - note: also reset on read of line status
380 if(!ier.uart_IE_RLS)
381 rls_int.reset;
382 else if(rx_fifo_full
383 || rx_fifo_first.parity_error
384 || rx_fifo_first.framing_error
385 || rx_fifo_first.break_error)
386 rls_int.posedge_set;
387
388 // received data available interrupt
389 UInt#(5) trigger_level;
390 case(fcr)
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;
396 endcase
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))
399 rda_int.set;
400 else
401 rda_int.reset;
402
403 // transmitter holding register empty interrupt
404 // if(!ier.uart_IE_THRE)
405 if(!ier.uart_IE_THRE || !tx_fifo_empty)
406 thre_int.reset;
407 else if(tx_fifo_empty)
408 thre_int.posedge_set;
409
410 // timer interrupt
411 if(!ier.uart_IE_RDA)
412 ti_int.reset;
413 else if(uart_rx.timeout)
414 ti_int.posedge_set;
415
416 // modem status interrupt
417 // - note: also reset by reading modem status
418 if(!ier.uart_IE_MS)
419 ms_int.reset;
420 else if({msr.uart_MS_DCTS, msr.uart_MS_DDSR, msr.uart_MS_TERI, msr.uart_MS_DDCD} != 0)
421 ms_int.posedge_set;
422 endrule
423
424 (* no_implicit_conditions *)
425 rule foward_lc_enable;
426 uart_tx.control(lcr, enable);
427 uart_rx.control(lcr, enable);
428 endrule
429
430 (* no_implicit_conditions *)
431 rule divisor_counter;
432 enable <= (dlc==0) && (dl>0);
433 if(isValid(dl_update))
434 begin
435 let newdl = fromMaybe(?, dl_update);
436 dl <= newdl;
437 dlc <= newdl-1;
438 `ifdef verbose $display("%05t: dl set to %1d", $time, newdl); `endif
439 end
440 else
441 dlc <= (dlc==0 ? dl : dlc) - 1;
442 endrule
443
444 (* no_implicit_conditions *)
445 rule forward_tx_clear(tx_fifo_clear_pw);
446 tx_fifo.clear;
447 endrule
448 rule forward_tx(!tx_fifo_clear_pw && tx_fifo.notEmpty);
449 uart_tx.tx_char(tx_fifo.first);
450 tx_fifo.deq;
451 endrule
452
453 rule forward_rx;
454 if(rx_fifo_clear_pw)
455 rx_fifo.clear;
456 else if(rx_fifo.notFull)
457 begin
458 RX_DATA_T rx <- uart_rx.rx_char;
459 rx_fifo.enq(rx);
460 if(rx.break_error || rx.parity_error || rx.framing_error)
461 count_error_up.send();
462 end
463 endrule
464
465 (* no_implicit_conditions *)
466 rule count_rx_errors;
467 if(count_error_clear)
468 count_error <= 0;
469 else
470 begin
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;
475 end
476 endrule
477
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;
483 endrule
484
485 rule capture_read_request;
486 let req <- pop_o (s_xactor.o_rd_addr);
487 ff_rd_addr.enq(req);
488 endrule
489 rule send_read_respone_to_bus;
490 s_xactor.i_rd_data.enq(ff_rd_resp.first);
491 ff_rd_resp.deq;
492 endrule
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);
496 ff_wr_addr.enq(req);
497 ff_wr_data.enq(wr_data);
498 endrule
499 rule send_write_response;
500 s_xactor.i_wr_resp.enq(ff_wr_resp.first);
501 ff_wr_resp.deq;
502 endrule
503
504
505 rule handle_axi4_read(ff_rd_addr.notEmpty);
506
507 Bool dlab = lcr.uart_LC_DL == 1'b1; // divisor latch enable
508 let req = ff_rd_addr.first;
509 ff_rd_addr.deq;
510 `ifdef verbose $display("RD_ADDR %h", req.araddr); `endif
511 UART_ADDR_T addr = unpack(req.araddr[5:3]);
512 Bool rtn_valid=True;
513 Bit#(8) rtn = 0;
514
515 let ls = UART_LS_T{
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
524
525 lsr <= ls;
526
527 UART_II_T ii;
528 if(rls_int.state) // highest priority interrupt - receiver line status
529 ii = UART_II_RLS;
530 else if(rda_int.state) // second priority interrupt - received data available
531 ii = UART_II_RDA;
532 else if(ti_int.state) // also second priority - timeout
533 ii = UART_II_TI;
534 else if(thre_int.state) // third priority - transmitter holding register empty
535 ii = UART_II_THRE;
536 else if(ms_int.state) // fourth - modem status change interrupt
537 ii = UART_II_MS;
538 else
539 ii = UART_II_NO_INT;
540 `ifdef verbose $display("addr_READ: %d",addr) ; `endif
541 case(addr)
542 UART_ADDR_DATA : if(dlab) // divisor latch enabled
543 rtn = dl1r;
544 else if(!rx_fifo_empty)
545 begin
546 RX_DATA_T rx = rx_fifo.first;
547 rtn = rx.data;
548 if(rx.break_error || rx.parity_error || rx.framing_error)
549 count_error_down.send;
550 rx_fifo.deq;
551 ti_int.reset;
552 rda_int.reset;
553 end
554 else
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
561 rls_int.reset;
562 rtn = pack(ls);
563 end
564 UART_ADDR_MODEM_STATUS : begin
565 ms_int.reset;
566 rtn = pack(msr);
567 msr_save_pin_state.send();
568 end
569 UART_ADDR_SCRATCH : rtn = scratch;
570
571 endcase
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
576 endrule
577
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
580 let ls = UART_LS_T{
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
589
590 lsr <= ls;
591
592 UART_II_T ii;
593 if(rls_int.state) // highest priority interrupt - receiver line status
594 ii = UART_II_RLS;
595 else if(rda_int.state) // second priority interrupt - received data available
596 ii = UART_II_RDA;
597 else if(ti_int.state) // also second priority - timeout
598 ii = UART_II_TI;
599 else if(thre_int.state) // third priority - transmitter holding register empty
600 ii = UART_II_THRE;
601 else if(ms_int.state) // fourth - modem status change interrupt
602 ii = UART_II_MS;
603 else
604 ii = UART_II_NO_INT;
605
606 let wr_addr = ff_wr_addr.first;
607 `ifdef verbose $display("WR_ADDR %h", wr_addr.awaddr); `endif
608 ff_wr_addr.deq;
609 let wr_data = ff_wr_data.first;
610 ff_wr_data.deq;
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));
614 Bit#(8) rtn=0;
615 Bool rtn_valid=True;
616 `ifdef verbose $display("addr_WRITE: %d",addr); `endif
617 case(addr)
618 UART_ADDR_DATA: if(dlab) // divisor latch enabled
619 begin
620 dl1r <= d;
621 dl_update <= tagged Valid ({dl2r,d});
622 end
623 else if(tx_fifo.notFull)
624 begin
625 tx_fifo.enq(unpack(d));
626 thre_int.reset;
627 end
628 UART_ADDR_INT_ENABLE: if(dlab)
629 dl2r <= unpack(d);
630 else
631 ier <= unpack(truncate(d));
632 UART_ADDR_INT_ID_FIFO_CTRL: begin
633 fcr <= d[7:6];
634 if(d[1]==1'b1)
635 begin
636 rx_fifo_clear_pw.send;
637 count_error_clear.send;
638 end
639 if(d[2]==1'b1)
640 tx_fifo_clear_pw.send;
641 end
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
647 endcase
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
653 endrule
654 /*
655 rule trans ;
656 $display("%05t: tx bit = %b", $time, pin_stx);
657 endrule
658 */
659 interface RS232_PHY_Ifc coe_rs232;
660
661 interface srx_in = interface Put
662 method Action put(Bit#(1) in);
663 pin_srx_sync <= in; // RX Input
664 endmethod
665 endinterface;
666
667 interface cts_in = interface Put
668 method Action put(Bit#(1) in);
669 pin_cts_sync <= in; // CTS Input
670 endmethod
671 endinterface;
672
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
677 endmethod
678 endinterface;
679
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
684 endmethod
685 endinterface;
686
687 interface dcd_in = interface Put
688 method Action put(Bit#(1) in);
689 pin_dcd_sync <= in; // Data carrier detect
690 endmethod
691 endinterface;
692
693 interface stx_out = interface Get
694 method ActionValue#(Bit#(1)) get;
695 return pin_stx; // Tx output
696 endmethod
697 endinterface;
698
699 interface rts_out = interface Get
700 method ActionValue#(Bit#(1)) get;
701 return pin_rts; // RTS output
702 endmethod
703 endinterface;
704
705 interface dtr_out = interface Get
706 method ActionValue#(Bit#(1)) get;
707 return pin_dtr; // Data Terminal Ready output
708 endmethod
709 endinterface;
710
711 endinterface
712
713 interface slave_axi_uart = s_xactor.axi_side;
714
715 method bit irq;
716 return interrupt_pw ? 1'b1 : 1'b0;
717 endmethod
718
719 endmodule
720
721
722
723
724 //////////////////////////////////////////////////////////////////////////////
725 // transmitter
726
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;
735 endinterface
736
737
738 module mkUART_transmitter(UART_transmitter_ifc);
739
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;
752
753 rule monitor_state_for_debug(last_tstate != tstate);
754
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
759
760 last_tstate <= tstate;
761 endrule
762
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;
767 endrule
768
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
771 stx_o_tmp <= 1;
772 endrule
773
774 rule pop_byte(enable && (tstate==STX_pop_byte));
775 case(lc.uart_LC_BITS) // number of bits in a word
776 0: begin
777 bit_counter <= 4;
778 parity_xor <= ^tx_fifo.first[4:0];
779 end
780 1: begin
781 bit_counter <= 5;
782 parity_xor <= ^tx_fifo.first[5:0];
783 end
784 2: begin
785 bit_counter <= 6;
786 parity_xor <= ^tx_fifo.first[6:0];
787 end
788 3: begin
789 bit_counter <= 7;
790 parity_xor <= ^tx_fifo.first[7:0];
791 end
792 endcase
793 shift_out[6:0] <= tx_fifo.first[7:1];
794 bit_out <= tx_fifo.first[0];
795 tstate <= STX_send_start;
796 endrule
797
798 rule send_start(enable && (tstate==STX_send_start));
799
800 if(counter==0)
801 counter <= 5'b01111;
802 else if(counter==1)
803 begin
804 counter <= 0;
805 tstate <= STX_send_byte;
806 end
807 else
808 counter <= counter-1;
809 stx_o_tmp <= 0;
810 endrule
811
812 rule send_byte(enable && (tstate==STX_send_byte));
813 if(counter==0)
814 counter <= 5'b01111;
815 else if(counter==1)
816 begin
817 if(bit_counter > 0)
818 begin
819 bit_counter <= bit_counter-1;
820 shift_out <= {1'b0,shift_out[6:1]};
821 bit_out <= shift_out[0];
822 end
823 else // end of byte
824 if(lc.uart_LC_PE == 0) // no partity bit
825 tstate <= STX_send_stop;
826 else
827 begin
828 case({lc.uart_LC_EP, lc.uart_LC_SP})
829 2'b00: bit_out <= ~parity_xor;
830 2'b01: bit_out <= 1;
831 2'b10: bit_out <= parity_xor;
832 2'b11: bit_out <= 0;
833 endcase
834 tstate <= STX_send_parity;
835 end
836 counter <= 0;
837 end
838 else
839 counter <= counter-1;
840 stx_o_tmp <= bit_out;
841 endrule
842
843 rule send_parity(enable && (tstate==STX_send_parity));
844 if(counter==0)
845 counter <= 5'b01111;
846 else if(counter==1)
847 begin
848 counter <= 0;
849 tstate <= STX_send_stop;
850 end
851 else
852 counter <= counter-1;
853 stx_o_tmp <= bit_out;
854
855 endrule
856
857 rule send_stop(enable && (tstate==STX_send_stop));
858 if(counter==0)
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
862 else if(counter==1)
863 begin
864 counter <= 0;
865 tstate <= STX_idle;
866 tx_fifo.deq;
867 end
868 else
869 counter <= counter-1;
870 stx_o_tmp <= 1;
871 endrule
872
873
874 method Action tx_char(Bit#(8) c);
875 tx_fifo.enq(c);
876 endmethod
877
878 method Bool tx_buf_empty = tx_fifo_empty;
879
880 method Action control(UART_LC_T lc_in, Bool enable_in);
881 lc <= lc_in;
882 enable <= enable_in;
883 endmethod
884
885 method bit output_stx = lc.uart_LC_BC==1 ? 0 : stx_o_tmp; // handle break condition
886
887 endmodule
888
889
890 //////////////////////////////////////////////////////////////////////////////
891 // receiver
892
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);
901 endinterface
902
903
904 module mkUART_receiver(UART_receiver_ifc);
905
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;
922
923 Bool break_error = counter_b==0;
924
925 rule monitor_state_for_debug(last_rstate != rstate);
926
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
931
932 last_rstate <= rstate;
933 endrule
934
935 (* no_implicit_conditions *)
936 rule receive_status_counters;
937 UInt#(10) toc_value;
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
941 4'b0001,
942 4'b1000: toc_value = 511; // 8 bits
943 4'b1100: toc_value = 543; // 8.5 bits
944 4'b0010,
945 4'b0101,
946 4'b1001: toc_value = 575; // 9 bits
947 4'b0011,
948 4'b0110,
949 4'b1010,
950 4'b1101: toc_value = 639; // 10 bits
951 4'b0111,
952 4'b1011,
953 4'b1110: toc_value = 703; // 11 bits
954 4'b1111: toc_value = 767; // 12 bits
955 default: toc_value = 511; // 8 bits
956 endcase
957
958 UInt#(8) brc_value = truncate(toc_value>>2); // break counter value
959
960 if(rx_stable==1)
961 counter_b <= brc_value;
962 else if((counter_b!=0) && enable)
963 counter_b <= counter_b-1;
964
965 if(counter_t_preset)
966 counter_t <= toc_value;
967 else if(enable && (counter_t!=0))
968 counter_t <= counter_t - 1;
969 endrule
970
971 // helper rule to decouple firing dependancies
972 rule couter_t_preset_on_fifo_empty(!rx_fifo.notEmpty);
973 counter_t_preset.send();
974 endrule
975
976 (* no_implicit_conditions *)
977 rule idle(enable && (rstate==SRX_idle));
978 rcounter <= 4'b1110;
979 if((rx_stable==0) && !break_error)
980 rstate <= SRX_rec_start;
981 endrule
982
983 rule rec_start(enable && (rstate==SRX_rec_start));
984 if(rcounter==7)
985 if(rx_stable==1) // no start bit
986 rstate <= SRX_idle;
987 else
988 rstate <= SRX_rec_prepare;
989 rcounter <= rcounter-1;
990 endrule
991
992 rule rec_prepare(enable && (rstate==SRX_rec_prepare));
993 rbit_counter <= unpack(zeroExtend(lc.uart_LC_BITS) + 4);
994 if(rcounter==0)
995 begin
996 rstate <= SRX_rec_bit;
997 rcounter <= 4'b1110;
998 rshift <= 0;
999 end
1000 else
1001 rcounter <= rcounter-1;
1002 endrule
1003
1004 rule rec_bit(enable && (rstate==SRX_rec_bit));
1005 if(rcounter==0)
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]};
1013 endcase
1014 rcounter <= rcounter-1;
1015 endrule
1016
1017 rule end_bit(enable && (rstate==SRX_end_bit));
1018 if(rbit_counter==0) // no more bits in the word
1019 begin
1020 rstate <= (lc.uart_LC_PE==1) ? SRX_rec_parity : SRX_rec_stop;
1021 rparity_error <= 0;
1022 end
1023 else
1024 rstate <= SRX_rec_bit;
1025 rbit_counter <= rbit_counter-1;
1026 rcounter <= rcounter-1;
1027 endrule
1028
1029 rule rec_parity(enable && (rstate==SRX_rec_parity));
1030 if(rcounter == 7) // read parity
1031 begin
1032 rparity <= rx_stable;
1033 rstate <= SRX_ca_lc_parity;
1034 end
1035 rcounter <= rcounter-1;
1036 //$display("%05t rx bit = %d", $time, rx_stable);
1037 endrule
1038 /*
1039 rule recie ;
1040 $display("%05t: rx bit = %d", $time, rx_stable);
1041 endrule
1042 */
1043 rule calc_parity(enable && (rstate==SRX_ca_lc_parity));
1044 rparity_xor <= ^{rshift, rparity};
1045 rstate <= SRX_check_parity;
1046 rcounter <= rcounter-1;
1047 endrule
1048
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;
1055 endcase
1056 rcounter <= rcounter-1;
1057 rstate <= SRX_wait1;
1058 endrule
1059
1060 rule wait1(enable && (rstate==SRX_wait1));
1061 if(rcounter==0)
1062 begin
1063 rcounter <= 4'b1110;
1064 rstate <= SRX_rec_stop;
1065 end
1066 else
1067 rcounter <= rcounter-1;
1068 endrule
1069
1070 rule rec_stop(enable && (rstate==SRX_rec_stop));
1071 if(rcounter==7) // read the stop bit
1072 begin
1073 rframing_error <= ~rx_stable; // no framing error if stop bit = 1
1074 rstate <= SRX_push;
1075 end
1076 rcounter <= rcounter-1;
1077 `ifdef verbose $display("%05t: rx bit = %d", $time, rx_stable); `endif
1078 endrule
1079
1080 rule push(enable && (rstate==SRX_push));
1081 if((rx_stable==1) || break_error)
1082 begin
1083 rstate <= SRX_idle;
1084 if(break_error)
1085 rx_fifo.enq(
1086 RX_DATA_T{
1087 data: 8'b0,
1088 break_error: True,
1089 parity_error: True,
1090 framing_error: False
1091 }
1092 );
1093 else
1094 rx_fifo.enq(
1095 RX_DATA_T{
1096 data: rshift,
1097 break_error: False,
1098 parity_error: rparity_error==1,
1099 framing_error: rframing_error==1
1100 }
1101 );
1102 counter_t_preset.send; // preset counter_t on an enq
1103 //$display("%05t: rx bit = %d", $time, rx_stable);
1104 end
1105 endrule
1106
1107 method ActionValue#(RX_DATA_T) rx_char();
1108 counter_t_preset.send; // preset counter_t on a deq
1109 rx_fifo.deq;
1110 return rx_fifo.first;
1111 endmethod
1112 method Bool timeout() = counter_t==0;
1113 method Action control(UART_LC_T lc_in, Bool enable_in);
1114 lc <= lc_in;
1115 enable <= enable_in;
1116 endmethod
1117 method Action input_srx(bit rx);
1118 rx_stable <= rx;
1119 endmethod
1120 endmodule
1121
1122
1123 //////////////////////////////////////////////////////////////////////////////
1124 // clocked RS (reset/set) flip-flow with reset dominating and edge triggering set
1125
1126 /*
1127 (* always_ready, always_enabled *)
1128 interface RS_ifc;
1129 method Action set;
1130 method Action reset;
1131 method Action enable(Bool en);
1132 method Bool state;
1133 endinterface
1134
1135
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);
1143
1144 (* no_implicit_conditions *)
1145 rule handle_state_update;
1146 Bool s_rise = s && !s_prev;
1147 q_next <= e && !r && (s_rise || q);
1148 q <= q_next;
1149 s_prev <= s;
1150 endrule
1151
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);
1156 e <= en;
1157 endmethod
1158
1159 endmodule
1160 */
1161
1162
1163 (* always_ready, always_enabled *)
1164 interface RS_ifc;
1165 method Action set;
1166 method Action reset;
1167 method Action posedge_set;
1168 method Action posedge_reset;
1169 method Bool state;
1170 endinterface
1171
1172 module mkRS(RS_ifc);
1173 PulseWire s <- mkPulseWireOR;
1174 PulseWire r <- mkPulseWireOR;
1175 PulseWire edge_s <- mkPulseWireOR;
1176 PulseWire edge_r <- mkPulseWireOR;
1177
1178 Reg#(Bool) q <- mkReg(False);
1179 Reg#(Bool) s_prev <- mkReg(False);
1180 Reg#(Bool) r_prev <- mkReg(False);
1181
1182
1183 (* no_implicit_conditions *)
1184 rule handle_edges_history;
1185 s_prev <= s;
1186 r_prev <= r;
1187 endrule
1188
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;
1193 endrule
1194
1195 (* no_implicit_conditions *)
1196 rule handle_state_update;
1197 q <= !r && (q || s);
1198 endrule
1199
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;
1205
1206 endmodule
1207
1208
1209 endpackage