数字IC验证系列之层次化TLM连接

2020-06-11 09:46:25 浏览数 (1)

(题目改为事务级与信号级的分工协作) 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

0 人点赞