You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
|
|
////////////////////////////////////////////////////////////////////////////////// // // // // // Author: meisq // // msq@qq.com // // ALINX(shanghai) Technology Co.,Ltd // // heijin // // WEB: http://www.alinx.cn/ // // BBS: http://www.heijin.org/ // // // ////////////////////////////////////////////////////////////////////////////////// // // // Copyright (c) 2017,ALINX(shanghai) Technology Co.,Ltd // // All rights reserved // // // // This source file may be used and distributed without restriction provided // // that this copyright statement is not removed from the file and that any // // derivative work contains the original copyright notice and the associated // // disclaimer. // // // //////////////////////////////////////////////////////////////////////////////////
//================================================================================ // Revision History: // Date By Revision Change Description //-------------------------------------------------------------------------------- //2017/8/1 1.0 Original //*******************************************************************************/ module uart_tx #( parameter CLK_FRE = 50, //clock frequency(Mhz) parameter BAUD_RATE = 115200 //serial baud rate ) ( input clk, //clock input input rst_n, //asynchronous reset input, low active input[7:0] tx_data, //data to send input tx_data_valid, //data to be sent is valid output reg tx_data_ready, //send ready output tx_pin //serial data output ); //calculates the clock cycle for baud rate localparam CYCLE = CLK_FRE * 1000000 / BAUD_RATE; //state machine code localparam S_IDLE = 1; localparam S_START = 2;//start bit localparam S_SEND_BYTE = 3;//data bits localparam S_STOP = 4;//stop bit reg[2:0] state; reg[2:0] next_state; reg[15:0] cycle_cnt; //baud counter reg[2:0] bit_cnt;//bit counter reg[7:0] tx_data_latch; //latch data to send reg tx_reg; //serial data output assign tx_pin = tx_reg; always@(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) state <= S_IDLE; else state <= next_state; end
always@(*)
begin case(state) S_IDLE: if(tx_data_valid == 1'b1) next_state <= S_START; else next_state <= S_IDLE; S_START: if(cycle_cnt == CYCLE - 1) next_state <= S_SEND_BYTE; else next_state <= S_START; S_SEND_BYTE: if(cycle_cnt == CYCLE - 1 && bit_cnt == 3'd7) next_state <= S_STOP; else next_state <= S_SEND_BYTE; S_STOP: if(cycle_cnt == CYCLE - 1) next_state <= S_IDLE; else next_state <= S_STOP; default: next_state <= S_IDLE; endcase end always@(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) begin tx_data_ready <= 1'b0; end else if(state == S_IDLE) if(tx_data_valid == 1'b1) tx_data_ready <= 1'b0; else tx_data_ready <= 1'b1; else if(state == S_STOP && cycle_cnt == CYCLE - 1) tx_data_ready <= 1'b1; end
always@(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) begin tx_data_latch <= 8'd0; end else if(state == S_IDLE && tx_data_valid == 1'b1) tx_data_latch <= tx_data; end
always@(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) begin bit_cnt <= 3'd0; end else if(state == S_SEND_BYTE) if(cycle_cnt == CYCLE - 1) bit_cnt <= bit_cnt + 3'd1; else bit_cnt <= bit_cnt; else bit_cnt <= 3'd0; end
always@(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) cycle_cnt <= 16'd0; else if((state == S_SEND_BYTE && cycle_cnt == CYCLE - 1) || next_state != state) cycle_cnt <= 16'd0; else cycle_cnt <= cycle_cnt + 16'd1; end
always@(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) tx_reg <= 1'b1; else case(state) S_IDLE,S_STOP: tx_reg <= 1'b1; S_START: tx_reg <= 1'b0; S_SEND_BYTE: tx_reg <= tx_data_latch[bit_cnt]; default: tx_reg <= 1'b1; endcase end
endmodule
|