根据Aurora发送时序,造Aurora 数据包,从而进行AXIS接口数据位宽转换仿真

首先Aurora采用AXIS接口

由于后续需要进行AXIS接口 不同时钟域的数据位宽转换(64bit和256bit之间的转换),因此分两次走。

第一种方法:采用AXIS数据位宽转换IP + AXIS跨时钟域IP
在这里插入图片描述
在这里插入图片描述

第二种方法:逻辑完成

下面记录逻辑实现方法。
为了能正常仿真,首先根据Aurora时序制造数据包。
s_tvlaid、s_tdata 通过计数器来创造,创造不同长度的数据包,其中包含非4的倍数的数据包、刚好4个数据的数据包,仅一个数据的数据包。

  //生成计数器(辅助生成s_tvlaid、s_tdata)
  always @(posedge USER_CLK)
      if(SYS_RST)
          r_cnt50 <= 0;
      else if(r_cnt50 == 6'd50)
          r_cnt50 <= 0;
      else 
         r_cnt50 <= r_cnt50 + 1'b1;
  
  //生成s_tvalid
  assign s_tvalid_en = (((r_cnt50 >= 6'd5) && (r_cnt50 <= 6'd15)) || ((r_cnt50 >= 6'd17)&& (r_cnt50 <= 6'd20)) || (r_cnt50 == 6'd40) ) ? 1 : 0;
  assign s_tvalid    =  r_tvalid;
  
  always @(posedge USER_CLK)
      if(s_tvalid_en)
          r_tvalid <= 'b1;
      else
          r_tvalid <= 'b0;
          
  //生成s_tdata    
  assign s_tdata    =  r_tdata;  
  
  always @(posedge USER_CLK)
   if(s_tvalid_en)
       r_tdata  <= r_tdata + 64'h5; //64'hecff_bc1f
   else
       r_tdata  <= 'b0;
       
  //生成s_tlast_en 
  assign s_tlast_en  = ((r_cnt50 == 6'd15) || (r_cnt50 == 6'd20) || (r_cnt50 == 6'd40)) ? 1: 0  ; 
  
    always @(posedge USER_CLK)
      if(s_tlast_en)
          r_tlast <= 'b1;
      else
          r_tlast <= 'b0;
          
  assign s_tlast  =   r_tlast;   
  
  //生成s_tkeep 
  assign s_tkeep  = s_tlast ? 8'hff : 8'b0;

在这里插入图片描述
接下来就是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)
      begin
          r1_s_tdata <= s_tdata ; 
          r2_s_tdata <= r1_s_tdata;
          r3_s_tdata <= r2_s_tdata;
      end
      
  assign s_data_256 =  {s_tdata,r1_s_tdata,r2_s_tdata,r3_s_tdata};

拼接后的波形图如下:
在这里插入图片描述


生成转换后的m_tvalid信号
由于64bit转256,所以比率是4:1
那么生成4计数器,从而指示转换成的256bit数据有效

 //设计  4:1计数器   
    always @(posedge USER_CLK)
    begin
        if(s_tlast & s_tvalid )
            r_CNT2                   <= 2'd0  ;
        else if(s_tvalid) 
            r_CNT2                   <= r_CNT2 + 1'b1  ;
        else
            r_CNT2                   <= r_CNT2 ;            
    end
    
   //生成 m_tvalid
   always @(posedge USER_CLK)
    begin
        if(((r_CNT2 == 2'd3) || s_tlast) & s_tvalid) 
            m_tvalid           <= 1'b1 ;  
        else
            m_tvalid           <= 1'b0 ;         
    end

生成tlast信号,不管数据包是不是4的倍数,总会被移入256bit寄存器,转换后的m_tlast信号相当于是比之前的s_talst晚一拍

  //生成m_tlast  
    always @(posedge USER_CLK)
    begin
        if( s_tlast & s_tvalid) 
            m_tlast           <= 1'b1 ;  
        else
            m_tlast           <= 1'b0 ;         
    end

在这里插入图片描述

生成m_tkeep ,首先确定最后一个256bit数据,即m_tlast对应的256bit数据的m_tkeep值,这里根据移入寄存器的个数有关。
也就是说,当计数器为0的表示,还没移入数据;当为1移入第一个64bit数据,因此是八个字节有效,所以最后一个数据位置的m_tkeep的低八位为1,即可8‘hff,以此类推。
从而确定最终的m_tkeep值。

  //生成m_tkeep  
    always @(*)
    begin
        case(r_CNT2)
            2'd0           :     r_tkeep_TEMP    =     {  8'h00 ,   8'h00,     8'h00 ,   s_tkeep     }      ;
            2'd1           :     r_tkeep_TEMP    =     {  8'h00 ,   8'h00,     s_tkeep ,  8'hff      }      ;
            2'd2           :     r_tkeep_TEMP    =     {  8'h00 ,   s_tkeep ,  8'hff ,    8'hff      }      ;
            2'd3           :     r_tkeep_TEMP    =     {  s_tkeep , 8'hff ,    8'hff ,    8'hff      }      ;
            default        :     r_tkeep_TEMP    =     32'd0     ;              
        endcase
    end
    //s_tlast位置对应的tkeep
   always @(posedge USER_CLK)
    begin
        if(s_tlast & s_tvalid)
            m_tkeep            <= r_tkeep_TEMP ;
        else
            m_tkeep            <= 32'hffff_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;
        else
            data_256_1 <= data_256_1;
            
   assign  data_256_2 = m_tvalid ? r_s_data_256 :'b0 ;
   
    always @(posedge USER_CLK)
    begin
        if(((r_CNT2 == 2'd3) || s_tlast) & s_tvalid)
            r_STDATA   <= s_data_256;
        else
            r_STDATA   <= r_STDATA;
    end 
    
    //方法二
    always @(*)
    begin
        case(r_CNT2)
            2'd0           :     r_s_tdata_tmp    =     {  8'h00 ,   8'h00,     8'h00 ,   s_tdata                       }      ;
            2'd1           :     r_s_tdata_tmp    =     {  8'h00 ,   8'h00,     s_tdata , r_s_tdata_SHIFT[255:192]      }      ;
            2'd2           :     r_s_tdata_tmp    =     {  8'h00 ,   s_tdata ,  r_s_tdata_SHIFT[255:128]                }      ;
            2'd3           :     r_s_tdata_tmp    =     {  s_tdata , r_s_tdata_SHIFT[255:64]                            }      ;
            default        :     r_s_tdata_tmp    =     256'd0     ;              
        endcase
    end
    
   always @(posedge USER_CLK)
    begin
        if(((r_CNT2 == 2'd3) || s_tlast) & s_tvalid)
            r_STDATA_1   <= r_s_tdata_tmp;
        else
            r_STDATA_1   <= r_STDATA_1;
    end  
    

简单记录一下该方法,后面还要用到,还需要在好好理解一下,尤其是转换前后tready信号,还是不大懂。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
时序数据转换成二维特征图的代码示例,可以参考以下步骤: 1. 将时序数据转换成二维矩阵格式,例如将每个时间步的特征作为矩阵的一行或一列,或者将多个时间步的特征作为矩阵的若干通道。 2. 定义卷积层和池化层,可以使用TensorFlow、PyTorch等深度学习框架提供的API,例如: ```python import tensorflow as tf input_data = tf.placeholder(tf.float32, [None, n_steps, n_features]) conv1 = tf.layers.conv1d(input_data, filters=32, kernel_size=3, activation=tf.nn.relu, padding='same') pool1 = tf.layers.max_pooling1d(conv1, pool_size=2, strides=2, padding='same') conv2 = tf.layers.conv1d(pool1, filters=64, kernel_size=3, activation=tf.nn.relu, padding='same') pool2 = tf.layers.max_pooling1d(conv2, pool_size=2, strides=2, padding='same') ``` 3. 根据具体需求设置卷积层和池化层的参数,例如卷积核大小、卷积核个数、池化大小等。 4. 将二维特征图展开成一维向量,作为分类或回归模型的输入,例如: ```python flatten = tf.layers.flatten(pool2) logits = tf.layers.dense(flatten, n_classes) predictions = tf.nn.softmax(logits) ``` 5. 定义损失函数和优化器,进行模型训练和评估,例如: ```python loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=labels)) optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss) correct_prediction = tf.equal(tf.argmax(predictions, axis=1), tf.argmax(labels, axis=1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) ``` 以上是一个简单的代码示例,具体实现方式可以根据具体需求进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fighting_FPGA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值