码迷,mamicode.com
首页 > Windows程序 > 详细

进阶项目(10)基于Altera厂商的SignalTapII在线调试逻辑分析仪使用讲解

时间:2019-09-15 10:46:03      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:描述   moni   芯片   重新编译   接收   alter   虚拟   存在   介绍   

写在前面的话

在诸多数字系统设计书籍中,关于FPGA开发的基本流程,几乎都介绍到了嵌入式逻辑分析仪(或称之为虚拟逻辑分析仪)的相关知识,包括为什么要有这样的在线调试逻辑分析仪,它可以做什么,什么情况下使用,基于什么样的原理,有哪些逻辑分析仪等等。读者在知道了它的种种之后,存在脑袋中的很大疑问就是如何使用,那么本篇章梦翼师兄就将带领大家解开这些疑团,教给大家如何使用基于Altera厂商的SignalTapII对具体的工程进行在线调试。

背景知识

如果您是经验丰富的FPGA数字系统设计工程师或者已经掌握SignalTap II的原理或者更喜欢Follow Me直接动手操作,那么完全可以跳过这一小节。但是,梦翼师兄仍要照顾到FPGA初学者,帮助他们从浩繁的资料中解脱出来,用简短且通俗易懂的描述,使其迅速建立一定的基础,以便轻松掌握SignalTap II工具的使用。好,直奔主题,让我们先看一组术语:

 在线调试:

   在线调试也称作板级调试,它是将工程下载到FPGA芯片后分析代码运行的情况。有人会以为,我们已经做过仿真了,甚至是时序仿真都通过了,还会存在问题么?但是在实际中,还有以下情况我们需要用到在线调试: 

Ⅰ、仿真不全面而没有发现的FPGA设计错误。很多情况下,由于太复杂,无法做到100%的代码覆盖率; 

Ⅱ、在板级交互中,存在异步事件,很难做仿真,或者仿真起来时间很长,无法运行;

Ⅲ、除了本身FPGA外,还可能存在板上互连可靠性问题、电源问题和IC之间的信号干扰问题,都可能导致系统运行出错; 

Ⅳ、其他潜在问题。 

在线调试的方式主要有两种,一种是利用外部测试设备,把内部信号传送到FPGA针脚上,然后用示波器或者逻辑分析仪观察信号,如图表1、图表2所示;另一种就是利用嵌入式逻辑分析仪,在设计中插入逻辑分析仪,利用JTAG边缘数据扫描和开发工具完成数据交互。

嵌入式逻辑分析仪的原理相当与在FPGA中开辟一个环形存储器,如图表3、图表4,存储器的大小决定了能够查看的数据的深度(多少),是可以人为设定的,但是不得超出FPGA所含有的逻辑资源。在FPGA内部,根据设置的采样时钟和需要查看的信号节点,对数据进行采样,并放置到设定的存储空间里,存储空间内容随时间更新。然后通过判断触发点来检查采集数据,一旦满足触发条件,这个时候会停止扫描,然后将触发点前后的一些数据返回给PC端的测试工具进行波形显示,供开发者进行调试。

目前的在线调试工具基本都是和对应的FPGA开发平台挂钩,不同FPGA厂商都会有自己的软件开发平台,嵌入式逻辑分析仪也就不同。Altera 厂家在QuartusII软件开发平台中集成是SignalTapII嵌入式逻辑分析仪,工具的具体使用在后面详细讲解。

技术图片

 

外部逻辑分析仪

传统的外部逻辑分析仪和示波器类似,但是就像图表1、图表2所展示的,在测试复杂的FPGA设计时,会面临如下一些问题:

Ⅰ、缺少空余I/O引脚。设计中器件的选择依据设计规模而定,通常所选器件的I/O 引脚数目和设计的需求是恰好匹配的。

Ⅱ、I/O 引脚难以引出。设计者为减小电路板的面积,大都采用细间距工艺技术,在不改变PCB 板布线的情况下引出I/O 引脚非常困难。

Ⅲ、外接逻辑分析仪有改变FPGA设计中信号原来状态的可能,因此难以保证信号的正确性。

Ⅳ、传统的逻辑分析仪价格昂贵,将会加重设计方的经济负担。

嵌入式逻辑分析仪

