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 *)
96 interface Put#(Bit#(1)) sin;
98 interface Get#(Bit#(1)) sout;
101 interface BaudGenerator;
102 method Action clock_enable();
103 method Action clear();
104 method Bool baud_tick_16x();
105 method Bool baud_tick_2x();
108 interface InputFilter#(numeric type size, type a);
109 method Action clock_enable();
113 (* always_ready, always_enabled *)
114 interface EdgeDetector#(type a);
115 method Bool rising();
116 method Bool falling();
119 (* always_ready, always_enabled *)
120 interface Synchronizer#(type a);
121 method Action _write(a x);
125 interface InputMovingFilter#(numeric type width, numeric type threshold, type a);
126 method Action sample();
127 method Action clear();
131 interface UART#(numeric type depth);
133 interface RS232 rs232;
134 interface Get#(Bit#(8)) tx;
135 interface Put#(Bit#(8)) rx;
136 method Bool transmission_done;
137 method Bool receiver_not_empty;
138 method Bool receiver_not_full;
139 method Bool transmittor_not_empty;
143 ////////////////////////////////////////////////////////////////////////////////
144 ////////////////////////////////////////////////////////////////////////////////
146 /// Implementation of Baud Generator
148 ////////////////////////////////////////////////////////////////////////////////
149 ////////////////////////////////////////////////////////////////////////////////
150 module mkBaudGenerator#(Bit#(16) divider)(BaudGenerator);
152 ////////////////////////////////////////////////////////////////////////////////
154 ////////////////////////////////////////////////////////////////////////////////
155 Counter#(16) rBaudCounter <- mkCounter(0);
156 PulseWire pwBaudTick16x <- mkPulseWire;
158 Counter#(3) rBaudTickCounter <- mkCounter(0);
159 PulseWire pwBaudTick2x <- mkPulseWire;
161 Wire#(Bit#(16)) wBaudCount <- mkWire;
162 rule baud_count_wire;
163 wBaudCount <= rBaudCounter.value;
165 Wire#(Bit#(3)) wBaudTickCount <- mkWire;
166 rule baud_tick_count_wire;
167 wBaudTickCount <= rBaudTickCounter.value;
170 ////////////////////////////////////////////////////////////////////////////////
172 ////////////////////////////////////////////////////////////////////////////////
173 rule count_baudtick_16x(pwBaudTick16x);
177 rule assert_2x_baud_tick(rBaudTickCounter.value() == 0 && pwBaudTick16x);
181 ////////////////////////////////////////////////////////////////////////////////
182 /// Interface Connections / Methods
183 ////////////////////////////////////////////////////////////////////////////////
184 method Action clock_enable();
185 if (rBaudCounter.value() + 1 >= divider) begin
194 method Action clear();
198 method Bool baud_tick_16x();
199 return pwBaudTick16x;
202 method Bool baud_tick_2x();
206 endmodule: mkBaudGenerator
208 ////////////////////////////////////////////////////////////////////////////////
209 ////////////////////////////////////////////////////////////////////////////////
211 /// Implementation of Input Filter
213 ////////////////////////////////////////////////////////////////////////////////
214 ////////////////////////////////////////////////////////////////////////////////
215 module mkInputFilter#(a initval, a din)(InputFilter#(size, a))
216 provisos( Bits#(a, sa)
219 , Log#(size, logsize)
220 , Add#(logsize, 1, csize)
223 ////////////////////////////////////////////////////////////////////////////////
225 ////////////////////////////////////////////////////////////////////////////////
226 Counter#(csize) counter <- mkCounter(0);
227 Reg#(a) rOut <- mkReg(initval);
229 ////////////////////////////////////////////////////////////////////////////////
231 ////////////////////////////////////////////////////////////////////////////////
233 ////////////////////////////////////////////////////////////////////////////////
234 /// Interface Connections / Methods
235 ////////////////////////////////////////////////////////////////////////////////
236 method Action clock_enable();
237 if (din == unpack(1) && counter.value() != fromInteger(valueof(size)))
239 else if (din == unpack(0) && counter.value() != 0)
242 if (counter.value() == fromInteger(valueof(size)))
244 else if (counter.value() == 0)
255 ////////////////////////////////////////////////////////////////////////////////
256 ////////////////////////////////////////////////////////////////////////////////
260 ////////////////////////////////////////////////////////////////////////////////
261 ////////////////////////////////////////////////////////////////////////////////
262 module mkEdgeDetector#(a initval, a din)(EdgeDetector#(a))
263 provisos( Bits#(a, sa)
268 ////////////////////////////////////////////////////////////////////////////////
270 ////////////////////////////////////////////////////////////////////////////////
271 Reg#(a) rDinD1 <- mkReg(initval);
273 ////////////////////////////////////////////////////////////////////////////////
275 ////////////////////////////////////////////////////////////////////////////////
276 (* fire_when_enabled *)
277 (* no_implicit_conditions *)
282 ////////////////////////////////////////////////////////////////////////////////
283 /// Interface Connections / Methods
284 ////////////////////////////////////////////////////////////////////////////////
285 method Bool rising();
286 return (din == unpack(1) && rDinD1 == unpack(0));
289 method Bool falling();
290 return (din == unpack(0) && rDinD1 == unpack(1));
293 endmodule: mkEdgeDetector
295 ////////////////////////////////////////////////////////////////////////////////
297 ////////////////////////////////////////////////////////////////////////////////
298 function Bool getRising(EdgeDetector#(a) ifc);
302 function Bool getFalling(EdgeDetector#(a) ifc);
306 ////////////////////////////////////////////////////////////////////////////////
307 ////////////////////////////////////////////////////////////////////////////////
309 /// Implementation of Synchronizer
311 ////////////////////////////////////////////////////////////////////////////////
312 ////////////////////////////////////////////////////////////////////////////////
313 module mkSynchronizer#(a initval)(Synchronizer#(a))
314 provisos( Bits#(a, sa)
318 ////////////////////////////////////////////////////////////////////////////////
320 ////////////////////////////////////////////////////////////////////////////////
321 Reg#(a) d1 <- mkReg(initval);
322 Reg#(a) d2 <- mkReg(initval);
324 ////////////////////////////////////////////////////////////////////////////////
325 /// Interface Connections / Methods
326 ////////////////////////////////////////////////////////////////////////////////
327 method Action _write(x);
336 endmodule: mkSynchronizer
338 ////////////////////////////////////////////////////////////////////////////////
339 ////////////////////////////////////////////////////////////////////////////////
341 /// Implementation of Input Filter
343 ////////////////////////////////////////////////////////////////////////////////
344 ////////////////////////////////////////////////////////////////////////////////
345 module mkInputMovingFilter#(a din)(InputMovingFilter#(width, threshold, a))
346 provisos( Bits#(a, sa)
351 ////////////////////////////////////////////////////////////////////////////////
353 ////////////////////////////////////////////////////////////////////////////////
354 Counter#(width) counter <- mkCounter(0);
355 Reg#(a) rOut <- mkReg(unpack(0));
356 PulseWire pwSample <- mkPulseWire;
358 ////////////////////////////////////////////////////////////////////////////////
360 ////////////////////////////////////////////////////////////////////////////////
361 (* preempts = "threshold_compare, take_sample" *)
362 rule threshold_compare(counter.value() >= fromInteger(valueof(threshold)));
366 rule take_sample(pwSample && din == unpack(1));
370 ////////////////////////////////////////////////////////////////////////////////
371 /// Interface Connections / Methods
372 ////////////////////////////////////////////////////////////////////////////////
373 method Action sample();
377 method Action clear();
389 ////////////////////////////////////////////////////////////////////////////////
390 ////////////////////////////////////////////////////////////////////////////////
392 /// Implementation of UART
394 ////////////////////////////////////////////////////////////////////////////////
395 ////////////////////////////////////////////////////////////////////////////////
396 module mkUART( Bit#(4) charsize
401 provisos(Add#(2, _1, d));
403 Integer fifodepth = valueof(d);
405 ////////////////////////////////////////////////////////////////////////////////
407 ////////////////////////////////////////////////////////////////////////////////
408 let baudGen <- mkBaudGenerator( divider );
410 ////////////////////////////////////////////////////////////////////////////////
412 ////////////////////////////////////////////////////////////////////////////////
413 FIFOLevelIfc#(Bit#(8), d) fifoRecv <- mkGFIFOLevel(True, False, True);
415 Vector#(8, Reg#(Bit#(1))) vrRecvBuffer <- replicateM(mkRegU);
417 Reg#(Bit#(1)) rRecvData <- mkReg(1);
419 Reg#(RecvState) rRecvState <- mkRegA(Start);
420 Reg#(Bit#(4)) rRecvCellCount <- mkRegA(0);
421 Reg#(Bit#(4)) rRecvBitCount <- mkRegA(0);
422 Reg#(Bit#(1)) rRecvParity <- mkRegA(0);
424 PulseWire pwRecvShiftBuffer <- mkPulseWire;
425 PulseWire pwRecvCellCountReset <- mkPulseWire;
426 PulseWire pwRecvResetBitCount <- mkPulseWire;
427 PulseWire pwRecvEnableBitCount <- mkPulseWire;
429 ////////////////////////////////////////////////////////////////////////////////
431 ////////////////////////////////////////////////////////////////////////////////
432 FIFOLevelIfc#(Bit#(8), d) fifoXmit <- mkGFIFOLevel(False, False, True);
434 Vector#(8, Reg#(Bit#(1))) vrXmitBuffer <- replicateM(mkRegU);
436 Reg#(XmitState) rXmitState <- mkRegA(Idle);
437 Reg#(Bit#(4)) rXmitCellCount <- mkRegA(0);
438 Reg#(Bit#(4)) rXmitBitCount <- mkRegA(0);
439 Reg#(Bit#(1)) rXmitDataOut <- mkRegA(1);
440 Reg#(Bit#(1)) rXmitParity <- mkRegA(0);
442 PulseWire pwXmitCellCountReset <- mkPulseWire;
443 PulseWire pwXmitResetBitCount <- mkPulseWire;
444 PulseWire pwXmitEnableBitCount <- mkPulseWire;
445 PulseWire pwXmitLoadBuffer <- mkPulseWire;
446 PulseWire pwXmitShiftBuffer <- mkPulseWire;
448 ////////////////////////////////////////////////////////////////////////////////
450 ////////////////////////////////////////////////////////////////////////////////
451 let tick = baudGen.baud_tick_16x;
453 ////////////////////////////////////////////////////////////////////////////////
454 /// Baud Clock Enable
455 ////////////////////////////////////////////////////////////////////////////////
456 (* no_implicit_conditions, fire_when_enabled *)
457 rule baud_generator_clock_enable;
458 baudGen.clock_enable;
461 ////////////////////////////////////////////////////////////////////////////////
463 ////////////////////////////////////////////////////////////////////////////////
464 rule receive_bit_cell_time_counter(tick);
465 if (pwRecvCellCountReset)
468 rRecvCellCount <= rRecvCellCount + 1;
471 rule receive_buffer_shift(pwRecvShiftBuffer);
472 let v = shiftInAtN(readVReg(vrRecvBuffer), rRecvData);
473 writeVReg(vrRecvBuffer, v);
476 rule receive_bit_counter;
477 if (pwRecvResetBitCount)
479 else if (pwRecvEnableBitCount)
480 rRecvBitCount <= rRecvBitCount + 1;
483 rule receive_wait_for_start_bit(rRecvState == Start && tick);
484 pwRecvCellCountReset.send();
485 if (rRecvData == 1'b0) begin
486 rRecvState <= Center;
490 pwRecvResetBitCount.send();
494 rule receive_find_center_of_bit_cell(rRecvState == Center && tick);
495 if (rRecvCellCount == 4'h4) begin
496 pwRecvCellCountReset.send();
497 if (rRecvData == 1'b0)
503 rRecvState <= Center;
507 rule receive_wait_bit_cell_time_for_sample(rRecvState == Wait && rRecvCellCount == 4'hF && tick);
508 pwRecvCellCountReset.send;
510 if (rRecvBitCount == charsize) begin
511 if (paritysel != NONE)
512 rRecvState <= Parity;
513 else if (stopbits != STOP_1)
514 rRecvState <= StopFirst;
516 rRecvState <= StopLast;
518 else if (rRecvBitCount == charsize + 1) begin
519 if (paritysel == NONE || stopbits == STOP_1)
520 rRecvState <= StopLast;
522 rRecvState <= StopFirst;
524 else if (rRecvBitCount == charsize + 2) begin
525 rRecvState <= StopLast;
528 rRecvState <= Sample;
532 rule receive_sample_pin(rRecvState == Sample && tick);
533 pwRecvShiftBuffer.send;
534 pwRecvEnableBitCount.send;
535 pwRecvCellCountReset.send;
539 rule receive_parity_bit(rRecvState == Parity && tick);
540 rRecvParity <= rRecvData;
541 pwRecvEnableBitCount.send;
542 pwRecvCellCountReset.send;
546 rule receive_stop_first_bit(rRecvState == StopFirst && tick);
547 pwRecvEnableBitCount.send;
548 pwRecvCellCountReset.send;
555 rule receive_stop_last_bit(rRecvState == StopLast && tick);
556 Vector#(8, Bit#(1)) data = take(readVReg(vrRecvBuffer));
557 Bit#(8) bitdata = pack(data) >> (8 - charsize);
559 fifoRecv.enq(bitdata);
561 pwRecvCellCountReset.send;
564 ////////////////////////////////////////////////////////////////////////////////
566 ////////////////////////////////////////////////////////////////////////////////
567 rule transmit_bit_cell_time_counter(tick);
568 if (pwXmitCellCountReset)
571 rXmitCellCount <= rXmitCellCount + 1;
574 rule transmit_bit_counter;
575 if (pwXmitResetBitCount)
577 else if (pwXmitEnableBitCount)
578 rXmitBitCount <= rXmitBitCount + 1;
581 rule transmit_buffer_load(pwXmitLoadBuffer);
582 Bit#(8) data = pack(fifoXmit.first);
585 writeVReg(vrXmitBuffer, unpack(data));
586 rXmitParity <= parity(data);
589 rule transmit_buffer_shift(!pwXmitLoadBuffer && pwXmitShiftBuffer);
590 let v = shiftInAtN(readVReg(vrXmitBuffer), 1);
591 writeVReg(vrXmitBuffer, v);
594 rule transmit_wait_for_start_command(rXmitState == Idle && tick);
595 rXmitDataOut <= 1'b1;
596 pwXmitResetBitCount.send;
597 if (fifoXmit.notEmpty) begin
598 pwXmitCellCountReset.send;
599 pwXmitLoadBuffer.send;
607 rule transmit_send_start_bit(rXmitState == Start && tick);
608 rXmitDataOut <= 1'b0;
609 if (rXmitCellCount == 4'hF) begin
611 pwXmitCellCountReset.send;
618 rule transmit_wait_1_bit_cell_time(rXmitState == Wait && tick);
619 rXmitDataOut <= head(readVReg(vrXmitBuffer));
620 if (rXmitCellCount == 4'hF) begin
621 pwXmitCellCountReset.send;
622 if (rXmitBitCount == (charsize - 1) && (paritysel == NONE)) begin
625 else if (rXmitBitCount == (charsize - 1) && (paritysel != NONE)) begin
626 rXmitState <= Parity;
630 pwXmitEnableBitCount.send;
638 rule transmit_shift_next_bit(rXmitState == Shift && tick);
639 rXmitDataOut <= head(readVReg(vrXmitBuffer));
641 pwXmitShiftBuffer.send;
644 rule transmit_send_parity_bit(rXmitState == Parity && tick);
645 case(paritysel) matches
646 ODD: rXmitDataOut <= rXmitParity;
647 EVEN: rXmitDataOut <= ~rXmitParity;
648 default: rXmitDataOut <= 1'b0;
651 if (rXmitCellCount == 4'hF) begin
653 pwXmitCellCountReset.send;
656 rXmitState <= Parity;
660 rule transmit_send_stop_bit(rXmitState == Stop && tick);
661 rXmitDataOut <= 1'b1;
662 if (rXmitCellCount == 4'hF && (stopbits == STOP_1)) begin
664 pwXmitCellCountReset.send;
666 else if (rXmitCellCount == 4'hF && (stopbits == STOP_2)) begin
668 pwXmitCellCountReset.send;
670 else if (rXmitCellCount == 4'hF && (stopbits == STOP_1_5)) begin
672 pwXmitCellCountReset.send;
679 rule transmit_send_stop_bit1_5(rXmitState == Stop5 && tick);
680 rXmitDataOut <= 1'b1;
681 if (rXmitCellCount == 4'h7) begin
683 pwXmitCellCountReset.send;
690 rule transmit_send_stop_bit2(rXmitState == Stop2 && tick);
691 rXmitDataOut <= 1'b1;
692 if (rXmitCellCount == 4'hF) begin
694 pwXmitCellCountReset.send;
701 ////////////////////////////////////////////////////////////////////////////////
702 /// Interface Connections / Methods
703 ////////////////////////////////////////////////////////////////////////////////
704 interface RS232 rs232;
705 interface sin = interface Put
706 method Action put(Bit#(1) in);
707 rRecvData._write(in);
710 interface sout = interface Get
711 method ActionValue#(Bit#(1)) get;
718 method ActionValue#(Bit#(8)) get;
719 let data = pack(fifoRecv.first);
726 method Action put(x);
731 method Bool transmission_done;
732 if(!fifoXmit.notEmpty && rXmitState==Idle)
738 method Bool receiver_not_empty;
739 return fifoRecv.notEmpty();
742 method Bool receiver_not_full;
743 return fifoRecv.notFull();
746 method Bool transmittor_not_empty;
747 return fifoXmit.notEmpty();