#systemverilog# 之 event region 和 timeslot 仿真调度(五)实战

news/2024/5/19 17:36:34 标签: systemverilog, SV仿真调度

目录

一 问题代码

二 解决方法 

2.1 调换代码顺序

2.2 #0 Delay

2.3 uvm class 执行移到re-avtive

2.4  搭建完备的UVM 验证平台

三 预期波形

经过之前文章的学习,想必大家对systemverilog 仿真调度的理解,应该八九不离十了。今天,我们结合实际中的例子,来实战一下,对之前的理解,做一个考核。

我们拿《UVM实战》中的2.2.1章节的例子,来讲解。

一 问题代码

(1)RTL 的设计实现

文件:src/ch2/dut/dut.sv[2]
  1 module dut(clk,
  2           rst_n,
  3           rxd,
  4           rx_dv,
  5           txd,
  6           tx_en);
  7 input clk;
  8 input rst_n;
  9 input[7:0] rxd;
 10 input rx_dv;
 11 output [7:0] txd;
 12 output tx_en;
 13
 14 reg[7:0] txd;
 15 reg tx_en;
 16
 17 always @(posedge clk) begin 
 18    if(!rst_n) begin
 19       txd <= 8'b0;
 20       tx_en <= 1'b0;
 21    end
 22    else begin
 23       txd <= rxd;
 24       tx_en <= rx_dv; 
 25    end
 26 end
 27 endmodule

(2)my_driver uvm component 的实现

文件:src/ch2/section2.2/2.2.1/my_driver.sv
  3 class my_driver extends uvm_driver;
  4
  5    function new(string name = "my_driver", uvm_component parent = null); 
  6       super.new(name, parent);
  7    endfunction
  8    extern virtual task main_phase(uvm_phase phase);
 
  9 endclass
 10
 11 task my_driver::main_phase(uvm_phase phase);
 12    top_tb.rxd <= 8'b0;
 13    top_tb.rx_dv <= 1'b0;
 14    while(!top_tb.rst_n)
 15       @(posedge top_tb.clk);
 16    for(int i = 0; i < 256; i++)begin
 17       @(posedge top_tb.clk);
 18       top_tb.rxd <= $urandom_range(0, 255);
 19       top_tb.rx_dv <= 1'b1;
 20       `uvm_info("my_driver", "data is drived", UVM_LOW) 
 21    end
 22    @(posedge top_tb.clk);
 23    top_tb.rx_dv <= 1'b0;
 24 endtask

(3)顶层TB的实现 

`timescale 1ns/1ps 
`include "uvm_macros.svh"
import uvm_pkg::*;

`include "my_driver.sv"

module top_tb;
reg clk;
reg rst_n;
reg[7:0] rxd;
reg rx_dv;
wire[7:0] txd;
wire tx_en;

dut my_dut(.clk(clk),
           .rst_n(rst_n),
           .rxd(rxd),
           .rx_dv(rx_dv),
           .txd(txd),
           .tx_en(tx_en));

initial begin
   my_driver drv;
   drv = new("drv", null);
   fork
     drv.main_phase(null);
   join
   $finish();
end

initial begin
   clk = 0;
   forever begin
      #100 clk = ~clk;
   end
end

initial begin
   rst_n = 1'b0;
   #1000;
   rst_n = 1'b1;
end

initial begin
$fsdbDumpfile("test.fsdb");
$fsdbDumpvars(0,top_tb);
$fsdbDumpMDA();
$fsdbDumpSVA();
end

endmodule

我们将上述代码,经VCS编译仿真运行,得到结果如下:

 我们发现:此仿真结果和实际DUT 行为不符合:在rst 复位期间,rxd[7:0] 竟然随机出来数据。这显然是不正确的。问题究竟出在哪里?

对了,此问题映照了今天的主题,是SV仿真调度机制的原因。

如上图所示:总体来看,右图显示,drv.main_phase(null)的执行是放在module:top_tb......endmodule:top_tb  中的   initial begin......end 之间,执行的。并且,driver 中的top_tb.rst_n 的采样,也是发生在 active 区域,而不是发生在re-active 调度区域,所有top_tb.rst_n 的采样执行 vs rst_n = 0 阻塞赋值执行,是在同一个区域,都是在active 域。那么,此时执行的顺序,是代码的位置顺序。所以,

while(!top_tb.rst_n)  @(poasedge top_tb.clk); 

执行的时候,rst_n =0 还未执行,while loop 跳过执行。

二 解决方法 

2.1 调换代码顺序

