core-v-verif系列之lib<60>

UVM环境介绍
HEAD commitID: 1f968ef

lib/uvm_agents/uvma_obi_memory/src/seq

// 
// Copyright 2021 OpenHW Group
// Copyright 2021 Silicon Labs
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
// 
// Licensed under the Solderpad Hardware License v 2.1 (the "License"); you may
// not use this file except in compliance with the License, or, at your option,
// the Apache License version 2.0. You may obtain a copy of the License at
// 
//     https://solderpad.org/licenses/SHL-2.1/
// 
// Unless required by applicable law or agreed to in writing, any work
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
// 

`ifndef __UVMA_OBI_MEMORY_VP_DEBUG_CONTROL_SEQ_SV__
`define __UVMA_OBI_MEMORY_VP_DEBUG_CONTROL_SEQ_SV__


/**
 * Virtual sequence implementing the cv32e40x virtual peripherals.
 * TODO Move most of the functionality to a cv32e env base class.
 */
virtual class uvma_obi_memory_vp_debug_control_seq_c extends uvma_obi_memory_vp_base_seq_c;

   `uvm_field_utils_begin(uvma_obi_memory_vp_debug_control_seq_c)
   `uvm_field_utils_end
      
   /**
    * Default constructor.
    */
   extern function new(string name="uvma_obi_memory_vp_debug_control_seq_c");

   /**
    * Implement number of peripherals
    */
   extern virtual function int unsigned get_num_words();

   /**
    * Implement sequence that will return a random number
    */
   extern virtual task vp_body(uvma_obi_memory_mon_trn_c mon_trn);

   /**
    * Start delayed debug thread
    */
   extern virtual task debug(bit dbg_req_value,
                             bit request_mode,
                             bit rand_pulse_duration,
                             bit rand_start_delay,
                             int unsigned dbg_pulse_duration,
                             int unsigned start_delay);

   /**
    * Must be implemented in dervied class to actually assert interrupt signals
    */
   pure virtual task set_debug_req(bit debug_req);

   /**
    * Must be implemented in dervied class to wait on appropriate clock
    */
   pure virtual task wait_n_clocks(int unsigned n);

endclass : uvma_obi_memory_vp_debug_control_seq_c

function uvma_obi_memory_vp_debug_control_seq_c::new(string name="uvma_obi_memory_vp_debug_control_seq_c");
   
   super.new(name);
   
endfunction : new

function int unsigned uvma_obi_memory_vp_debug_control_seq_c::get_num_words();

   return 1;

endfunction : get_num_words

task uvma_obi_memory_vp_debug_control_seq_c::vp_body(uvma_obi_memory_mon_trn_c mon_trn);
   
   uvma_obi_memory_slv_seq_item_c  slv_rsp;

   `uvm_create  (slv_rsp)
   slv_rsp.orig_trn = mon_trn;   
   slv_rsp.err = 1'b0;

   if (mon_trn.access_type == UVMA_OBI_MEMORY_ACCESS_WRITE) begin

      `uvm_info("VP_VSEQ", $sformatf("Call to virtual peripheral 'vp_debug_control':\n%s", mon_trn.sprint()), UVM_HIGH)            
      debug(.dbg_req_value       (mon_trn.data[31]),
            .request_mode        (mon_trn.data[30]),
            .rand_pulse_duration (mon_trn.data[29]),
            .dbg_pulse_duration  (mon_trn.data[28:16]),
            .rand_start_delay    (mon_trn.data[15]),
            .start_delay         (mon_trn.data[14:0]));
   end
   else if (mon_trn.access_type == UVMA_OBI_MEMORY_ACCESS_READ) begin
      slv_rsp.rdata = 0;
   end
   
   add_r_fields(mon_trn, slv_rsp);
   slv_rsp.set_sequencer(p_sequencer);
   `uvm_send(slv_rsp)

endtask : vp_body

task uvma_obi_memory_vp_debug_control_seq_c::debug(bit dbg_req_value,
                                                   bit request_mode,
                                                   bit rand_pulse_duration,
                                                   bit rand_start_delay,
                                                   int unsigned dbg_pulse_duration,
                                                   int unsigned start_delay);

   // SVTB.29.1.3.1 - Banned random number system functions and methods calls
   // Waive-abe because we just do not need the fine tune control of
   // constraints in this situation.
   //@DVT_LINTER_WAIVER_START "MT20211214_9" disable SVTB.29.1.3.1
   fork
      begin
         if (rand_start_delay) begin
            wait_n_clocks($urandom_range(start_delay, 0));
         end
         else begin
            wait_n_clocks(start_delay);
         end

         if (request_mode) begin
            set_debug_req(dbg_req_value);

            if (rand_pulse_duration) begin
               if (dbg_pulse_duration == 0)
                  wait_n_clocks($urandom_range(128,1));
               else
                  wait_n_clocks($urandom_range(dbg_pulse_duration, 1));
            end
            else begin
               wait_n_clocks(dbg_pulse_duration);
            end
            set_debug_req(!dbg_req_value);
         end
         else begin
            set_debug_req(dbg_req_value);
         end
      end
   join_none
   //@DVT_LINTER_WAIVER_END "MT20211214_9"

endtask : debug

`endif // __UVMA_OBI_MEMORY_VP_DEBUG_CONTROL_SEQ_SV__

