ZeBu Transactors
ZeBu Transactors
实际是一些协议相关的外围器件的统称,可以方便的在SOC验证环境中调用,它支持一些常见的协议,比如:PCI Express 3.0, AMBA, USB, MIPI CSI-2, MIPI DSI, I2C, I2S, 以太网,视频接口和JTAG.
这些transactors包含可综合总线模型(Synthesizable Bus Functional Models, BFMs),这些模型可以直接下载到FPGA硬件,这样可以得到更高的性能并保证和仿真系统的同步。
Transactors
本身包含C/C++的接口,可以快速建立仿真环境,用户也可以自己定制自己的可综合的transator。
ZEMI-3接口
ZEMI-3是一个标准的协同仿真接口,它与SystemVerilog编译的BFM模型可以通信,也就是说可以通过C/C++与System Verilog的testbench交换数据,形式上类似于DPI-C.
ZEMI-3的特点:
- 根据System Verilog的行为级模型自动产生BFM
- 自动检测最有效的数据传输方式
- 代码易于管理
- 相比于SCE-MI更为有效率
ZEMI-3中硬件与软件的交互是基于DPI机制的,它也是SystemVerilog标准的一部分,transactor的硬件描述通过SystemVerilog行为级模型描述。以下是一个基本的结构框图:
SystemVerilog DPI
通过SystemVerilog DPI我们可以实现通过函数调用进行硬件系统和软件系统的数据交换,这种数据交换是双向的。
Import functions: 这些是C语言中可供SystemVerilog调用的函数,在ZEMI框架里面代表这硬件模块调用软件testbench。
Export Functions: 可供C调用的System Verilog函数,ZEMI框架中代表软件模型调用硬件模型。
Export Tasks: 可供C调用的System Verilog任务。
函数和任务的区别:函数是立即返回的,不会消耗仿真时间,任务是可以消耗仿真时间的。
在ZEMI-3的硬件模型中,我们可以采用行为级代码(可以用非综合代码),这样代码可以简化比如:
- always块和其它块中可以包含Events
- Clock, edges和其它一些事件可以混合在一个wait中
- 信号可以在多个process中写入
- 允许非绑定循环
ZEMI-4
Native System Verilog Transactor Infrastructure允许你建立一个工业级别的仿真环境。一个仿真环境通常包含BFM, DUT,时钟和复位产生逻辑,这些模块统一封装在仿真的顶层,一般仿真顶层可以分为两个部分:
- 可综合的部分,一般会有一个自己的顶层,这个顶层直接连接到模拟器
- 仿真模型,一般是不可综合的Hardware Verification Language(HVL)描述,也有自己的单独顶层,运行于仿真器
Transactor就是位于模拟器(emulator)和仿真器(Simulator)之间的一个部分,可以实现HDL和HVL的双向通信。这部分的实现也有两种不同的形式:
- 基于类构造方式实现
- 基于
uvm_config_db
机制实现
类的构造方式实现
transactor中包含硬件的BFM接口和软件的BFM接口两个部分,二者必须保持一致才能有效的工作,具体的实现方式可以通过基于SystemVerilog的参数传递方式进行类的构造实现。
interface Xtgor(input clk, input rst _)
apb_monitor apb_mon_h;
task set_mon_handle (apb_monitor apb_mon_n)
apb_mon_h = apb_mon_n;
endtask
endinterface
/********************************************/
class apb_monitor;
virtual Xtor xtor_mh;
function new(virtual Xtor xtor_n);
this.xtor_mh = xtor_n;
xtor_mh.set_mon_handle(this);
endfunction
endclass
/********************************************/
module HDL_Top;
Xtor xtor_inst(...);
endmodule
/********************************************/
modult TB_Top;
apb_monitor apbm;
apb_driver apbd;
initial begin
apbm = new(HDL_Top.Xtor);
apbd = new(HDL_Top.Xtor);
end
endmodule
uvm_config_db
机制
interface apb_monitor_bfm(<port_list>);
apb_monitor m_mon;
function void configure (input apb_monitor hvl_scope);
m_mon = hvl_scope;
endfunction
endinterface
/********************************************/
class apb_monitor extends uvm_monitor;
local virtual apb_monitor_bfm m_bfm;
function void connect_phase(uvm_phase phase);
if (!uvm_config_db#(virtual apb_monitor_bfm)::
get(this, "", "mon_bfm", m_bfm)) begin
`uvm_fatal("APB/MSTR/MON", "No ...")
end
endfunction
task run_phase(uvm_phase phase);
m_bfm.configure(this);
endtask
endclass: apb_monitor
/********************************************/
module rtl_top;
...
apb_monitor_bfm apb_mon0(<port_list>);
endmodule
/********************************************/
module tb_top;
initial begin
uvm_config_db#(virtual apb_monitor_bfm)::
set(null, "uvm_test_top.env.apb0.*",
"mon_bfm", rtl_top.apb_mon0);
endmodule
C/C++ Co-Simulation
#include <iostream>
#include <unistd.h>
#include <stdexcept>
#include <exception>
#include <libZebu.hh>
#include "counterDriver.hh"
using namespace ZEBU;
using namespace std;
int main (int argc, char *argv[]) {
Board* board = NULL;
try {
// open the ZeBu board
board = Board::open("../zcui.work/zebu.work");
// initialize the transactor
CounterDriver *cnt = new CounterDriver;
cnt->init (board, "hw_top.counterDriver_0");
// initialize the ZeBu board
board->init(NULL);
// stimulate the design using transactions
cnt->load(10);
cnt->run(100);
cnt->idle(20);
cnt->run(5);
printf("Got %d\n", cnt->read() );
}
catch(exception &xcep) {
cerr << "ERROR : " << xcep.what() << endl;
}
// close the ZeBu board
board->close();
return 0;
}
UART的例子
首先来看看基本的结构:
详细结构
ZeBu UART transactor包含以下几部分:
- 应用模式,运行于PC可以实现对DUT UART接口的读写操作
- 服务器模式,基于TCP socket,支持远程访问
- 交互式终端接口,直接调用一个xterm终端,可以直接实现UART接口的调用
- 支持5-8位的数据比特
- 1-2个停止位
- 奇偶校验
- RTS/CTS的流控和全双工模式
可以看出,整个UART和实际的UART基本上没有差异。
最后更新于 2019-01-22 08:02:21 并被添加「」标签,已有 10157 位童鞋阅读过。
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。