Click Here To Return:

Verilog FPGA Transmit UART (tx_uart.v):


//////////////////////////////////////////////////////////////////
//
//  tx_uart Module
//
//     This is the UART section for transmit only.  It has been
//		 seperated out and modified from the original full version
//		 for our uses here.  This unit furter instantiates a 4 deep
//     8 wide fifo.
//
//////////////////////////////////////////////////////////////////

`include "timescale.v"

module tx_uart(
			input wire clk,
			input wire rst,
			output reg txd_o,
			input wire sio_ce,
			input wire [7:0] din_i,
			input wire we_i,
			output wire full_o,
			output wire output_active
			);

///////////////////////////////////////////////////////////////////
//
// Local Wires and Registers
//

parameter	START_BIT	= 1'b0,
		STOP_BIT	= 1'b1,
		IDLE_BIT	= 1'b1;

wire	[7:0]	txd_p;
reg		load;
wire		load_e;
reg	[9:0]	hold_reg;	// ****KYM
wire		txf_empty;
reg		shift_en;
reg	[3:0]	tx_bit_cnt;
wire		start;
reg		txf_empty_r;
reg		shift_en_r;

reg [1:0] out_active_counter;
reg			sio_r;

///////////////////////////////////////////////////////////////////
//
// IO Fifo's
//

fifo_33 #(8) tx_fifo(
			.clk(clk),
			.rst(rst),
			.din(din_i),
			.we(we_i),
			.dout(txd_p),
			.re(load_e),
			.full(full_o),
			.empty(txf_empty)
			);

///////////////////////////////////////////////////////////////////
//
// Transmit Logic
//

always @(posedge clk)
begin
	sio_r <= #1 sio_ce;
end

always @(posedge clk)
begin
	if(rst)
		out_active_counter[1:0] <= #1 2'b11;
	else 
	begin
		if(shift_en | (~txf_empty))
			out_active_counter[1:0] <= #1 2'b00;
		else if(sio_ce & ~sio_r & (out_active_counter[1:0] != 2'b11))
		out_active_counter[1:0] <= #1 out_active_counter[1:0] + 2'b01;
	end
end

assign #1 output_active = (out_active_counter[1:0] != 2'b11);

always @(posedge clk)
begin
	if(rst)
		txf_empty_r <= #1 1'b1;
	else if(sio_ce)
		txf_empty_r <= #1 txf_empty;
end

always @(posedge clk)
	load <= #1 !txf_empty_r & !shift_en;

assign load_e = load & sio_ce;

always @(posedge clk)
begin
	if(load_e)
		hold_reg <= #1 {STOP_BIT, txd_p[7:0], START_BIT};
	else if(shift_en & sio_ce)
		hold_reg <= #1 {IDLE_BIT, hold_reg[9:1]};
end

always @(posedge clk)
begin
	if(rst)
		txd_o <= #1 IDLE_BIT;
	else if(sio_ce)
		if(shift_en || shift_en_r)
			txd_o <= #1 hold_reg[0];
		else
			txd_o <= #1 IDLE_BIT;
end

always @(posedge clk)
begin
   if(rst)
		tx_bit_cnt <= #1 4'h9;
	else if(load_e)
		tx_bit_cnt <= #1 4'h0;
	else if(shift_en & sio_ce)
		tx_bit_cnt <= #1 tx_bit_cnt + 4'h1;
end

always @(posedge clk)
begin
	shift_en <= #1 (tx_bit_cnt != 4'h9);
end

always @(posedge clk)
begin
	if(rst)
		shift_en_r <= #1 1'b0;
	else if(sio_ce)
		shift_en_r <= #1 shift_en;
end

endmodule

Click Here To Return: