Initial commit: LVDS Protocol Analyser v1.0.0
This commit is contained in:
81
uart_tx.v
Normal file
81
uart_tx.v
Normal file
@@ -0,0 +1,81 @@
|
||||
// uart_tx.v
|
||||
//
|
||||
// Byte-at-a-time UART transmitter. 8N1, no flow control.
|
||||
// Default 115200 baud from a 50 MHz clock (divisor = 434, ~0.06% error).
|
||||
//
|
||||
// Handshake: assert `start` for one clk with `data` valid. The byte is
|
||||
// captured on that edge; `busy` then goes high until the stop bit
|
||||
// completes. Hold off further `start` pulses while `busy` is high.
|
||||
|
||||
module uart_tx #(
|
||||
parameter integer CLK_HZ = 50_000_000,
|
||||
parameter integer BAUD = 115_200
|
||||
)(
|
||||
input wire clk,
|
||||
input wire rst_n,
|
||||
input wire start,
|
||||
input wire [7:0] data,
|
||||
output reg tx,
|
||||
output reg busy
|
||||
);
|
||||
|
||||
localparam integer DIV = (CLK_HZ + BAUD/2) / BAUD;
|
||||
localparam integer DW = $clog2(DIV);
|
||||
|
||||
localparam [3:0] S_IDLE = 4'd0,
|
||||
S_START = 4'd1,
|
||||
S_D0 = 4'd2, S_D1 = 4'd3, S_D2 = 4'd4, S_D3 = 4'd5,
|
||||
S_D4 = 4'd6, S_D5 = 4'd7, S_D6 = 4'd8, S_D7 = 4'd9,
|
||||
S_STOP = 4'd10;
|
||||
|
||||
reg [3:0] state;
|
||||
reg [DW-1:0] tick;
|
||||
reg [7:0] shift;
|
||||
|
||||
wire tick_done = (tick == DIV-1);
|
||||
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
state <= S_IDLE;
|
||||
tick <= 0;
|
||||
shift <= 8'd0;
|
||||
tx <= 1'b1;
|
||||
busy <= 1'b0;
|
||||
end else begin
|
||||
case (state)
|
||||
S_IDLE: begin
|
||||
tx <= 1'b1;
|
||||
busy <= 1'b0;
|
||||
tick <= 0;
|
||||
if (start) begin
|
||||
shift <= data;
|
||||
state <= S_START;
|
||||
busy <= 1'b1;
|
||||
tx <= 1'b0; // start bit asserted immediately
|
||||
end
|
||||
end
|
||||
default: begin
|
||||
if (tick_done) begin
|
||||
tick <= 0;
|
||||
case (state)
|
||||
S_START: begin tx <= shift[0]; state <= S_D0; end
|
||||
S_D0: begin tx <= shift[1]; state <= S_D1; end
|
||||
S_D1: begin tx <= shift[2]; state <= S_D2; end
|
||||
S_D2: begin tx <= shift[3]; state <= S_D3; end
|
||||
S_D3: begin tx <= shift[4]; state <= S_D4; end
|
||||
S_D4: begin tx <= shift[5]; state <= S_D5; end
|
||||
S_D5: begin tx <= shift[6]; state <= S_D6; end
|
||||
S_D6: begin tx <= shift[7]; state <= S_D7; end
|
||||
S_D7: begin tx <= 1'b1; state <= S_STOP; end
|
||||
S_STOP: begin state <= S_IDLE; busy <= 1'b0; end
|
||||
default: state <= S_IDLE;
|
||||
endcase
|
||||
end else begin
|
||||
tick <= tick + 1'b1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user