[SystemVerilog] interface array configuration

最近用到interface array,了解到可以用generate 来产生,而不需要一个一个来写,不多说,直接上code~~

bit ck[`IF_NUM];
bit ex_ck;

generate 
  for(genvar ii=0;ii<`IF_NUM;ii++)begin:if_loop
    if(ii < `IF_NUM-1)begin:nor_ck
      clk_if  ck_vif(.clk(ck[ii]));
    end
    else begin:nor_ck
      clk_if  ck_vif(.clk(ex_ck));
    end
    initial begin
      uvm_config_db#(virtual clk_if)::set(uvm_root::get(),$sformatf("uvm_test_top.env.ck_agt[%0d].*",ii),"vif",if_loop[ii].nor_ck.ck_vif);
    end
  end
endgenerate

注意上面引用ck_vif的hierarchy,要加上if_loop[ii].nor_ck ! ! !


stream_if strm_vif[`STM_NUM](.clk(por_ck));

initial begin
  force strm_vif[2].clk = 0;
end

上述代码原本期望的结果是只有strm_vif[2].clk被force成0,而实际 产生的结果是所有的strm_vif的clk全部force成了0;

建议声明interface array时 传入的参数也要是array ,上述可结合最上面的例子。

generate
  for(genvar ii=0;ii<`STM_NUM;ii++)begin:if_loop
    stream_if strm_vif (.clk(por_ck[ii]));
  end
endgenerate

initial begin
  force if_loop[2].strm_vif.clk = 0;
end

补充下generate相关知识:

  • All unnamed generate blocks will be given the name “genblk< n >”
  • generate 块如果不显式声明 label name,系统提供default name genblk< n >”,比如genblk1,genblk2….
  • Each generate construct is assigned its number as described in the previous paragraph even if it does not contain any unnamed generate blocks.
  • generate 块如果显式声明 label name,系统仍然会为其产生一个name:genblk< n >.
  • If such a name would conflict with an explicitly declared name,then leading zeros are added in front of the number until the name does not conflict.
  • 如果系统产生的名字和现存变量冲突,系统会在原来name**前面加0**,知道不冲突为止。比如,user已经定义变量genblk1,系统则会把需要给第一个块产生name就为genblk01.
module top;
  parameter genblk2 = 0;
  genvar i;

// The following generate block is implicitly named genblk1

if (genblk2) logic a; // top.genblk1.a
else logic b; // top.genblk1.b

// The following generate block is implicitly named genblk02
// as genblk2 is already a declared identifier

if (genblk2) logic a; // top.genblk02.a
else logic b; // top.genblk02.b

// The following generate block would have been named genblk3
// but is explicitly named g1

for (i = 0; i < 1; i = i + 1) begin : g1 // block name
  // The following generate block is implicitly named genblk1
  // as the first nested scope inside g1
  if (1) logic a; // top.g1[0].genblk1.a
end

// The following generate block is implicitly named genblk4 since
// it belongs to the fourth generate construct in scope "top".
// The previous generate block would have been
// named genblk3 if it had not been explicitly named g1

for (i = 0; i < 1; i = i + 1)
  // The following generate block is implicitly named genblk1
  // as the first nested generate block in genblk4

  if (1) logic a; // top.genblk4[0].genblk1.a

  // The following generate block is implicitly named genblk5

  if (1) logic a; // top.genblk5.a
endmodule

module top;
  typedef enum {
    AMBA_BUS1,
    AMBA_BUS2,
    AMBA_BUS_QUANTITY
  } amba_bus_t;

  const amba_bus_t  amba_bus_first;  

  amba_interface    i_amba_interface[AMBA_BUS_QUANTITY]();

  for (genvar i = 0; i < AMBA_BUS_QUANTITY; i++) begin 
    initial begin
      automatic amba_bus_t local_label = amba_bus_first.next(i);
      uvm_config_db#(virtual amba_interface)::set(uvm_root::get(), "uvm_test_top", local_label.name(), top.i_amba_interface[i]);
    end
  end
endmodule : top

猜你喜欢

转载自blog.csdn.net/lbt_dvshare/article/details/81459658
今日推荐