uvma_obi_memory_vp_debug_control_seq.sv

1. 简要介绍

该文件是OBI内存接口调试控制虚拟外设序列类,主要功能包括:

  1. 提供调试请求控制功能
  2. 支持延迟调试信号生成
  3. 实现随机脉冲持续时间
  4. 作为调试控制虚拟外设的抽象基类

2. 接口介绍

2.1 类定义
virtual class uvma_obi_memory_vp_debug_control_seq_c extends uvma_obi_memory_vp_base_seq_c;
  • 代码介绍:定义抽象调试控制虚拟外设类
  • 继承关系:继承自虚拟外设基类
  • 特点:使用virtual关键字声明为抽象类

3. 参数介绍

3.1 UVM自动化注册
`uvm_field_utils_begin(uvma_obi_memory_vp_debug_control_seq_c)
`uvm_field_utils_end
  • 参数说明:空字段注册
  • 用途:保持UVM对象标准操作

4. 模块实现介绍

4.1 调试任务
task debug(bit dbg_req_value,
           bit request_mode,
           bit rand_pulse_duration,
           bit rand_start_delay,
           int unsigned dbg_pulse_duration,
           int unsigned start_delay);
  • 代码分析
    1. 支持多种调试模式
    2. 可配置延迟和持续时间
    3. 使用随机数生成器
    4. 并行执行调试操作
4.2 纯虚函数
pure virtual task set_debug_req(bit debug_req);
pure virtual task wait_n_clocks(int unsigned n);
  • 代码分析
    1. 定义必须实现的接口
    2. 强制子类提供具体实现
    3. 确保调试功能完整性

5. 总结

该调试控制虚拟外设序列类具有以下特点:

  1. 灵活的调试信号控制
  2. 可配置的延迟参数
  3. 严格的抽象接口定义
  4. 标准化的UVM实现

作为验证环境的高级组件,它为调试功能提供了统一的控制框架,确保能够方便地实现各类调试场景。

// 
// Copyright 2021 OpenHW Group
// Copyright 2021 Silicon Labs
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
// 
// Licensed under the Solderpad Hardware License v 2.1 (the "License"); you may
// not use this file except in compliance with the License, or, at your option,
// the Apache License version 2.0. You may obtain a copy of the License at
// 
//     https://solderpad.org/licenses/SHL-2.1/
// 
// Unless required by applicable law or agreed to in writing, any work
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
// 

`ifndef __UVMA_OBI_MEMORY_VP_DIRECTED_SLV_RESP_SEQ_SV__
`define __UVMA_OBI_MEMORY_VP_DIRECTED_SLV_RESP_SEQ_SV__


/**
 * Virtual sequence implementing the cv32e40x virtual peripherals.
 * TODO Move most of the functionality to a cv32e env base class.
 */
class uvma_obi_memory_vp_directed_slv_resp_seq_c#(OBI_PERIPHS=1) extends uvma_obi_memory_vp_base_seq_c;

   localparam ERR_ADDR_MIN_INDEX    = 0;
   localparam ERR_ADDR_MAX_INDEX    = 1;
   localparam ERR_VALID_INDEX       = 2;

   localparam EXOKAY_ADDR_MIN_INDEX = 3;
   localparam EXOKAY_ADDR_MAX_INDEX = 4;
   localparam EXOKAY_VALID_INDEX    = 5;

   localparam WORDS_PER_OBI = EXOKAY_VALID_INDEX + 1;

   // An array of OBI memory configurations
   // This enables a single set of virtual peripheral registers (6*OBI_PERIPHS) to control
   // OBI_PERIPHS number of OBIs 
   // For example, in a typical OBI-I, OBI-D configuration, only the OBI-D is writable
   // but we would also need to control the OBI-I as well
   uvma_obi_memory_cfg_c obi_cfg[];

   `uvm_object_param_utils_begin(uvma_obi_memory_vp_directed_slv_resp_seq_c#(OBI_PERIPHS))
   `uvm_object_utils_end
   
   /**
    * Default constructor.
    */
   extern function new(string name="uvma_obi_memory_vp_directed_slv_resp_seq_c");

   /**
    * Implement number of peripherals
    */
   extern virtual function int unsigned get_num_words();

   /**
    * Implement sequence that will return a random number
    */
   extern virtual task vp_body(uvma_obi_memory_mon_trn_c mon_trn);


