在结合 Tudor 提供的意见和讨论中的链接之后,这里是向 reg 模型添加突发操作的方法。
这个实现没有显示所有代码,而只是添加突发操作所需的部分,我已经测试了它的串行协议(SPI / I2C)的读写操作。寄存器模型值正确更新以及 RTL 寄存器更新。
创建一个类来保存数据和突发长度:
class burst_class extends uvm_object;
`uvm_object_utils (....);
int burst_length;
byte data [$];
function new (string name);
super.new(name);
endfunction
endclass
内部寄存器序列(用于读取不初始化数据)
burst_class obj;
obj = new ("burstInfo");
obj.burst_length = 4; // replace with actual length
obj.data.push_back (data1);
obj.data.push_back (data2);
obj.data.push_back (data3);
obj.data.push_back (data4);
start_reg.read (status,...., .extension(obj));
start_reg.write (status, ...., .extension (obj));
成功操作后,数据值应写入或收集到 obj 对象中的适配器类中(reg2bus 更新为写入,bus2reg 更新为读取) reg2bus 中除了读取时的数据外,所有有关事务的信息都可用。
适配器类 uvm_reg_item start_reg;整数突发长度;突发类适配器_obj;
reg2bus 实现
start_reg = this.get_item;
adapter_obj = new ("adapter_obj");
if($cast (adapter_obj, start_reg.extension)) begin
if (adapter_obj != null) begin
burst_length = adapter_obj.burst_length;
end
else
burst_length = 1; /// so that current implementation of adapter still works
end
根据 burst_length 更新这里的事务大小并正确分配数据。至于读取bus2reg需要更新
bus2reg 实现(已经拥有所有控制信息,因为 reg2bus 总是在 bus2reg 之前执行,使用 reg2bus 中捕获的值)
根据 burst_length 在这种情况下仅将数据分配给通过扩展传递的对象 adapter_obj