我是靠谱客的博主 负责导师,最近开发中收集的这篇文章主要介绍波特率分频监测模块理解-基于apb_uart项目,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

    • 模块介绍
    • 波特率定义
    • 主要代码描述
    • 代码实例

模块介绍

该组件模块只要功能是检测特定波特率下的时钟分频是否正确,主要指IRQ.CLK在寄存器的控制下,是否正确分频成baud_out,其中 DIV2与 DIV2 寄存器的值和各个波形之间的频率关系如下图所示:通过验证在相邻两个 brg_en 时钟的上升沿之间有 16*{DIV2, DIV1}个 IRO.CLK 时钟的上升沿,可以说明寄存器 的功能是正确的。{DIV2, DIV1}指的是在特定波特率下时钟的周期数。

在这里插入图片描述

波特率定义

波特率既1s发送的数据位数。一般选择的波特率有,9600,19200,115200等。通过波特率可以计算出时钟在指定波特率条件下发送1bits数据所需要的时间以及计数次数。下面以50M时钟频率,波特率9600为例计算。

对于50M时钟,其周期为1/50 *106, 则1s的时间内,时钟会产生50 *106个上升沿,即计数50000000次。那么对于这个时钟,计数一次需要1/50 * 106 s的时间。
同样,在波特率9600控制下,传输1bit数据需要1/9600 s的时间,在这个时间内时钟计数的次数则为1/9600 * 50 * 106次,即5208次。

主要代码描述

该组件中使用了三个 task:monitor_apb()、count_clocks()和 monitor_baudout()。
任务monitor_apb()用来监测DIV1 或 DIV2寄存器是否被写入新值,当DIV1或DIV2寄存器被写入以后,计数器会清零重启。
任务 count_clocks则是用来记录 IRQ.clk上升沿的个数,每当一个上升沿来临时, 其内部的 clk_count 就自增 1。
任务monitor_baudout()则用来比对结果,内部的两个变量分别用来存储在 baud_out前后两个上升沿时采样的 clk_count 数值,取差值后与{DIV2, DIV1}进行比对, 从而得出检测结果。

代码实例

task baud_rate_checker::count_clocks();
  forever begin
    @(posedge IRQ.CLK);
    clk_count++;
  end
endtask: count_clocks

function void baud_rate_checker::check_count(bit[15:0] div, int clk_count);
  if(clk_count != div) begin
    `uvm_error("check_count", $sformatf("Baudrate divisor error - Divisor:%0d Clock interval:%0d", div, clk_count))
    div_errors++;
  end
  else begin
    baud_rate_cg.sample(div);
  end
endfunction: check_count

task baud_rate_checker::monitor_baudout();//比对结果

  forever begin
    @(posedge IRQ.baud_out);
    if((new_value_written == 0) && (br_value_invalid == 0)) begin
      div1 = rm.DIV1.DIV.get_mirrored_value();//读取寄存器中的mirrored值
      div2 = rm.DIV2.DIV.get_mirrored_value();
      div = {div2[7:0], div1[7:0]};
      check_count(div, clk_count);//将寄存器中读到的div1和div2的值与clk_count进行对比
    end
    new_value_written = 0;
    clk_count = 0;//重启计数器
  end

endtask: monitor_baudout

task baud_rate_checker::monitor_apb();
  apb_seq_item apb;

  forever begin
    apb_fifo.get(apb);
    if(apb.we == 1) begin
      case(apb.addr[7:0])
        8'h1c: begin
                 new_value_written = 1;
                 br_value_invalid = 0;
               end
        8'h20: br_value_invalid = 1;
      endcase
    end
  end

endtask: monitor_apb

最后

以上就是负责导师为你收集整理的波特率分频监测模块理解-基于apb_uart项目的全部内容,希望文章能够帮你解决波特率分频监测模块理解-基于apb_uart项目所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(54)

评论列表共有 0 条评论

立即
投稿
返回
顶部