endclass : uvma_obi_memory_vp_directed_slv_resp_seq_c

function uvma_obi_memory_vp_directed_slv_resp_seq_c::new(string name="uvma_obi_memory_vp_directed_slv_resp_seq_c");
   
   super.new(name);
   
   obi_cfg = new[OBI_PERIPHS];

endfunction : new

function int unsigned uvma_obi_memory_vp_directed_slv_resp_seq_c::get_num_words();
   
   return WORDS_PER_OBI * OBI_PERIPHS;

endfunction : get_num_words

task uvma_obi_memory_vp_directed_slv_resp_seq_c::vp_body(uvma_obi_memory_mon_trn_c mon_trn);

   int unsigned obi_index;

   uvma_obi_memory_slv_seq_item_c  slv_rsp;
   
   `uvm_create(slv_rsp)
   
   slv_rsp.orig_trn = mon_trn;
   slv_rsp.err = 1'b0;

   obi_index = get_vp_index(mon_trn) / WORDS_PER_OBI;
   case (get_vp_index(mon_trn) % WORDS_PER_OBI)
      ERR_ADDR_MIN_INDEX:    obi_cfg[obi_index].directed_slv_err_addr_min    = slv_rsp.orig_trn.data;
      ERR_ADDR_MAX_INDEX:    obi_cfg[obi_index].directed_slv_err_addr_max    = slv_rsp.orig_trn.data;
      ERR_VALID_INDEX:       obi_cfg[obi_index].directed_slv_err_valid       = slv_rsp.orig_trn.data[0];
      EXOKAY_ADDR_MIN_INDEX: obi_cfg[obi_index].directed_slv_exokay_addr_min = slv_rsp.orig_trn.data;
      EXOKAY_ADDR_MAX_INDEX: obi_cfg[obi_index].directed_slv_exokay_addr_max = slv_rsp.orig_trn.data;
      EXOKAY_VALID_INDEX:    obi_cfg[obi_index].directed_slv_exokay_valid    = slv_rsp.orig_trn.data[0];
   endcase

   add_r_fields(mon_trn, slv_rsp);
   slv_rsp.set_sequencer(p_sequencer);
   `uvm_send(slv_rsp)

endtask : vp_body

