2 Copyright (c) 2013, 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 ////////////////////////////////////////////////////////////////////////////////
15 // Copyright (c) 2010 Bluespec, Inc. ALL RIGHTS RESERVED.
16 ////////////////////////////////////////////////////////////////////////////////
17 // Filename : RS232.bsv
18 // Description : Simple UART BFM RS232 <-> Bit#(8)
19 ////////////////////////////////////////////////////////////////////////////////
20 package RS232_modified;
24 ////////////////////////////////////////////////////////////////////////////////
26 ////////////////////////////////////////////////////////////////////////////////
29 import Connectable ::*;
35 ////////////////////////////////////////////////////////////////////////////////
37 ////////////////////////////////////////////////////////////////////////////////
40 export BaudGenerator (..);
43 export InputFilter (..);
44 export Synchronizer (..);
45 export EdgeDetector (..);
46 export InputMovingFilter (..);
48 export mkBaudGenerator;
50 export mkSynchronizer;
51 export mkEdgeDetector;
52 export mkInputMovingFilter;
54 ////////////////////////////////////////////////////////////////////////////////
56 ////////////////////////////////////////////////////////////////////////////////
57 typedef union tagged {
65 } RecvState deriving (Bits, Eq);
67 typedef union tagged {
76 } XmitState deriving (Bits, Eq);
82 } Parity deriving (Bits, Eq);
88 } StopBits deriving (Bits, Eq);
90 ////////////////////////////////////////////////////////////////////////////////
92 ////////////////////////////////////////////////////////////////////////////////
93 (* always_ready, always_enabled *)
97 method Action sin((* port = "SIN" *)Bit#(1) x);
99 (* prefix = "", result = "SOUT" *)
100 method Bit#(1) sout();
103 interface BaudGenerator;
104 method Action clock_enable();
105 method Action clear();
106 method Bool baud_tick_16x();
107 method Bool baud_tick_2x();
110 interface InputFilter#(numeric type size, type a);
111 method Action clock_enable();
115 (* always_ready, always_enabled *)
116 interface EdgeDetector#(type a);
117 method Bool rising();
118 method Bool falling();
121 (* always_ready, always_enabled *)
122 interface Synchronizer#(type a);
123 method Action _write(a x);
127 interface InputMovingFilter#(numeric type width, numeric type threshold, type a);
128 method Action sample();
129 method Action clear();
133 interface UART#(numeric type depth);
135 interface RS232 rs232;
136 interface Get#(Bit#(8)) tx;
137 interface Put#(Bit#(8)) rx;
138 method Bool transmission_done;
139 method Bool receiver_not_empty;
140 method Bool receiver_not_full;
141 method Bool transmittor_not_empty;
145 ////////////////////////////////////////////////////////////////////////////////
146 ////////////////////////////////////////////////////////////////////////////////
148 /// Implementation of Baud Generator
150 ////////////////////////////////////////////////////////////////////////////////
151 ////////////////////////////////////////////////////////////////////////////////
152 module mkBaudGenerator#(Bit#(16) divider)(BaudGenerator);
154 ////////////////////////////////////////////////////////////////////////////////
156 ////////////////////////////////////////////////////////////////////////////////
157 Counter#(16) rBaudCounter <- mkCounter(0);
158 PulseWire pwBaudTick16x <- mkPulseWire;
160 Counter#(3) rBaudTickCounter <- mkCounter(0);
161 PulseWire pwBaudTick2x <- mkPulseWire;
163 Wire#(Bit#(16)) wBaudCount <- mkWire;
164 rule baud_count_wire;
165 wBaudCount <= rBaudCounter.value;
167 Wire#(Bit#(3)) wBaudTickCount <- mkWire;
168 rule baud_tick_count_wire;
169 wBaudTickCount <= rBaudTickCounter.value;
172 ////////////////////////////////////////////////////////////////////////////////
174 ////////////////////////////////////////////////////////////////////////////////
175 rule count_baudtick_16x(pwBaudTick16x);
179 rule assert_2x_baud_tick(rBaudTickCounter.value() == 0 && pwBaudTick16x);
183 ////////////////////////////////////////////////////////////////////////////////
184 /// Interface Connections / Methods
185 ////////////////////////////////////////////////////////////////////////////////
186 method Action clock_enable();
187 if (rBaudCounter.value() + 1 >= divider) begin
196 method Action clear();
200 method Bool baud_tick_16x();
201 return pwBaudTick16x;
204 method Bool baud_tick_2x();
208 endmodule: mkBaudGenerator
210 ////////////////////////////////////////////////////////////////////////////////
211 ////////////////////////////////////////////////////////////////////////////////
213 /// Implementation of Input Filter
215 ////////////////////////////////////////////////////////////////////////////////
216 ////////////////////////////////////////////////////////////////////////////////
217 module mkInputFilter#(a initval, a din)(InputFilter#(size, a))
218 provisos( Bits#(a, sa)
221 , Log#(size, logsize)
222 , Add#(logsize, 1, csize)
225 ////////////////////////////////////////////////////////////////////////////////
227 ////////////////////////////////////////////////////////////////////////////////
228 Counter#(csize) counter <- mkCounter(0);
229 Reg#(a) rOut <- mkReg(initval);
231 ////////////////////////////////////////////////////////////////////////////////
233 ////////////////////////////////////////////////////////////////////////////////
235 ////////////////////////////////////////////////////////////////////////////////
236 /// Interface Connections / Methods
237 ////////////////////////////////////////////////////////////////////////////////
238 method Action clock_enable();
239 if (din == unpack(1) && counter.value() != fromInteger(valueof(size)))
241 else if (din == unpack(0) && counter.value() != 0)
244 if (counter.value() == fromInteger(valueof(size)))
246 else if (counter.value() == 0)
257 ////////////////////////////////////////////////////////////////////////////////
258 ////////////////////////////////////////////////////////////////////////////////
262 ////////////////////////////////////////////////////////////////////////////////
263 ////////////////////////////////////////////////////////////////////////////////
264 module mkEdgeDetector#(a initval, a din)(EdgeDetector#(a))
265 provisos( Bits#(a, sa)
270 ////////////////////////////////////////////////////////////////////////////////
272 ////////////////////////////////////////////////////////////////////////////////
273 Reg#(a) rDinD1 <- mkReg(initval);
275 ////////////////////////////////////////////////////////////////////////////////
277 ////////////////////////////////////////////////////////////////////////////////
278 (* fire_when_enabled *)
279 (* no_implicit_conditions *)
284 ////////////////////////////////////////////////////////////////////////////////
285 /// Interface Connections / Methods
286 ////////////////////////////////////////////////////////////////////////////////
287 method Bool rising();
288 return (din == unpack(1) && rDinD1 == unpack(0));
291 method Bool falling();
292 return (din == unpack(0) && rDinD1 == unpack(1));
295 endmodule: mkEdgeDetector
297 ////////////////////////////////////////////////////////////////////////////////
299 ////////////////////////////////////////////////////////////////////////////////
300 function Bool getRising(EdgeDetector#(a) ifc);
304 function Bool getFalling(EdgeDetector#(a) ifc);
308 ////////////////////////////////////////////////////////////////////////////////
309 ////////////////////////////////////////////////////////////////////////////////
311 /// Implementation of Synchronizer
313 ////////////////////////////////////////////////////////////////////////////////
314 ////////////////////////////////////////////////////////////////////////////////
315 module mkSynchronizer#(a initval)(Synchronizer#(a))
316 provisos( Bits#(a, sa)
320 ////////////////////////////////////////////////////////////////////////////////
322 ////////////////////////////////////////////////////////////////////////////////
323 Reg#(a) d1 <- mkReg(initval);
324 Reg#(a) d2 <- mkReg(initval);
326 ////////////////////////////////////////////////////////////////////////////////
327 /// Interface Connections / Methods
328 ////////////////////////////////////////////////////////////////////////////////
329 method Action _write(x);
338 endmodule: mkSynchronizer
340 ////////////////////////////////////////////////////////////////////////////////
341 ////////////////////////////////////////////////////////////////////////////////
343 /// Implementation of Input Filter
345 ////////////////////////////////////////////////////////////////////////////////
346 ////////////////////////////////////////////////////////////////////////////////
347 module mkInputMovingFilter#(a din)(InputMovingFilter#(width, threshold, a))
348 provisos( Bits#(a, sa)
353 ////////////////////////////////////////////////////////////////////////////////
355 ////////////////////////////////////////////////////////////////////////////////
356 Counter#(width) counter <- mkCounter(0);
357 Reg#(a) rOut <- mkReg(unpack(0));
358 PulseWire pwSample <- mkPulseWire;
360 ////////////////////////////////////////////////////////////////////////////////
362 ////////////////////////////////////////////////////////////////////////////////
363 (* preempts = "threshold_compare, take_sample" *)
364 rule threshold_compare(counter.value() >= fromInteger(valueof(threshold)));
368 rule take_sample(pwSample && din == unpack(1));
372 ////////////////////////////////////////////////////////////////////////////////
373 /// Interface Connections / Methods
374 ////////////////////////////////////////////////////////////////////////////////
375 method Action sample();
379 method Action clear();
391 ////////////////////////////////////////////////////////////////////////////////
392 ////////////////////////////////////////////////////////////////////////////////
394 /// Implementation of UART
396 ////////////////////////////////////////////////////////////////////////////////
397 ////////////////////////////////////////////////////////////////////////////////
398 module mkUART( Bit#(4) charsize
403 provisos(Add#(2, _1, d));
405 Integer fifodepth = valueof(d);
407 ////////////////////////////////////////////////////////////////////////////////
409 ////////////////////////////////////////////////////////////////////////////////
410 let baudGen <- mkBaudGenerator( divider );
412 ////////////////////////////////////////////////////////////////////////////////
414 ////////////////////////////////////////////////////////////////////////////////
415 FIFOLevelIfc#(Bit#(8), d) fifoRecv <- mkGFIFOLevel(True, False, True);
417 Vector#(8, Reg#(Bit#(1))) vrRecvBuffer <- replicateM(mkRegU);
419 Reg#(Bit#(1)) rRecvData <- mkReg(1);
421 Reg#(RecvState) rRecvState <- mkRegA(Start);
422 Reg#(Bit#(4)) rRecvCellCount <- mkRegA(0);
423 Reg#(Bit#(4)) rRecvBitCount <- mkRegA(0);
424 Reg#(Bit#(1)) rRecvParity <- mkRegA(0);
426 PulseWire pwRecvShiftBuffer <- mkPulseWire;
427 PulseWire pwRecvCellCountReset <- mkPulseWire;
428 PulseWire pwRecvResetBitCount <- mkPulseWire;
429 PulseWire pwRecvEnableBitCount <- mkPulseWire;
431 ////////////////////////////////////////////////////////////////////////////////
433 ////////////////////////////////////////////////////////////////////////////////
434 FIFOLevelIfc#(Bit#(8), d) fifoXmit <- mkGFIFOLevel(False, False, True);
436 Vector#(8, Reg#(Bit#(1))) vrXmitBuffer <- replicateM(mkRegU);
438 Reg#(XmitState) rXmitState <- mkRegA(Idle);
439 Reg#(Bit#(4)) rXmitCellCount <- mkRegA(0);
440 Reg#(Bit#(4)) rXmitBitCount <- mkRegA(0);
441 Reg#(Bit#(1)) rXmitDataOut <- mkRegA(1);
442 Reg#(Bit#(1)) rXmitParity <- mkRegA(0);
444 PulseWire pwXmitCellCountReset <- mkPulseWire;
445 PulseWire pwXmitResetBitCount <- mkPulseWire;
446 PulseWire pwXmitEnableBitCount <- mkPulseWire;
447 PulseWire pwXmitLoadBuffer <- mkPulseWire;
448 PulseWire pwXmitShiftBuffer <- mkPulseWire;
450 ////////////////////////////////////////////////////////////////////////////////
452 ////////////////////////////////////////////////////////////////////////////////
453 let tick = baudGen.baud_tick_16x;
455 ////////////////////////////////////////////////////////////////////////////////
456 /// Baud Clock Enable
457 ////////////////////////////////////////////////////////////////////////////////
458 (* no_implicit_conditions, fire_when_enabled *)
459 rule baud_generator_clock_enable;
460 baudGen.clock_enable;
463 ////////////////////////////////////////////////////////////////////////////////
465 ////////////////////////////////////////////////////////////////////////////////
466 rule receive_bit_cell_time_counter(tick);
467 if (pwRecvCellCountReset)
470 rRecvCellCount <= rRecvCellCount + 1;
473 rule receive_buffer_shift(pwRecvShiftBuffer);
474 let v = shiftInAtN(readVReg(vrRecvBuffer), rRecvData);
475 writeVReg(vrRecvBuffer, v);
478 rule receive_bit_counter;
479 if (pwRecvResetBitCount)
481 else if (pwRecvEnableBitCount)
482 rRecvBitCount <= rRecvBitCount + 1;
485 rule receive_wait_for_start_bit(rRecvState == Start && tick);
486 pwRecvCellCountReset.send();
487 if (rRecvData == 1'b0) begin
488 rRecvState <= Center;
492 pwRecvResetBitCount.send();
496 rule receive_find_center_of_bit_cell(rRecvState == Center && tick);
497 if (rRecvCellCount == 4'h4) begin
498 pwRecvCellCountReset.send();
499 if (rRecvData == 1'b0)
505 rRecvState <= Center;
509 rule receive_wait_bit_cell_time_for_sample(rRecvState == Wait && rRecvCellCount == 4'hF && tick);
510 pwRecvCellCountReset.send;
512 if (rRecvBitCount == charsize) begin
513 if (paritysel != NONE)
514 rRecvState <= Parity;
515 else if (stopbits != STOP_1)
516 rRecvState <= StopFirst;
518 rRecvState <= StopLast;
520 else if (rRecvBitCount == charsize + 1) begin
521 if (paritysel == NONE || stopbits == STOP_1)
522 rRecvState <= StopLast;
524 rRecvState <= StopFirst;
526 else if (rRecvBitCount == charsize + 2) begin
527 rRecvState <= StopLast;
530 rRecvState <= Sample;
534 rule receive_sample_pin(rRecvState == Sample && tick);
535 pwRecvShiftBuffer.send;
536 pwRecvEnableBitCount.send;
537 pwRecvCellCountReset.send;
541 rule receive_parity_bit(rRecvState == Parity && tick);
542 rRecvParity <= rRecvData;
543 pwRecvEnableBitCount.send;
544 pwRecvCellCountReset.send;
548 rule receive_stop_first_bit(rRecvState == StopFirst && tick);
549 pwRecvEnableBitCount.send;
550 pwRecvCellCountReset.send;
557 rule receive_stop_last_bit(rRecvState == StopLast && tick);
558 Vector#(8, Bit#(1)) data = take(readVReg(vrRecvBuffer));
559 Bit#(8) bitdata = pack(data) >> (8 - charsize);
561 fifoRecv.enq(bitdata);
563 pwRecvCellCountReset.send;
566 ////////////////////////////////////////////////////////////////////////////////
568 ////////////////////////////////////////////////////////////////////////////////
569 rule transmit_bit_cell_time_counter(tick);
570 if (pwXmitCellCountReset)
573 rXmitCellCount <= rXmitCellCount + 1;
576 rule transmit_bit_counter;
577 if (pwXmitResetBitCount)
579 else if (pwXmitEnableBitCount)
580 rXmitBitCount <= rXmitBitCount + 1;
583 rule transmit_buffer_load(pwXmitLoadBuffer);
584 Bit#(8) data = pack(fifoXmit.first);
587 writeVReg(vrXmitBuffer, unpack(data));
588 rXmitParity <= parity(data);
591 rule transmit_buffer_shift(!pwXmitLoadBuffer && pwXmitShiftBuffer);
592 let v = shiftInAtN(readVReg(vrXmitBuffer), 1);
593 writeVReg(vrXmitBuffer, v);
596 rule transmit_wait_for_start_command(rXmitState == Idle && tick);
597 rXmitDataOut <= 1'b1;
598 pwXmitResetBitCount.send;
599 if (fifoXmit.notEmpty) begin
600 pwXmitCellCountReset.send;
601 pwXmitLoadBuffer.send;
609 rule transmit_send_start_bit(rXmitState == Start && tick);
610 rXmitDataOut <= 1'b0;
611 if (rXmitCellCount == 4'hF) begin
613 pwXmitCellCountReset.send;
620 rule transmit_wait_1_bit_cell_time(rXmitState == Wait && tick);
621 rXmitDataOut <= head(readVReg(vrXmitBuffer));
622 if (rXmitCellCount == 4'hF) begin
623 pwXmitCellCountReset.send;
624 if (rXmitBitCount == (charsize - 1) && (paritysel == NONE)) begin
627 else if (rXmitBitCount == (charsize - 1) && (paritysel != NONE)) begin
628 rXmitState <= Parity;
632 pwXmitEnableBitCount.send;
640 rule transmit_shift_next_bit(rXmitState == Shift && tick);
641 rXmitDataOut <= head(readVReg(vrXmitBuffer));
643 pwXmitShiftBuffer.send;
646 rule transmit_send_parity_bit(rXmitState == Parity && tick);
647 case(paritysel) matches
648 ODD: rXmitDataOut <= rXmitParity;
649 EVEN: rXmitDataOut <= ~rXmitParity;
650 default: rXmitDataOut <= 1'b0;
653 if (rXmitCellCount == 4'hF) begin
655 pwXmitCellCountReset.send;
658 rXmitState <= Parity;
662 rule transmit_send_stop_bit(rXmitState == Stop && tick);
663 rXmitDataOut <= 1'b1;
664 if (rXmitCellCount == 4'hF && (stopbits == STOP_1)) begin
666 pwXmitCellCountReset.send;
668 else if (rXmitCellCount == 4'hF && (stopbits == STOP_2)) begin
670 pwXmitCellCountReset.send;
672 else if (rXmitCellCount == 4'hF && (stopbits == STOP_1_5)) begin
674 pwXmitCellCountReset.send;
681 rule transmit_send_stop_bit1_5(rXmitState == Stop5 && tick);
682 rXmitDataOut <= 1'b1;
683 if (rXmitCellCount == 4'h7) begin
685 pwXmitCellCountReset.send;
692 rule transmit_send_stop_bit2(rXmitState == Stop2 && tick);
693 rXmitDataOut <= 1'b1;
694 if (rXmitCellCount == 4'hF) begin
696 pwXmitCellCountReset.send;
703 ////////////////////////////////////////////////////////////////////////////////
704 /// Interface Connections / Methods
705 ////////////////////////////////////////////////////////////////////////////////
706 interface RS232 rs232;
707 method sout = rXmitDataOut;
708 method sin = rRecvData._write;
712 method ActionValue#(Bit#(8)) get;
713 let data = pack(fifoRecv.first);
720 method Action put(x);
725 method Bool transmission_done;
726 if(!fifoXmit.notEmpty && rXmitState==Idle)
732 method Bool receiver_not_empty;
733 return fifoRecv.notEmpty();
736 method Bool receiver_not_full;
737 return fifoRecv.notFull();
740 method Bool transmittor_not_empty;
741 return fifoXmit.notEmpty();