唐山网站建设那家性价比高,河北邢台特产,wordpress ftp连接不上,wordpress 文章背景首先Aurora采用AXIS接口
由于后续需要进行AXIS接口 不同时钟域的数据位宽转换#xff08;64bit和256bit之间的转换#xff09;#xff0c;因此分两次走。
第一种方法#xff1a;采用AXIS数据位宽转换IP AXIS跨时钟域IP
第二种方法#xff1a;逻辑完成
下面记录逻辑…首先Aurora采用AXIS接口
由于后续需要进行AXIS接口 不同时钟域的数据位宽转换64bit和256bit之间的转换因此分两次走。
第一种方法采用AXIS数据位宽转换IP AXIS跨时钟域IP
第二种方法逻辑完成
下面记录逻辑实现方法。 为了能正常仿真首先根据Aurora时序制造数据包。 s_tvlaid、s_tdata 通过计数器来创造创造不同长度的数据包其中包含非4的倍数的数据包、刚好4个数据的数据包仅一个数据的数据包。 //生成计数器辅助生成s_tvlaid、s_tdataalways (posedge USER_CLK)if(SYS_RST)r_cnt50 0;else if(r_cnt50 6d50)r_cnt50 0;else r_cnt50 r_cnt50 1b1;//生成s_tvalidassign s_tvalid_en (((r_cnt50 6d5) (r_cnt50 6d15)) || ((r_cnt50 6d17) (r_cnt50 6d20)) || (r_cnt50 6d40) ) ? 1 : 0;assign s_tvalid r_tvalid;always (posedge USER_CLK)if(s_tvalid_en)r_tvalid b1;elser_tvalid b0;//生成s_tdata assign s_tdata r_tdata; always (posedge USER_CLK)if(s_tvalid_en)r_tdata r_tdata 64h5; //64hecff_bc1felser_tdata b0;//生成s_tlast_en assign s_tlast_en ((r_cnt50 6d15) || (r_cnt50 6d20) || (r_cnt50 6d40)) ? 1: 0 ; always (posedge USER_CLK)if(s_tlast_en)r_tlast b1;elser_tlast b0;assign s_tlast r_tlast; //生成s_tkeep assign s_tkeep s_tlast ? 8hff : 8b0;接下来就是AXIS接口 64bit转256bit
首先设计256bit移位寄存器
第一种方法 //设计移位寄存器先进的放低位always (posedge USER_CLK)if(s_tvalid)r_s_tdata_SHIFT {s_tdata,r_s_tdata_SHIFT[255:64]}; else r_s_tdata_SHIFT r_s_tdata_SHIFT;第二种方法 reg [63:0] r1_s_tdata b0;reg [63:0] r2_s_tdata b0;reg [63:0] r3_s_tdata b0;wire [255:0] s_data_256 ;//s_tdata打三拍always (posedge USER_CLK)beginr1_s_tdata s_tdata ; r2_s_tdata r1_s_tdata;r3_s_tdata r2_s_tdata;endassign s_data_256 {s_tdata,r1_s_tdata,r2_s_tdata,r3_s_tdata};拼接后的波形图如下 生成转换后的m_tvalid信号 由于64bit转256所以比率是41 那么生成4计数器从而指示转换成的256bit数据有效 //设计 41计数器 always (posedge USER_CLK)beginif(s_tlast s_tvalid )r_CNT2 2d0 ;else if(s_tvalid) r_CNT2 r_CNT2 1b1 ;elser_CNT2 r_CNT2 ; end//生成 m_tvalidalways (posedge USER_CLK)beginif(((r_CNT2 2d3) || s_tlast) s_tvalid) m_tvalid 1b1 ; elsem_tvalid 1b0 ; end生成tlast信号不管数据包是不是4的倍数总会被移入256bit寄存器转换后的m_tlast信号相当于是比之前的s_talst晚一拍 //生成m_tlast always (posedge USER_CLK)beginif( s_tlast s_tvalid) m_tlast 1b1 ; elsem_tlast 1b0 ; end生成m_tkeep 首先确定最后一个256bit数据即m_tlast对应的256bit数据的m_tkeep值这里根据移入寄存器的个数有关。 也就是说当计数器为0的表示还没移入数据当为1移入第一个64bit数据因此是八个字节有效所以最后一个数据位置的m_tkeep的低八位为1即可8‘hff以此类推。 从而确定最终的m_tkeep值。 //生成m_tkeep always (*)begincase(r_CNT2)2d0 : r_tkeep_TEMP { 8h00 , 8h00, 8h00 , s_tkeep } ;2d1 : r_tkeep_TEMP { 8h00 , 8h00, s_tkeep , 8hff } ;2d2 : r_tkeep_TEMP { 8h00 , s_tkeep , 8hff , 8hff } ;2d3 : r_tkeep_TEMP { s_tkeep , 8hff , 8hff , 8hff } ;default : r_tkeep_TEMP 32d0 ; endcaseend//s_tlast位置对应的tkeepalways (posedge USER_CLK)beginif(s_tlast s_tvalid)m_tkeep r_tkeep_TEMP ;elsem_tkeep 32hffff_ffff;end 由于我们发的第一个数据包中有11个64bit数据因此最后一拍256bit数据中仅包含3个64bit数据所以24个字节有效因此m_tkeep的高两位为0剩下为f。 把拼接后的256bit数据取出来。 重点在于取出的256bit数据要保证在m_tvalid时刻有效不然是不符合axis接口时序的后续没办法使用。 //把拼接数据取出reg [255:0] r_s_data_256 b0 ;reg [255:0] data_256_1 b0 ;wire [255:0] data_256_2 ;reg [255:0] r_STDATA b0 ;reg [255:0] r_s_tdata_tmp b0 ;reg [255:0] r_STDATA_1 b0 ;always (posedge USER_CLK)r_s_data_256 s_data_256;always (posedge USER_CLK)if(m_tvalid)data_256_1 r_s_data_256;elsedata_256_1 data_256_1;assign data_256_2 m_tvalid ? r_s_data_256 :b0 ;always (posedge USER_CLK)beginif(((r_CNT2 2d3) || s_tlast) s_tvalid)r_STDATA s_data_256;elser_STDATA r_STDATA;end //方法二always (*)begincase(r_CNT2)2d0 : r_s_tdata_tmp { 8h00 , 8h00, 8h00 , s_tdata } ;2d1 : r_s_tdata_tmp { 8h00 , 8h00, s_tdata , r_s_tdata_SHIFT[255:192] } ;2d2 : r_s_tdata_tmp { 8h00 , s_tdata , r_s_tdata_SHIFT[255:128] } ;2d3 : r_s_tdata_tmp { s_tdata , r_s_tdata_SHIFT[255:64] } ;default : r_s_tdata_tmp 256d0 ; endcaseendalways (posedge USER_CLK)beginif(((r_CNT2 2d3) || s_tlast) s_tvalid)r_STDATA_1 r_s_tdata_tmp;elser_STDATA_1 r_STDATA_1;end
简单记录一下该方法后面还要用到还需要在好好理解一下尤其是转换前后tready信号还是不大懂。