`endif // __UVMA_OBI_MEMORY_VP_DIRECTED_SLV_RESP_SEQ_SV__



uvma_obi_memory_vp_directed_slv_resp_seq.sv

1. 简要介绍

该文件实现了一个定向从设备响应虚拟外设序列,主要功能包括:

  1. 提供错误和exokay响应控制
  2. 支持多OBI外设配置
  3. 实现地址范围检查
  4. 作为虚拟外设的具体实现

2. 接口介绍

2.1 类定义
class uvma_obi_memory_vp_directed_slv_resp_seq_c#(OBI_PERIPHS=1) extends uvma_obi_memory_vp_base_seq_c;
  • 代码介绍:定义参数化定向响应虚拟外设类
  • 模板参数:OBI_PERIPHS控制外设数量
  • 继承关系:继承自虚拟外设基类

3. 参数介绍

3.1 本地参数
localparam ERR_ADDR_MIN_INDEX = 0;
localparam EXOKAY_VALID_INDEX = 5;
localparam WORDS_PER_OBI = EXOKAY_VALID_INDEX + 1;
  • 参数说明
    • 定义寄存器索引范围
    • 每个OBI外设占用6个字
    • 用于地址映射计算
3.2 配置数组
uvma_obi_memory_cfg_c obi_cfg[];
  • 参数说明:存储多个OBI配置
  • 初始化:在构造函数中根据OBI_PERIPHS动态分配

4. 模块实现介绍

4.1 主体任务
task vp_body(uvma_obi_memory_mon_trn_c mon_trn);
   obi_index = get_vp_index(mon_trn) / WORDS_PER_OBI;
   case (get_vp_index(mon_trn) % WORDS_PER_OBI)
      ERR_ADDR_MIN_INDEX: obi_cfg[obi_index].directed_slv_err_addr_min = slv_rsp.orig_trn.data;
   endcase
  • 代码分析
    1. 计算OBI外设索引
    2. 根据寄存器索引配置参数
    3. 支持错误地址范围和exokay响应配置
4.2 寄存器数量
function int unsigned get_num_words();
   return WORDS_PER_OBI * OBI_PERIPHS; 
endfunction
  • 代码分析
    1. 动态计算寄存器总数
    2. 基于模板参数扩展

5. 总结

该定向从设备响应序列具有以下特点:

  1. 灵活的多外设支持
  2. 精确的响应控制
  3. 可配置的错误注入
  4. 标准化的虚拟外设接口

作为验证环境的高级组件,它为复杂的OBI从设备响应场景提供了统一的控制框架。

// 
// Copyright 2021 OpenHW Group
// Copyright 2021 Silicon Labs
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
// 
// Licensed under the Solderpad Hardware License v 2.1 (the "License"); you may
// not use this file except in compliance with the License, or, at your option,
// the Apache License version 2.0. You may obtain a copy of the License at
// 
//     https://solderpad.org/licenses/SHL-2.1/
// 
// Unless required by applicable law or agreed to in writing, any work
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
// 

`ifndef __UVMA_OBI_MEMORY_VP_INTERRUPT_TIMER_SEQ_SV__
`define __UVMA_OBI_MEMORY_VP_INTERRUPT_TIMER_SEQ_SV__


/**
 * Virtual sequence implementing the cv32e40x virtual peripherals.
 * TODO Move most of the functionality to a cv32e env base class.
 */
virtual class uvma_obi_memory_vp_interrupt_timer_seq_c extends uvma_obi_memory_vp_base_seq_c;

   bit[31:0]    interrupt_value;
   int unsigned interrupt_timer_value;
   event        interrupt_timer_start;   

   `uvm_field_utils_begin(uvma_obi_memory_vp_interrupt_timer_seq_c)
      `uvm_field_int(interrupt_value,       UVM_DEFAULT)
      `uvm_field_int(interrupt_timer_value, UVM_DEFAULT)
   `uvm_field_utils_end
      
   /**
    * Default constructor.
    */
   extern function new(string name="uvma_obi_memory_vp_interrupt_timer_seq_c");

   /**
    * Body will start cycle counting thread before starting parent
    */
   extern virtual task body();

   /**
    * Implement number of peripherals
    */
   extern virtual function int unsigned get_num_words();

   /**
    * Implement sequence that will return a random number
    */
   extern virtual task vp_body(uvma_obi_memory_mon_trn_c mon_trn);

   /**
    * Implements the interrupt_timer thread
    */
   extern virtual task interrupt_timer();

   /**
    * Must be implemented in dervied class to actually assert interrupt signals
    */
   pure virtual task set_interrupt();

endclass : uvma_obi_memory_vp_interrupt_timer_seq_c

function uvma_obi_memory_vp_interrupt_timer_seq_c::new(string name="uvma_obi_memory_vp_interrupt_timer_seq_c");
   
   super.new(name);
   
endfunction : new


task uvma_obi_memory_vp_interrupt_timer_seq_c::body();

   fork
      interrupt_timer();
   join_none

   super.body();

endtask : body

function int unsigned uvma_obi_memory_vp_interrupt_timer_seq_c::get_num_words();

   return 2;
   
endfunction : get_num_words

task uvma_obi_memory_vp_interrupt_timer_seq_c::vp_body(uvma_obi_memory_mon_trn_c mon_trn);
   
   uvma_obi_memory_slv_seq_item_c  slv_rsp;

   `uvm_create(slv_rsp)
   slv_rsp.orig_trn = mon_trn;   
   slv_rsp.err = 1'b0;

   if (mon_trn.access_type == UVMA_OBI_MEMORY_ACCESS_WRITE) begin

      `uvm_info("VP_VSEQ", $sformatf("Call to virtual peripheral 'interrupt_timer_control':\n%s", mon_trn.sprint()), UVM_HIGH)
      if (get_vp_index(mon_trn) == 0) begin
         interrupt_value = mon_trn.data;
      end
      else if (get_vp_index(mon_trn) == 1) begin
         interrupt_timer_value = mon_trn.data;
         ->interrupt_timer_start;
      end
      else begin
         `uvm_info("VP_VSEQ", $sformatf("Call to virtual peripheral 'interrupt_timer_control':\n%s", mon_trn.sprint()), UVM_HIGH)
      end      
   end
   else if (mon_trn.access_type == UVMA_OBI_MEMORY_ACCESS_READ) begin
      slv_rsp.rdata = 0;
   end
   
   add_r_fields(mon_trn, slv_rsp);
   slv_rsp.set_sequencer(p_sequencer);
   `uvm_send(slv_rsp)

endtask : vp_body

task uvma_obi_memory_vp_interrupt_timer_seq_c::interrupt_timer();

   while(1) begin
      @interrupt_timer_start;
      `uvm_info("VP_VSEQ", "@interrupt_timer_start", UVM_HIGH)
      while (interrupt_timer_value > 0) begin
         @(cntxt.vif.mon_cb);
         interrupt_timer_value = interrupt_timer_value - 1;
      end

      `uvm_info("VP_VSEQ", $sformatf("Done waiting for interrupt_timer_value to be 0, setting interrupts to 0x%08x", interrupt_value), UVM_HIGH)
      set_interrupt();
   end

endtask : interrupt_timer

`endif // __UVMA_OBI_MEMORY_VP_INTERRUPT_TIMER_SEQ_SV__