SignalTap II基本上采用了典型外部逻辑分析仪的理念和功能,却无需额外的逻辑分析设备、测试I/O、电路板走线和探点,只要建立一个对应的.stp文件并做相关设置后,与当前工程捆绑编译,用一根JTAG 接口的下载电缆连接到要调试的FPGA 器件即可。SignalTap II 对FPGA 的引脚和内部的连线信号进行捕获后,将数据存储在一定的RAM 块中。因此,用于保存采样时钟信号和被捕获的待测信号的RAM 块,也会占用逻辑资源(LE)、Memory资源(Block RAM)和布线资源。占用逻辑资源的多少基于信号或者被监测的通道数量,以及触发条件的复杂程度;所使用的存储器数量取决于被监测的通道数量和采样深度。理论上可支持1024个通道,每个通道可采集128k Bit数据,但是这两个极限值没办法同时满足,因为若同时满足,则等价于占用32768个M4K模块,没有FPGA器件能够提供那么多存储器资源。所以在存储资源方面,传统外部逻辑分析仪的优势就体现出来了。

 技术图片典型的SignalTap II调试流程

技术图片

 

我们不妨对上图所示的调试流程进行一个笼统的描述,让读者有整体的感性认识,之后再Step By Step教大家详细步骤:

Ⅰ、至少准备一个完整的FPGA设计工程,以满足能够下载到FPGA器件中进行在线调试;

Ⅱ、使用.stp文件在该工程中建立嵌入式逻辑分析仪,并进行相关设置,包括指定采集时钟、采样深度、触发条件、存储器模式、触发级别和添加采样信号等;

Ⅲ、根据需要对工程进行编译。当第一次将逻辑分析仪加入到工程中,或者对逻辑分析仪各项设置参数进行了较大改动,例如增加了要监测的新信号,那么需要进行编译或重新编译。对现有SignalTap II的某些基本改动是运行时可配置的,例如禁用某一触发条件,则不需要重新编译;

Ⅳ、将含有逻辑分析仪的设计下载至FPGA器件,通过JTAG链接来运行并控制它

Ⅴ、出现触发事件时,逻辑分析仪停止,采集到的数据被传送到SignalTap II文件窗口。用户在该窗口进行查看、分析、保存,找到设计中的问题;

Ⅵ、调试后判断是否发现并改正了问题,如果是,则将捆绑在工程中的逻辑分析仪去掉,整个调试流程结束;相反,则重新配置逻辑分析仪,调整触发条件,再次寻找其他问题或漏洞。

SignalTap II调试具体操作步骤

一番准备工作之后,按道理今天的主角——如何使用SignalTap II终于要登场了,可笔者还要卖个关子,先制定几条约定:

Ⅰ、在设计中嵌入SignalTap Ⅱ逻辑分析仪有两种方法:第一种方法是建立一个SignalTap Ⅱ文件(.stp),然后定义STP文件的详细内容;第二种方法是用MegaWizard Plug-InManager建立并配置STP文件,然后用MegaWizard实例化一个HDL输出模块。对于工程来讲掌握哪种方式的都是可行的,但是比较常用或者说通用好用的方式还是第一种方式,我们这里便介绍第一种方法。对于类似的情况,笔者均详写官方推荐的方式,其他方式则一笔带过。毕竟,我们的重点是要快速上手、高效掌握一种工具而不像分析数学题一样讲究一“题”多解。

Ⅱ、默认读者已经掌握在QuartusII软件中输入设计代码、综合,会使用modelsim进行简单仿真,能够编译整个工程,分配好引脚后,下载到FPGA器件。

Ⅲ、梦翼师兄的目的是让大家从浩繁的资料中解脱出来,但是自己在撰写本文时却参考了许多前人的智慧和劳动成果,在此向那些付出辛勤汗水的原创者们表达我个人的敬意!     

具体步骤

准备待测工程

我们使用如下所示工程led_six作为待测实例。Verilog源代码在ModelSim中仿真验证结果正确,经QuartusII软件综合编译后下载到开发板亦得到预期结果。 

/****************************************************          

 *   Engineer      :   梦翼师兄

 *   QQ            :   761664056

 *   The module function:按键消抖测试模块

 ****************************************************/

01  module led_six(

02          clk_50M,//系统50MHZ时钟输入

03          rst_n,//低电平复位信号

04          sel,//数码管位选信号

05          seg//数码管段选信号

06          );

