106 lines
2.6 KiB
Verilog
106 lines
2.6 KiB
Verilog
module uart_tx (
|
|
input wire clk,
|
|
input wire rst_n,
|
|
input wire tx_en,
|
|
input wire tx_start,
|
|
input wire [7:0] tx_data,
|
|
output reg tx_busy,
|
|
output reg tx_out
|
|
);
|
|
|
|
reg[1:0] state;
|
|
|
|
parameter STA_OFF = 2'd0;
|
|
parameter STA_IDLE = 2'd1;
|
|
parameter STA_DATA = 2'd2;
|
|
reg[7:0] data;
|
|
reg[3:0] cnt;
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if(~rst_n) begin
|
|
state <= STA_OFF;
|
|
end
|
|
else begin
|
|
if(tx_en == 1'b1) begin
|
|
case(state)
|
|
STA_OFF: begin
|
|
state <= STA_IDLE;
|
|
end
|
|
STA_IDLE: begin
|
|
if(tx_start == 1'b1) begin
|
|
state <= STA_DATA;
|
|
end
|
|
else begin
|
|
state <= STA_IDLE;
|
|
end
|
|
end
|
|
STA_DATA: begin
|
|
if(cnt == 4'd9) begin
|
|
state <= STA_IDLE;
|
|
end
|
|
else begin
|
|
state <= STA_DATA;
|
|
end
|
|
end
|
|
default state <= state;
|
|
endcase
|
|
end
|
|
else begin
|
|
state <= STA_OFF;
|
|
end
|
|
end
|
|
end
|
|
always @(state) begin
|
|
case(state)
|
|
STA_OFF: data<= 8'b0;
|
|
STA_DATA: begin
|
|
data <= tx_data;
|
|
end
|
|
default: begin
|
|
data <= data;
|
|
end
|
|
endcase
|
|
end
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if(~rst_n) begin
|
|
tx_out <= 1'b1;
|
|
cnt <= 4'd0;
|
|
end
|
|
else begin
|
|
case(state)
|
|
STA_OFF: begin
|
|
tx_out <= 1'b1;
|
|
cnt <= 4'd0;
|
|
end
|
|
STA_IDLE: begin
|
|
tx_out <= 1'b1 ;
|
|
cnt <= 4'd0;
|
|
end
|
|
STA_DATA: begin
|
|
if(cnt == 4'd0)begin
|
|
tx_out <= 1'b0;
|
|
cnt <= cnt + 1'b1;
|
|
end
|
|
else if (cnt < 4'd9) begin
|
|
// 1 - 8
|
|
tx_out <= data[cnt-1'b1];
|
|
cnt <= cnt + 1'b1;
|
|
end
|
|
else begin
|
|
cnt <= 4'd9;
|
|
tx_out <= 1'b1;
|
|
end
|
|
end
|
|
default: begin
|
|
tx_out <= 1'b1;
|
|
cnt <= 4'd0;
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
always @(*) begin
|
|
case (state)
|
|
STA_DATA: tx_busy = 1'b1;
|
|
default: tx_busy = 1'b0;
|
|
endcase
|
|
end
|
|
endmodule //uart_tx
|