uvma_obi_memory_vp_interrupt_timer_seq.sv

1. 简要介绍

该文件实现了一个中断定时器虚拟外设序列,主要功能包括:

  1. 提供可配置的中断触发机制
  2. 支持定时器计数功能
  3. 实现中断值存储
  4. 作为虚拟外设的抽象基类

2. 接口介绍

2.1 类定义
virtual class uvma_obi_memory_vp_interrupt_timer_seq_c extends uvma_obi_memory_vp_base_seq_c;
  • 代码介绍:定义抽象中断定时器虚拟外设类
  • 继承关系:继承自虚拟外设基类
  • 特点:使用virtual关键字声明为抽象类

3. 参数介绍

3.1 中断值参数
bit[31:0] interrupt_value;
  • 参数说明:32位中断值
  • 用途:存储要触发的中断值
3.2 定时器参数
int unsigned interrupt_timer_value;
  • 参数说明:无符号定时器值
  • 用途:控制中断触发时间

4. 模块实现介绍

4.1 主体任务
task body();
   fork
      interrupt_timer();
   join_none
   super.body();
endtask
  • 代码分析
    1. 启动中断定时器线程
    2. 并行执行父类body任务
    3. 使用fork-join_none实现非阻塞
4.2 中断定时器
task interrupt_timer();
   while(1) begin
      @interrupt_timer_start;
      while (interrupt_timer_value > 0) begin
         @(cntxt.vif.mon_cb);
         interrupt_timer_value--;
      end
      set_interrupt();
   end
endtask
  • 代码分析
    1. 无限循环等待启动事件
    2. 每个时钟周期递减定时器
    3. 定时器归零后触发中断
    4. 使用事件驱动机制

5. 总结

该中断定时器虚拟外设序列具有以下特点:

  1. 精确的定时中断控制
  2. 灵活的中断值配置
  3. 标准化的虚拟外设接口
  4. 可扩展的设计架构

作为验证环境的高级组件,它为中断测试场景提供了可靠的定时触发机制,确保能够准确验证各类中断处理逻辑。

//
// Copyright 2021 OpenHW Group
// Copyright 2021 Silicon Labs
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the "License"); you may
// not use this file except in compliance with the License, or, at your option,
// the Apache License version 2.0. You may obtain a copy of the License at
//
//     https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
//

`ifndef __UVMA_OBI_MEMORY_VP_RAND_NUM_SEQ_SV__
`define __UVMA_OBI_MEMORY_VP_RAND_NUM_SEQ_SV__


/**
 * Virtual sequence implementing the cv32e40x virtual peripherals.
 * TODO Move most of the functionality to a cv32e env base class.
 */
class uvma_obi_memory_vp_rand_num_seq_c extends uvma_obi_memory_vp_base_seq_c;

   rand uvma_obi_memory_data_b_t   rdata;

   `uvm_object_utils_begin(uvma_obi_memory_vp_rand_num_seq_c)
   `uvm_object_utils_end

   /**
    * Default constructor.
    */
   extern function new(string name="uvma_obi_memory_vp_rand_num_seq_c");

   /**
    * Implement number of peripherals
    */
   extern virtual function int unsigned get_num_words();

   /**
    * Implement sequence that will return a random number
    */
   extern virtual task vp_body(uvma_obi_memory_mon_trn_c mon_trn);

endclass : uvma_obi_memory_vp_rand_num_seq_c


function uvma_obi_memory_vp_rand_num_seq_c::new(string name="uvma_obi_memory_vp_rand_num_seq_c");

   super.new(name);

endfunction : new

function int unsigned uvma_obi_memory_vp_rand_num_seq_c::get_num_words();

   return 1;

endfunction : get_num_words

task uvma_obi_memory_vp_rand_num_seq_c::vp_body(uvma_obi_memory_mon_trn_c mon_trn);

   uvma_obi_memory_slv_seq_item_c  slv_rsp;

   `uvm_create(slv_rsp)

   slv_rsp.orig_trn = mon_trn;
   if (!this.randomize()) begin
      `uvm_fatal("VPRNDSEQ", "Failed to randomize")
   end
   else begin
      slv_rsp.rdata = this.rdata;
   end
   slv_rsp.err = 1'b0;

   `uvm_info("VPRNDSEQ", $sformatf("Issuing a random number: 0x%08x", slv_rsp.rdata), UVM_HIGH);

   add_r_fields(mon_trn, slv_rsp);
   `uvm_send(slv_rsp)

