基于FPGA的UART回环设计(2)

本文详细介绍基于FPGA的UART_TX模块设计,包括模块时序图、代码实现及测试代码,采用线性序列机方法,适合初学者学习串行通信模块的硬件设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

uart_tx模块的时序图

从上一篇文章中,我们已经学习了uart_rx的设计,也已经附上了详细的代码,详细同学们已经学会了该模块的设计。这篇文章我们主要介绍uart_tx模块的设计,与上篇文章相同,我们将先给出模块的时序图,再给出相应的代码,最后给出模块的测试代码。uart_tx模块的时序图如下:
在这里插入图片描述

uart_tx模块的代码

这里没有什么特别解释,同学们结合时序图与代码肯定可以看懂。这里直接上代码:

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : nnzhang1996@foxmail.com
// Website      : 
// Module Name  : uart_tx.v
// Create Time  : 2020-01-04 14:20:35
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************

module uart_tx(
    input                   sclk            ,
    input                   rst_n           ,
    input           [ 7:0]  pi_data         ,
    input                   fifo_empty      ,
    output  reg             rd_en           ,
    output  reg             tx              
);
 
//========================================================================================\
//**************Define Parameter and  Internal Signals**********************************
//========================================================================================/
parameter   BAUD_CNT        =       433     ;
reg                 [ 7:0]  pi_data_r       ;
reg                         rd_en_r         ;
reg                         tx_flag         ;
reg                 [14:0]  cnt_baud        ;
reg                         bit_flag        ;
reg                 [ 3:0]  bit_cnt         ;

 
//========================================================================================\
//**************     Main      Code        **********************************
//========================================================================================/
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        pi_data_r           <=      8'd0;
    else if(rd_en)
        pi_data_r           <=      pi_data;
    else
        pi_data_r           <=      pi_data_r;
          
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        rd_en_r             <=      1'b0;
    else if(fifo_empty == 1'b0 && tx_flag == 1'b0)
        rd_en_r             <=      1'b1;
    else
        rd_en_r             <=      1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        rd_en               <=      1'b0;
    else if(rd_en_r == 1'b1 && tx_flag == 1'b0)
        rd_en               <=      1'b1;
    else
        rd_en               <=      1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        tx_flag             <=      1'b0;
    else if(rd_en_r == 1'b1)
        tx_flag             <=      1'b1;
    else if(bit_flag == 1'b1 && bit_cnt == 4'd9)
        tx_flag             <=      1'b0;
    else
        tx_flag             <=      tx_flag;
        
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        cnt_baud            <=      15'd0;
    else if(tx_flag == 1'b0 || cnt_baud == BAUD_CNT) 
        cnt_baud            <=      15'd0;
    else if(tx_flag == 1'b1)
        cnt_baud            <=      cnt_baud + 1'b1;
    else
        cnt_baud            <=      cnt_baud;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        bit_flag            <=      1'b0;
    else if(cnt_baud == BAUD_CNT-1) 
        bit_flag            <=      1'b1;
    else
        bit_flag            <=      1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        bit_cnt             <=      4'd0;
    else if(bit_flag == 1'b1 && bit_cnt == 4'd9) 
        bit_cnt             <=      4'd0;
    else if(bit_flag == 1'b1)
        bit_cnt             <=      bit_cnt + 1'b1;
        
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        tx                  <=      1'b1;
    else if(bit_flag == 1'b1 && bit_cnt <= 4'd7)
        tx                  <=      pi_data_r[bit_cnt];
    else if(bit_cnt == 4'd0 && tx_flag == 1'b1) 
        tx                  <=      1'b0;
    else if(bit_cnt == 4'd9 && tx_flag == 1'b1)
        tx                  <=      1'b1;

endmodule

该模块所采用的方法同样是线性序列机的方法,这里不再多说。

uart_tx测试模块的代码

为了方便大家调试,uart_tx模块的测试代码如下:

`timescale 1ns / 1ps
`define     CLOCK       20
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : nnzhang1996@foxmail.com
// Website      : 
// Module Name  : uart_tx_tb.v
// Create Time  : 2020-01-04 14:54:40
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************

module uart_tx_tb();


reg                        sclk            ;
reg                        rst_n           ;
reg                [ 7:0]  pi_data         ;
wire                       rd_en           ;
wire                       tx              ;        

initial begin
    sclk            <=      1'b0;
    rst_n           =       1'b0;
    #(100*`CLOCK)
    rst_n           =       1'b1;
end
always #(`CLOCK/2)  sclk        <=      ~sclk;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        pi_data     <=      8'd0;     
    else if(rd_en == 1'b1) 
        pi_data     <=      pi_data + 1'b1;
    else
        pi_data     <=      pi_data;
        

uart_tx uart_tx_inst(
    .sclk               (sclk               ),
    .rst_n              (rst_n              ),
    .pi_data            (pi_data            ),
    .fifo_empty         (1'b0               ),
    .rd_en              (rd_en              ),
    .tx                 (tx                 )
);


endmodule

相信大家从上面的三个材料中肯定可以学会uart_tx模块的写法。

结束语

对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值