`timescale 1ns/1ps 
`include "uvm_macros.svh"
import uvm_pkg::*;

`include "my_driver.sv"

module top_tb;
reg clk;
reg rst_n;
reg[7:0] rxd;
reg rx_dv;
wire[7:0] txd;
wire tx_en;

initial begin
   clk = 0;
   forever begin
      #100 clk = ~clk;
   end
end

initial begin
   rst_n = 1'b0;
   #1000;
   rst_n = 1'b1;
end


dut my_dut(.clk(clk),
           .rst_n(rst_n),
           .rxd(rxd),
           .rx_dv(rx_dv),
           .txd(txd),
           .tx_en(tx_en));

initial begin
   my_driver drv;
   drv = new("drv", null);
   fork
     drv.main_phase(null);
   join
   $finish();
end


initial begin
$fsdbDumpfile("test.fsdb");
$fsdbDumpvars(0,top_tb);
$fsdbDumpMDA();
$fsdbDumpSVA();
end

endmodule

2.2 #0 Delay

这里来看,uvm class 中的 task 是顺序执行的。但是也遵守调度规则。 

2.3 uvm class 执行移到re-avtive

2.4  搭建完备的UVM 验证平台

预期波形

 


http://www.niftyadmin.cn/n/333447.html

相关文章

Mybatis 代码生成器

MBG与Example GitHub - mybatis/generator: A code generator for MyBatis. 我们在项目中使用Mybatis的时候&#xff0c;针对需要操作的一张表&#xff0c;需要创建实体类、Mapper映射器、Mapper接口&#xff0c;里面又有很多的字段和方法的配置&#xff0c;这部分的工作是非常…

Nginx系列--upstream模块的使用

原文网址&#xff1a;Nginx系列--upstream模块的使用_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍nginx的upstream模块的使用。 nginx的upstream模块是用于负载均衡的。 upstream模块介绍 Nginx的负载均衡功能依赖于ngx_http_upsteam_module模块&#xff0c;所支持的代理…

ChatGPT:2. 使用OpenAI创建自己的AI网站:1. 初探API

使用OpenAI创建自己的AI网站 如果你还是一个OpenAI的小白&#xff0c;有OpenAI的账号&#xff0c;但想调用OpenAI的API搞一些有意思的事&#xff0c;那么这一系列的教程将仔细的为你讲解如何使用OpenAI的API制作属于自己的AI网站。博主只能利用下班时间更新&#xff0c;进度慢…

chatgpt赋能Python-pycharm取消venv

PyCharm取消venv&#xff1a;一种更简便的虚拟环境管理方式 虚拟环境是Python开发中的重要组成部分之一。它可以让您在同一台机器上使用不同的Python版本、不同的库以及不同的项目而不会干扰彼此之间的功能独立性。而在Python开发中&#xff0c;venv是创建虚拟环境的常用方式之…

[230523]托福写作第一次课 | 10:20~11:20

目录 1. 第一课内容 2. 独立写作 Sample1 Sample2 练习Sample3 3. 作业 1. 第一课内容 1. 分析同学们当前的基础和学习计划 2. 分析托福写作考察重点 3. 讲解独立写作题型分类 4. 讲解文章展开技巧 5. 重点练习开头段展开方法 2. 独立写作 Sample1 agree or disagree: l…

HTTPS如何防止DNS欺骗?

HTTPS加密可以有效帮助服务器应对DNS欺骗、DNS劫持、ARP攻击等安全威胁。DNS是什么&#xff1f;DNS如何被利用&#xff1f;HTTPS如何防止DNS欺骗&#xff1f; DNS如何工作&#xff1f; 如果您想访问www.example.com&#xff0c;您的浏览器需要找到该特定Web服务器的IP地址。它…

STM32独立按键扫描,支持同时按下、长按、快速键值

背景 有个项目在实际应用中&#xff0c;采用8个独立按键&#xff0c;每个按键都赋予不同功能&#xff0c;实际使用过程中很多时候都是需要比较特殊的按键操作&#xff0c;例如&#xff1a;长按10s按键、长按5s按键&#xff0c;或者长按需要有快速按键值的反馈&#xff0c;这个…

深度学习用于医学预后-第二课第四周1-4节随堂作业

作业名&#xff1a;C2_W4_lecture.ipynb 作业地址&#xff1a; github --> bharathikannann/AI-for-Medicine-Specialization-deeplearning.ai --> AI for Medical Prognosis --> Week 4 One-hot encode categorical variables 首先我们来看一下哪些特征是分类特征…