endtask : vp_body

`endif // __UVMA_OBI_MEMORY_VP_RAND_NUM_SEQ_SV__

uvma_obi_memory_vp_rand_num_seq.sv

1. 简要介绍

该文件实现了一个随机数生成虚拟外设序列,主要功能包括:

  1. 提供随机数生成功能
  2. 响应主设备读取请求
  3. 作为虚拟外设的具体实现
  4. 集成到OBI内存验证环境中

2. 接口介绍

2.1 类定义
class uvma_obi_memory_vp_rand_num_seq_c extends uvma_obi_memory_vp_base_seq_c;
  • 代码介绍:定义随机数生成虚拟外设类
  • 继承关系:继承自虚拟外设基类
  • 特点:实现具体随机数生成功能

3. 参数介绍

3.1 随机数参数
rand uvma_obi_memory_data_b_t rdata;
  • 参数说明:32位随机数
  • 特点:使用rand关键字声明为随机变量
  • 用途:存储生成的随机数值

4. 模块实现介绍

4.1 UVM自动化注册
`uvm_object_utils_begin(uvma_obi_memory_vp_rand_num_seq_c)
`uvm_object_utils_end
  • 代码分析
    1. 标准UVM对象注册
    2. 无额外字段需要注册
    3. 保持UVM框架兼容性
4.2 主体任务
task vp_body(uvma_obi_memory_mon_trn_c mon_trn);
   if (!this.randomize()) begin
      `uvm_fatal("VPRNDSEQ", "Failed to randomize")
   end
   else begin
      slv_rsp.rdata = this.rdata;
   end
endtask
  • 代码分析
    1. 调用randomize()生成随机数
    2. 错误处理机制
    3. 将随机数赋值给响应对象
    4. 使用UVM宏记录日志

5. 总结

该随机数生成虚拟外设序列具有以下特点:

  1. 简单的随机数生成功能
  2. 标准化的UVM实现
  3. 可靠的错误处理机制
  4. 清晰的日志记录

作为验证环境的辅助组件,它为测试场景提供了可预测的随机数据源,确保能够验证各类数据处理逻辑。

//
// Copyright 2021 OpenHW Group
// Copyright 2021 Silicon Labs
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the "License"); you may
// not use this file except in compliance with the License, or, at your option,
// the Apache License version 2.0. You may obtain a copy of the License at
//
//     https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
//

`ifndef __UVMA_OBI_MEMORY_VP_SIG_WRITER_SEQ_SV__
`define __UVMA_OBI_MEMORY_VP_SIG_WRITER_SEQ_SV__


/**
 * Virtual sequence implementing the cv32e40x virtual peripherals.
 * TODO Move most of the functionality to a cv32e env base class.
 */
virtual class uvma_obi_memory_vp_sig_writer_seq_c extends uvma_obi_memory_vp_base_seq_c;

   localparam    NUM_WORDS = 3;

   bit[31:0]     signature_start_address;
   bit[31:0]     signature_end_address;
   string        sig_file     = "";
   int           sig_fd       = 0;
   bit           use_sig_file = 0;

   `uvm_field_utils_begin(uvma_obi_memory_vp_sig_writer_seq_c)
      `uvm_field_int(signature_start_address, UVM_DEFAULT)
      `uvm_field_int(signature_end_address,   UVM_DEFAULT)
   `uvm_field_utils_end

   /**
    * Default constructor.
    */
   extern function new(string name="uvma_obi_memory_vp_sig_writer_seq_c");

   /**
    * Implement number of peripherals
    */
   extern virtual function int unsigned get_num_words();

   /**
    * Implement sequence that will return a random number
    */
   extern virtual task vp_body(uvma_obi_memory_mon_trn_c mon_trn);

   /**
    * Set virtual exit in core
    */
   pure virtual task set_exit_valid();

endclass : uvma_obi_memory_vp_sig_writer_seq_c


