forked from tanchou/Verilog
		
	
		
			
				
	
	
		
			75 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
			
		
		
	
	
			75 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
| module uart_tx(
 | |
|     input wire clk,
 | |
|     input wire start,
 | |
|     input wire [7:0] data,
 | |
|     
 | |
|     output reg tx = 1,
 | |
|     output reg busy = 0
 | |
| );
 | |
| 
 | |
|     parameter CLK_FREQ = 27_000_000;             
 | |
|     parameter BAUD_RATE = 115_200;              
 | |
|     localparam BIT_PERIOD = CLK_FREQ / BAUD_RATE; 
 | |
| 
 | |
|     localparam IDLE  = 2'b00;
 | |
|     localparam START = 2'b01;
 | |
|     localparam DATA  = 2'b10;
 | |
|     localparam STOP  = 2'b11;
 | |
| 
 | |
|     reg [1:0] state = IDLE;
 | |
|     reg [3:0] bit_index = 0;            
 | |
|     reg [15:0] clk_count = 0;           
 | |
|     reg [7:0]  tx_data = 0;
 | |
| 
 | |
|     always @(posedge clk) begin
 | |
|         case(state)
 | |
|             IDLE: begin
 | |
|                 tx <= 1; 
 | |
| 
 | |
|                 if (start) begin
 | |
|                     tx_data <= data;
 | |
|                     bit_index <= 0;
 | |
|                     clk_count <= 0;
 | |
|                     busy <= 1;
 | |
|                     state <= START;
 | |
|                 end
 | |
|             end
 | |
| 
 | |
|             START: begin
 | |
|                 if (clk_count < BIT_PERIOD - 1) begin
 | |
|                     clk_count <= clk_count + 1;
 | |
|                     tx <= 0;
 | |
|                 end else begin
 | |
|                     state <= DATA;
 | |
|                     clk_count <= 0;
 | |
|                 end
 | |
|             end
 | |
| 
 | |
|             DATA: begin
 | |
|                 if (clk_count < BIT_PERIOD - 1) begin
 | |
|                     clk_count <= clk_count + 1;
 | |
| 
 | |
|                 end else if (bit_index < 8) begin
 | |
|                     tx <= tx_data[bit_index];
 | |
|                     bit_index <= bit_index + 1;
 | |
|                     clk_count <= 0;
 | |
| 
 | |
|                 end else begin
 | |
|                     state <= STOP;
 | |
|                 end
 | |
|             end
 | |
| 
 | |
|             STOP: begin
 | |
|                 tx <= 1;
 | |
|                 if (clk_count < BIT_PERIOD - 1) begin
 | |
|                     clk_count <= clk_count + 1;
 | |
|                 end else begin
 | |
|                     clk_count <= 0;
 | |
|                     busy <= 0;
 | |
|                     state <= IDLE;
 | |
|                 end
 | |
|             end
 | |
|         endcase
 | |
|     end
 | |
| endmodule
 |