UVM学习(2)uvm_sequence

uvm sequence机制是通过控制和产生一系列的事物,并通过某种方法将事物发送给driver的机制。

(1)Sequence:当sequence的start的函数启动,sequence会执行body方法,产生事物,并将事物发送给sequencer放入FIFO中储存。Sequence会等待一个driver的完成响应,得到之后会退出该次事物的产生

(2)Sequencer: 当sequencer启动时,首先会检查自身的default_sequence是否配置,如果配置了就会创建实体,设置该sequence的starting_phase并随机化该sequence。最后调用sequence的start()函数启动该sequence。

(3)Driver:首先向sequencer发送一个事物请求,然后等待事物,sequencer会将产生好的事物发送给driver,driver在处理完该事物后,返回一个完成响应。

`include "uvm_macros.svh"

package user_pkg;

  import uvm_pkg::*;
  `include "uvm_macros.svh"
  typedef enum { BUS_READ, BUS_WRITE } bus_op_t;
  typedef enum { STATUS_OK, STATUS_NOT_OK } status_t;

  //--------------------------------------------------------------------
  // bus_trans
  //--------------------------------------------------------------------
  class bus_trans extends uvm_sequence_item;

    bit [11:0] addr;
    bit [7:0] data;
    bus_op_t op;

    function new();
      super.new();
`uvm_info(get_name(),"has been new",UVM_MEDIUM);
    endfunction

    function uvm_object clone();
      bus_trans t; t = new();
      t.copy(this);
      return t;
    endfunction

    function void copy (bus_trans t);
      super.copy(t);
      addr = t.addr;
      data = t.data;
      op = t.op;
    endfunction

    function bit compare(bus_trans t);
      return ((op == t.op) && (addr == t.addr) && (data == t.data));
    endfunction

    function string convert2string();
      string s;
     // $sformat(s, "op %s: addr=%03x, data=%02x", op.name(), addr, data);
      return s;
    endfunction

  endclass

  //--------------------------------------------------------------------
  // bus_req
  //--------------------------------------------------------------------
  class bus_req extends bus_trans;

    function uvm_object clone();
      bus_req t; t = new();
      t.copy(this);
      return t;
    endfunction

    function void copy (bus_req t);
      super.copy(t);
    endfunction

  endclass

  //--------------------------------------------------------------------
  // bus_rsp
  //--------------------------------------------------------------------
  class bus_rsp extends bus_trans;

    status_t status;

    function uvm_object clone();
      bus_rsp t; t = new();
      t.copy(this);
      return t;
    endfunction

    function void copy (bus_rsp t);
      super.copy(t);
      status = t.status;
    endfunction

    function void copy_req (bus_req t);
      super.copy(t);
    endfunction

    function string convert2string();
      string s;
    //  $sformat(s, "op %s, status=%s", super.convert2string(), status.name());
      return s;
    endfunction

  endclass

class my_driver #(type REQ = uvm_sequence_item, 
                  type RSP = uvm_sequence_item)  extends uvm_driver #(REQ, RSP);

  int data_array[511:0];

  function new(string name, uvm_component parent);
    super.new(name, parent);
`uvm_info(get_name(),"has been new",UVM_MEDIUM);
  endfunction

  task run_phase(uvm_phase phase);

    REQ req;
    RSP rsp;

    forever begin
      seq_item_port.get(req);
      rsp = new();
      rsp.set_id_info(req);

      // Actually do the read or write here
      if (req.op == BUS_READ) begin
        rsp.addr = req.addr[8:0];
        rsp.data = data_array[rsp.addr];
        `uvm_info("my_driver",rsp.convert2string(),UVM_MEDIUM);
      end else begin
        data_array[req.addr[8:0]] = req.data;
        `uvm_info("my_driver",req.convert2string(),UVM_MEDIUM);
      end
      seq_item_port.put(rsp);
    end
  endtask
endclass


`define num_loops 10

class sequenceA #(type REQ = uvm_sequence_item,
                  type RSP = uvm_sequence_item) extends uvm_sequence #(REQ, RSP);

  static integer g_my_id = 1;
  rand integer my_id;
  
  function new(string name);
    super.new(name);
`uvm_info(get_name(),"has been new",UVM_MEDIUM);
    my_id = g_my_id++;
  endfunction
  task pre_body();
    `uvm_info("sequenceA", "pre_body()", UVM_MEDIUM)
  endtask
  task body();
    string prstring;
    int  ret_data;
    REQ  req;
    RSP  rsp;
    `uvm_info("sequenceA", "body()", UVM_MEDIUM)
    `uvm_info("sequenceA", "Starting sequence", UVM_MEDIUM)
    
    for(int unsigned i = 0; i < `num_loops; i++) begin
      req = new();
      req.addr = (my_id * `num_loops) + i;
      req.data = my_id + i + 55;
      req.op   = BUS_WRITE;

      wait_for_grant();
      send_request(req);
      get_response(rsp);
      
      req = new();
      req.addr = (my_id * `num_loops) + i;
      req.data = 0;
      req.op   = BUS_READ;

      wait_for_grant();
      send_request(req);
      get_response(rsp);
      
      if (rsp.data != (my_id + i + 55)) begin
        $sformat(prstring, "Error, addr: %0d, expected data: %0d, actual data: %0d",
                 req.addr, req.data, rsp.data);
        `uvm_error("SequenceA", prstring)
      end
    end
    `uvm_info("sequenceA", "Finishing sequence", UVM_MEDIUM)
  endtask // body

endclass

`define NUM_SEQS 10

class env extends uvm_env;
  int i;
  uvm_sequencer #(bus_req, bus_rsp) sqr;

  sequenceA #(bus_req, bus_rsp) sequence_a[`NUM_SEQS];
  my_driver #(bus_req, bus_rsp) drv ;

  function new(string name, uvm_component parent);
    string str;

    super.new(name, parent);
    sqr = new("sequence_controller", this);

    for (i = 0; i < `NUM_SEQS; i++) begin
      sequence_a[i] = new("sequence");
    end
    
    // create and connect driver
    drv = new("slave", this);
    drv.seq_item_port.connect(sqr.seq_item_export);
  endfunction

task run_phase(uvm_phase phase);
    int i;

    phase.raise_objection(this);
    `uvm_info(get_name(), "sequence.start()", UVM_MEDIUM)
    sequence_a[0].start(sqr, null);
/*
    for (i = 0; i < `NUM_SEQS; i++) begin
      fork

        sequence_a[i].start(sqr, null);
      join_none
      #0;
    end
    wait fork;
*/
    phase.drop_objection(this);
endtask

endclass
class test_base extends uvm_test;
 env e;
`uvm_component_utils(test_base)
 function new(string name, uvm_component parent);
    super.new(name, parent);
    e = new("env", null);
  endfunction
//function build_phase();

//endfunction
endclass
endpackage

`include "uvm_pkg.sv"
module uvm_sequence;

  `include "uvm_macros.svh"
  import user_pkg::*;
  import uvm_pkg::*;
`uvm_info("sequenceA", "body()", UVM_MEDIUM)

  initial begin
    `uvm_info("top","In top initial block",UVM_MEDIUM);
   
    run_test("test_base");
  end
endmodule

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值