本文转载自:十年老鸟的CSDN博客
前言
因为工作原因,需要对rapidio 的协议进行了解,在xilinx的IP核中,是对应着Serial RapidIO Gen2 这个IP核。因为之前从来没有接触过这个IP核,因此希望像之前学习JESD IP那样,一开始从xilinx的example开始入手。
IP 设置
因为一开始什么都不太明白,所以我一开始对IP的设置保持初始状态,就在这个的基础上生成example
生成example之后,对srio_gen2_0的端口进行简单的观察,发现大部分端口都是输出的,说明大部分端口都不需要进行控制,而里面有几组总线是需要进行控制的
s_axis_ireq_*
m_axis_iresp_*
s_axis_tresp_*
m_axis_treq_*
s_axi_maintr_*
也就是说我们只要关注这些总线如何进行使用。
srio_gen2_0 srio_gen2_0_inst (//--------------------------------------------------------------- .sys_clkp (sys_clkp ), // input .sys_clkn (sys_clkn ), // input .sys_rst (sys_rst ), // input // all clocks as output in shared logic mode .log_clk_out (log_clk ), // output .phy_clk_out (phy_clk ), // output .gt_clk_out (gt_clk ), // output .gt_pcs_clk_out (gt_pcs_clk), // output .drpclk_out (drpclk ), // output .refclk_out (refclk ), // output .clk_lock_out (clk_lock ), // output // all resets as output in shared logic mode .log_rst_out (log_rst ), // output .phy_rst_out (phy_rst ), // output .buf_rst_out (buf_rst ), // output .cfg_rst_out (cfg_rst ), // output .gt_pcs_rst_out (gt_pcs_rst), // output //--------------------------------------------------------------- .gt0_qpll_clk_out (gt0_qpll_clk_out ), // output .gt0_qpll_out_refclk_out (gt0_qpll_out_refclk_out), // output // //--------------------------------------------------------------- .srio_rxn0 (srio_rxn0), // input .srio_rxp0 (srio_rxp0), // input .srio_txn0 (srio_txn0), // output .srio_txp0 (srio_txp0), // output .s_axis_ireq_tvalid (ireq_tvalid), // input .s_axis_ireq_tready (ireq_tready), // output .s_axis_ireq_tlast (ireq_tlast), // input .s_axis_ireq_tdata (ireq_tdata), // input [63 : 0] .s_axis_ireq_tkeep (ireq_tkeep), // input [7 : 0] .s_axis_ireq_tuser (ireq_tuser), // input [31 : 0] .m_axis_iresp_tvalid (iresp_tvalid), // output .m_axis_iresp_tready (iresp_tready), // input .m_axis_iresp_tlast (iresp_tlast), // output .m_axis_iresp_tdata (iresp_tdata), // output [63 : 0] .m_axis_iresp_tkeep (iresp_tkeep), // output [7 : 0] .m_axis_iresp_tuser (iresp_tuser), // output [31 : 0] .s_axis_tresp_tvalid (tresp_tvalid), // input .s_axis_tresp_tready (tresp_tready), // output .s_axis_tresp_tlast (tresp_tlast), // input .s_axis_tresp_tdata (tresp_tdata), // input [63 : 0] .s_axis_tresp_tkeep (tresp_tkeep), // input [7 : 0] .s_axis_tresp_tuser (tresp_tuser), // input [31 : 0] .m_axis_treq_tvalid (treq_tvalid), // output .m_axis_treq_tready (treq_tready), // input .m_axis_treq_tlast (treq_tlast), // output .m_axis_treq_tdata (treq_tdata), // output [63 : 0] .m_axis_treq_tkeep (treq_tkeep), // output [7 : 0] .m_axis_treq_tuser (treq_tuser), // output [31 : 0] .s_axi_maintr_rst (maintr_rst), // input .s_axi_maintr_awvalid (maintr_awvalid), // input .s_axi_maintr_awready (maintr_awready), // output .s_axi_maintr_awaddr (maintr_awaddr), // input [31 : 0] .s_axi_maintr_wvalid (maintr_wvalid), // input .s_axi_maintr_wready (maintr_wready), // output .s_axi_maintr_wdata (maintr_wdata), // input [31 : 0] .s_axi_maintr_bvalid (maintr_bvalid), // output .s_axi_maintr_bready (maintr_bready), // input .s_axi_maintr_bresp (maintr_bresp), // output [1 : 0] .s_axi_maintr_arvalid (maintr_arvalid), // input .s_axi_maintr_arready (maintr_arready), // output .s_axi_maintr_araddr (maintr_araddr), // input [31 : 0] .s_axi_maintr_rvalid (maintr_rvalid), // output .s_axi_maintr_rready (maintr_rready), // input .s_axi_maintr_rdata (maintr_rdata), // output [31 : 0] .s_axi_maintr_rresp (maintr_rresp), // output [1 : 0] .sim_train_en (sim_train_en), // input .phy_mce (phy_mce), // input .phy_link_reset (phy_link_reset), // input .force_reinit (force_reinit), // input .phy_rcvd_mce (phy_rcvd_mce ), // output .phy_rcvd_link_reset (phy_rcvd_link_reset), // output .phy_debug (phy_debug ), // output [223 : 0] .gtrx_disperr_or (gtrx_disperr_or ), // output .gtrx_notintable_or (gtrx_notintable_or ), // output .port_error (port_error ), // output .port_timeout (port_timeout ), // output [23 : 0] .srio_host (srio_host ), // output .port_decode_error (port_decode_error ), // output .deviceid (deviceid ), // output [15 : 0] .idle2_selected (idle2_selected ), // output .phy_lcl_master_enable_out (), // these are side band output only signals .buf_lcl_response_only_out (), .buf_lcl_tx_flow_control_out (), .buf_lcl_phy_buf_stat_out (), .phy_lcl_phy_next_fm_out (), .phy_lcl_phy_last_ack_out (), .phy_lcl_phy_rewind_out (), .phy_lcl_phy_rcvd_buf_stat_out (), .phy_lcl_maint_only_out (), //--- //--- .port_initialized (port_initialized ), // output .link_initialized (link_initialized ), // output .idle_selected (idle_selected ), // output .mode_1x (mode_1x ) // output );
而且通过观察各个总线的tdata的输入输出方向,可以看出
.s_axis_ireq_tvalid (ireq_tvalid), // input .s_axis_ireq_tready (ireq_tready), // output .s_axis_ireq_tlast (ireq_tlast), // input .s_axis_ireq_tdata (ireq_tdata), // input [63 : 0] .s_axis_ireq_tkeep (ireq_tkeep), // input [7 : 0] .s_axis_ireq_tuser (ireq_tuser), // input [31 : 0]
上面这组控制线肯定是用于发送数据的
.m_axis_treq_tvalid (treq_tvalid), // output .m_axis_treq_tready (treq_tready), // input .m_axis_treq_tlast (treq_tlast), // output .m_axis_treq_tdata (treq_tdata), // output [63 : 0] .m_axis_treq_tkeep (treq_tkeep), // output [7 : 0] .m_axis_treq_tuser (treq_tuser), // output [31 : 0]
而上面这组控制线肯定是用于接收数据的,这两组应该是有对应关系。也就是说从s_axis_ireq_*发送出去的数据应该从m_axis_iresp_*获得。
同样的,
.s_axis_tresp_tvalid (tresp_tvalid), // input .s_axis_tresp_tready (tresp_tready), // output .s_axis_tresp_tlast (tresp_tlast), // input .s_axis_tresp_tdata (tresp_tdata), // input [63 : 0] .s_axis_tresp_tkeep (tresp_tkeep), // input [7 : 0] .s_axis_tresp_tuser (tresp_tuser), // input [31 : 0]
上面这组控制线肯定是用于发送数据的
.m_axis_iresp_tvalid (iresp_tvalid), // output .m_axis_iresp_tready (iresp_tready), // input .m_axis_iresp_tlast (iresp_tlast), // output .m_axis_iresp_tdata (iresp_tdata), // output [63 : 0] .m_axis_iresp_tkeep (iresp_tkeep), // output [7 : 0] .m_axis_iresp_tuser (iresp_tuser), // output [31 : 0]
而上面这组控制线肯定是用于接收数据的,这两组应该是有对应关系。也就是说从s_axis_tresp_*发送出去的数据应该从m_axis_treq_*获得。
程序框图如下:
总结
以上就是对srio ip example的一个直观的认识,希望后面慢慢能够加深其理解。