草庐IT

FPGA开发之SRIO接口

青柠味的乐事 2023-04-19 原文

FPGA开发之SRIO接口回环测试

一、接口部分

s_axis_ireq:发送接口

m_axis_treq:接收接口

m_axis_iresp:接收应答接口

s_axis_tresp:发送应答接口

tvalid : 表示数据有效

tdata : 有效数据,要有HELLO包头

tready : IP核输出,表示可以向其发送数据

tlast : 标志最后一个数据

tuser : ID号,仅tvalid 的第一个时钟周期内有效

tkeep : 固定为8’hFF

二、HELLO包头

见官方手册《PG007》P.76
HELLO格式的包中Size域的值等于传输的字节的总数减1,Size域的有效值范围为0~255字节
RapidIO协议定义了七种事务类型,每种事务类型执行不同的功能。RapidIO包格式中的FTYPE字段与TTYPE字段共同确定了事务的类型

三、外设数据传输

发送外设数据流总体流程是:

  1. 产生64位数据 :具体多少位依据IP核的配置

  1. 写s_axis_ireq接口时序 :只提供一种简单的时序,还有另一种多HELLO包传输格式的。注意一定要有包头!!!,tready在接收到包头后会输出1T的电平后拉高,所以包头后紧跟的数据需要多保持1T,具体可以看最后的仿真图;tvalid一定要保持高电平!!!,否则会进入第二种传输格式,本人在此处走了大量弯路。
    但是,如果你的数据无法连续,那么就在D0后拉低tvalid,等待有效数据,当再次拉高tvalid后tready依旧会在下1T拉低,之后再有效,详见仿真二。

  2. IP核自动通过srio_tx_p和srio_tx_n 发送数据

  3. 短接srio_tx_p核srio_rx_p 、srio_tx_n 和srio_rx_n

  4. 抓取m_axis_treq接口输出信号,可以看到包头已被修变,载荷正常
    仿真一:数据连续


    仿真二:数据不连续,注意在tready拉低时不要丢失数据,这里丢失了3

四、程序

module srio_top(

    input clk_125m_p,
    input clk_125m_n,
    input rstn,

    output srio_tx_p,
    output srio_tx_n,
    input  srio_rx_p,
    input  srio_rx_n

    );
    
    reg            ireq_tvalid  ;
    wire           ireq_tready  ;
    reg            ireq_tlast   ;
    reg   [63:0]   ireq_tdata   ;
    reg   [7:0]    ireq_tkeep   ;
    reg   [31:0]   ireq_tuser   ;
    wire           treq_tvalid ;
    wire           treq_tready ;
    wire           treq_tlast  ;
    wire  [63:0]   treq_tdata  ;
    wire  [7:0]    treq_tkeep  ;
    wire  [31:0]   treq_tuser  ;
    
    wire            log_clk;
    wire            log_rst;
    
    reg [7:0] SM_COUNT;
    reg [31:0] cnt_interval;
    reg [31:0] cnt_sent;
