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
|