module SerialBuffer(CLK, serial_CLK, reset, RXD, charRcvd, received, displayed); input CLK; input serial_CLK; // baud rate clock input reset; input RXD; // serial data input from RS232 cable input displayed; // handshake with received output charRcvd; reg charRcvd; // holds output to converted from serial to parallel output received; reg received; // handshake with displayed reg [3:0] bitCounter; // keep count of number of bits received reg [1:0] cycleCounter; // used to divide input clock by 4 reg [9:0] characterReceived; // start bit plus 8 data bits plus stop bit reg [8:0] characterToOutput; // storage used to shift data out reg [3:0] shiftCounter; // number of bits pushed out the data stream reg receiving; // flag indicating a character is arriving on RXD reg shifting; // flag indicating a character is being shifted out reg done; // flag to keep track of whether character has been shifted out or not // this always section uses the baud rate clock to receive a character into a 10-bit register // corresponding to 1 start, 8 data, and 1 stop bits // it oversamples the input 4 times to make sure to catch the start bit always @(posedge serial_CLK) begin if (reset) begin receiving <= 0; received <= 0; end else begin if (!receiving && !received && !displayed && RXD) // serial line is still quiet, nothing to do ; if (!receiving && !received && !displayed && !RXD) begin //found a start bit, reset the counters and set to receiving receiving <=1; cycleCounter <= 0; bitCounter <= 0; end if (receiving) begin // every four cycles . . . if (cycleCounter == 0) begin // copy sample into character bit array characterReceived[bitCounter] <= RXD; // if the counter has not reached 9 increment it if (bitCounter < 9) bitCounter <= bitCounter + 1; else begin // otherwise, signal that the entire character has been // received by starting handshake and resetting counter and flag receiving <= 0; received <= 1; end end cycleCounter <= cycleCounter + 1; // increment counter end if (received && displayed) begin // reset received once displayed is asserted, completing handshake received <= 0; end end end // this always section re-serializes the data to go to your parallelizer // it serves as a double buffer so that if another character is received on the // RS232 cable, it will not over-write the one currently being shifted out always @(posedge CLK) begin if (reset) begin shifting <= 0; done <= 0; charRcvd <= 1; end else if (received && !shifting && !done) begin // copy data into register to be shifted out on system clock cycles characterToOutput <= characterReceived[8:0]; shiftCounter <= 0; shifting <= 1; end else if (shifting && (shiftCounter < 9)) begin // output the next value in the buffer charRcvd <= characterToOutput[shiftCounter]; shiftCounter <= shiftCounter + 1; end else if (shifting && (shiftCounter >= 9)) begin // if done shifting, reset shifting, set done and keep output high shifting <= 0; done <= 1; charRcvd <= 1; end else if (!received) begin // reset done once handshake completes in other always block or if nothing is happening done <= 0; end end endmodule