| |
Connect/TwoKingdomsFactory
Abstract/base Class
Abstract / base类被定义为测试平台中agent的一部分。在此示例中,它是基类driver,包括用于连接到wishbone总线agent的其余部分的端口。
Wrapper module
创建包装器模块,其包括BFM和DUT的实例。concrete类在模块内定义,因此其域将是包装器模块。
在包装器模块内部创建concrete类的实例。使用uvm_container将此实例的句柄放在配置数据库中。
【此处需一幅图】
以下是WISHBONE总线BFM的代码。
module wishbone_bus_syscon_bfm #(int num_masters = 8, int num_slaves = 8,
int data_width = 32, int addr_width = 32) ();
...
// WISHBONE signals
bit clk;
bit rst;
...
// WISHBONE bus arbitration logic
...
//Slave address decode
...
// BFM tasks
//WRITE 1 or more write cycles
task wb_write_cycle(wb_txn req_txn, bit [2:0] m_id = 1);
...
endtask
//READ 1 or more cycles
task wb_read_cycle(wb_txn req_txn, bit [2:0] m_id = 1, output wb_txn rsp_txn);
...
endtask
// Monitor bus transactions
task monitor(output wb_txn txn);
...
endtask
endmodule
下面是WISHBONE总线包装模块的代码。注意BFM(wishbone_bus_syscon_bfm)、slave memory(wb_slave_mem)和以太网MAC(eth_top)的实例。除了未示出或讨论的WISHBONE接口之外,MAC芯片还具有媒体独立接口(MII)。实际上,在此总线包装器中定义了两个concrete类 - driver和monitor,但仅显示和讨论了driver(wb_bus_bfm_driver_c)。
module wb_bus_wrapper #(int WB_ID = 0);
...
// WISHBONE BFM instance
// Supports up to 8 masters and up to 8 slaves
wishbone_bus_syscon_bfm wb_bfm();
// WISHBONE 0, slave 0: 000000 - 0fffff
wb_slave_mem #(mem_slave_size) wb_s_0 ( ... );
// MAC 0
// It is WISHBONE slave 1: address range 100000 - 100fff
// It is WISHBONE Master 0
eth_top mac_0 ( ... );
// Concrete driver class
class wb_bus_bfm_driver_c #(int ID = WB_ID) extends wb_bus_bfm_driver_base;
...
endclass
...
endmodule
例如,如果concrete driver class接收到WISHBONE写入事务,则它调用其本地wb_write_cycle() task,该 task又调用BFM内的wb_write_cycle() task。
module wb_bus_wrapper #(int WB_ID = 0);
...
// Concrete driver class
class wb_bus_bfm_driver_c #(int ID = WB_ID) extends wb_bus_bfm_driver_base;
...
task run_phase(uvm_phase phase);
wb_txn req_txn;
forever begin
seq_item_port.get(req_txn); // get transaction
@ ( posedge wb_bfm.clk) #1; // sync to clock edge + 1 time step
case(req_txn.txn_type) //what type of transaction?
NONE: `uvm_info($sformatf("WB_M_DRVR_%0d",m_id),
$sformatf("wb_txn %0d the wb_txn_type was type NONE",req_txn.get_transaction_id()),UVM_LOW )
WRITE: wb_write_cycle(req_txn);
READ: wb_read_cycle(req_txn);
RMW: wb_rmw_cycle(req_txn);
WAIT_IRQ: fork wb_irq(req_txn); join_none
default: `uvm_error($sformatf("WB_M_DRVR_%0d",m_id),
$sformatf("wb_txn %0d the wb_txn_type was type illegal",req_txn.get_transaction_id()) )
endcase
end
endtask : run_phase
// Methods
// calls corresponding BFM methods
//WRITE 1 or more write cycles
task wb_write_cycle(wb_txn req_txn);
wb_txn orig_req_txn;
$cast(orig_req_txn, req_txn.clone()); //save off copy of original req transaction
wb_bfm.wb_write_cycle(req_txn, m_id);
wb_drv_ap.write(orig_req_txn); //broadcast orignal transaction
endtask
...
endclass
...
endmodule