//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
// uart transmit module
|
// uart transmit module
|
//
|
//
|
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
|
|
module uart_tx
|
module uart_tx
|
(
|
(
|
clock, reset,
|
clock, reset,
|
ce_16, tx_data, new_tx_data,
|
ce_16, tx_data, new_tx_data,
|
ser_out, tx_busy
|
ser_out, tx_busy
|
);
|
);
|
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
// modules inputs and outputs
|
// modules inputs and outputs
|
input clock; // global clock input
|
input clock; // global clock input
|
input reset; // global reset input
|
input reset; // global reset input
|
input ce_16; // baud rate multiplyed by 16 - generated by baud module
|
input ce_16; // baud rate multiplyed by 16 - generated by baud module
|
input [7:0] tx_data; // data byte to transmit
|
input [7:0] tx_data; // data byte to transmit
|
input new_tx_data; // asserted to indicate that there is a new data byte for transmission
|
input new_tx_data; // asserted to indicate that there is a new data byte for transmission
|
output ser_out; // serial data output
|
output ser_out; // serial data output
|
output tx_busy; // signs that transmitter is busy
|
output tx_busy; // signs that transmitter is busy
|
|
|
// internal wires
|
// internal wires
|
wire ce_1; // clock enable at bit rate
|
wire ce_1; // clock enable at bit rate
|
|
|
// internal registers
|
// internal registers
|
reg ser_out;
|
reg ser_out;
|
reg tx_busy;
|
reg tx_busy;
|
reg [3:0] count16;
|
reg [3:0] count16;
|
reg [3:0] bit_count;
|
reg [3:0] bit_count;
|
reg [8:0] data_buf;
|
reg [8:0] data_buf;
|
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
// module implementation
|
// module implementation
|
// a counter to count 16 pulses of ce_16 to generate the ce_1 pulse
|
// a counter to count 16 pulses of ce_16 to generate the ce_1 pulse
|
always @ (posedge clock or posedge reset)
|
always @ (posedge clock or posedge reset)
|
begin
|
begin
|
if (reset)
|
if (reset)
|
count16 <= 4'b0;
|
count16 <= 4'b0;
|
else if (tx_busy & ce_16)
|
else if (tx_busy & ce_16)
|
count16 <= count16 + 4'b1;
|
count16 <= count16 + 4'b1;
|
else if (~tx_busy)
|
else if (~tx_busy)
|
count16 <= 4'b0;
|
count16 <= 4'b0;
|
end
|
end
|
|
|
// ce_1 pulse indicating output data bit should be updated
|
// ce_1 pulse indicating output data bit should be updated
|
assign ce_1 = (count16 == 4'b1111) & ce_16;
|
assign ce_1 = (count16 == 4'b1111) & ce_16;
|
|
|
// tx_busy flag
|
// tx_busy flag
|
always @ (posedge clock or posedge reset)
|
always @ (posedge clock or posedge reset)
|
begin
|
begin
|
if (reset)
|
if (reset)
|
tx_busy <= 1'b0;
|
tx_busy <= 1'b0;
|
else if (~tx_busy & new_tx_data)
|
else if (~tx_busy & new_tx_data)
|
tx_busy <= 1'b1;
|
tx_busy <= 1'b1;
|
else if (tx_busy & (bit_count == 4'ha) & ce_1)
|
else if (tx_busy & (bit_count == 4'h9) & ce_1)
|
tx_busy <= 1'b0;
|
tx_busy <= 1'b0;
|
end
|
end
|
|
|
// output bit counter
|
// output bit counter
|
always @ (posedge clock or posedge reset)
|
always @ (posedge clock or posedge reset)
|
begin
|
begin
|
if (reset)
|
if (reset)
|
bit_count <= 4'h0;
|
bit_count <= 4'h0;
|
else if (tx_busy & ce_1)
|
else if (tx_busy & ce_1)
|
bit_count <= bit_count + 4'h1;
|
bit_count <= bit_count + 4'h1;
|
else if (~tx_busy)
|
else if (~tx_busy)
|
bit_count <= 4'h0;
|
bit_count <= 4'h0;
|
end
|
end
|
|
|
// data shift register
|
// data shift register
|
always @ (posedge clock or posedge reset)
|
always @ (posedge clock or posedge reset)
|
begin
|
begin
|
if (reset)
|
if (reset)
|
data_buf <= 9'b0;
|
data_buf <= 9'b0;
|
else if (~tx_busy)
|
else if (~tx_busy)
|
data_buf <= {tx_data, 1'b0};
|
data_buf <= {tx_data, 1'b0};
|
else if (tx_busy & ce_1)
|
else if (tx_busy & ce_1)
|
data_buf <= {1'b1, data_buf[8:1]};
|
data_buf <= {1'b1, data_buf[8:1]};
|
end
|
end
|
|
|
// output data bit
|
// output data bit
|
always @ (posedge clock or posedge reset)
|
always @ (posedge clock or posedge reset)
|
begin
|
begin
|
if (reset)
|
if (reset)
|
ser_out <= 1'b1;
|
ser_out <= 1'b1;
|
else if (tx_busy)
|
else if (tx_busy)
|
ser_out <= data_buf[0];
|
ser_out <= data_buf[0];
|
else
|
else
|
ser_out <= 1'b1;
|
ser_out <= 1'b1;
|
end
|
end
|
|
|
endmodule
|
endmodule
|
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
// Th.. Th.. Th.. Thats all folks !!!
|
// Th.. Th.. Th.. Thats all folks !!!
|
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
|
|