主动事务处理器编写BFM
来源:互联网 发布:天正软件已过期 编辑:程序博客网 时间:2024/05/17 06:54
本篇文章介绍命令层主动事务处理器的编写方法。命令层事务处理器就是一个一端是事务级接口,一端连接物理信号,也称为BFM。如图所示:
第一步:
第二步:
第三步:事务描述符(同命令层监视器)
第四步:主动事务处理器
现在开始写主动性事务处理器,它是由vmm_xactor基类扩展来的类。
实现读和写周期的任务在类中实现。它们定义为virtual,这样就可以在事务处理器的扩展类中修改它们的行为。它们定义为protected,以防止他们在类外被调用和出现同时访问总线的问题。
`ifndef APB_MASTER__SV `define APB_MASTER__SV `include “apb_if.sv” `include “apb_rw.sv” ... class apb_master extends vmm_xactor; ... virtual protected task read(input bit [31:0] addr, output logic [31:0] data); ... endtask: read virtual protected task write(input bit [31:0] addr, input bit [31:0] data); ... endtask: write ... endclass: apb_master
本事务处理器需要一个事务级接口来接收事务和一个物理级接口。前者用vmm_channel实例,后者用虚拟端口virtual modport。它们都通过构造函数传递给事务处理器,都保存在公共类属性中。
`ifndef APB_MASTER__SV `define APB_MASTER__SV `include “apb_if.sv” `include “apb_rw.sv” ... class apb_master extends vmm_xactor; apb_rw_channel in_chan; virtual apb_if.master sigs; function new(string name, int unsigned stream_id, virtual apb_if.master sigs, apb_rw_channel in_chan = null); super.new(“APB Master”, name, stream_id); this.sigs = sigs; if (in_chan == null) in_chan = new(“APB Master Input Channel”, name); this.in_chan = in_chan; ... endfunction: new ... virtual protected task read(input bit [31:0] addr, output logic [31:0] data); ... endtask: read virtual protected task write(input bit [31:0] addr, input bit [31:0] data); ... endtask: write ... endclass: apb_master `endif
当事务处理器复位时,输入通道必须排空,关键的输出信号必须被驱动为空闲状态。这些都在vmm_xactor::reset_xactor方法的扩展类中实现。可在事务处理器的构造函数中初始化输出信号。
`ifndef APB_MASTER__SV `define APB_MASTER__SV `include “apb_if.sv” `include “apb_rw.sv” ... class apb_master extends vmm_xactor; apb_rw_channel in_chan; virtual apb_if.master sigs; function new(string name, int unsigned stream_id, virtual apb_if.master sigs, apb_rw_channel in_chan = null); super.new(“APB Master”, name, stream_id); this.sigs = sigs; if (in_chan == null) in_chan = new(“APB Master Input Channel”, name); this.in_chan = in chan; this.sigs.mck.psel <= ’0; this.sigs.mck.penable <= ’0; endfunction: new virtual function void reset_xactor(reset_e rst_typ = SOFT_RST); super.reset(rst_typ); this.in_chan.flush(); //排空输入通道 this.sigs.mck.psel <= ’0; this.sigs.mck.penable <= ’0; endfunction: reset_xactor
最灵活的事务处理器执行机制使用支持阻塞,非阻塞,乱序的有效时隙。因为协议支持事务之间的暂停,所以要应该用vmm_xactor;;wart_if_stopped_or_empty方法来停止事务处理器。
virtual protected task main(); super.main(); @ (this.sigs.mck); forever begin apb_rw tr; this.wait_if_stopped_or_empty(this.in_chan); this.in_chan.activate(tr); ... this.in_chan.start(); case (tr.kind) apb_rw::READ : this.read(tr.addr, tr.data); apb_rw::WRITE: this.write(tr.addr, tr.data); endcase this.in_chan.complete(); ...
第六步:扩展点
前面的事务处理器具有基本的功能。但是可重用性低。回调方法允许用户在不修改事务处理器本身就能扩展事务处理器的行为。应该编写在事务处理前后的回调方法。"pre-transaction"回调方法允许注入错误和延迟;"post-transaction"回调方法允许插入延迟,或将事务的值记录在功能覆盖模型中,或与期望响应做对照。
要在回调基类的扩展类(callback facade)中把回调方法定义为virtual tasks 或这virtual void functions。在"pre-transaction"回调方法中创建一个允许丢弃事务的机制无疑是一个好的想法。
`ifndef APB_MASTER__SV `define APB_MASTER__SV `include “apb_if.sv” `include “apb_rw.sv” typedef class apb_master; class apb_master_cbs extends vmm_xactor_callbacks; virtual task pre_cycle(apb_master xactor, apb_rw cycle, ref bit drop); endtask: pre_cycle virtual task post_cycle(apb_master xactor, apb_rw cycle); endtask: post_cycle endclass: apb_master_cbs class apb_master extends vmm_xactor; apb_rw_channel in_chan; virtual apb_if.master sigs; function new(string name, int unsigned stream_id, virtual apb_if.master sigs, apb_rw_channel in_chan = null);
应该在恰当的点应用回调方法,用`vmm_callback()宏来实现。
virtual protected task main(); super.main(); @ (this.sigs.mck); forever begin apb_rw tr; bit drop; this.wait_if_stopped_or_empty(this.in_chan); this.in_chan.activate(tr); drop = 0; `vmm_callback(apb_master_cbs, pre_cycle(this, tr, drop)); if (drop) begin this.in_chan.remove(); continue; end this.in_chan.start(); case (tr.kind) apb_rw::READ : this.read(tr.addr, tr.data); apb_rw::WRITE: this.write(tr.addr, tr.data); endcase this.in_chan.complete(); `vmm_callback(apb_master_cbs, post_cycle(this, tr)); this.in_chan.remove(); end endtask: main virtual protected task read(input bit [31:0] addr, output logic [31:0] data); ... endtask: read virtual protected task write(input bit [31:0] addr, input bit [31:0] data); ... endtask: write endclass: apb_master `endif
第七步:调试信息
为了能完全的重用,应该不用查看源代码就能理解事务处理器在做什么和调试它的操作。调试信息应该加到合适的点来表明事务处理器将做什么,正在做什么,已经做了什么操作。这些调试信息要通过`vmm_trace,`vmm_debug,`vmm_verbose发出。
virtual protected task main(); super.main(); @ (this.sigs.mck); forever begin apb_rw tr; bit drop; this.wait_if_stopped_or_empty(this.in_chan); this.in_chan.activate(tr); drop = 0; `vmm_callback(apb_master_cbs, pre_cycle(this, tr, drop)); if (drop) begin `vmm_debug(log, {“Dropping transaction.../n”, tr.psdisplay(“ “)}); this.in_chan.remove(); continue; end `vmm_trace(log, {“Starting transaction.../n”, tr.psdisplay(“ “)}); this.in_chan.start(); case (tr.kind) apb_rw::READ : this.read(tr.addr, tr.data); apb_rw::WRITE: this.write(tr.addr, tr.data); endcase this.in_chan.complete(); `vmm_trace(log, {“Completed transaction.../n”, tr.psdisplay(“ “)}); `vmm_callback(apb_master_cbs, post_cycle(this, tr)); this.in_chan.remove(); end endtask: main
- 主动事务处理器编写BFM
- 从动性事务处理器编写(slave transactor)
- CommitProcessor事务提交处理器
- SyncRequestProcessor事务日志记录处理器
- 【个人经验】关于BFM
- BFM-总线功能模型
- 编写注解处理器拼接SQL
- BFM:总线功能模型 zz
- 事务的编写
- Spring事务编写
- 事务的编写
- Spring具体事务处理器的实现
- 可能阻塞接收事务处理器的Module
- spring 声明式事务配置,主动抛出异常不回滚
- DB2 的命令行处理器和脚本编写
- 利用JavaSwing编写一款天气数据处理器
- 编写自己的注解处理器小栗子
- VS编写程序主动要求系统管理员权限(UAC控制)
- DUnit初步学习及TTestCase中的方法详解
- 深度剖析PS通道磨皮法原理应用
- 关于管理
- 开始我的CSDN之旅
- 日期加减运算符重载C++修改
- 主动事务处理器编写BFM
- flex相关网站
- struts练习 按照浪曦视频的写
- 3G提速了,你敢用吗?
- 点阵字体显示系列之一:ASCII码字库的显示
- the chosen operation is not currently available
- 程序出错后,程序员给测试人员的20条高频回复
- 点阵字体显示系列之二:汉字显示
- Flex自定义组件与自定义事件