4.串口发送模块

zhanglei 2022年10月19日 454次浏览

4.串口发送模块

4.1串口发送模块的设计

uart_byte_tx

module uart_byte_tx(
    Clk,
    Reset_n,
    Data,
    Send_Go,
    Baud_set,
    uart_tx,
    Tx_done
    );
    input Clk;
    input Reset_n;
    input [7:0]Data;
    input Send_Go;
    input [2:0] Baud_set;
    output reg uart_tx;
    output reg Tx_done;
    
    // Baud_set = 0  就让波特率 = 9600
    // Baud_set = 1  就让波特率 = 19200
    // Baud_set = 2  就让波特率 = 38400
    // Baud_set = 3  就让波特率 = 57600
    // Baud_set = 4  就让波特率 = 115200
    // 如果波特率是9600,那么1000000000/9600/20 = bps_DR
    reg [17:0] bps_DR;
    always@(*)
        case(Baud_set)
            0:bps_DR = 1000000000/9600/20;
            1:bps_DR = 1000000000/19200/20;
            2:bps_DR = 1000000000/38400/20;
            3:bps_DR = 1000000000/57600/20;
            4:bps_DR = 1000000000/115200/20;
            //默认为9600
            default:bps_DR = 1000000000/9600/20;
        endcase
    
    reg Send_en;
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        Send_en <= 0;
    else if(Send_Go)
        Send_en <= 1;
    else if(Tx_done)
        Send_en <= 0;
    
    reg[7:0] r_Data;     
    always@(posedge Clk)
    if(Send_Go)
        r_Data <= Data;
    else
        r_Data <= r_Data;
        
    reg[17:0] div_cnt;
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        div_cnt <= 0;
    else if(Send_en)begin
        if(div_cnt == bps_DR - 1)
            div_cnt <= 0;
        else 
             div_cnt <=  div_cnt + 1'b1;
     end
     else
        div_cnt <= 0;
        
    reg[3:0] bps_cnt;
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        bps_cnt <= 0;
    else if(Send_en)begin
        if(div_cnt == 1)begin
            if(bps_cnt == 11)
                bps_cnt <= 0;
            else
                bps_cnt <= bps_cnt + 1'b1;
         end
     end
     else 
        bps_cnt <= 0;
  
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)begin
        uart_tx <= 1'b1;
    end
    else begin
        case(bps_cnt)
            1: uart_tx <= 0;
            2:uart_tx <= r_Data[0];
            3:uart_tx <= r_Data[1];
            4:uart_tx <= r_Data[2];
            5:uart_tx <= r_Data[3];
            6:uart_tx <= r_Data[4];
            7:uart_tx <= r_Data[5];
            8:uart_tx <= r_Data[6];
            9:uart_tx <= r_Data[7];
            10:uart_tx <= 1;
            11:begin uart_tx <= 1;end
            default: uart_tx <= 1;
        endcase
    end
    
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        Tx_done <= 0;
    else if((div_cnt == 1) && (bps_cnt == 10))
        Tx_done <= 1;
    else 
        Tx_done <= 0;
endmodule

uart_byte_tx_tb

`timescale 1ns / 1ps

module uart_byte_tx_tb();
     reg Clk;
     reg Reset_n;
     reg [7:0] Data;
     reg Send_Go;
     reg [2:0]Baud_set;
     wire uart_tx;
     wire Tx_done;
     
     uart_byte_tx DUT(
        .Clk(Clk),
        .Reset_n(Reset_n),
        .Data(Data),
        .Send_Go(Send_Go),
        .Baud_set(Baud_set),
        .uart_tx(uart_tx),
        .Tx_done(Tx_done)
     );
     
     initial Clk = 1;
     always#10 Clk = ~Clk;
     
     initial begin
        Reset_n = 0;
        Data = 0;
        Send_Go = 0;
        Baud_set = 4;//波特率设为115200
        #201;
        Reset_n = 1;
        #100;
        Data = 8'h57;
        Send_Go = 1;
        #20
        @(posedge Tx_done)
         Data = 8'h75;
        Send_Go = 1;
        #20
        @(posedge Tx_done)
        #20000;
        Send_Go = 0;
        $stop;
    end
endmodule

仿真波形

image-20221019191320960