芯片家
芯片家

2019年07月28日 阅读423


Soc debug经验<4>

  在soc芯片验证的时候,有时候需要我们验证一段数据通路,我们需要发送一个数据包,让这笔数据包从起始端,到达我们想要的目的端。这里有两个比较重要的点是需要注意的,第一个点是如何保证这笔数据包按照我们想要的数据通路走;第二个点是如果已经按照我们想要的数据通路走下去了,如何保证这笔数据能成功穿过每一个模块而不丢掉。

1.       如何保证这笔数据按照我们想要的数据通路走。

例如数据通路A<->B<->C<->D<->E。我们想让数据通过A->B->C->D->C->B->F。在Soc芯片中,如果我们想从A模块发送数据到F中,在编译的时候需要A模块是一个A模块的UVC,也就不是A模块的rtl代码,这样我们就可以利用A模块的UVC发送数据包 。从A发出来的数据包到达了D之后,可以有两路通路,一个是到E模块,另一个可以是从D返回去,也就是D->C->B->F,到达F模块。那这里如何保证数据包到达D模块之后,让数据包沿着D->C->B->F,到达F模块。

     在模块D中,会有各种各样的Decoder小模块,这些Decoder决定了到达模块D之后,数据包接下来的走向。这些Decoder是根据来源不同划分的,比如从模块A发出来的数据包可以叫A_Decoder,从其他模块A1发出来的,可以叫A1_DecoderAA1大概率属于不同类型的模块。这两个Decoder的逻辑很相似,里面都会有一个信号destination,该信号的值决定了要到达哪一个模块。

   举例:

   assign Destination= ~enable? 0:F_mem? `to_F : E_mem? `to_E: 0;

可以看到,我们要想让数据包成功到达F,必须让F_mem拉高。我们继续追踪F_mem

可能会发现这个F_mem的逻辑是对地址的范围判断。

   举例:

   assign F_mem=(addr >=F_mem_low)&&(addr<=F_mem_high);

这里就是说,我们从A模块发送到F模块的地址是有限制的,如果这个地址在F模块的memory区间里,接下来D模块就会发送数据到F,沿着D->C->B->F模块走。这里可能牵扯到在我们的case 里面,要先配置F_mem_low F_mem_high之后,才去从模块A发送数据包。如果你知道配置哪一个寄存器可以配置F_mem_low F_mem_high,那更好了,如果你不知道配置哪一个寄存器,这也没有关系,你可以读完接下来我要说的第二点去找到该寄存器。

 

2.       如果已经按照我们想要的数据通路走下去了,如何保证这笔数据能成功穿过每一个模块而不丢掉。

       假设我们想验证A->B->C->D->C->B->F这段数据通路。从模块A发送出来的地址到达模块C 的输入端口之后,这个时候发现数据包在CD的输出端口上没有了。我们去追踪该输出地址接口,可能会发现如下逻辑。

  Case (state)

  `idle:

       If(enable)

        begin

            C_D_addr<=C_D_addr_;

            state<=`send;

        end

   `send:

        …..

     我们可能发现C_D_addr_是有数据的,但是这个enable是等于0的,这个状态机只停留在idle状态,C_D_addr没有数据。

    这里enable没有起来,所以我们会继续追踪enable为什么没有被拉起来。(这个就像第一个点里面F_mem_lowF_mem_high没有数据是一样的)我们一直追踪enable,会发现如下decoder代码。

case(addr[7:0])

20:  enable_C_D_reg_control <=1;

30:  …….

…….

    我们如果追踪addr,能看到完整的地址,在波形中的这些地址都是我们已经配置的寄存器,这里显然没有我们想要的那个寄存器。实际也没有必要去追踪addr了。首先我们要明白,enable_C_D_reg_control是我们要配置寄存器的一个域,然后要配置寄存器地址的后面8位是20。所有寄存器地址define一般都会放在一个文件里。我们可以通过匹配一些关键词去找到该寄存器。

格式如下:

` enable_C_D_reg  10122120

 …….

    比如我们找到了该寄存器叫enable_C_D_reg,我们还需要确定域enable_C_D_reg_controlenable_C_D_reg是第几位。一般情况下,我们可以去查询寄存器的spec,去了解一下enable_C_D_reg寄存器,也可以通过查询UVM的寄存器模型去了解该寄存器。假设我们查到了该域enable_C_D_reg_control32位寄存器enable_C_D_reg的第二位。那在我们从A端发送数据包之前,需要在自己的case cpp里面配置该寄存器。每个验证环境配置具体函数不一样,但是大致思路都是一样的。配置思路代码如下:

data= api.read(enable_C_D_reg);

data=data|0x00000002;

Api.write(enable_C_D_reg,data);

0 个评论

要回复文章请先登录注册