棋子 · 4月26日

PCIe debug设计:锁存ltssm状态

image.png
图1:debug设计添加位置

image.png
图2:ltssm状态切换图

image.png

pcie_ltssm作为PCIe链路训练状态机的实时状态,能够有效显示当前链路的链路状态。

一旦PCIe出现问题,pcie_ltssm最近的数值跳变情况是进行分析的重要依据。本节采用移位寄存器实现了一种简单的锁存机制,能够锁存最近若干个(锁存个数已参数化)的数值。

image.png
图3 pcie_ltssm_debug波形图

如图所示,i_pcie_ltssm作为输入信号,每隔一段时间会发生变化,o_latch_ltssm作为状态锁存信号会送到cfg_csr模块。在如下代码波形中,o_latch_ltssm锁存了i_pcie_ltssm最近的10次数值,pcie_ltssm数值发生变化,则锁存一次。

o_latch_ltssm#n 为1(#n表示1~9)表示o_latch_ltssm#n 为有效锁存数据。

o_latch_ltssm0 表示最新的锁存结果

o_latch_ltssm9 表示最早的锁存结果

案例中代码采用移位的方式实现了i_pcie_ltssm数值的锁存,当i_pcie_ltssm数值发生变化,则由o_latch_ltssm0锁存最新的pcie_ltssm,o_latch_ltssm0置1表示当前锁存数值有效,而o_latch_ltssm0 锁存的数据则赋值给o_latch_ltssm1 ,o_latch_ltssm1 锁存的数据则赋值给o_latch_ltssm2 ,以此类推,o_latch_ltssm8 锁存的数据则赋值给o_latch_ltssm9 ,而o_latch_ltssm9的锁存数据因为无处可存了,因此直接丢弃了。


module pcie_ltssm_debug
#(  parameter LTSSM_LATCH_NUM=10)
(
    input                                               clk                                     ,   //
    input                                               rst_n                                   ,   //
    input               [5-1:0]                         i_pcie_ltssm                            ,   //
    output  reg         [LTSSM_LATCH_NUM-1:0] [6-1:0]   o_latch_ltssm                               //

);

reg             [5-1:0]                                 i_pcie_ltssm_d1                           ;   //

reg             [LTSSM_LATCH_NUM-1:0]                   latch_ltssm_vld                          ;   //

always@(posedge clk)
    if(!rst_n) begin
        i_pcie_ltssm_d1                   <=              'b0                                     ;   
    end
    else begin
        i_pcie_ltssm_d1                   <=              i_pcie_ltssm                            ;   
    end
    
assign  latch_ltssm_vld                             =   (i_pcie_ltssm_d1!=i_pcie_ltssm)            ;   //


for (genvar i=0;i<LTSSM_LATCH_NUM;i=i+1) begin: latch_shift
    if(i==0)  begin
    always@(posedge clk)
        if(!rst_n) begin
            o_latch_ltssm[i][5-1:0]  <=              'b0                                     ;   
            o_latch_ltssm[i][5]      <=              'b0                                     ;   
        end
        else if(latch_ltssm_vld) begin
            o_latch_ltssm[i][5-1:0]  <=              i_pcie_ltssm                            ;   
            o_latch_ltssm[i][5]      <=              'b1                                     ;   
        end
    end
    else //i>0
    begin
    always@(posedge clk)
        if(!rst_n) begin
            o_latch_ltssm[i][5-1:0]  <=              'b0                                     ;   
            o_latch_ltssm[i][5]      <=              'b0                                     ;   
        end
        else if((latch_ltssm_vld&&o_latch_ltssm[i-1][5]) ) begin
            o_latch_ltssm[i][5-1:0]  <=              o_latch_ltssm[i-1][5-1:0]        ;   
            o_latch_ltssm[i][5]      <=              o_latch_ltssm[i-1][5]            ;   
        end
    end
    
end


endmodule
作者:IC小鸽
文章来源:IC芯视界

推荐阅读

更多IC设计干货请关注IC设计专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。
推荐阅读
关注数
20176
内容数
1307
主要交流IC以及SoC设计流程相关的技术和知识
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息