07

08  input clk_50M;//系统50MHZ时钟输入

09  input rst_n;//低电平复位信号

10  output [2:0] sel;//数码管位选信号

11  output [7:0] seg;//数码管段选信号

12  

13  reg [2:0] sel;//定义为reg类型

14  reg [7:0] seg;

15  reg [17:0] counter; //定义一个18位计数器

16  

17      

18  //利用定义的18位计数器counter50MHZ分频为慢时钟,使其频率适用于扫描数码管

19  always @ (posedge clk_50M or negedge rst_n)

20    begin

21     if(!rst_n) begin

22         counter <= 18‘d0;//复位后counter清零

23      end

24      else

25          if(!counter[16])//检测counter17位不为1时自增1

26              counter <= counter + 18‘d1;

27          else

28              counter <= 18‘d0;//检测counter17位为1时清零

29  end 

30  

31  //利用counter[16]上升沿(等同于慢时钟上升沿),扫描驱动数码管

32  always @ (posedge counter[16] or negedge rst_n)

33    begin

34     if(!rst_n) begin

35         sel <= 3‘b111;//复位后sel置空

36         seg <= 8‘b1111_1111;//复位后seg置空

37      end

38      else 

39         case (sel)

40              3‘b111 : begin

41                          sel <= 3‘b000;//选中右起第六个数码管,并完成状态跳转

42                          seg<= 8‘b1000_0010;//使右起第六个数码管显示“6”

43                       end    

44              3‘b000 : begin

45                          sel <= 3‘b001;//选中右起第五个数码管,并完成状态跳转

46                          seg <= 8‘b1001_0010;//使右起第六个数码管显示“5”

47                       end    

48              3‘b001 : begin

49                          sel <= 3‘b010;//选中右起第四个数码管,并完成状态跳转

50                          seg <= 8‘b1001_1001;//使右起第六个数码管显示“4”

51                       end    

52              3‘b010 : begin

53                          sel <= 3‘b011;//选中右起第三个数码管,并完成状态跳转

54                          seg <= 8‘b1011_0000;//使右起第六个数码管显示“3”

55                       end    

56              3‘b011 : begin

57                          sel <= 3‘b100;//选中右起第二个数码管,并完成状态跳转

58                          seg <= 8‘b1010_0100;//使右起第六个数码管显示“2”

59                       end    

60              3‘b100 : begin

61                          sel <= 3‘b101;//选中右起第一个数码管,并完成状态跳转

62                          seg <= 8‘b1111_1001;//使右起第六个数码管显示“1”

63                       end    

64              3‘b101 : begin

65                          sel <= 3‘b000;//选中右起第六个数码管,并完成状态跳转

66                          seg <= 8‘b1000_0010;//使右起第六个数码管显示“6”

67                       end                

68              default:sel <= 3‘b111;//默认项sel置空

69      endcase

70  end 

endmodule  

 编写测试代码如下: 

/****************************************************          

 *   Engineer      :   梦翼师兄

 *   QQ             :   761664056

 *   The module function:led_six测试代码

 ****************************************************/