function uvma_obi_memory_vp_sig_writer_seq_c::new(string name="uvma_obi_memory_vp_sig_writer_seq_c");

   super.new(name);


   if ($value$plusargs("signature=%s", sig_file)) begin
      sig_fd = $fopen(sig_file, "w");
      if (sig_fd == 0) begin
          `uvm_error("VP_VSEQ", $sformatf("Could not open file %s for writing", sig_file));
          use_sig_file = 0;
      end
      else begin
          use_sig_file = 1;
      end
   end

endfunction : new

function int unsigned uvma_obi_memory_vp_sig_writer_seq_c::get_num_words();

   return NUM_WORDS;

endfunction : get_num_words

task uvma_obi_memory_vp_sig_writer_seq_c::vp_body(uvma_obi_memory_mon_trn_c mon_trn);

   uvma_obi_memory_slv_seq_item_c  slv_rsp;

   `uvm_create  (slv_rsp)
   slv_rsp.orig_trn = mon_trn;
   slv_rsp.err = 1'b0;

   if (mon_trn.access_type == UVMA_OBI_MEMORY_ACCESS_WRITE) begin
      case (get_vp_index(mon_trn))
         0: signature_start_address = mon_trn.data;
         1: signature_end_address = mon_trn.data;

         2: begin
            for (int unsigned ii=signature_start_address; ii<signature_end_address; ii += 4) begin
               `uvm_info("VP_SIG_WRITER", "Dumping signature", UVM_HIGH)
               if (use_sig_file) begin
                  $fdisplay(sig_fd, "%x%x%x%x", cntxt.mem.read(ii+3),
                                                cntxt.mem.read(ii+2),
                                                cntxt.mem.read(ii+1),
                                                cntxt.mem.read(ii+0));
               end
               else begin
                  `uvm_info("VP_VSEQ", $sformatf("%x%x%x%x", cntxt.mem.read(ii+3),
                                                            cntxt.mem.read(ii+2),
                                                            cntxt.mem.read(ii+1),
                                                            cntxt.mem.read(ii+0)), UVM_HIGH)
               end
            end

            set_exit_valid();
         end
      endcase
   end
   else if (mon_trn.access_type == UVMA_OBI_MEMORY_ACCESS_READ) begin
      slv_rsp.rdata = 0;
   end

   add_r_fields(mon_trn, slv_rsp);
   slv_rsp.set_sequencer(p_sequencer);
   `uvm_send(slv_rsp)

endtask : vp_body

`endif // __UVMA_OBI_MEMORY_VP_SIG_WRITER_SEQ_SV__

uvma_obi_memory_vp_sig_writer_seq.sv

1. 简要介绍

该文件实现了一个签名文件写入虚拟外设序列,主要功能包括:

  1. 提供签名文件生成功能
  2. 支持内存区域转储
  3. 实现签名地址范围配置
  4. 作为虚拟外设的抽象基类

2. 接口介绍

2.1 类定义
virtual class uvma_obi_memory_vp_sig_writer_seq_c extends uvma_obi_memory_vp_base_seq_c;
  • 代码介绍:定义抽象签名写入虚拟外设类
  • 继承关系:继承自虚拟外设基类
  • 特点:使用virtual关键字声明为抽象类

3. 参数介绍

3.1 签名地址参数
bit[31:0] signature_start_address;
bit[31:0] signature_end_address;
  • 参数说明:32位起始和结束地址
  • 用途:定义签名转储的内存范围
3.2 文件参数
string sig_file = "";
int sig_fd = 0;
bit use_sig_file = 0;
  • 参数说明
    • sig_file:签名文件路径
    • sig_fd:文件描述符
    • use_sig_file:文件使用标志

4. 模块实现介绍

4.1 构造函数
function new(string name="uvma_obi_memory_vp_sig_writer_seq_c");
   if ($value$plusargs("signature=%s", sig_file)) begin
      sig_fd = $fopen(sig_file, "w");
   end
endfunction
  • 代码分析
    1. 通过plusargs获取签名文件路径
    2. 尝试打开文件写入
    3. 设置文件使用标志
4.2 主体任务
task vp_body(uvma_obi_memory_mon_trn_c mon_trn);
   for (int unsigned ii=signature_start_address; ii<signature_end_address; ii += 4) begin
      $fdisplay(sig_fd, "%x%x%x%x", cntxt.mem.read(ii+3),
                                    cntxt.mem.read(ii+2),
                                    cntxt.mem.read(ii+1),
                                    cntxt.mem.read(ii+0));
   end
endtask
  • 代码分析
    1. 遍历指定内存范围
    2. 以小端格式写入文件
    3. 每4字节为一行输出

5. 总结

该签名文件写入虚拟外设序列具有以下特点:

  1. 灵活的内存转储功能
  2. 可配置的地址范围
  3. 标准化的文件输出格式
  4. 可扩展的设计架构

作为验证环境的高级组件,它为测试结果验证提供了可靠的签名生成机制,确保能够准确验证内存内容。

//
// Copyright 2021 OpenHW Group
// Copyright 2021 Silicon Labs
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the "License"); you may
// not use this file except in compliance with the License, or, at your option,
// the Apache License version 2.0. You may obtain a copy of the License at
//
//     https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
//

