电子产业一站式赋能平台

PCB联盟网

搜索
查看: 301|回复: 0
收起左侧

【芯片设计】绑一个超然于环境的带宽统计器

[复制链接]
匿名  发表于 2024-12-2 12:01:00 |阅读模式
继续最近的交付总结系列更新,本篇遇到和处理的问题和带宽统计以及性能有关。简单说就是在推进过程中,需要一些方法来实时/分阶段/整体的统计一下有效带宽,以确定一些环境的异常报错是环境引起的还是RTL内部的问题。
最开始想到了多年前的一个统计带宽的脚本,这个脚本是tcl做的工具,能够嵌入verdi里,然后对着你的波形一顿扫描。只要你的波形里做了en和size两个信号,脚本就能够统计出从黄线到白线之间的总数据量,然后根据时间计算出来平均带宽。

对了,统计的时候这个黄线还在实时动态的往白线那移动,所以很长时间我都觉得这个脚本太神奇了。后来试了好几次想复现但是因为tcl的基础太弱对verdi的dpi也不熟悉,所以一直搞不出来,如果谁会咱们好好聊一聊。所以没有办法,就另辟蹊径吧。
目前需求比较明确:
1.能够进行感兴趣时间段的流量带宽统计;
2.不影响已有的RTL结构和验证环境,独立于RTL交付和验证环境之外;
3.可以同时监控多个模块、多个接口的流量;
基于这三个需求,我觉得用一个RTL的组件来做可以了,没有太难。于是快进到组件的开发,在此也没研究有没有现成的组件哈,总觉得简单的这个功夫自己就写完了(?_?)。先看进行带宽统计,这个其实不难办,核心就是跟刚刚提到的脚本一样做一个模块对关心的接口进行采样。所以把这个模块的顶层搞出来:
  • module flow_cnt #(  //parameter  parameter realtime START_TIME = 0ns,  parameter realtime END_TIME = -1ns,   parameter BIT_W  = 10, //max 1023bit per cycle  parameter MAX_W  = 64  //bit cnt max)( /*AUTOARG*/   // Inputs   clk, rst_n, power, bit_cnt   );
    // ----------------------------------------------------------------// Interface declare// ----------------------------------------------------------------input              clk;input              rst_n;input              power;input [BIT_W  -1:0]bit_cnt;
    endmodule四个parameter,START_TIME~END_TIME就是我们关心的时间段,BIT_W是送进来的size(模块里我叫bit_cnt)的位宽,MAX_W是内部数据量计数器的位宽。
    接口就更简单了,时钟复位使能和使能时的数据有效量。顶层搞定了,那里面怎么办呢,也很简单在关心的时间段里power有效就把bit_cnt往上累加呗(要是累加加翻了就把MAX_W设置的大一些嗷):
  • logic [MAX_W -1:0]whole_bit_cnt;
    always @(posedge clk or negedge rst_n) begin  if(!rst_n) begin    whole_bit_cnt   end   else if($realtime>=START_TIME && ($realtime    if(power)       whole_bit_cnt   end end然后,等到时间一超过END_TIME,就根据累加值和时间间隔,把带宽给算出来:
  • initial begin: BANDWIDTH_REPORT  real flow_bandwidth;  realtime time_duration;  while(1)begin    @(posedge clk);    if($realtimebegin      continue;    end    else begin      time_duration  = $realtime - START_TIME;      flow_bandwidth = whole_bit_cnt/time_duration;      $display("==============================================================================");      $display("%m bandwidth report at %t:", $realtime);      $display("    whole_bit_cnt = %0dbit = %0dByte", whole_bit_cnt, whole_bit_cnt/8);      $display("    time_duration  = %t", time_duration);      $display("    flow_bandwidth = %fGbps", flow_bandwidth);      $display("==============================================================================");      break;    end  endend好了,代码看起来就搞定了。开始思考第二个需求,如何合入已有的RTL结构和验证环境中,还能尽量不影响原本的代码呢?例化在RTL内是肯定不可能的,例化在验证环境中还要去动别人的代码,这也不行那也不行,就只能借助bind来搞定了。在绝大部分场景中,bind都是用来搞并发断言的,但其实bind的使用场景很多,各种我们自己写的不需要交付的辅助小组件小模块都可以用bind的方式与需要监控的模块或结构进行绑定。那么再看下第三个需求,可以监控多模块多接口。那其实这件事也就简单了,在flow_cnt上封装一个顶层,在顶层里对确切的某个inst进行bind就可以了呀!
    我们借助sync_fifo那个验证环境,在该环境中sync_fifo例化在testbench中:
  • //-------------------------------------{{{rtl instsync_fifo #(    .WIDTH(WIDTH),    .DEPTH(DEPTH)) u_sync_fifo(    .clk(clk),    .rst_n(rst_n),    .afull_th(afull_th),    .aempty_th(aempty_th),    .winc(winc),    .wdata(wdata),    .wfull(wfull),    .almost_wfull(almost_wfull),    .rinc(rinc),    .rdata(rdata),    .rempty(rempty),    .rvld(rvld),    .almost_rempty(almost_rempty));我们监控其一段时间内的输出带宽,那么power即rvld信号,bit_cnt其实就是WIDTH每笔数据固定的数据量为WIDTH。因此在flow_cnt.sv同一层级做bind_fifo_flow_cnt.sv文件,文件内容如下:
  • bind testbench.u_sync_fifo flow_cnt #(  .START_TIME(800ns),  .END_TIME(80000ns)) u_fifo_flow_cnt(  .clk(clk),  .rst_n(rst_n),  .power(rvld),  .bit_cnt(WIDTH));将testbench.u_sync_fifo的信号和parameter作为flow_cnt的输入,将flow_cnt bind在testbench.u_sync_fifo模块上进行接口采样,采样时间为800ns~80000ns。然后只需要把这两个文件放到filelist中,而不需要对验证环境进行任何的改动:
  • +libext+.v+.sv+incdir+/home/ICer/gitee_path/verilog_fifo_code/src/ut_ver/../rtl-y /home/ICer/gitee_path/verilog_fifo_code/src/ut_ver/../rtl
    /home/ICer/gitee_path/verilog_fifo_code/src/bind/flow_cnt.sv/home/ICer/gitee_path/verilog_fifo_code/src/bind/bind_fifo_flow_cnt.sv
    ../ver/sync_fifo_pkg.sv/home/ICer/gitee_path/verilog_fifo_code/src/ut_ver/../rtl/sync_fifo.v../top/testbench.sv咱们先来理论上算一下,目前环境的配置是时钟周期10ns,fifo位宽WIDTH=16,如果满通路输出那么计算的平均带宽应该是:
  • 16bit/10ns = 1.6 * 10^9 bps = 1.6Gbps在sim目录下执行仿真,得到仿真结果:

    对应时间段的波形确实是满带宽输出:

    看起来好像算的还是挺准的。那么因为有个bind_fifo_flow_cnt.sv这个顶层存在,只需要在bind时给定具体inst路径,就可以在该文件里对感兴趣的多个模块和内部总线进行监控了。
    基本的工作就完成啦!后面只需要按自己的需求,在flow_cnt.sv的基础上分装一个axi_flow_cnt.sv来对AXI总监挂接监控带宽就可以,这里就不多聊了。

    系列文章入口——
    【芯片设计】SoC 101(一):绪论
    【芯片设计】FIFO漫谈(零)从无处不在的FIFO开始说起
    【芯片设计】计算机体系结构(一)虚拟内存
    【芯片设计】深入理解AMBA总线(零)绪论
    【芯片设计】握手协议的介绍与时序说明
    【芯片设计】复位那些小事 —— 复位消抖
    【芯片设计】快速入门数字芯片设计(一)Introduction
    【芯片验证】UVM源码计划(零)下定决心读源码前的自测环节
    【芯片设计】异步电路碎碎念(一) 到底什么是异步电路
    【芯片设计】从RTL到GDS(一):Introduction
    其他文章链接——
    【芯片验证】sva_assertion: 15道助力飞升的断言练习
    【芯片验证】可能是RTL定向验证的巅峰之作
    【芯片验证】RTL仿真中X态行为的传播 —— 从xprop说起
    【芯片验证】年轻人的第一个systemVerilog验证环境全工程与解析
    【芯片设计】verilog中有符号数和无符号数的本质探究
    【芯片设计】论RTL中always语法的消失术
    【芯片设计】代码即注释,注释即代码
    【芯片设计】700行代码的risc处理器你确实不能要求太多了
    入职芯片开发部门后,每天摸鱼之外的时间我们要做些什么呢
    如何计算系统的outstanding 和 burst length?
    芯片搬砖日常·逼死强迫症的关键词不对齐事件
    熟人社会里,一群没有社会价值的局外人
  • 本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x
    回复

    使用道具

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表