uart联系

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/07/09 20:32:42
// Design Name: 
// Module Name: uart_drive
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module uart_drive#(
    parameter                           P_SYSTEM_CLK        =   50_000_000  ,
    parameter                           P_UART_DATA_WIDTH   =   8           ,
    parameter                           P_UART_BUAD_CLK     =   9600        ,
    parameter                           P_UART_STOP_WIDTH   =   1           ,
    parameter                           P_UART_CHECK        =   0             
)
(
    input                               i_sys_clk                           ,
    input                               i_sys_rst                           ,

    input                               i_uart_rx                           ,
    output                               o_uart_tx                           ,

    input   [P_UART_DATA_WIDTH-1:0]     i_uart_tx_data                      ,
    input                               i_uart_tx_vaild                     ,
    output                              o_uart_tx_ready                     ,

    output  [P_UART_DATA_WIDTH-1:0]     o_uart_rx_data                      ,  
    output                              o_uart_rx_vaild                     ,
    output                              o_buad_clk                          ,
    output                              o_buad_clk_rst  
);

    localparam                          P_DIV   =   P_SYSTEM_CLK/P_UART_BUAD_CLK    ;

    wire                                w_buad_clk                          ;  
    wire                                w_buad_clk_rst                      ;
    wire                                w_uart_rx_vaild                     ;
    wire                                w_rx_clk                            ;

    reg                                 r_rx_rst                            ;
    reg                                 r_uart_rx_vaild                     ;
    reg                                 o_uart_rx_vaild
    reg     [2:0]                       r_rx_overvalue                      ;
    reg     [2:0]                       r_rx_overvalue_1d                   ;
    reg                                 r_rx_overlock                       ;
       

    assign  o_buad_clk =w_buad_clk;
    assign  o_buad_clk_rst= w_buad_clk_rst;

    clk_div#(
        .P_CLK_DIV                 (P_DIV              )                
    )
    clk_div_u0
    (
        .i_sys_clk                     (i_sys_clk           )               ,
        .i_sys_rst                     (i_sys_rst           )               ,
        .o_clk_div                     (w_buad_clk          )
    );


    clk_div#(
        .P_CLK_DIV                 (P_DIV              )                
    )
    clk_div_u1
    (
        .i_sys_clk                     (i_sys_clk           )               ,
        .i_sys_rst                     (r_rx_rst           )               ,
        .o_clk_div                     (w_rx_clk            )
    );


    rst_gen#(
    .P_RST_CYCLE                       ( 4                  )               
    )
    rst_gen_u0
(
    .i_sys_clk                         (w_buad_clk          )                   ,
    .o_sys_rst                             (w_buad_clk_rst      )                            
);


uart_tx#(
    .P_UART_DATA_WIDTH                  (P_UART_DATA_WIDTH  )                    ,
    .P_UART_STOP_WIDTH                  (P_UART_STOP_WIDTH  )                    ,
    .P_UART_CHECK                       (P_UART_CHECK       )               
)
uart_tx_u0
(
    .i_uart_tx_data                     (i_uart_tx_data     )                   ,
    .i_clk                              (w_buad_clk         )                   ,
    .i_rst                              (w_buad_clk_rst     )                   ,
    .i_uart_tx_vaild                    (i_uart_tx_vaild    )                   ,

    .o_uart_tx_ready                    (o_uart_tx_ready    )                   ,
    .o_uart_tx                          (o_uart_tx          )  
);


uart_rx#(
    .P_UART_DATA_WIDTH                  (P_UART_DATA_WIDTH  )                   ,
    .P_UART_STOP_WIDTH                  (P_UART_STOP_WIDTH  )                   ,
    .P_UART_CHECK                       (P_UART_CHECK       )                       
)
uart_rx_u0
(
    .i_uart_rx                          (i_uart_rx)                             ,
    .i_clk                              (w_rx_clk)                               ,
    .i_rst                              (w_buad_clk_rst)                        ,

    .o_uart_rx_data                     (o_uart_rx_data)                        ,
    .o_uart_rx_vaild                    (w_uart_rx_vaild)                      
);


always@(posedge i_sys_clk or posedge i_sys_rst)
begin
  if(i_sys_rst)
    r_rx_overvalue<=3'b111;
  else if(!r_rx_overlock)
    r_rx_overvalue<={r_rx_overvalue[1:0],i_uart_rx};
  else
    r_rx_overvalue<=3'b111;
end

always@(posedge i_sys_clk or posedge i_sys_rst)
begin
  if(i_sys_rst)
    r_rx_overvalue_1d<=3'b111;
  else
    r_rx_overvalue_1d<= r_rx_overvalue;
end