01  `timescale 1ns/1ps

02  module led_six_tb;

03   

04  reg clk_50M;//系统50MHZ时钟输入

05  reg rst_n;//低电平复位信号

06  wire [2:0] sel;//数码管位选信号

07  wire [7:0] seg;//数码管段选信号

08  reg  [39:0] monitor;//定义一个monitor用以实时监测seg,译为对应的Acical 码,便于观察

09  

10  led_six led_six(               //例化led_six模块

11          .clk_50M(clk_50M),

12          .rst_n(rst_n),

13          .sel(sel),

14          .seg(seg)

15          );

16

17   initial begin//初始化

18      clk_50M = 1;//上电时钟为高电平

19      rst_n = 1;//上电复位为高电平

20      #200.1 rst_n = 0;//延迟200.1ns全局复位

21      #40    rst_n = 1;//2个时钟周期置位

22  end

23

24  always #10 clk_50M = ~clk_50M;//产生一个50MHZ时钟

25  

26  always @ (*)                  //monitor用以实时监测seg,译为对应的Acical 码,便于观察

27  begin

28      case(seg)

29          8‘b1000_0010 : monitor = "SIX";

30          8‘b1001_0010 : monitor = "FIVE";

31          8‘b1001_1001 : monitor = "FOUR";

32          8‘b1011_0000 : monitor = "THREE";

33          8‘b1010_0100 : monitor = "TWO";

34          8‘b1111_1001 : monitor = "ONE";

35          8‘b1111_1111 : monitor = "OFF";

36      endcase

37  end

endmodule 

 

仿真结果如下图:

技术图片

创建.stp文件,启动SignalTap II

步骤如下:

在Quartus Ⅱ软件中,选择菜单栏【File】→【New】命令。

 技术图片在弹出的New对话框中,选择【SignalTapⅡLogic AnalyzerFile】 。

技术图片

点击【OK】,会出现一个新的SignalTap Ⅱ窗口。

技术图片

与其他文件一样,SignalTap II文件也需要保存。选择【File】 → 【Save as】命令,输入此SignalTap II文件名为led_six.stp。

技术图片

单击【保存(S)】按钮后,将弹出提示“”,此时单击【OK】按钮。

技术图片

提示"Do you want to enable SignalTap II...",此时单击【Yes】按钮,表示同意再次编译时将此SignalTap II文件与工程捆绑在一起综合、适配,以便共同下载进FPGA芯片中实现实时测试。

 

 

 技术图片

 

 

 注意:如果我们需要在工程中不使用该SignalTap II文件,或者不使用SignalTap II逻辑分析仪,在Quartus II界面中选择【Assignments】->【Settings】。然后在打开窗口左边的分类列表中选择【SignalTap II Logic Analyzer】,如下图所示。可以把【Enable SignalTap II Logic Analyzer】前面的勾去掉来关闭逻辑分析仪。

 

 技术图片

在一个工程中可能同时会有多个SignalTap文件,但在同一时刻只能有一个有效。多个SignalTap II文件是非常有用的,比如工程很大,在工程中不同的部分都需要用SignalTap II来捕捉信号,这样探测不同的部分时我们只需要使用不同的SignalTap II文件就可以了,避免反复设定SignalTap II文件。按照步骤7.5.5.2可以建立新的SignalTap II文件,不同的SignalTap II文件拥有不同的文件名。如果要改变当前工程中已经关联的SignalTap II文件,在下图中的【SignalTap II File name】选择框中点右边的浏览按钮,选择所需要的SignalTap II文件,然后点击【Open】,最后点击【OK】就可以了。在本篇章中,我们选中【Enable SignalTap II Logic Analyzer】选项并使用led_six.stp文件。设定好后点击【OK】按钮关闭设置窗口。

设置采集时钟

在使用SignalTap Ⅱ逻辑分析仪进行数据采集之前,首先应该设置采集时钟,Altera建议最好使用全局时钟作为采集时钟。

步骤如下:

在SignalTap Ⅱ逻辑分析仪窗口,点击【Setup】标签页。

 技术图片

点击Clock栏后面的【Browse Node Finder】按钮,打开Node Finder对话框。

技术图片

在Node Finder对话框中,在Filter列表中选择【SignalTapⅡ:post-fitting】或     【SignalTap Ⅱ:pre-synthesis】。

技术图片

 

  注意: Node Finder(节点发现器)对话框内,Filter (过滤器)栏下提供大概十多种过滤器,我们通用的也是官方推荐的是【SignalTapⅡ:pre-synthesis    

和【SignalTapⅡ:post-fitting】这两种。pre-synthesis(预综合)提取的信号表示寄存器传输级(RTL)信号,post-fitting(后适配)提取的信号表示物理综合优化以及布局、布线操作后的信号。post-fitting过滤器并不能“提取”到所有Note(节点),寄存器端口和组合逻辑端口可以被提取到,而一些进位链信号、IP加密信号则不可以,究竟哪些可以被提取哪些不能被提取,详情请参阅手册。

 

技术图片框中点击【…】按钮,通过层次化列表指定某层模块中的信号,再点击【List】按钮,在Nodes Found中就会显示出能被观察到的节点。我们添加采样时钟信号为clk_50M,如组图。无论哪种方式添加采集时钟,都不要忘记:Nodes Found中选择后,点击按钮,添加到Selected Node中。最后点击【OK】,结果如组图。

 技术图片

注意:用户必须分配采样时钟   

添加待测信号

步骤如下:

在SignalTap Ⅱ逻辑分析仪窗口,点击【Setup】标签页;

 技术图片

在STP窗口的Setup标签页中双击鼠标左键,弹出Node Finder对话框。(该标签页内有一行灰色提示Double-click to add nodes :双击添加节点信号)

技术图片

在Node Finder对话框的Filter列表中选择【SignalTap Ⅱ:pre-synthesis】或【SignalTapⅡ:post-fitting】。 

技术图片

在Look in对话框中指定层次,点击List按钮查找节点。在Nodes Found中选择要加入STP文件中的节点或总线。点击按钮将选择的节点或总线拷贝到Selected Nodes中。点击【OK】按钮,将选择的节点或总线插入STP文件。(详细步骤和图示类似添加采集时钟,在此不赘述)。

我们按照上面的方法步骤把要观测的信号seg[7:0]、sel[2:0]添加进来如下组图。技术图片

 

技术图片

指定采样深度和触发位置

在触发事件开始之前,用户可以指定要观测数据的采样数量,即数据存储深度。前面我们介绍到,采集的数据被放置在一个环形数据缓冲区中,这个环形数据缓冲区的大小即等于用户设置的数据存储深度。为方便观察被采到的数据,我们常常要设置合适的触发位置。

步骤如下:

Signal Configuration(信号配置区)的Data栏,点击Sample depth框右侧列表,选择采样深度。本例选用【1K】。

 技术图片

注意:细心的读者不难发现,Sample depth框右侧还有一个RAM type 框,通过RAM类型设置,用户可以选择使用哪一类型的存储器模块资源(例如M4K、M9K、M512)来实现signaltap存储器缓冲,从而防止使用到其他的存储器,避免对源设计的影响。但是这一设置只适用于有多种存储器模块类型的FPGA器件,例如,Stratix II器件。对于不支持这一特性的器件,这一设置将被设置为AUTO,显示为灰色。 本例中采用Cyclone IV器件,并不支持该特性,所以显示为灰色AUTO。另外,如果采样深度选择过大,在我们的设计中将可能没有足够的资源来实现,这样,设计就不能编译。如果这种情况发生,请减小采样深度的大小。

² 在Trigger栏中,在Trigger position(触发位置)列表中可以选择触发位置前后数据的比例,我们选择【Pre trigger position】。

技术图片

注意:Trigger position触发位置设置允许用户指定SignalTap Ⅱ逻辑分析仪在触发信号发生前后需要捕获的采样点数,其中:

Pre trigger position:保存触发信号发生之前的信号状态信息(88%触发前数据,12%触发后数据);

Center trigger position:保存触发信号发生前后的数据信息,各占50%;

Post trigger position:保存触发信号发生之后的信号状态信息(12%触发前数据,88%触发后数据);

逻辑分析仪触发控制

逻辑分析仪触发控制包括设置触发类型和触发条件(也叫触发级数)。

步骤如下:

触发类型

在Setup标签页中,Trigger Conditions框下方的下拉菜单中,选择【Basic】类型

 技术图片

在seg[0]~sel[2]任意行的Trigger Conditions框鼠标右键单击选中,会出现一个复选列表,即Basic触发类型中包含的各种方式。包括:Don’t Care(无关项触发),Low(低电平触发),High(高电平触发),Falling Edge(下降沿触发),Rising Edge(上升沿触发)以及EitherEdge(双沿触发)。如下方组图所示:

技术图片

 

技术图片

 

我们可以逐个设置sel[0]、sel[1]、sel[2]的触发方式,也可以将sel位选信号和seg段选信号分别设置为一组信号向量。具体操作为:选中所需要的seg[n](读者在设置分组时,可选中所有的seg[n]),单击鼠标右键,选中【Group】,对sel分组同理。该信号向量名之后会出现与之对应位宽的16进制数,可以填入合适的数值作为触发条件。如下组图:

 技术图片

 

技术图片

我们设置Sel[2:0]值为3h,注意下图seg[2]~seg[0]的变化。

技术图片

 

触发条件(触发级数)

SignalTap Ⅱ逻辑分析仪的多级触发特性为设计者提供了更精确的触发条件设置功能。在多级触发中,Signal]1ap II逻辑分析仪首先对第一级触发模式进行触发;当第一级触发表达式满足条件,测试结果为TRUE时,SignalTap Ⅱ逻辑分析仪对第二级触发表达式进行测试;依次类推,直到所有触发级完成测试,并且最后一级触发条件测试结果为TRUE时,SignalTap Ⅱ逻辑分析仪开始捕获信号状态。

 Trigger Conditions】可以横向设置触发条件的个数,如下图所示,SignalTap Ⅱ逻辑分析仪最大可以选择触发级数为10级,我们这里设置成1就够了。 

技术图片

保存并编译嵌入SignalTap Ⅱ逻辑分析仪后的设计

步骤如下:

保存的详细步骤前文已经讲解,因为我们在生成 .STP文件之后立刻对该文件进行了保存,所以此处只需点击菜单栏【File】→【Save】。

 技术图片

 

配置好STP文件以后,在使用SignalTap Ⅱ逻辑分析仪之前必须编译Quartus II设计工程。回到Quartus II工程中后,重新点击全编译技术图片

 

 

 技术图片

 

SignalTap Ⅱ分析器件编程

如前面所约定,默认读者已经具备分配引脚,将.sof文件下载到FPGA器件的能力。在设计中嵌入SignalTal Ⅱ逻辑分析仪并编译完成后,就可以将生成的新.sof文件下载到手头的开发板进行在线调试了。下面,笔者教大家从STP文件界面进行下载设置。

步骤如下:

 将电源、下载线和开发板连接好,下载线连接的是JTAG口

JTAG Chain Configuration栏点击【Setup】

技术图片

双击鼠标左键选中【USB-Blaster】,点击技术图片

技术图片

从HardWare列表中选择【USB-Blaster  [USB-0]】

技术图片

如果开发板电源已打开,会扫描得到我们的硬件FPGA,如下图

技术图片

点击SOF Manage框后面的【…】按钮

技术图片选中已经嵌入SignalTap Ⅱ逻辑分析仪的配置文件led_six.sof,点击【Open】

 技术图片点击技术图片按钮下载

技术图片查看SignalTap Ⅱ采样数据

步骤如下:

SiganlTap Ⅱ窗口中,SignalTap Ⅱ工具条上有四个执行逻辑分析仪选项,在实体窗口中选中当前实体后,四个选项高亮起来可以操作,如组图:

 技术图片

<Ⅰ>选中前四按钮为灰色

技术图片

<Ⅱ>选中后四按钮变高亮

注意:  

Run Analysis】: 单步执行SignalTap Ⅱ逻辑分析仪。即执行该命令后,SignalTap Ⅱ逻辑分析仪等待触发事件,当触发事件发生时开始采集数据,然后停止。

AutoRun Analysis】: 执行该命令后, SignalTap Ⅱ逻辑分析仪连续捕获数据,直到用户按下Stop Analysis为止。

Stop Analysis】: 停止SignalTap Ⅱ分析。如果触发事件还没有发生,则没有接收数据显示出来。

Read Data】: 显示捕获的数据。如果触发事件还没有发生,用户可以点击该按钮查看当前捕获的数据

选择【Run Analysis】技术图片按钮启动SignalTap Ⅱ逻辑分析仪。

SignalTap Ⅱ逻辑分析仪自动将采集数据显示在SignalTap Ⅱ界面的Data标签页中

 技术图片

 

 

 

 

数据保存

SignalTap II嵌入式逻辑分析仪可以采用矢量波形(.vwf)、矢量表(.tbl)、矢量文件(.vec)、逗号分割数据(.csv)和Verilog数值更改转存(.vcd) 文件格式输出所捕获的数据。这些文件格式可以被第三方验证工具读入,显示和分析SignalTap II嵌入式逻辑分析仪所捕获的数据。

² 点击【File】中的【export】,选择合适的文件类型,点击【OK】保存即可。

 技术图片

同时,在Data Log中会保存我们采样操作的波形结果,如下图:

 技术图片

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

进阶项目(10)基于Altera厂商的SignalTapII在线调试逻辑分析仪使用讲解

标签:描述   moni   芯片   重新编译   接收   alter   虚拟   存在   介绍   

原文地址:https://www.cnblogs.com/mengyi1989/p/11521075.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!