// Simple transmit-only UART model
|
// Simple transmit-only UART model
|
|
|
module uart #(
|
module uart #(
|
parameter BAUD = 115200,
|
parameter [28:0] BAUD = 115200,
|
parameter IN_CLOCK = 50000000)
|
parameter [28:0] IN_CLOCK = 50000000)
|
(
|
(
|
// Outputs
|
// Outputs
|
output wire busy, // Set when busy transmitting
|
output wire busy, // Set when busy transmitting
|
output reg uart_tx, // UART transmit wire
|
output reg uart_tx, // UART transmit wire
|
// Inputs
|
// Inputs
|
input wire wr, // Write a new byte to transmit
|
input wire wr, // Write a new byte to transmit
|
input wire [7:0] data, // 8-bit data
|
input wire [7:0] data, // 8-bit data
|
input wire clk,
|
input wire clk,
|
input wire reset
|
input wire reset
|
);
|
);
|
|
|
reg [3:0] bitcount;
|
reg [3:0] bitcount;
|
reg [8:0] shifter;
|
reg [8:0] shifter;
|
|
|
assign busy = |bitcount[3:1];
|
assign busy = |bitcount[3:1];
|
wire sending = |bitcount;
|
wire sending = |bitcount;
|
|
|
// Calculate UART clock based on the input clock
|
// Calculate UART clock based on the input clock
|
reg [28:0] d;
|
reg [28:0] d;
|
wire [28:0] inc = d[28] ? 29'(BAUD) : 29'(BAUD - IN_CLOCK);
|
wire [28:0] inc = d[28] ? (BAUD) : (BAUD - IN_CLOCK);
|
wire [28:0] delta = d + inc;
|
wire [28:0] delta = d + inc;
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
begin
|
begin
|
if (reset)
|
if (reset)
|
begin
|
begin
|
d = 0;
|
d = 0;
|
end else
|
end else
|
begin
|
begin
|
d = delta;
|
d = delta;
|
end
|
end
|
end
|
end
|
|
|
wire ser_clk = ~d[28]; // UART clock
|
wire ser_clk = ~d[28]; // UART clock
|
|
|
always @(posedge clk) begin
|
always @(posedge clk) begin
|
if (reset)
|
if (reset)
|
begin
|
begin
|
uart_tx <= 1;
|
uart_tx <= 1;
|
bitcount <= 0;
|
bitcount <= 0;
|
shifter <= 0;
|
shifter <= 0;
|
end else
|
end else
|
begin
|
begin
|
if (wr & ~busy)
|
if (wr & ~busy)
|
begin
|
begin
|
// synopsys translate_off
|
// synopsys translate_off
|
$strobe("[UART] %c", data[7:0]);
|
$strobe("[UART] %c", data[7:0]);
|
// synopsys translate_on
|
// synopsys translate_on
|
shifter <= { data[7:0], 1'h0 };
|
shifter <= { data[7:0], 1'h0 };
|
bitcount <= 4'd11; // 1 + 8 + 2
|
bitcount <= 4'd11; // 1 + 8 + 2
|
end
|
end
|
|
|
if (sending & ser_clk)
|
if (sending & ser_clk)
|
begin
|
begin
|
{ shifter, uart_tx } <= { 1'h1, shifter };
|
{ shifter, uart_tx } <= { 1'h1, shifter };
|
bitcount <= bitcount - 4'd1;
|
bitcount <= bitcount - 4'd1;
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
endmodule
|
endmodule
|
|
|