目录
引言:接着上篇的MCDF实验4(3),解释一下添加的检查
其中, mcdf_checker 中添加了两个检查:1)对寄存器输出使能端口chnl_en[id],来控制slave开关的检查
2)对 arbiter 的仲裁功能的检查,通过获得哪个slave的优先级高,进而打开对应slave的允许发送数据到arbiter的端口a2s_acks[id]。
1)通道 en=0 时的检查
task do_channel_disable_check(int id); // 多了这个 数据通道的检查
forever begin
@(posedge this.mcdf_vif.clk iff (this.mcdf_vif.rstn && this.mcdf_vif.mon_ck.chnl_en[id]===0)); // chnl_en 这个信号是内部信号
if(this.chnl_vifs[id].mon_ck.ch_valid===1 && this.chnl_vifs[id].mon_ck.ch_ready===1)
rpt_pkg::rpt_msg("[CHKERR]",
$sformatf("ERROR! %0t when channel disabled, ready signal raised when valid high",$time),
rpt_pkg::ERROR,
rpt_pkg::TOP);
end
endtask
其中,this.mcdf_vif.mon_ck.chnl_en[id] 是通过连接 mcdf_vif 监测的寄存器硬件信号chnl_en[id],
这个的前提是,寄存器的配置以及寄存器与通道slave的连接功能都是正确的。
还可以替换成: refmod.get_field_value(id,RW_EN), 这个是通过参考模型里的寄存器对于域的获取函数,获得的从端使能信号,这个的前提是,我们参考模型的寄存器与硬件是相符的
获得某个通道的使能端=0时,证明此通道是处于关着的状态,再通过chnl_vif[id] 接口, 监测如果有硬件的valid 和 ready 同时为1,说明通道从端的关功能没有实现
当然也存在,如果前提假设不成立,寄存器和通道的连接失败,那么也会出现valid 和 ready 同时为1,这时通道关闭状态的监测就不准确了
2)arbiter 的仲裁功能的检查
task do_arbiter_priority_check(); // 还有这个 优先级的检查
int id;
forever begin
@(posedge this.arb_vif.clk iff (this.arb_vif.rstn && this.arb_vif.mon_ck.f2a_id_req===1));
id = this.get_slave_id_with_prio();
if(id >= 0) begin
@(posedge this.arb_vif.clk);
if(this.arb_vif.mon_ck.a2s_acks[id] !== 1)
rpt_pkg::rpt_msg("[CHKERR]",
$sformatf("ERROR! %0t arbiter received f2a_id_req===1 and channel[%0d] raising request with high priority, but is not granted by arbiter", $time, id),
rpt_pkg::ERROR,
rpt_pkg::TOP);
end
end
endtask
function int get_slave_id_with_prio();
int id=-1;
int prio=999;
foreach(this.arb_vif.mon_ck.slv_prios[i]) begin
if(this.arb_vif.mon_ck.slv_prios[i] < prio && this.arb_vif.mon_ck.slv_reqs[i]===1) begin
id = i;
prio = this.arb_vif.mon_ck.slv_prios[i];
end
end
return id;
endfunction
首先,模拟硬件获取哪个通道的优先级最高,并且收到发送数据请求的 slv_reqs 为高,时返回 通道id。
然后再监测此通道在arbiter,是否被允许,也就是 a2s_acks[id] 是否 ==1,不等于1, 说明arbiter的仲裁功能没有实现。注意这里是:(!==)