`ifndef __UVMA_OBI_MEMORY_VP_VIRTUAL_PRINTER_SEQ_SV__
`define __UVMA_OBI_MEMORY_VP_VIRTUAL_PRINTER_SEQ_SV__


/**
 * Virtual sequence implementing the cv32e40x virtual peripherals.
 * TODO Move most of the functionality to a cv32e env base class.
 */
class uvma_obi_memory_vp_virtual_printer_seq_c extends uvma_obi_memory_vp_base_seq_c;

   localparam NUM_WORDS = 11;

   `uvm_object_utils_begin(uvma_obi_memory_vp_virtual_printer_seq_c)
   `uvm_object_utils_end

   /**
    * Default constructor.
    */
   extern function new(string name="uvma_obi_memory_vp_virtual_printer_seq_c");

   /**
    * Implement number of peripherals
    */
   extern virtual function int unsigned get_num_words();

   /**
    * Implement sequence that will return a random number
    */
   extern virtual task vp_body(uvma_obi_memory_mon_trn_c mon_trn);

endclass : uvma_obi_memory_vp_virtual_printer_seq_c


function uvma_obi_memory_vp_virtual_printer_seq_c::new(string name="uvma_obi_memory_vp_virtual_printer_seq_c");

   super.new(name);

endfunction : new

function int unsigned uvma_obi_memory_vp_virtual_printer_seq_c::get_num_words();

   return NUM_WORDS;

endfunction : get_num_words

task uvma_obi_memory_vp_virtual_printer_seq_c::vp_body(uvma_obi_memory_mon_trn_c mon_trn);

   uvma_obi_memory_slv_seq_item_c  slv_rsp;

   `uvm_create(slv_rsp)
   slv_rsp.orig_trn = mon_trn;

   if (mon_trn.access_type == UVMA_OBI_MEMORY_ACCESS_WRITE) begin
      `uvm_info("VP_VSEQ", $sformatf("Call to virtual peripheral 'virtual_printer':\n%s", mon_trn.sprint()), UVM_DEBUG)
      // Allow $write as this acts as a UART/serial printer
      //@DVT_LINTER_WAIVER_START "SR20211012" disable SVTB.29.1.7
      $write("%c", mon_trn.data[7:0]);
      //@DVT_LINTER_WAIVER_END "SR20211012"
   end
   else if (mon_trn.access_type == UVMA_OBI_MEMORY_ACCESS_READ) begin
      // If reading from virtual printer, simply return 0
      slv_rsp.rdata =0;
   end

   add_r_fields(mon_trn, slv_rsp);
   `uvm_send(slv_rsp)

endtask : vp_body

`endif // __UVMA_OBI_MEMORY_VP_VIRTUAL_PRINTER_SEQ_SV__

uvma_obi_memory_vp_virtual_printer_seq.sv

1. 简要介绍

该文件实现了一个虚拟打印机外设序列,主要功能包括:

  1. 模拟UART/串行打印机行为
  2. 响应主设备写入请求
  3. 支持字符输出功能
  4. 作为虚拟外设的具体实现

2. 接口介绍

2.1 类定义
class uvma_obi_memory_vp_virtual_printer_seq_c extends uvma_obi_memory_vp_base_seq_c;
  • 代码介绍:定义虚拟打印机外设类
  • 继承关系:继承自虚拟外设基类
  • 特点:实现具体打印功能

3. 参数介绍

3.1 本地参数
localparam NUM_WORDS = 11;
  • 参数说明:定义寄存器数量
  • 用途:控制虚拟外设地址空间

4. 模块实现介绍

4.1 UVM自动化注册
`uvm_object_utils_begin(uvma_obi_memory_vp_virtual_printer_seq_c)
`uvm_object_utils_end
  • 代码分析
    1. 标准UVM对象注册
    2. 无额外字段需要注册
    3. 保持UVM框架兼容性
4.2 主体任务
task vp_body(uvma_obi_memory_mon_trn_c mon_trn);
   if (mon_trn.access_type == UVMA_OBI_MEMORY_ACCESS_WRITE) begin
      $write("%c", mon_trn.data[7:0]);
   end
endtask
  • 代码分析
    1. 处理写入请求
    2. 提取低8位作为ASCII字符
    3. 使用$write系统任务输出
    4. 包含DVT Linter豁免注释

5. 总结

该虚拟打印机外设序列具有以下特点:

  1. 简单的字符输出功能
  2. 标准化的UVM实现
  3. 完善的日志记录
  4. 清晰的代码结构

作为验证环境的辅助组件,它为调试信息输出提供了可靠的打印功能,确保能够方便地查看测试过程中的关键信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值