目录
1.什么是寄存器
寄存器可以理解为数字设计模块中,软件可以控制的配置单元。硬件在特定的配置下以特定的方式运行。
例如我们可以设计一个32位的寄存器,其中包含了多个独立的字段,每个字段代表特定的功能,在需要时,可以由软件对其进行配置。

| 偏移 | 名字 | 类型 | 宽度 | 含义 |
|---|---|---|---|---|
| 0 | en | RW | 1 | 使能,1表示使用,0表示禁用 |
| 1 | mode | RW | 3 | 支持的模式: 000: xxx 001: xxx …… |
| 4 | halt | RW | 1 | 暂停。1表示暂停,0表示继续 |
| 5 | auto | RW | 1 | 自动。1表示自动。 |
| 6 | reserved | RO | 5 | 保留 |
| 11 | speed | RW | 5 | 设置速度 |
| 16 | reserved | RO | 16 | 保留 |
2.寄存器块
将寄存器组合到一起,每个寄存器有自己的字段和配置,我们可以根据相关地址进行访问,这就是一个寄存器块。

因为我们的寄存器是32bit,所以每个的寄存器的偏移是0x4。
3.UVM寄存器模型
我们可以通过UVM RAL来定义单个字段,寄存器和寄存器块。寄存器模型是一个实体,它包含了我们需要描述的每个寄存器,以及每个寄存器的各个字段。我们可以通过寄存器模型对设计执行读写的操作。
3.1 期望值
字面意思。就是我们预期寄存器的值。在寄存器模型内部需要通过一个更新动作,更新对应寄存器的值。
3.2 镜像值
寄存器模型中对寄存器内部值的一个镜像。每次对寄存器的读写操作,都可能更新寄存器内部的值,有了镜像值后,我们不用每次都去读取寄存器的值,可以直接读取镜像值即可。

3.3 创建寄存器类
class my_reg extends uvm_reg;
//申明寄存器字段
rand vum_reg_field en;
rand uvm_reg_field mode;
rand uvm_reg_field halt;
rand uvm_reg_field auto;
rand uvm_reg_field speed;
function new (string name = "my_reg");
super.new(name);
endfunction
//定义寄存器相关内容
virtual function void build();
//创建每个字段
this.en =uvm_reg_field::type_id::create("en");
this.mode =uvm_reg_field::type_id::create("mode");
this.halt =uvm_reg_field::type_id::create("halt");
this.auto =uvm_reg_field::type_id::create("auto");
this.speed =uvm_reg_field::type_id::create("speed");
//配置每个字段
this.en.configure(this, 1, 0, "RW", 0, 1'h0, 1, 1, 1);
this.mode.configure(this, 3, 1, "RW", 0, 3'h2, 1, 1, 1);
this.halt.configure(this, 1, 4, "RW", 0, 1'h1, 1, 1, 1);
this.auto.configure(this, 1, 5, "RW", 0, 1'h0, 1, 1, 1);
this.speed.configure(this, 5, 11, "RW", 0, 5'h1c, 1, 1, 1);
endfunction
endclass
类似的,我们可以对每个寄存器进行定义。
3.4 定义寄存器块
寄存器块就是寄存器模型,可以用于对寄存器的访问。
class my_reg_block extends uvm_reg_block;
rand reg_1 reg1;
rand reg_2 reg2;
`uvm_object_utils(my_reg_block )
function new(string name = "my_reg_block ");
super.new(name, build_coverage(UVM_NO_COVERAGE));
endfunction
virtual function void build();
this.default_map = create_map("", 0, 4, UVM_LITTLE_ENDIAN, 0);
this.reg1 = reg_ctl::type_id::create("reg1", get_full_name());
this.reg1.configure(this, null, "");
this.reg1.build();
this.default_map.add_reg(this.reg1, `UVM_REG_ADDR_WIDTH'h0, "RW", 0);
this.reg2 = reg_stat::type_id::create("reg2", get_full_name());
this.reg2.configure(this, null, "");
this.reg2.build();
this.default_map.add_reg(this.reg2, `UVM_REG_ADDR_WIDTH'hc, "RO", 0);
endfunction
3.5 寄存器env
class my_env extends uvm_env;
`uvm_component_utils(my_env)
function new(string name = "my_env", uvm_component parent);
super.new(name, parent);
endfunction
reg_env m_reg_env;
my_agent m_agent;
virtual function void build_phase (uvm_phase phase);
super.build_phase(phase);
m_reg_env = reg_env::type_id::create("m_reg_env", this);
m_agent = my_agent::type_id::create("m_agent", this);
endfunction
virtual function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
m_agent.m_mon.mon_ap.connect(m_reg_env.m_apb2re

文章介绍了寄存器的概念,包括它们在硬件设计中的作用,以及如何使用UVM寄存器抽象层(UVM_RAL)构建寄存器模型。详细展示了如何创建寄存器类、定义寄存器块,以及如何在UVM环境中搭建寄存器环境,包括driver、monitor、agent和env等组件。同时,文章提供了一个基于APB协议的寄存器设计示例,并展示了如何进行读写操作和测试序列的编写。
4187

被折叠的 条评论
为什么被折叠?



