(题目改为事务级与信号级的分工协作) UVM验证平台一直在努力降低组件之间的耦合度,拆分那些处理多项任务的组件,只处理单个任务,使各个组件更容易调试和复用。
在验证平台中的事务级激励生成和信号级驱动之间存在着明显不同的工作风格,将它们编码在一个文件中非常不利于调试和复用。
所以在验证平台中需要将事务级激励的生成,和信号级驱动区分开来,即验证平台中事务级和信号级之间的分工与协作。
在事务级激励生成中,完成事务级指令产生工作,例如复位、读和写
在信号级驱动中,完成事务级指令到信号级的翻译工作。
根据功能拆分,降低验证的耦合度,不仅提高了复用性和调试能力,同时让验证工程师集中精力,更专业化地完成相关验证工作。
上图中的正方形和圆圈分别是TLM中的port和export。
在Transaction command组件当中,生成事务级激励,将其发送到FIFO当中
代码语言:javascript复制virtual class Transaction_command extends uvm_component;
`uvm_component_utils(Transaction_command)
uvm_put_port #(command_s) command_port;
function void build_phase(uvm_phase phase);
command_port =new("command_port", this);
endfunction : build_phase
pure virtual function operation_t get_op();
pure virtual function byte get_data();
task run_phase(uvm_phasephase);
command_s command;
phase.raise_objection(this);
command.op = rst_op;
command_port.put(command);
repeat (1000) begin :random_loop
command.op = get_op();
command.A = get_data();
command.B = get_data();
command_port.put(command);
end : random_loop
#500;
phase.drop_objection(this);
endtask : run_phase
function new (string name,uvm_component parent);
super.new(name, parent);
endfunction : new
endclass : Transaction_command
这时候可以发现,这种功能分工使得信号级协议的翻译工作不会影响事物级指令的产生get_op()和get_data(),只需要产生事物级指令,然后通过TLM put.port发送到FIFO当中即可
在Singal drive组件当中从FIFO当中取出事物级激励,将其翻译成信号级。
代码语言:javascript复制class Singal_drive extends uvm_component;
`uvm_component_utils(Singal_drive)
virtual tinyalu_bfm bfm;
uvm_get_port #(command_s)command_port;
function void build_phase(uvm_phase phase);
if(!uvm_config_db #(virtualtinyalu_bfm)::get(null, "*","bfm", bfm))
$fatal("Failed toget BFM");
command_port =new("command_port",this);
endfunction : build_phase
task run_phase(uvm_phasephase);
command_s command;
shortint result;
forever begin :command_loop
command_port.get(command);
bfm.send_op(command.A,command.B, command.op, result);
end : command_loop
endtask : run_phase
function new (string name,uvm_component parent);
super.new(name, parent);
endfunction : new
endclass : Singal_drive
在信号级协议的翻译工作当中,也无需关心指令完成的功能,只需要遵循特定的接口协议BFM完成事物级指令的翻译工作send_op即可。
上图中的Transaction command、FIFO和Singal drive在更高的层级进行例化和连接。
代码语言:javascript复制class env extends uvm_env;
`uvm_component_utils(env);
Transaction_command Transaction_command_h;
Singal_drive Singal_drive_h;
uvm_tlm_fifo #(command_s) command_f;
function void build_phase(uvm_phase phase);
command_f = new("command_f", this);
Transaction_command_h = Transaction_command::type_id::create("Transaction_command_h",this);
Singal_drive_h = Singal_drive::type_id::create("drive_h",this);
function void connect_phase(uvm_phase phase);
Singal_drive_h.command_port.connect(command_f.get_export);
Transaction_command_h.command_port.connect(command_f.put_export);
endfunction : connect_phase
function new (string name, uvm_component parent);
super.new(name,parent);
endfunction : new
endclass