SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解

目录

1. 概述

2. 参考文件

3. SRIO协议介绍

3.1 SRIO的数据流

3.2 SRIO的数据协议

3.3 SRIO常用FPGA支持的模式

3.4 SRIO例程代码的时钟计算

4. SRIO的例程代码结构

4.1 SRIO发送模块详解

4.1.1 发送数据部分代码功能说明

4.1.2 接收响应部分的代码功能详解

4.2 SRIO接收模块详解

4.2.1 接收数据部分的代码功能说明

4.2.2 发送响应部分的代码功能说明

5. 疑点

疑点1:

疑点2:


1. 概述

本文是用于记录srio的学习情况,以及一些对xilinx的vivado 2017.4中生成srio例程代码的解释。

2. 参考文件

《pg007_srio_gen2》

3. SRIO协议介绍

本处将从SRIO的数据流,数据协议,常用FPGA支持模式,以及IP例程中的时钟大小计算等部分介绍SRIO的情况。

 

3.1 SRIO的数据流

SRIO通过生成IP后,通常情况下主要使用的接口为四组:ireq,iresp,treq,tresp。每个IP生成后都有这四组接口,即可以同时用于发送数据,接收数据,发送响应数据,接收响应数据。而这些接口间的信号流向如下图所示:

 

SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解

即其信号流为IREQ发出给TREQ,TRESP发出给IRESP。

 

3.2 SRIO的数据协议

SRIO传输与响应的包类型很多,具体看手册P73-P74页。

 

在使用Xilinx的ip核时,通常用的都是HELLO包,所以这里指给HELLO包的格式。如下图所示。Packet 中的具体符号表示意义请查看手册P76-P77页。其中的size为一包传输byte的数据量,范围为1-256 bytes。

SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解

    其典型的传输数据的用户接口代码的波形协议如下图所示:

SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解

 

3.3 SRIO常用FPGA支持的模式

SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解

 

 

3.4 SRIO例程代码的时钟计算

refclk可使用时钟如下图table3-3所示。其中典型的时钟计算如Table3-4表头所示。:

gt_clk     = line_rate/20;

gt_pcs_clk = line_rate/40;

phy_clk    = (gt_clk*link_width)/4;

log_clk    = phy_clk;

cfg_clk    = phy_clk;

SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解

SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解

 

4. SRIO的例程代码结构

SRIO生成例程后,其例程结构如下图所示。看着有8个文件,但常规情况下与我们相关的只有只有两个文件,即下图高亮的两个文件:

  1. srio_request_gen_srio_gen2_0(发送数据模块);
  2. srio_response_gen_srio_gen2_0(接收数据模块)

SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解

 

 

4.1 SRIO发送模块详解

SRIO发送模块中主要有两部分代码,发送数据部分(ireq),发送响应数据部分(iresp)。接收部分端口如下图所示:

SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解

 

 

 

4.1.1 发送数据部分代码功能说明

发送的包头数据的来源为“request_data_out = instruction[request_ address]”,即数据是从`include "instruction_list.vh"文件中调入的。而选择其文件中的哪些数据则是根据request_address算来的,具体如下图部分所示。

SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解

 

最终包头的格式为:

SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解

 

    而包中去掉包头后传输的数据为每8位递增数据数据,具体如下图所示。

SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解

 

重点:发送用户自己的数据与包头时设置,将go的值设置为0x01。

SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解

 

 

 

4.1.2 接收响应部分的代码功能详解

接收响应部分主要功能是在期望的得到回应的包类型时,检查是否回应的对应包头类型。

而判断包头类型是否正确主要是根据预判的ftype(expected_ftype)时,检查接收到的ttype是否为协议规定的类型。判断的方式为下图位置:

SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解

 

4.2 SRIO接收模块详解

SRIO接收模块中主要有两部分代码,接收数据部分(treq),接收响应数据部分(tresp)。接收部分端口如下图所示:

SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解

 

 

4.2.1 接收数据部分的代码功能说明

接收部分主要是通过解析接收端口的信号,实时的解析如下图的信息,以及first_beat(beat为1个时钟的*_data),之后将每包数据去掉包头后丢入“RAMB36SDP(local_data_store)”中,但是每一包丢入数据时的首地址是current_addr[10:3]。

SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解

 

 

 

4.2.2 发送响应部分的代码功能说明

响应部分的代码分两部分,第一部分是响应的包头信号部分,第二部分是响应的数据部分。

包头信号部分信息与响应的包类型相关,如下图所示,详细信息参考《pg007》的p76页。

SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解

 

数据部分的信息主要是提取treq中输入的信号。但提取的方式是根据starting_read_addr = {1'b0, response_data_out[29:22]}开始提取数据输出,即是根据current_addr[10:3]的地址提取数据。也就是说这个提取数据的位置是根据输入数据包中的地址中的一部分作为首地址来定位的数据开始地方。

当然是否需要反馈数据部分得根据接收到的包头类型而定,有些包只需要反馈包头不需要数据,有些包不需要进行反馈,详情参考手册P73页。

保证存入“RAMB36SDP(response_queue_inst)”的包头判断信息无误的依据是RAMB36SB的写使能WREN(generate_a_response),generate_a_response是在接收到的first_beat时,且这个包头是需要反馈数据的包头时才会拉高使能。需要反馈的依据在《pg007》的Table 3-1,具体信息如下图所示:

SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解

 

 

5. 疑点

疑点1:

虽然理论上来说反馈的数据提取数据是根据包头信息在同一个位置提取的,那么反馈的数据就和接收的对应包数据相同。但是由于接收到的数据包头的地址可能相同,至少current_addr[10:3]有很大几率相同,那么就会存在数据覆盖的现象,那么就会导致反馈的数据不是想要的数据,即返回的数据与接收到的数据不同。

 

疑点2:

    为何把“current_addr[23:16] == 8'h12”作为pull_from_store(从存储地址开始拉高)?

   

    答:这个只是对应SRIO例程的发射数据,发射数据自定义的“真实起始地址”,参考手册P161,如下图所示。在自己使用时可以屏蔽掉与这个相关的信号。

SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解