always@(posedge i_sys_clk or posedge i_sys_rst)
begin
  if(i_sys_rst)
    r_rx_overlock<='d0;
  else if(!r_uart_rx_vaild && w_uart_rx_vaild)
    r_rx_overlock<='d0;
  else if(!(r_rx_overvalue_1d==3'b000)&&r_rx_overvalue==3'b000)
    r_rx_overlock<='d1;
  else
    r_rx_overlock<=r_rx_overlock;
end
 
always@(posedge i_sys_clk or posedge i_sys_rst)
begin
  if(i_sys_rst)
    r_uart_rx_vaild<='d0;
  else
    r_uart_rx_vaild<=w_uart_rx_vaild;
end

always@(posedge i_sys_clk or posedge i_sys_rst)
begin
  if(i_sys_rst) 
    r_rx_rst<='d1;
  else if(!r_uart_rx_vaild && w_uart_rx_vaild)
    r_rx_rst<='d1;
  else if(!(r_rx_overvalue_1d==3'b000)&&r_rx_overvalue==3'b000)
    r_rx_rst<='d0;
  else
    r_rx_rst<=r_rx_rst;
end

endmodule

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/07/09 20:32:42
// 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                               P_UART_DATA_WIDTH   =   8           ,
    parameter                               P_UART_STOP_WIDTH   =   1           ,
    parameter                               P_UART_CHECK        =   1               
)
(
    input       [P_UART_DATA_WIDTH-1:0]     i_uart_tx_data                      ,
    input                                   i_clk                               ,
    input                                   i_rst                               ,
    input                                   i_uart_tx_vaild                     ,

    output                                  o_uart_tx_ready                     ,
    output                                  o_uart_tx   
);

    reg                                     r_uart_tx                           ;
    reg                                     r_uart_tx_ready                     ;
    reg         [P_UART_DATA_WIDTH-1:0]     r_uart_tx_data                      ;
    reg         [15:0]                      r_cnt                               ;
    reg                                     r_uart_check                        ;

    wire                                    w_tx_active                         ;

    assign      w_tx_active         =   i_uart_tx_vaild &&  r_uart_tx_ready     ;       //握手信号,激活发送
    assign      o_uart_tx_ready     =   r_uart_tx_data                          ;
    assign      o_uart_tx           =   r_uart_tx                               ;


    //数据寄存
always@(posedge i_clk or posedge i_rst)
begin
  if(i_rst)
    r_uart_tx_data<='d0;
  else if(w_tx_active)
    r_uart_tx_data<=i_uart_tx_data;
  else if(!r_uart_tx_ready)
    r_uart_tx_data>>1;
  else
    r_uart_tx_data<=r_uart_tx_data;
end

//计数器
always@(posedge i_clk or posedge i_rst)
begin
  if(i_rst)
    r_cnt<='d0;
  else if((r_cnt==1+P_UART_DATA_WIDTH+1+P_UART_STOP_WIDTH-1)&&P_UART_CHECK>0)
    r_cnt<='d0;
  else if((r_cnt==1+P_UART_DATA_WIDTH+P_UART_STOP_WIDTH-1)&&P_UART_CHECK=0)
    r_cnt<='d0;
  else if(!r_uart_tx_ready)
    r_cnt<=r_cnt+'d1;
  else 
    r_cnt<=r_cnt    ;  
end

//准备信号
always@(posedge i_clk or posedge i_rst)
begin
  if(i_rst)
    r_uart_tx_ready<=1;
  else if((r_cnt==1+P_UART_DATA_WIDTH+1+P_UART_STOP_WIDTH-2)&&P_UART_CHECK>0)
    r_uart_tx_ready<=1;
  else if((r_cnt==1+P_UART_DATA_WIDTH+P_UART_STOP_WIDTH-2)&&P_UART_CHECK=0)
    r_uart_tx_ready<=1;
  else if(w_tx_active)
    r_uart_tx_ready<=0;
  else
    r_uart_tx_ready<=r_uart_tx_ready;
end

//奇偶校验
always@(posedge i_clk or posedge i_rst)
begin
  if(i_rst)
    r_uart_check<=0;
  else if(!r_uart_tx_ready)
    r_uart_check<=r_uart_check^r_uart_tx_data[0];
  else
    r_uart_check<=r_uart_check;
end

//数据发送
always@(posedge i_clk or posedge i_rst)
begin
  if(i_rst)
    r_uart_tx<=1;
  else if(w_tx_active)
    r_uart_tx<='d0;
  else if(!r_uart_tx_ready&&r_cnt<8)
    r_uart_tx<=r_uart_tx_data[0];
  else if(r_cnt==8&&P_UART_CHECK==0)
    r_uart_tx<=1;
  else if(r_cnt==8&&P_UART_CHECK==1)
    r_uart_tx<=~r_uart_check;
  else if(r_cnt==8&&P_UART_CHECK==2)
    r_uart_tx<=r_uart_check;
  else if(r_cnt>8)
    r_uart_tx<=1;
  else
    r_uart_tx<=1;
end

endmodule

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值