配置寄存器其实就是大家经常提到的包括配置、状态、中断等寄存器单元的寄存器模块,对应验证里的就是ral_model,因为怕写标准寄存器有歧义所以写成了配置寄存器。那么标准配置寄存器是啥呢,我这里想要指的是由VCS工具提供的寄存器生成流程(会生成RAL+RTL)生成的寄存器模块。这个东西展开就比较大了,之前在专栏里讨论和实践过,加之和今天的内容不是强相关所以就一笔带过,当然也欢迎查看和订阅专栏《uvm ral_model与寄存器集成》。
那么直入主题,VCS在基础框架的层面提供了若干种寄存器域类型供使用,具体可以在$VCS_HOME/etc/vmm/sv/RAL/RTL路径下查看:
$cd /tools/synopsys/vcs/vcs-mx_vL-2016.06/etc/vmm/sv/RAL/RTL/
total 40
-rw-r--r--. 1 xiaotu xiaotu 1608 May 25 2016 vmm_ral_a0_field_rtl.sv
-rw-r--r--. 1 xiaotu xiaotu 1606 May 25 2016 vmm_ral_a1_field_rtl.sv
-rw-r--r--. 1 xiaotu xiaotu 1610 May 25 2016 vmm_ral_host_itf.sv
-rw-r--r--. 1 xiaotu xiaotu 1201 May 25 2016 vmm_ral_notifier_rtl.sv
-rw-r--r--. 1 xiaotu xiaotu 1554 May 25 2016 vmm_ral_rc_field_rtl.sv
-rw-r--r--. 1 xiaotu xiaotu 1095 May 25 2016 vmm_ral_ro_field_rtl.sv
-rw-r--r--. 1 xiaotu xiaotu 1445 May 25 2016 vmm_ral_ru_field_rtl.sv
-rw-r--r--. 1 xiaotu xiaotu 1549 May 25 2016 vmm_ral_rw_field_rtl.sv
-rw-r--r--. 1 xiaotu xiaotu 1611 May 25 2016 vmm_ral_w1c_field_rtl.sv
-rw-r--r--. 1 xiaotu xiaotu 1362 May 25 2016 vmm_ral_wo_field_rtl.sv
module vmm_ral_notifier_rtl(clk, rstn, sel, wen, rd, wr);
input sel, wen;
input clk, rstn;
output rd, wr;
reg rd, wr;
always @(posedge clk or negedge rstn)
begin
if (!rstn) begin
rd <= 0;
wr <= 0;
end
else begin
rd <= sel & ~wen;
wr <= sel & wen;
end
end
endmodule
vmm_ral_rw_field_rtl #(4, 'h8)
intp_cfg(clk, rstn, intp_cfg_out,
hst_wdat[3:0], hst_sel[0], hst_wen,
intp_cfg_in, intp_cfg_wen);
vmm_ral_rw_field_rtl #(4, ('h1234567>>0))
rsvd_3_0(clk, rstn, rsvd_out[3:0],
hst_wdat[7:4], hst_sel[0], hst_wen,
rsvd_in[3:0], rsvd_wen);
vmm_ral_rw_field_rtl #(8, ('h1234567>>4))
rsvd_11_4(clk, rstn, rsvd_out[11:4],
hst_wdat[15:8], hst_sel[1], hst_wen,
rsvd_in[11:4], rsvd_wen);
vmm_ral_rw_field_rtl #(8, ('h1234567>>12))
rsvd_19_12(clk, rstn, rsvd_out[19:12],
hst_wdat[23:16], hst_sel[2], hst_wen,
rsvd_in[19:12], rsvd_wen);
vmm_ral_rw_field_rtl #(8, ('h1234567>>20))
rsvd_27_20(clk, rstn, rsvd_out[27:20],
hst_wdat[31:24], hst_sel[3], hst_wen,
rsvd_in[27:20], rsvd_wen);
vmm_ral_notifier_rtl _n_intp_cfg(clk, rstn, hst_sel[0], hst_wen, intp_cfg_rd, intp_cfg_wr);
vmm_ral_notifier_rtl _n_rsvd(clk, rstn, |hst_sel[3:0], hst_wen, rsvd_rd, rsvd_wr);
module ral_reg_MVU_REG_global_cfg_AXI_W_CFG_rtl(input clk,
input rstn,
input [31:0] hst_wdat,
output [31:0] hst_rdat,
input [3:0] hst_sel,
input hst_wen,
output [1:0] awburst_out,
output awburst_rd, awburst_wr,
input awburst_wen,
input [1:0] awburst_in,
output [3:0] awcache_out,
...
然后最近不是提升gating比例么,所以我就通过工具排查了一下哪些模块gating比例比较低,准备进行优化。随机发现了一个模块不大但是比例超级低,这里面主要的逻辑是什么呢:
就是这样的结构,需要根据几个寄存器的配置计算出一个值,这个值再去参与后续的逻辑运算。因为每个寄存器都是可以带流改配的,因此这个的打拍我选择了不带使能的寄存器dffr。而后就可想而知了,这个48bit的dffr完全插不进去gating,当然这里也没有开-gate_clock因此不会自动根据D端和Q端综合出带EN端的dffre。但是即使通过D!=Q来产生EN了这里的逻辑深度也太深了,直接干到en端-240ps/d端-160ps的violation,不能接受。
在思考怎么解决这个问题的时候突然就悟了,这里如果有三个配置寄存器的总线写有效信号就好了,如果任一配置发生了更新,才需要更新后面的dffre,也就是en = reg_a_wr || reg_b_wr || reg_c_wr。这样即使寄存器是随时可带流配置的,也不会有什么问题,直接一手cover住。于是就理解了为什么工具提供的标准模块会有这组信号,一定是有许许多多类似的小经验小巧思最后才凝结为一个通用的交付模块的。
当然,这个思考发现也不一定准确,单纯是一次总结输出吧。
系列文章入口——
【芯片验证】sva_assertion: 15道助力飞升的断言练习 |
【芯片验证】可能是RTL定向验证的巅峰之作 |
【芯片验证】RTL仿真中X态行为的传播 —— 从xprop说起 |
【芯片验证】年轻人的第一个systemVerilog验证环境全工程与解析 |
【芯片设计】verilog中有符号数和无符号数的本质探究 |
【芯片设计】论RTL中always语法的消失术 |
【芯片设计】代码即注释,注释即代码 |
【芯片设计】700行代码的risc处理器你确实不能要求太多了 |
入职芯片开发部门后,每天摸鱼之外的时间我们要做些什么呢 |
如何计算系统的outstanding 和 burst length? |
芯片搬砖日常·逼死强迫症的关键词不对齐事件 |
熟人社会里,一群没有社会价值的局外人 |