assign treq_tready = 1'b1;
    always @(posedge log_clk or posedge log_rst) begin
        if(log_rst == 1'b1) begin
            ireq_tvalid <= 0;
            ireq_tlast  <= 0; 
            ireq_tdata  <= 0; 
            ireq_tkeep  <= 8'hff; 
            ireq_tuser  <= 8'd1; 
            SM_COUNT    <= 0;
            cnt_sent    <= 0;
        end
        else begin
            case (SM_COUNT)
                8'd0: begin
                    if(cnt_interval >= 32'd125_000_000)
                        SM_COUNT <= 1;
                    else begin
                        SM_COUNT <= 0;
                        ireq_tvalid <= 1'b0;
                        ireq_tlast  <= 1'b0;
                    end
                end
                8'd1: begin
                    ireq_tdata <= 64'h0154_2c80_0000_0007;
                    SM_COUNT <= 2;
                end
                8'd2: begin
                    ireq_tvalid <= 1'b1;
                    SM_COUNT <= 3;
                end
                8'd3: begin
                    ireq_tdata  <= 64'h0;
                    SM_COUNT    <= 4;
                end
                8'd4: begin
                    ireq_tdata  <= ireq_tdata + 64'h01;
                    if(cnt_sent <= 4'd10)begin
                        cnt_sent    <= cnt_sent + 1;
                        SM_COUNT    <= 4;
                    end
                    else begin
                        SM_COUNT    <= 0;
                        ireq_tlast  <= 1;
                        cnt_sent    <= 0;
                    end
                end
                default: ;
            endcase
        end
    end
    
    
    always @(posedge log_clk or posedge log_rst) begin
        if(log_rst == 1'b1) begin
            cnt_interval <= 32'd0;
        end
        else if(SM_COUNT == 8'd0) begin
            cnt_interval <= cnt_interval + 32'd1;
        end
        else
            cnt_interval <= 32'd0;
    end
    
    
    
    
 srio_gen2_0 srio_gen_inst (
  .sys_clkp(clk_125m_p),                                            // input wire sys_clkp
  .sys_clkn(clk_125m_n),                                            // input wire sys_clkn
  .sys_rst(~rstn),                                              // input wire sys_rst
  .log_clk_out(log_clk),                                      // output wire log_clk_out
  .buf_rst_out( ),                                      // output wire buf_rst_out
  .log_rst_out(log_rst),                                      // output wire log_rst_out
  .gt_pcs_rst_out( ),                                // output wire gt_pcs_rst_out
  .gt_pcs_clk_out( ),                                // output wire gt_pcs_clk_out
  .cfg_rst_out( ),                                      // output wire cfg_rst_out
  .deviceid( ),                                            // output wire [15 : 0] deviceid
  .port_decode_error( ),                          // output wire port_decode_error
  .s_axis_ireq_tvalid(ireq_tvalid),                        // input wire s_axis_ireq_tvalid
  .s_axis_ireq_tready(ireq_tready),                        // output wire s_axis_ireq_tready
  .s_axis_ireq_tlast( ireq_tlast),                          // input wire s_axis_ireq_tlast
  .s_axis_ireq_tdata(ireq_tdata),                          // input wire [63 : 0] s_axis_ireq_tdata
  .s_axis_ireq_tkeep(ireq_tkeep),                          // input wire [7 : 0] s_axis_ireq_tkeep
  .s_axis_ireq_tuser(ireq_tuser),                          // input wire [31 : 0] s_axis_ireq_tuser
  .m_axis_iresp_tvalid( ),                      // output wire m_axis_iresp_tvalid
  .m_axis_iresp_tready(0 ),                      // input wire m_axis_iresp_tready
  .m_axis_iresp_tlast( ),                        // output wire m_axis_iresp_tlast
  .m_axis_iresp_tdata( ),                        // output wire [63 : 0] m_axis_iresp_tdata
  .m_axis_iresp_tkeep( ),                        // output wire [7 : 0] m_axis_iresp_tkeep
  .m_axis_iresp_tuser( ),                        // output wire [31 : 0] m_axis_iresp_tuser
  .m_axis_treq_tvalid(treq_tvalid),                        // output wire m_axis_treq_tvalid
  .m_axis_treq_tready(treq_tready),                        // input wire m_axis_treq_tready
  .m_axis_treq_tlast (treq_tlast ),                          // output wire m_axis_treq_tlast
  .m_axis_treq_tdata (treq_tdata ),                          // output wire [63 : 0] m_axis_treq_tdata
  .m_axis_treq_tkeep (treq_tkeep ),                          // output wire [7 : 0] m_axis_treq_tkeep
  .m_axis_treq_tuser (treq_tuser ),                          // output wire [31 : 0] m_axis_treq_tuser
  .s_axis_tresp_tvalid(0 ),                      // input wire s_axis_tresp_tvalid
  .s_axis_tresp_tready( ),                      // output wire s_axis_tresp_tready
  .s_axis_tresp_tlast(0 ),                        // input wire s_axis_tresp_tlast
  .s_axis_tresp_tdata(0 ),                        // input wire [63 : 0] s_axis_tresp_tdata
  .s_axis_tresp_tkeep(0 ),                        // input wire [7 : 0] s_axis_tresp_tkeep
  .s_axis_tresp_tuser(0 ),                        // input wire [31 : 0] s_axis_tresp_tuser
  .s_axi_maintr_rst(0 ),                            // input wire s_axi_maintr_rst
  .s_axi_maintr_awvalid(0 ),                    // input wire s_axi_maintr_awvalid
  .s_axi_maintr_awready( ),                    // output wire s_axi_maintr_awready
  .s_axi_maintr_awaddr(0 ),                      // input wire [31 : 0] s_axi_maintr_awaddr
  .s_axi_maintr_wvalid(0 ),                      // input wire s_axi_maintr_wvalid
  .s_axi_maintr_wready( ),                      // output wire s_axi_maintr_wready
  .s_axi_maintr_wdata(0 ),                        // input wire [31 : 0] s_axi_maintr_wdata
  .s_axi_maintr_bvalid( ),                      // output wire s_axi_maintr_bvalid
  .s_axi_maintr_bready(0 ),                      // input wire s_axi_maintr_bready
  .s_axi_maintr_bresp( ),                        // output wire [1 : 0] s_axi_maintr_bresp
  .s_axi_maintr_arvalid(0 ),                    // input wire s_axi_maintr_arvalid
  .s_axi_maintr_arready( ),                    // output wire s_axi_maintr_arready
  .s_axi_maintr_araddr(0 ),                      // input wire [31 : 0] s_axi_maintr_araddr
  .s_axi_maintr_rvalid( ),                      // output wire s_axi_maintr_rvalid
  .s_axi_maintr_rready(0 ),                      // input wire s_axi_maintr_rready
  .s_axi_maintr_rdata( ),                        // output wire [31 : 0] s_axi_maintr_rdata
  .s_axi_maintr_rresp( ),                        // output wire [1 : 0] s_axi_maintr_rresp
  .gt_clk_out( ),                                        // output wire gt_clk_out
  .drpclk_out( ),                                        // output wire drpclk_out
  .refclk_out( ),                                        // output wire refclk_out
  .buf_lcl_response_only_out( ),          // output wire buf_lcl_response_only_out
  .buf_lcl_tx_flow_control_out( ),      // output wire buf_lcl_tx_flow_control_out
  .idle2_selected( ),                                // output wire idle2_selected
  .idle_selected( ),                                  // output wire idle_selected
  .buf_lcl_phy_buf_stat_out( ),            // output wire [5 : 0] buf_lcl_phy_buf_stat_out
  .phy_clk_out( ),                                      // output wire phy_clk_out
  .gt0_qpll_clk_out( ),                            // output wire gt0_qpll_clk_out
  .gt0_qpll_out_refclk_out( ),              // output wire gt0_qpll_out_refclk_out
  .phy_rst_out( ),                                      // output wire phy_rst_out
  .sim_train_en(0),                                    // input wire sim_train_en
  .phy_mce( ),                                              // input wire phy_mce
  .phy_link_reset( ),                                // input wire phy_link_reset
  .force_reinit( ),                                    // input wire force_reinit
  .phy_lcl_phy_next_fm_out( ),              // output wire [5 : 0] phy_lcl_phy_next_fm_out
  .phy_lcl_phy_last_ack_out( ),            // output wire [5 : 0] phy_lcl_phy_last_ack_out
  .link_initialized( ),                            // output wire link_initialized
  .phy_lcl_phy_rewind_out( ),                // output wire phy_lcl_phy_rewind_out
  .phy_lcl_phy_rcvd_buf_stat_out( ),  // output wire [5 : 0] phy_lcl_phy_rcvd_buf_stat_out
  .phy_rcvd_mce( ),                                    // output wire phy_rcvd_mce
  .phy_rcvd_link_reset( ),                      // output wire phy_rcvd_link_reset
  .port_error( ),                                        // output wire port_error
  .port_initialized( ),                            // output wire port_initialized
  .clk_lock_out( ),                                    // output wire clk_lock_out
  .mode_1x( ),                                              // output wire mode_1x
  .port_timeout( ),                                    // output wire [23 : 0] port_timeout
  .srio_host( ),                                          // output wire srio_host
  .phy_lcl_master_enable_out( ),          // output wire phy_lcl_master_enable_out
  .phy_lcl_maint_only_out( ),                // output wire phy_lcl_maint_only_out
  .gtrx_disperr_or( ),                              // output wire gtrx_disperr_or
  .gtrx_notintable_or( ),                        // output wire gtrx_notintable_or
  .phy_debug( ),                                          // output wire [223 : 0] phy_debug
  .srio_txn0(srio_tx_n),                                          // output wire srio_txn0
  .srio_txp0(srio_tx_p),                                          // output wire srio_txp0
  .srio_rxn0(srio_rx_n),                                          // input wire srio_rxn0
  .srio_rxp0(srio_rx_p)                                          // input wire srio_rxp0
);
    
ila_0 your_instance_name (
	.clk(log_clk), // input wire clk


	.probe0(ireq_tvalid ), // input wire [0:0]  probe0  
	.probe1(ireq_tready ), // input wire [0:0]  probe1 
	.probe2(ireq_tlast  ), // input wire [0:0]  probe2 
	.probe3(ireq_tdata  ), // input wire [63:0]  probe3 
	.probe4(treq_tvalid ), // input wire [0:0]  probe4 
	.probe5(treq_tready ), // input wire [0:0]  probe5 
	.probe6(treq_tlast  ), // input wire [0:0]  probe6 
	.probe7(treq_tdata  ) // input wire [63:0]  probe7
);    
    
    
    
    
    
endmodule

有关FPGA开发之SRIO接口的更多相关文章

  1. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  2. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  3. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

    我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

  4. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  5. ruby-on-rails - 在 Rails 开发环境中为 .ogv 文件设置 Mime 类型 - 2

    我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain

  6. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  7. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  8. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  9. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  10. ruby-on-rails - environment.rb 中设置的常量在开发模式中消失 - 2

    了解Rails缓存如何工作的人可以真正帮助我。这是嵌套在Rails::Initializer.runblock中的代码:config.after_initializedoSomeClass.const_set'SOME_CONST','SOME_VAL'end现在,如果我运行script/server并发出请求,一切都很好。然而,在我的Rails应用程序的第二个请求中,一切都因单元化常量错误而变得糟糕。在生产模式下,我可以成功发出第二个请求,这意味着常量仍然存在。我已通过将以上内容更改为以下内容来解决问题:config.after_initializedorequire'some_cl

随机推荐