(二)verilog uart tx 串口发送一个字节数据

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    18:57:31 06/18/2019 
// Design Name: 
// Module Name:    uart_tx 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module uart_tx
#(
    parameter CLK_FRE = 50,
    parameter BAUD_RATE = 115200
)
(
    input clk,
    input rst_n,
    input[7:0] tx_data,
    input tx_data_valid,
    output reg tx_data_ready,
    output tx_pin
    );
     
localparam CYCLE = CLK_FRE*1000000/BAUD_RATE;
localparam S_IDLE         =1;
localparam S_START        =2;
localparam S_SEND_BYTE    =3;
localparam S_STOP         =4;

reg[2:0]  state;
reg[2:0]  next_state;
reg[15:0] cycle_cnt;
reg[2:0] bit_cnt;
reg[7:0] tx_data_latch;
reg tx_reg;

//对发送引脚赋值
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
        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

//获取想要发送的8位数据

always @(posedge clk or negedge rst_n)
begin
    if(rst_n == 1'b0)
        tx_data_latch <= 8'd0;
    else if(state == S_START && 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
        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)
        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'd1;
    else 
        case(state)
            S_START:
                tx_reg <= 1'd0;
            S_SEND_BYTE:
                tx_reg <= tx_data_latch[bit_cnt];
            S_STOP:
                tx_reg <= 1'd1;
            default :
                tx_reg <= 1'd1;
        endcase
    
end

endmodule
 

你可能感兴趣的:(Xilinx,FPAG)