njithjw的个人空间 https://blog.eetop.cn/505866 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

将位宽不固定的数据拼接为固定位宽的数据

已有 982 次阅读| 2016-11-6 23:58 |个人分类:FPGA_Verilog|系统分类:芯片设计

module byte_combine
    (
    input                       rst_n,
    input                       clk,

    input                       sop,
    input                       eop,
    input                       data_valid,
    input           [3:0]       byte_valid,
    input           [63:0]      data_in,

    output  reg                 sop_out,
    output  reg                 eop_out,
    output  reg                 data_valid_out,
    output  reg     [3:0]       byte_valid_out,
    output  reg     [63:0]      data_out,

    output  reg     [6:0]       dma_type_packet_cnt

    );


reg                 wr_en;
reg     [3:0]       mod_byte;
wire    [3:0]       total_byte;
reg     [63:0]      data_remain;
reg     [3:0]       byte_acc;
reg                 eop_dly;
reg                 data_valid_dly;
//----------------------------------------------------------------------------//
assign total_byte = sop? byte_valid: (mod_byte + byte_valid);

always @ (posedge clk or negedge rst_n)
begin
    if (rst_n == 1'b0)
        mod_byte <= 4'd0;
    else if (sop == 1'b1)
        mod_byte <= {1'b0,byte_valid[2:0]};
    else if (total_byte[3] == 1'b1)
        mod_byte <= {1'b0,total_byte[2:0]};
    else
        mod_byte <= total_byte;
end

always @ (*)
begin
    if ((eop == 1'b1) && (mod_byte + byte_valid < 4'd8))
        wr_en = 1'b1;
    else if (total_byte[3] && data_valid)
        wr_en = 1'b1;
    else
        wr_en = 1'b0;
end

always @ (posedge clk or negedge rst_n)
begin
    if (rst_n == 1'b0)
        data_remain <= 64'd0;
    else if (sop == 1'b1)
    begin
        if (byte_valid == 4'd8)
            data_remain <= 64'd0;
        else
            data_remain <= data_in >> {8 - byte_valid, 3'd0};
    end
    else if (wr_en == 1'b1)
        data_remain <= data_in >> {4'd8 - mod_byte, 3'd0};
    else
        data_remain <= data_remain | data_in << {mod_byte,3'd0};
end

always @ (posedge clk or negedge rst_n)
begin
    if (rst_n == 1'b0)
        data_out <= 64'd0;
    else if (sop == 1'b1)
    begin
        if (byte_valid == 4'd8)
            data_out <= data_in;
        else
            data_out <= 64'd0;
    end
    else if (eop_dly == 1'b1)
        data_out <= data_remain;
    else if (wr_en == 1'b1)
        data_out <= data_remain | data_in << {mod_byte,3'd0};
    else
        data_out <= 64'd0;
end
//----------------------------------------------------------------------------//
always @ (posedge clk or negedge rst_n)
begin
    if (rst_n == 1'b0)
        byte_acc <= 4'd0;
    else if (sop == 1'b1)
        byte_acc <= byte_valid;
    else if (byte_acc < 4'd8)
        byte_acc <= byte_acc + byte_valid ;
    else ;
end

always @ (posedge clk or negedge rst_n)
begin
    if (rst_n == 1'b0)
        sop_out <= 1'b0;
    else if ((sop == 1'b1) && (byte_valid == 4'd8))
        sop_out <= 1'b1;
    else if ((byte_acc < 4'd8) && (byte_acc + byte_valid >= 4'd8))
        sop_out <= 1'b1;
    else
        sop_out <= 1'b0;
end
//----------------------------------------------------------------------------//
always @ (posedge clk or negedge rst_n)
begin
    if (rst_n == 1'b0)
        eop_dly <= 1'b0;
    else
        eop_dly <= eop;
end

always @ (posedge clk or negedge rst_n)
begin
    if (rst_n == 1'b0)
        eop_out <= 1'b0;
    else if ((eop == 1'b1) && (byte_valid + mod_byte <= 4'd8))
        eop_out <= 1'b1;
    else if ((eop_dly == 1'b1) && (eop_out == 1'b0))
        eop_out <= 1'b1;
    else
        eop_out <= 1'b0;
end

always @ (posedge clk or negedge rst_n)
begin
    if (rst_n == 1'b0)
        data_valid_dly <= 1'b0;
    else
        data_valid_dly <= data_valid;
end

always @ (posedge clk or negedge rst_n)
begin
    if (rst_n == 1'b0)
        data_valid_out <= 1'b0;
    else if (data_valid_dly && eop_dly && (~eop_out))
        data_valid_out <= 1'b1;
    else
        data_valid_out <= wr_en;
end

always @ (posedge clk or negedge rst_n)
begin
    if (rst_n == 1'b0)
        byte_valid_out <= 4'd0;
    else if ((eop == 1'b1) && (total_byte < 4'd8))
        byte_valid_out <= total_byte;
    else if (wr_en == 1'b1)
        byte_valid_out <= 4'd8;
    else if (data_valid_dly && eop_dly && (~eop_out))
        byte_valid_out <= mod_byte;
    else
        byte_valid_out <= 4'd0;
end


//----------------------------------------------------------------------------//

always @ (posedge clk or negedge rst_n)
begin
    if (rst_n == 1'b0)
        dma_type_packet_cnt <= 7'd0;
    else if ((sop == 1'b1) && (byte_valid == 4'd8))
        dma_type_packet_cnt <= 7'd0;
    else if ((byte_acc < 4'd8) && (byte_acc + byte_valid >= 4'd8))
        dma_type_packet_cnt <= 7'd0;
    else if ((wr_en == 1'b1) || ((eop == 1'b1) && (total_byte < 4'd8)) || (data_valid_dly && eop_dly && (~eop_out)))
        dma_type_packet_cnt <= dma_type_packet_cnt + 7'd1;
    else ;
end
//----------------------------------------------------------------------------//

endmodule


点赞

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 2

    粉丝
  • 0

    好友
  • 0

    获赞
  • 17

    评论
  • 3512

    访问数
关闭

站长推荐 上一条 /2 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-25 06:49 , Processed in 0.017098 second(s), 8 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部