OpenCores
URL https://opencores.org/ocsvn/light8080/light8080/trunk

Subversion Repositories light8080

[/] [light8080/] [trunk/] [verilog/] [rtl/] [uart.v] - Rev 71

Go to most recent revision | Compare with Previous | Blame | View Log

//---------------------------------------------------------------------------------------
// uart top level module  
//
//---------------------------------------------------------------------------------------
 
module uart 
(
	clock, reset,
	serIn, serOut,
	txData, txValid, 
	txBusy, txDone, 
	rxData, rxValid, 
	baudDiv
);
//---------------------------------------------------------------------------------------
// module interfaces 
// global signals 
input 			clock;		// global clock input 
input 			reset;		// global reset input 
// uart serial signals 
input			serIn;		// serial data input 
output			serOut;		// serial data output 
// transmit and receive internal interface signals 
input	[7:0]	txData;		// data byte to transmit 
input			txValid;	// asserted to indicate that there is a new data byte for transmission 
output 			txBusy;		// signs that transmitter is busy 
output			txDone;		// transmitter done pulse 
output	[7:0]	rxData;		// data byte received 
output 			rxValid;	// signs that a new byte was received 
// baud rate configuration register 
input	[15:0]	baudDiv;	// baud rate setting register = round(clock_freq/baud_rate/16) - 1
 
//---------------------------------------------------------------------------------------
// internal declarations 
// registered output 
reg serOut, txBusy, txDone, rxValid;
reg [7:0] rxData;
 
// internals 
reg [8:0] txShiftReg;
reg [7:0] rxShiftReg;
reg [3:0] txBaudCnt, txBitCnt, rxBaudCnt, rxBitCnt;
reg [15:0] baudCount;
reg baudCE16, sserIn, rxBusy;
 
//---------------------------------------------------------------------------------------
// module implementation 
// transmitter control process 
always @ (posedge reset or posedge clock)
begin 
	if (reset) 
	begin 
		txBusy <= 1'b0;
		txDone <= 1'b0;
		txShiftReg <= 9'b0;
		serOut <= 1'b1;
		txBaudCnt <= 4'b0;
		txBitCnt <= 4'b0;
	end 
	else if (!txBusy) 
	begin 
		// check if transmitter operation should start 
		if (txValid) 
		begin 
			// register the data shift register and assert the transmitter busy flag 
			txShiftReg <= {txData, 1'b0};
			txBusy <= 1'b1;
		end 
 
		// defaults 
		serOut <= 1'b1;
		txDone <= 1'b0;
		txBaudCnt <= 4'b0;
		txBitCnt <= 4'b0;
	end 
	else if (baudCE16) 
	begin 
		// check if next bit should be sent out 
		if (txBaudCnt == 4'b0) 
		begin 
			//check if this is the last bit 
			if (txBitCnt == 4'd10) 
			begin 
				// clear the busy flag and pulse done flag 
				txBusy <= 1'b0;
				txDone <= 1'b1;
			end 
 
			// update the bit counter 
			txBitCnt <= txBitCnt + 4'd1;
 
			// update the serial output and shift register 
			serOut <= txShiftReg[0];
			txShiftReg <= {1'b1, txShiftReg[8:1]};
		end 
 
		// update the baud clock counter 
		txBaudCnt <= txBaudCnt + 4'd1;
	end 
end 
 
// receiver control process 
always @ (posedge reset or posedge clock)
begin 
	if (reset) 
	begin 
		rxBusy <= 1'b0;
		rxShiftReg <= 8'b0;
		rxBaudCnt <= 4'b0;
		rxBitCnt <= 4'b0;
		rxData <= 8'b0;
		rxValid <= 1'b0;
	end 
	else if (!rxBusy) 
	begin 
		// check start bit 
		if (!sserIn && baudCE16) 
		begin 
			// check if the serial input is zero for 8 baudCE16 cycles 
			if (rxBaudCnt == 4'd7)
			begin 
				// sign that receiver is busy and clear the bit counter 
				rxBusy <= 1'b1;
				rxBaudCnt <= 4'b0;
			end 
			else 
				rxBaudCnt <= rxBaudCnt + 4'd1;
		end 
 
		// defaults 
		rxBitCnt <= 4'b0;
		rxValid <= 1'b0;
	end 
	else if (baudCE16)
	begin 
		// check if bit should be sampled 
		if (rxBaudCnt == 4'd15) 
		begin 
			// update the input shift register and bit counter 
			rxShiftReg <= {sserIn, rxShiftReg[7:1]};
			rxBitCnt <= rxBitCnt + 4'd1;
 
			// check if this is the last data bit 
			if (rxBitCnt == 4'd8)
			begin 
				// sample the received data byte 
				rxData <= rxShiftReg;
				rxValid <= 1'b1;
 
				// clear receiver busy flag 
				rxBusy <= 1'b0;
			end 
		end 
 
		// update the baud clock counter 
		rxBaudCnt <= rxBaudCnt + 4'd1;
	end 
end 
 
// sample serial input 
always @ (posedge reset or posedge clock)
begin 
	if (reset) 
		sserIn <= 1'b0;
	else 
		sserIn <= serIn;
end 
 
// baud rate clock generator 
always @ (posedge reset or posedge clock)
begin 
	if (reset) 
	begin 
		baudCount <= 16'b0;
		baudCE16 <= 1'b0;
	end 
	else if (baudCount == baudDiv) 
	begin 
		// clear the divider counter and pulse the clock enable signal 
		baudCount <= 16'b0;
		baudCE16 <= 1'b1;
	end 
	else 
	begin 
		// update the clock divider counter and clear the 
		baudCount <= baudCount + 16'd1;
		baudCE16 <= 1'b0;
	end 
end 
 
endmodule
//---------------------------------------------------------------------------------------
//						Th.. Th.. Th.. Thats all folks !!!
//---------------------------------------------------------------------------------------
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.