伙伴关系(DUT)
这就是新的DUT(jelly_bean_partnership)的外观。
合作模块(DUT)
合作伙伴模块包括我们的旧jelly_bean_taster以及新的jelly_bean_partner。 我们还添加了一个名为taster_id的新信号,用于选择品尝者或伙伴,以供jelly_bean_if使用。
module jelly_bean_partnership( jelly_bean_if.slave_mp jb_if );
import jelly_bean_pkg::*;
jelly_bean_if jb_if0( jb_if.clk );
jelly_bean_if jb_if1( jb_if.clk );
jelly_bean_taster taster ( jb_if0 );
jelly_bean_partner partner( jb_if1 );
always @* begin
jb_if0.flavor = jb_if.flavor;
jb_if1.flavor = jb_if.flavor;
jb_if0.color = jb_if.color;
jb_if1.color = jb_if.color;
jb_if0.sugar_free = jb_if.sugar_free;
jb_if1.sugar_free = jb_if.sugar_free;
jb_if0.sour = jb_if.sour;
jb_if1.sour = jb_if.sour;
if ( jb_if.taster_id == 0 ) begin
jb_if0.command = jb_if.command;
jb_if1.command = NO_OP;
jb_if.taste = jb_if0.taste;
end else begin
jb_if0.command = NO_OP;
jb_if1.command = jb_if.command;
jb_if.taste = jb_if1.taste;
end
end // always @ *
endmodule: jelly_bean_partnership
伙伴
合作伙伴模块以与jelly_bean_taster类似的方式进行 jelly-bean品尝。它具有与jelly_bean_taster相同的寄存器,但其结构不同。尤其是:
- 合作伙伴有一个5位整合的color_and_flavor寄存器(第5行)。
- sour和free_free寄存器位于另一个称为extra的模块实例中(第37和38行)。
module jelly_bean_partner( jelly_bean_if.slave_mp jb_if );
import jelly_bean_pkg::*;
reg [1:0] taste;
reg [4:0] color_and_flavor;
reg [1:0] command;
jelly_bean_extra extra();
initial begin
color_and_flavor = 0;
extra.sugar_free = 0;
extra.sour = 0;
command = 0;
taste = 0;
end
always @ ( posedge jb_if.clk ) begin
command < = jb_if.command;
if ( jb_if.command == JB_WRITE ) begin
color_and_flavor <= { jb_if.color, jb_if.flavor };
extra.sugar_free <= jb_if.sugar_free;
extra.sour <= jb_if.sour;
end else if ( jb_if.command == JB_READ ) begin
jb_if.taste <= #2ns taste;
end
end
always @ ( posedge jb_if.clk ) begin
if ( jb_if.flavor == CHOCOLATE && jb_if.sour ) taste <= YUCKY;
else if ( jb_if.flavor != NO_FLAVOR ) taste <= YUMMY;
end
endmodule: jelly_bean_partner
module jelly_bean_extra;
reg sugar_free;
reg sour;
endmodule: jelly_bean_extra
寄存器模型
顶层寄存器块(jelly_bean_partnership_reg_block)实例化我们之前创建的两个jelly_bean_reg_blocks;一个(jb_reg_blocks [0])用于品尝者,另一个(jb_reg_block [1])用于伙伴。
顶层寄存器模型
然后,我们将jb_reg_blocks [0]的HDL路径设置为“taster”(第16行),它与jelly_bean_partnership模块中的jelly_bean_taster的实例名称相匹配(请参阅上面的jelly_bean_partnership的第7行)。同样,我们将jb_reg_blocks [1]的HDL路径设置为“partner”(第21行),它与jelly_bean_partnership模块中的jelly_bean_partner的实例名称相匹配(请参阅上面的jelly_bean_partnership的第8行)。
class jelly_bean_partnership_reg_block extends uvm_reg_block;
`uvm_object_utils( jelly_bean_partnership_reg_block )
rand jelly_bean_reg_block jb_reg_blocks[2];
uvm_reg_map reg_map;
function new( string name = "jelly_bean_partnership_reg_block" );
super.new( .name( name ), .has_coverage( UVM_NO_COVERAGE ) );
endfunction: new
virtual function void build();
reg_map = create_map( .name( "reg_map" ), .base_addr( 8'h00 ),
.n_bytes( 1 ), .endian( UVM_LITTLE_ENDIAN ) );
jb_reg_blocks[0] = jelly_bean_reg_block::type_id::create( "jb_reg_blocks[0]" );
jb_reg_blocks[0].configure( .parent( this ), .hdl_path( "taster" ) );
jb_reg_blocks[0].build();
reg_map.add_submap( .child_map( jb_reg_blocks[0].reg_map ), .offset( 0 ) );
jb_reg_blocks[1] = jelly_bean_reg_block::type_id::create( "jb_reg_blocks[1]" );
jb_reg_blocks[1].configure( .parent( this ), .hdl_path( "partner" ) );
jb_reg_blocks[1].build();
reg_map.add_submap( .child_map( jb_reg_blocks[1].reg_map ), .offset( 2 ) );
endfunction: build
endclass: jelly_bean_partnership_reg_block
设置HDL路径
现在我们准备实例化顶层寄存器模型。首先,假设我们有以下顶层验证平台,我们将顶层寄存器块的HDL路径设置为“top.dut”(下面的jelly_bean_base_test的第18行)。
module top;
import uvm_pkg::*;
reg clk;
jelly_bean_if jb_if( clk );
jelly_bean_partnership dut( jb_if ); // DUT
// ... omit ...
endmodule: top
然后,我们将HDL路径片段设置为伙伴的recipe 寄存器(第22至24行)。请注意,我们在设置切片之前清除了第21行上的jb_recipe_reg的HDL路径。这是因为重用的jelly_bean_recipe_reg已经有HDL路径片段,它们与搭档的HDL路径不匹配(如果您有兴趣,请通过后门在Register Register中查看jelly_bean_recipe_reg的第66至69行)。
class jelly_bean_base_test extends uvm_test;
`uvm_component_utils( jelly_bean_base_test )
jelly_bean_env jb_env;
jelly_bean_env_config jb_env_cfg;
jelly_bean_agent_config jb_agent_cfg;
jelly_bean_partnership_reg_block jb_partnership_reg_block;
function new( string name, uvm_component parent );
super.new( name, parent );
endfunction: new
function void build_phase( uvm_phase phase );
jelly_bean_recipe_reg jb_recipe_reg;
super.build_phase( phase );
jb_partnership_reg_block = jelly_bean_partnership_reg_block::type_id::create( "jb_partnership_reg_block" );
jb_partnership_reg_block.configure( .hdl_path( "top.dut" ) );
jb_partnership_reg_block.build();
jb_recipe_reg = jb_partnership_reg_block.jb_reg_blocks[1].jb_recipe_reg; // shorthand
jb_recipe_reg.clear_hdl_path();
jb_recipe_reg.add_hdl_path_slice( .name( "color_and_flavor" ), .offset( 0 ), .size( 5 ) );
jb_recipe_reg.add_hdl_path_slice( .name( "extra.sugar_free" ), .offset( 5 ), .size( 1 ) );
jb_recipe_reg.add_hdl_path_slice( .name( "extra.sour" ), .offset( 6 ), .size( 1 ) );
jb_partnership_reg_block.lock_model(); // finalize the address mapping
// ... omit ...
endclass: jelly_bean_base_test
下表总结了我们为伙伴的配方寄存器定义的总体HDL路径。
Model | jb_partnership_reg_block | jb_reg_block[1] | jb_recipe_reg |
---|---|---|---|
Path | top.dut | partner | color_and_flavor |
Path | top.dut | partner | extra.sugar_free |
Path | top.dut | partner | extra.sour |
合作伙伴的品味寄存器使用我们已经在jelly_bean_taste_reg中定义的HDL路径(味道)。
Model | jb_partnership_reg_block | jb_reg_block[1] | jb_taste_reg |
---|---|---|---|
Path | top.dut | partner | taste |
仅供参考,下表总结了我们为品尝者提供的总体HDL路径。
Model | jb_partnership_reg_block | jb_reg_block[0] | jb_recipe_reg |
---|---|---|---|
Path | top.dut | taster | flavor |
Path | top.dut | taster | color |
Path | top.dut | taster | sugar_free |
Path | top.dut | taster | sour |
Model | jb_partnership_reg_block | jb_reg_block[0] | jb_taste_reg |
---|---|---|---|
Path | top.dut | taster | taste |
寄存器访问sequence
我们使用以下序列验证HDL路径。我们在序列中有三个后门写入(突出显示)。
class jelly_bean_reg_sequence extends uvm_reg_sequence;
`uvm_object_utils( jelly_bean_reg_sequence )
function new( string name = "" );
super.new( name );
endfunction: new
virtual task body();
jelly_bean_partnership_reg_block jb_partnership_reg_block;
jelly_bean_reg_block partner_reg_block;
flavor_e flavor;
color_e color;
bit sugar_free;
bit sour;
uvm_status_e status;
uvm_reg_data_t value;
$cast( jb_partnership_reg_block, model );
partner_reg_block = jb_partnership_reg_block.jb_reg_blocks[1]; // shorthand
sugar_free = 0;
sour = 1;
// back-door writes
flavor = BLUEBERRY;
color = BLUE;
poke_reg( partner_reg_block.jb_recipe_reg, status,
{ sour, sugar_free, color, flavor } ); // 'h5A
#10ns ;
flavor = BUBBLE_GUM;
color = GREEN;
write_reg( partner_reg_block.jb_recipe_reg, status,
{ sour, sugar_free, color, flavor }, UVM_BACKDOOR ); // 'h53
#10ns ;
flavor = CHOCOLATE;
color = RED;
partner_reg_block.jb_recipe_reg.write( status,
{ sour, sugar_free, color, flavor }, UVM_BACKDOOR, .parent( this ) ); // 'h4C
#10ns ;
endtask: body
endclass: jelly_bean_reg_sequence
仿真
当你运行一个仿真时,你应该看到像这样的结果:
# KERNEL: UVM_INFO /home/build/vlib1/vlib/uvm-1.2/src/reg/uvm_reg.svh(2820) @ 0:
reporter [RegModel] Poked register "jb_partnership_reg_block.jb_reg_blocks[1].jb_recipe_reg": 'h000000000000005a
# KERNEL: UVM_INFO @ 10: reporter [RegModel] Wrote register via DPI backdoor:
jb_partnership_reg_block.jb_reg_blocks[1].jb_recipe_reg=0x53
# KERNEL: UVM_INFO @ 20: reporter [RegModel] Wrote register via DPI backdoor:
jb_partnership_reg_block.jb_reg_blocks[1].jb_recipe_reg=0x4c
我希望这篇文章能帮助你澄清HDL路径。
您可以在EDA Playground上查看并运行代码。