FIFO的加头数据练习

一、在数据FIFO前加数据个数包文
此处是输入一个完整包文后才输出
如何在FIFO的前面加上表示其个数的包文,使用计数器计数,将其值存储到信息FIFO中。在发送的时候,先发送数据个数的包文,之后再发送数据FIFO,那么怎么选择发送的是数据还是计数的数据。
此时就需要有一个状态信号,标识是发送数据还是发送计数的数据。

//计数器
always @(posedge clk or negedge rst_n)begin
    if(rst_n==0)begin
        cnt <= 0;
    end
    else if(add_cnt)begin
       if(end_cnt)begin
           cnt <= 0;
       end
       else begin
           cnt <= cnt + 1'b1;
       end
    end
end
assign    add_cnt = din_vld ;
assign    end_cnt = add_cnt && din_eop;

//数据FIFO的写数据和写使能
assign    wr_en = din_vld;
assign    wdata = {din_sop,din_eop,din};

//信息FIFO的写数据和写使能
assign    msg_wr_en = end_cnt ;
assign    msg_wdata = cnt + 1 ;

//需要一个信号来选择到底是发送状态还是非发送状态
//flag == 1,表示发送的是数据
//flag == 0,表示发送的是长度
assign    flag_start = flag == 0 && msg_empty == 0; //发送的是长度
always  @(posedge clk or negedge rst_n)begin
   if(rst_n==0)begin
      flag <= 0;
   end
   else if(flag_start)begin
      flag <= 1;  
   end
   else if(flag == 1 && dout_eop_tmp)begin
      flag <= 0;
   end
end

assign   dout_eop_tmp = rd_en && q[8];

//数据FIFO的读使能
assign   rd_en = flag && msg_empty == 0 ;
//数据FIFO的读使能
assign   msg_rd_en = dout_eop_tmp ;//输出一个完整的包文后清空总线上的数据,总线上出现下一个长度数据等待被读

//dout

always  @(posedge clk or negedge rst_n)begin
   if(rst_n==0)begin
      dout <= 0;
   end
   else if(flag_start)begin
      dout <= msg_q[7:0];
   end
   else begin
      dout <= q[7:0];  
   end
end
//dout_sop
always @(posedge clk or negedge rst_n)begin
    if(rst_n==0)begin
       dout_sop <= 0;
    end
    else begin
       dout_sop <= flag_start; //注意,此刻的SOP信号是第一个输出,即在数据长度位需要打上SOP
    end
end

//dout_eop
always @(posedge clk or negedge rst_n)begin
    if(rst_n==0)begin
       dout_eop <= 0;
    end
    else begin
       dout_eop <= rd_en && q[8];
    end
end


//dout_vld
always @(posedge clk or negedge rst_n)begin
    if(rst_n==0)begin
       dout_vld <= 0;
    end
    else begin
       dout_vld <= rd_en || flag_start;
    end
end

二、加上数据长度和校验和
发送顺序 : 数据长度,校验和,数据。
首先,数据长度和【一】中的实现方法一样,在此不再重复。而校验和需要设计,校验和的校验规则如下:

  1. 数据依次相加,将得到的值记为a;
  2. 若两数相加产生进位,则将a的进位加到a的低16位得到和b;
  3. 将b重复上述步骤,直到算出最后的结果
  4. 对结果取取反便是最终的校验和
//需要注意的问题
//1. SOP时的值要清0,即赋值给它最初的和
//2. 第17位和第15位有没有相加
//3.写入信息FIFO的有没有相加
always @ (*)begin
   if(din_vld)begin
      if(din_sop)begin
        sum_tmp_a = din;
      end
      else begin
        sum_tmp_a = sum + din; 
      end
   end
   else begin
       sum_tmp_a = sum;
   end
end

assign   sum_tmp_b = sum_tmp_a[16] + sum_tmp_a[15:0];
always @(posedge clk or negedge rst_n)begin
    if(rst_n==0)begin
       sum <= 0;
    end
    else begin
       sum <= sum_tmp_b;
    end
end

//写数据与写使能与【一】相同,此处不相同

//信息FIFO的写使能和写数据
assign    msg_wr_en = end_cnt ;
assign    msg_wdata = {cnt , ~sum_tmp_c};


指示信号也与【一】中差不多

//flag == 1,表示发送数据,flag==0 表示发送的是长度和校验和
always @(posedge clk or negedge rst_n)begin
    if(rst_n==0)begin
        flag <= 0;
    end
    else if(end_cnt1)begin
        flag <= 1;
    end
    else if(flag==1 && dout_eop_tmp)begin
        flag <= 0;
    end
end
assign   dout_eop_tmp = rd_en && q[16];

always @(posedge clk or negedge rst_n)begin
    if(rst_n==0)begin
       cnt1 <= 0;
    end
    else if(add_cnt1)begin
       if(end_cnt1)begin
          cnt1 <= 0;
       end
       else 
         cnt1 <= cnt1 + 1'b1;
    end
end
assign   add_cnt1 = msg_empty == 0 && empty == 0 && flag == 0;
assign   end_cnt1 = add_cnt1 && cnt1 == 2 - 1;

//数据FIFO读使能
assign   rd_en = flag && empty == 0;
//信息FIFO读使能
assign   msg_rd_en = dout_eop_tmp;

输出数据和指示信号等

//dout
always @(posedge clk or negedge rst_n)begin
    if(rst_n==0)begin
         dout <= 0;
    end
    else if(add_cnt1)begin
        dout <= msg_q[31 - 16*cnt1 -:16];
    end
    else begin
        dout <= q[15:0];
    end
end

//dout_sop
//注意,该SOP信号应该出现在第一个发送的数上,即数据长度
always @(posedge clk or negedge rst_n)begin
     if(rst_n==0)begin
        dout_vld <= 0;
     end
     else begin
        dout_vld <= add_cnt1 && cnt1 == 1-1;
     end
end
//其他信号设计与上面基本一致
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值