首页 > 其他 > 详细

verilong 串口通信程序及原理

时间:2021-01-06 22:05:49      阅读:48      评论:0      收藏:0      [点我收藏+]

通过回环测试,可以先用串口把数据链路验证。接收程序

 


module  uart_rx
#(
    parameter   UART_BPS    =   d9600,         //串口波特率
    parameter   CLK_FREQ    =   d50_000_000    //时钟频率
)
(
    input   wire            sys_clk     ,   //系统时钟50MHz
    input   wire            sys_rst_n   ,   //全局复位
    input   wire            rx          ,   //串口接收数据

    output  reg     [7:0]   po_data     ,   //串转并后的8bit数据
    output  reg             po_flag         //串转并后的数据有效标志信号
);

//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//
//localparam    define
localparam  BAUD_CNT_MAX    =   CLK_FREQ/UART_BPS   ;

//reg   define
reg         rx_reg1     ;
reg         rx_reg2     ;
reg         rx_reg3     ;
reg         start_nedge ;
reg         work_en     ;
reg [12:0]  baud_cnt    ;
reg         bit_flag    ;
reg [3:0]   bit_cnt     ;
reg [7:0]   rx_data     ;
reg         rx_flag     ;

//********************************************************************//
//***************************** Main Code ****************************//
//********************************************************************//
//插入两级寄存器进行数据同步,用来消除亚稳态
//rx_reg1:第一级寄存器,寄存器空闲状态复位为1
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1b0)
        rx_reg1 <= 1b1;
    else
        rx_reg1 <= rx;

//rx_reg2:第二级寄存器,寄存器空闲状态复位为1
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1b0)
        rx_reg2 <= 1b1;
    else
        rx_reg2 <= rx_reg1;

//rx_reg3:第三级寄存器和第二级寄存器共同构成下降沿检测
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1b0)
        rx_reg3 <= 1b1;
    else
        rx_reg3 <= rx_reg2;

//start_nedge:检测到下降沿时start_nedge产生一个时钟的高电平
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1b0)
        start_nedge <= 1b0;
    else    if((~rx_reg2) && (rx_reg3))
        start_nedge <= 1b1;
    else
        start_nedge <= 1b0;

//work_en:接收数据工作使能信号
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1b0)
        work_en <= 1b0;
    else    if(start_nedge == 1b1)
        work_en <= 1b1;
    else    if((bit_cnt == 4d8) && (bit_flag == 1b1))
        work_en <= 1b0;

//baud_cnt:波特率计数器计数,从0计数到BAUD_CNT_MAX - 1
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1b0)
        baud_cnt <= 13b0;
    else    if((baud_cnt == BAUD_CNT_MAX - 1) || (work_en == 1b0))
        baud_cnt <= 13b0;
    else    if(work_en == 1b1)
        baud_cnt <= baud_cnt + 1b1;

//bit_flag:当baud_cnt计数器计数到中间数时采样的数据最稳定,
//此时拉高一个标志信号表示数据可以被取走
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1b0)
        bit_flag <= 1b0;
    else    if(baud_cnt == BAUD_CNT_MAX/2 - 1)
        bit_flag <= 1b1;
    else
        bit_flag <= 1b0;

//bit_cnt:有效数据个数计数器,当8个有效数据(不含起始位和停止位)
//都接收完成后计数器清零
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1b0)
        bit_cnt <= 4b0;
    else    if((bit_cnt == 4d8) && (bit_flag == 1b1))
        bit_cnt <= 4b0;
     else    if(bit_flag ==1b1)
         bit_cnt <= bit_cnt + 1b1;

//rx_data:输入数据进行移位
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1b0)
        rx_data <= 8b0;
    else    if((bit_cnt >= 4d1)&&(bit_cnt <= 4d8)&&(bit_flag == 1b1))
        rx_data <= {rx_reg3, rx_data[7:1]};

//rx_flag:输入数据移位完成时rx_flag拉高一个时钟的高电平
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1b0)
        rx_flag <= 1b0;
    else    if((bit_cnt == 4d8) && (bit_flag == 1b1))
        rx_flag <= 1b1;
    else
        rx_flag <= 1b0;

//po_data:输出完整的8位有效数据
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1b0)
        po_data <= 8b0;
    else    if(rx_flag == 1b1)
        po_data <= rx_data;

//po_flag:输出数据有效标志(比rx_flag延后一个时钟周期,为了和po_data同步)
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1b0)
        po_flag <= 1b0;
    else
        po_flag <= rx_flag;

endmodule

 


 

verilong 串口通信程序及原理

原文:https://www.cnblogs.com/Fifthspace/p/14121245.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!