自学内容网 自学内容网

数据分包:145字节版本

分包

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/08/04 14:35:21
// Design Name: 
// Module Name: dat_send_blocks_v
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module dat_send_blocks(
    clk      ,//系统时钟,110M
    rst      ,//系统复位,高有效
    din      ,//接收到的数据,第一个数据为总帧长[16],其余数据均为8比特数据
    din_clk_p,//接收到的数据时钟,脉冲型
    
    dout      ,//链路数据,8比特
    dout_clk_p //链路数据时钟,脉冲型
);
//
input clk        ;//系统时钟,110M
input rst        ;//系统复位,高有效
input [7:0] din ;//接收到的数据,第一个数据为总帧长[16],其余数据均为8比特数据
input din_clk_p  ;//接收到的数据时钟,脉冲型

output [7:0] dout;//链路数据,8比特
output dout_clk_p;//链路数据时钟,脉冲型

//===========================================================================
//       检测数据完成
//===========================================================================
wire [31:0] RST_TIME = 32'd10;//时间自己设定
reg [31:0] stop_cnts = 32'hffff_ffff;
always @ (posedge clk )
begin
    if(din_clk_p)
begin
stop_cnts<=32'd0;
end

else if(stop_cnts<=RST_TIME)
begin
stop_cnts<= stop_cnts + 1'b1;
end

else
begin
stop_cnts<= stop_cnts;
end
end

reg pulse_stop=1'b0;
always @ (posedge clk)
begin
if(stop_cnts==RST_TIME)
begin
pulse_stop<=  1'b1;
end

else
begin
pulse_stop<=  1'b0;
end
end

reg delay_pulse_stop;
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    delay_pulse_stop<=1'b0;
    end
    
    else
    begin
    delay_pulse_stop<=pulse_stop;
    end
end
//
reg din_rd_en                   ;
wire [7:0] din_dout             ;
wire din_full                   ;
wire din_empty                  ;
wire  [10 : 0] din_rd_data_count;
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
fifo_common_8_8_2048 FIFO (
  .clk(clk                     ),// input wire clk
  .srst(rst                    ),// input wire srst
  .din(din                     ),// input wire [7 : 0] din
  .wr_en(din_clk_p             ),// input wire wr_en
  .rd_en(din_rd_en             ),// input wire rd_en
  .dout(din_dout               ),// output wire [7 : 0] dout
  .full(din_full               ),// output wire full
  .empty(din_empty             ),// output wire empty
  .data_count(din_rd_data_count) // output wire [10 : 0] data_count
);

reg [15:0] cnts;// 包总数长度
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    cnts<=16'hffff;
    end
    
    else if(stop_cnts == (RST_TIME-1'b1))
    begin
    cnts<=din_rd_data_count;
    end
    
    else
    begin
    cnts<=cnts;
    end
end



reg [7:0] pack_cnts;// 包帧计数
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    pack_cnts<=8'd0;
    end
    
    else if((delay_pulse_stop==1'b1)&&(pulse_stop==1'b0))//posedge
    begin
    pack_cnts<=pack_cnts + 1'b1;
    end
    
    else
    begin
    pack_cnts<=pack_cnts;
    end
end

reg [3:0] num_cnts;
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    num_cnts<=4'h0;
    end
    
    else if((delay_pulse_stop==1'b0)&&(pulse_stop==1'b1))//negedge
    begin
    
        if(cnts<=16'd142)
        begin
        num_cnts<=4'd1;
        end
        
        else if(cnts<=16'd284)
        begin
        num_cnts<=4'd2;       
        end

        else if(cnts<=16'd426)
        begin
        num_cnts<=4'd3;       
        end

        else if(cnts<=16'd568)
        begin
        num_cnts<=4'd4;       
        end

        else if(cnts<=16'd710)
        begin
        num_cnts<=4'd5;       
        end

        else if(cnts<=16'd852)
        begin
        num_cnts<=4'd6;       
        end

        else if(cnts<=16'd994)
        begin
        num_cnts<=4'd7;       
        end
        
        else if(cnts<=16'd1136)
        begin
        num_cnts<=4'd8;       
        end
        
        else
        begin
        num_cnts<=num_cnts;
        end                              
    end
    
    else
    begin
    num_cnts<=num_cnts;
    end
end

reg [7:0] negedge_cnts;
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    negedge_cnts<=8'hff;
    end

    else if(negedge_cnts<=8'd10)//negedge
    begin
    negedge_cnts<=negedge_cnts + 1'b1;                          
    end
        
    else if((delay_pulse_stop==1'b0)&&(pulse_stop==1'b1))//negedge
    begin
    negedge_cnts<=8'd0;                          
    end
    
    else
    begin
    negedge_cnts<=negedge_cnts;
    end
end

reg [15:0] start_cnts;
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    start_cnts<=16'hffff;
    end

    else if(start_cnts<=16'd2047)//negedge
    begin
    start_cnts<= start_cnts + 1'b1;            
    end
    
    else if(negedge_cnts==8'd7)//negedge
    begin
    start_cnts<=16'd0;            
    end
            
    else
    begin
    start_cnts<=start_cnts;
    end
end

reg [15:0] pack_num;
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    pack_num<=16'd0;
    end

    else if((delay_pulse_stop==1'b0)&&(pulse_stop==1'b1))//negedge
    begin
    pack_num<=cnts;
    end
        
    else if((pack_num>=16'd1)&&
     ( ((start_cnts>={8'd0,8'd10})&&(start_cnts<={8'd0,8'd151}))//1
    || ((start_cnts>={8'd1,8'd10})&&(start_cnts<={8'd1,8'd151}))//2
    || ((start_cnts>={8'd2,8'd10})&&(start_cnts<={8'd2,8'd151}))//3
    || ((start_cnts>={8'd3,8'd10})&&(start_cnts<={8'd3,8'd151}))//4
    || ((start_cnts>={8'd4,8'd10})&&(start_cnts<={8'd4,8'd151}))//5
    || ((start_cnts>={8'd5,8'd10})&&(start_cnts<={8'd5,8'd151}))//6
    || ((start_cnts>={8'd6,8'd10})&&(start_cnts<={8'd6,8'd151}))//7
    || ((start_cnts>={8'd7,8'd10})&&(start_cnts<={8'd7,8'd151})))//1 
    )//posedge
    begin
    pack_num<=pack_num - 1'b1;
    end
    
    else
    begin
    pack_num<=pack_num;
    end
end


reg [7:0] pack_num_new;
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    pack_num_new<=8'd0;
    end
    
    else if(pack_num>=16'd142)//posedge
    begin
    pack_num_new<=8'd142;
    end
    
    else
    begin
    pack_num_new<=pack_num[7:0] ;
    end
end

reg [7:0] dout;
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    dout<=8'd0;
    end
            
    else
    begin
    case(start_cnts)
    {8'd0,8'd1}:begin dout<=pack_cnts      ;end
    {8'd0,8'd2}:begin dout<={4'd1,num_cnts};end
    {8'd0,8'd3}:begin dout<=pack_num_new   ;end  
    
    {8'd1,8'd1}:begin dout<=pack_cnts      ;end
    {8'd1,8'd2}:begin dout<={4'd2,num_cnts};end
    {8'd1,8'd3}:begin dout<=pack_num_new   ;end  
    
    {8'd2,8'd1}:begin dout<=pack_cnts      ;end
    {8'd2,8'd2}:begin dout<={4'd3,num_cnts};end
    {8'd2,8'd3}:begin dout<=pack_num_new   ;end      
    
    {8'd3,8'd1}:begin dout<=pack_cnts      ;end
    {8'd3,8'd2}:begin dout<={4'd4,num_cnts};end
    {8'd3,8'd3}:begin dout<=pack_num_new   ;end     
    
    {8'd4,8'd1}:begin dout<=pack_cnts      ;end
    {8'd4,8'd2}:begin dout<={4'd5,num_cnts};end
    {8'd4,8'd3}:begin dout<=pack_num_new   ;end  
 
    {8'd5,8'd1}:begin dout<=pack_cnts      ;end
    {8'd5,8'd2}:begin dout<={4'd6,num_cnts};end
    {8'd5,8'd3}:begin dout<=pack_num_new   ;end   
 
    {8'd6,8'd1}:begin dout<=pack_cnts      ;end
    {8'd6,8'd2}:begin dout<={4'd7,num_cnts};end
    {8'd6,8'd3}:begin dout<=pack_num_new   ;end   
    
    {8'd7,8'd1}:begin dout<=pack_cnts      ;end
    {8'd7,8'd2}:begin dout<={4'd8,num_cnts};end
    {8'd7,8'd3}:begin dout<=pack_num_new   ;end 
      
     default:begin dout<=din_dout          ;end      
     endcase
    end
end


reg [15:0] pack_num_rd;
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    pack_num_rd<=16'd0;
    end

    else if((delay_pulse_stop==1'b0)&&(pulse_stop==1'b1))//negedge
    begin
    pack_num_rd <= cnts  + 1'b1 ;
    end
        
    else if((pack_num_rd>=16'd1)&&
     ( ((start_cnts>={8'd0,8'd1})&&(start_cnts<={8'd0,8'd142}))//1
    || ((start_cnts>={8'd1,8'd1})&&(start_cnts<={8'd1,8'd142}))//2
    || ((start_cnts>={8'd2,8'd1})&&(start_cnts<={8'd2,8'd142}))//3
    || ((start_cnts>={8'd3,8'd1})&&(start_cnts<={8'd3,8'd142}))//4
    || ((start_cnts>={8'd4,8'd1})&&(start_cnts<={8'd4,8'd142}))//5
    || ((start_cnts>={8'd5,8'd1})&&(start_cnts<={8'd5,8'd142}))//6
    || ((start_cnts>={8'd6,8'd1})&&(start_cnts<={8'd6,8'd142}))//6
    || ((start_cnts>={8'd7,8'd1})&&(start_cnts<={8'd7,8'd142})))//7 
    )//posedge
    begin
    pack_num_rd<=pack_num_rd - 1'b1;
    end
    
    else
    begin
    pack_num_rd<=pack_num_rd;
    end
end


always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    din_rd_en<=1'b0;
    end
        
    else if((pack_num_rd>=16'd1)&&
     ( ((start_cnts>={8'd0,8'd2})&&(start_cnts<={8'd0,8'd143}))//1
    || ((start_cnts>={8'd1,8'd2})&&(start_cnts<={8'd1,8'd143}))//2
    || ((start_cnts>={8'd2,8'd2})&&(start_cnts<={8'd2,8'd143}))//3
    || ((start_cnts>={8'd3,8'd2})&&(start_cnts<={8'd3,8'd143}))//4
    || ((start_cnts>={8'd4,8'd2})&&(start_cnts<={8'd4,8'd143}))//5
    || ((start_cnts>={8'd5,8'd2})&&(start_cnts<={8'd5,8'd143}))//6
    || ((start_cnts>={8'd6,8'd2})&&(start_cnts<={8'd6,8'd143}))//7
    || ((start_cnts>={8'd7,8'd2})&&(start_cnts<={8'd7,8'd143})))//1 
    )//posedge
    begin
    din_rd_en<=1'b1;
    end
    
    else
    begin
    din_rd_en<=1'b0;
    end
end

reg dout_clk_p;
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    dout_clk_p<=1'b0;
    end
        
    else if((num_cnts==4'd1)&&
     ( 
     ((start_cnts>={8'd0,8'd1})&&(start_cnts<={8'd0,8'd145}))//1
     )
    )//posedge
    begin
    dout_clk_p<=1'b1;
    end

    else if((num_cnts==4'd2)&&
     ( 
       ((start_cnts>={8'd0,8'd1})&&(start_cnts<={8'd0,8'd145}))//1
    || ((start_cnts>={8'd1,8'd1})&&(start_cnts<={8'd1,8'd145}))//2     
     )
    )//posedge
    begin
    dout_clk_p<=1'b1;
    end

    else if((num_cnts==4'd3)&&
     ( 
       ((start_cnts>={8'd0,8'd1})&&(start_cnts<={8'd0,8'd145}))//1
    || ((start_cnts>={8'd1,8'd1})&&(start_cnts<={8'd1,8'd145}))//2   
    || ((start_cnts>={8'd2,8'd1})&&(start_cnts<={8'd2,8'd145}))//3         
     )
    )//posedge
    begin
    dout_clk_p<=1'b1;
    end

    else if((num_cnts==4'd4)&&
     ( 
       ((start_cnts>={8'd0,8'd1})&&(start_cnts<={8'd0,8'd145}))//1
    || ((start_cnts>={8'd1,8'd1})&&(start_cnts<={8'd1,8'd145}))//2   
    || ((start_cnts>={8'd2,8'd1})&&(start_cnts<={8'd2,8'd145}))//3 
    || ((start_cnts>={8'd3,8'd1})&&(start_cnts<={8'd3,8'd145}))//4             
     )
    )//posedge
    begin
    dout_clk_p<=1'b1;
    end

    else if((num_cnts==4'd5)&&
     ( 
       ((start_cnts>={8'd0,8'd1})&&(start_cnts<={8'd0,8'd145}))//1
    || ((start_cnts>={8'd1,8'd1})&&(start_cnts<={8'd1,8'd145}))//2   
    || ((start_cnts>={8'd2,8'd1})&&(start_cnts<={8'd2,8'd145}))//3 
    || ((start_cnts>={8'd3,8'd1})&&(start_cnts<={8'd3,8'd145}))//4             
    || ((start_cnts>={8'd4,8'd1})&&(start_cnts<={8'd4,8'd145}))//5                 
     )
    )//posedge
    begin
    dout_clk_p<=1'b1;
    end   

    else if((num_cnts==4'd6)&&
     ( 
       ((start_cnts>={8'd0,8'd1})&&(start_cnts<={8'd0,8'd145}))//1
    || ((start_cnts>={8'd1,8'd1})&&(start_cnts<={8'd1,8'd145}))//2   
    || ((start_cnts>={8'd2,8'd1})&&(start_cnts<={8'd2,8'd145}))//3 
    || ((start_cnts>={8'd3,8'd1})&&(start_cnts<={8'd3,8'd145}))//4             
    || ((start_cnts>={8'd4,8'd1})&&(start_cnts<={8'd4,8'd145}))//5   
    || ((start_cnts>={8'd5,8'd1})&&(start_cnts<={8'd5,8'd145}))//6                          
     )
    )//posedge
    begin
    dout_clk_p<=1'b1;
    end   
    
    else if((num_cnts==4'd7)&&
     ( 
       ((start_cnts>={8'd0,8'd1})&&(start_cnts<={8'd0,8'd145}))//1
    || ((start_cnts>={8'd1,8'd1})&&(start_cnts<={8'd1,8'd145}))//2   
    || ((start_cnts>={8'd2,8'd1})&&(start_cnts<={8'd2,8'd145}))//3 
    || ((start_cnts>={8'd3,8'd1})&&(start_cnts<={8'd3,8'd145}))//4             
    || ((start_cnts>={8'd4,8'd1})&&(start_cnts<={8'd4,8'd145}))//5   
    || ((start_cnts>={8'd5,8'd1})&&(start_cnts<={8'd5,8'd145}))//6          
    || ((start_cnts>={8'd6,8'd1})&&(start_cnts<={8'd6,8'd145}))//7                              
     )
    )//posedge
    begin
    dout_clk_p<=1'b1;
    end
    
    else if((num_cnts==4'd8)&&
     ( 
       ((start_cnts>={8'd0,8'd1})&&(start_cnts<={8'd0,8'd145}))//1
    || ((start_cnts>={8'd1,8'd1})&&(start_cnts<={8'd1,8'd145}))//2   
    || ((start_cnts>={8'd2,8'd1})&&(start_cnts<={8'd2,8'd145}))//3 
    || ((start_cnts>={8'd3,8'd1})&&(start_cnts<={8'd3,8'd145}))//4             
    || ((start_cnts>={8'd4,8'd1})&&(start_cnts<={8'd4,8'd145}))//5   
    || ((start_cnts>={8'd5,8'd1})&&(start_cnts<={8'd5,8'd145}))//6          
    || ((start_cnts>={8'd6,8'd1})&&(start_cnts<={8'd6,8'd145}))//7        
    || ((start_cnts>={8'd7,8'd1})&&(start_cnts<={8'd7,8'd145}))//7                      
     )
    )//posedge
    begin
    dout_clk_p<=1'b1;
    end 
                       
    else
    begin
    dout_clk_p<=1'b0;
    end
end

endmodule

拆包

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// Create Date: 2022/02/09 18:26:01
// Design Name: 
// Module Name: dat_recv_blocks
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// Dependencies: 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 接收两种帧格式,并完成组帧
//
module dat_recv_blocks(
    clk               ,//系统时钟,110M
    rst               ,//系统复位,高有效
    din               ,//接收到的数据,第一个数据为总帧长[8],其余数据均为8比特数据
    din_clk_p         ,//接收到的数据时钟,脉冲型
    
    dout              ,//链路数据,16比特
    dout_clk_p         //链路数据时钟,脉冲型
);
//
input clk         ;//系统时钟,110M
input rst         ;//系统复位,高有效
input [7:0] din   ;//接收到的数据,第一个数据为总帧长[16],其余数据均为8比特数据
input din_clk_p   ;//接收到的数据时钟,脉冲型

output [15:0] dout;//链路数据,16比特
output dout_clk_p ;//链路数据时钟,脉冲型
//
reg delay_din_clk_p;
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    delay_din_clk_p<=1'b0;
    end
    
    else
    begin
    delay_din_clk_p<=din_clk_p;
    end
end
//
reg select_0_1    ;
always @ (posedge clk or posedge rst)//提取帧计数,将前后两包区分开,避免两帧不是同一包的情况
begin
    if(rst)
    begin
    select_0_1<=1'b0;
    end
    
    else if((din_clk_p==1'b1)&&(delay_din_clk_p==1'b0))//posedge
    begin
    select_0_1<=din[0];
    end
    
    else
    begin
    select_0_1<=select_0_1;
    end
end
//
reg pack_check_pulse;// 检测到一包数据
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    pack_check_pulse<=1'b0;
    end
    
    else if((din_clk_p==1'b1)&&(delay_din_clk_p==1'b0))//posedge
    begin
    pack_check_pulse<=1'b1;
    end
    
    else
    begin
    pack_check_pulse<=1'b0;
    end
end
//
reg [15:0] min_length; // 求出这包数据的最短长度,用于最终判决是否丢数据
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    min_length<=16'd0;
    end 
    
    else if(pack_check_pulse==1'b1)//pulse
    begin
    case(din[3:0])
    4'd1: begin min_length<=16'd0;    end
    4'd2: begin min_length<=16'd142;  end
    4'd3: begin min_length<=16'd284;  end
    4'd4: begin min_length<=16'd426;  end
    4'd5: begin min_length<=16'd568;  end
    4'd6: begin min_length<=16'd710;  end
    4'd7: begin min_length<=16'd852;  end
    4'd8: begin min_length<=16'd994;  end
    4'd9: begin min_length<=16'd1136; end
    default: begin min_length<=16'd0; end
    endcase
    end
    
    else
    begin
    min_length<=min_length;//hold
    end
end
//
reg pack_check;//接收到的包指示是否正确判决
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    pack_check<=1'b0;
    end 
    
    else if(pack_check_pulse==1'b1)//pulse
    begin
        if((din[7:4]<=din[3:0])&&(din[7:4]>=4'd1)&&(din[7:4]<=4'd8))//区间正确
        begin
        pack_check<=1'b1;
        end
        
        else
        begin
        pack_check<=1'b0;//区间错误,检查存在异常
        end
    end
    
    else
    begin
    pack_check<=pack_check;//hold
    end
end
//
reg pack_end; // 检测最后一包
always @ (posedge clk or posedge rst)//接收到的包指示是否正确判决
begin
    if(rst)
    begin
    pack_end<=1'b0;
    end 
    
    else if(pack_check_pulse==1'b1)//pulse
    begin
        if((din[7:4]==din[3:0])&&(din[7:4]>=4'd1)&&(din[7:4]<=4'd8))//区间正确
        begin
        pack_end<=1'b1;
        end
        
        else
        begin
        pack_end<=1'b0;//区间错误,检查存在异常
        end
    end
    
    else
    begin
    pack_end<=pack_end;//hold
    end
end
//
reg length_check_pulse;// pack_check 延迟一拍
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    length_check_pulse<=1'b0;
    end
        
    else
    begin
    length_check_pulse<=pack_check_pulse;
    end
end
//
reg length_check;//包长度检测 
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    length_check<=1'b0;
    end
        
    else if(length_check_pulse)
    begin
       if((din<=8'd142)&&(din>=8'd1))//当前数据包长度也正确
       begin
       length_check<=1'b1;
       end
       
       else
       begin
       length_check<=1'b0;    //当前数据包长度错误
       end
    end
    
    else
    begin
    length_check<=length_check;//保持
    end
end
//
reg [7:0] local_length;//从每一包中提取长度
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    local_length<=8'd0;
    end
        
    else if(length_check_pulse)
    begin
    local_length<=din;
    end
    
    else
    begin
    local_length<=local_length;//保持
    end
end
//
reg wr_pulse;//    pack_check 延迟二拍
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    wr_pulse<=1'b0;
    end
        
    else
    begin
    wr_pulse<=length_check_pulse;
    end
end
//
reg [15:0] local_cnts; // 检测通过的情况下,根据 wr_pulse 开始计数
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    local_cnts<=16'hffff;
    end

    else if(local_cnts<=16'd150)
    begin
    local_cnts<=local_cnts + 1'b1;
    end
        
    else if((wr_pulse==1'b1)&&(length_check==1'b1)&&(pack_check==1'b1))
    begin
    local_cnts<=16'd0;
    end
    
    else
    begin
    local_cnts<=local_cnts;    
    end     
end
//
reg wea_0         ;
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    wea_0<=1'b0;
    end

    else if((select_0_1==1'b0)&&(local_cnts<=16'd142)&&(local_cnts<=local_length)&&(local_cnts>=16'd1))
    begin
    wea_0<=1'b1;
    end
        
    else
    begin
    wea_0<=1'b0;
    end     
end
//
reg wea_1         ; // 写入 ramenable 信号
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    wea_1<=1'b0;
    end

    else if((select_0_1==1'b1)&&(local_cnts<=16'd142)&&(local_cnts<=local_length)&&(local_cnts>=16'd1))
    begin
    wea_1<=1'b1;
    end
        
    else
    begin
    wea_1<=1'b0;
    end     
end
//
reg [15:0] addra_0;
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    addra_0<=16'd0;
    end

    else if((select_0_1==1'b0)&&(local_cnts==16'd150)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
    addra_0<=16'd0;
    end
    
    else if((select_0_1==1'b0)&&(local_cnts<=16'd143)&&(local_cnts<=(local_length + 1'b1))&&(local_cnts>=16'd2))
    begin
    addra_0<=addra_0 + 1'b1;
    end
        
    else
    begin
    addra_0<=addra_0;
    end     
end
//
reg [15:0] addra_1; // 写入 ram 的 地址
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    addra_1<=16'd0;
    end

    else if((select_0_1==1'b1)&&(local_cnts==16'd150)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
    addra_1<=16'd0;
    end
    
    else if((select_0_1==1'b1)&&(local_cnts<=16'd143)&&(local_cnts<=(local_length +1'b1 ))&&(local_cnts>=16'd2))
    begin
    addra_1<=addra_1 + 1'b1;
    end
        
    else
    begin
    addra_1<=addra_1;
    end     
end
//
reg [7:0] delay_dina_0  ; // 延迟 din 
reg [7:0] delay_dina_1  ; // 延迟 din 
reg [7:0] delay_dina_2  ; // 延迟 din 
//
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    delay_dina_0<=8'd0;
    end
 
    else
    begin
    delay_dina_0<=din;
    end     
end
//
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    delay_dina_1<=8'd0;
    end
 
    else
    begin
    delay_dina_1<=delay_dina_0;
    end     
end
//
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    delay_dina_2<=8'd0;
    end
 
    else
    begin
    delay_dina_2<=delay_dina_1;
    end     
end
//RD STATE
reg [15:0] all_dat_num_0;
reg [15:0] all_dat_num_1; // 写入的总数
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    all_dat_num_0<=16'd2047;
    end

    else if((select_0_1==1'b0)&&(local_cnts==16'd146)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
    all_dat_num_0<=addra_0;
    end
            
    else
    begin
    all_dat_num_0<=all_dat_num_0;
    end     
end

always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    all_dat_num_1<=16'd2047;
    end

    else if((select_0_1==1'b1)&&(local_cnts==16'd146)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
    all_dat_num_1<=addra_1;
    end
            
    else
    begin
    all_dat_num_1<=all_dat_num_1;
    end     
end
//
reg output_flag; // 检测数据包的长度是否大于最小的长度,符合则输出,不符合则丢弃这包数据
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    output_flag<=1'b1;
    end

    else if((select_0_1==1'b0)&&(local_cnts==16'd146)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
        if(addra_0 >= min_length)
        begin
        output_flag<=1'b1;
        end
        
        else
        begin
        output_flag<=1'b0;
        end
    end
    
    else if((select_0_1==1'b1)&&(local_cnts==16'd146)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
        if(addra_1 >= min_length)
        begin
        output_flag<=1'b1;
        end
        
        else
        begin
        output_flag<=1'b0;
        end
    end
            
    else
    begin
    output_flag<=output_flag;
    end     
end

//
reg [15:0] rd_cnts; // 计数器  开始往外 写数据
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    rd_cnts<=16'hffff;
    end

    else if(rd_cnts<=16'd1600)//写完包的最后一个。清零,不影响下一帧的写入
    begin
    rd_cnts<=rd_cnts + 1'b1;
    end
    
    else if((local_cnts==16'd150)&&(pack_end==1'b1)&&(output_flag==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
    rd_cnts<=16'd0;
    end
        
    else
    begin
    rd_cnts<=rd_cnts;
    end     
end
//
reg [15:0] addrb_0;
reg [15:0] addrb_1;
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    addrb_0<=16'd0;
    end

    else if(rd_cnts==16'd1599)
    begin
    addrb_0<=16'd0;
    end
        
    else if((select_0_1==1'b0)&&(rd_cnts<=16'd1539)&&(rd_cnts<=all_dat_num_0)&&(rd_cnts>=16'd0))
    begin
    addrb_0<=addrb_0 + 1'b1;
    end
        
    else
    begin
    addrb_0<=addrb_0;
    end     
end
//
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    addrb_1<=16'd0;
    end

    else if(rd_cnts==16'd1599)
    begin
    addrb_1<=16'd0;
    end
        
    else if((select_0_1==1'b1)&&(rd_cnts<=16'd1539)&&(rd_cnts<=all_dat_num_1)&&(rd_cnts>=16'd0))
    begin
    addrb_1<=addrb_1 + 1'b1;
    end
        
    else
    begin
    addrb_1<=addrb_1;
    end     
end

reg dout_clk_p; // 原文有 bug
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    dout_clk_p<=1'b0;
    end
    
    else if((rd_cnts>=16'd2)&&(rd_cnts<=16'd1541))   
    begin
        if(( select_0_1==1'b1 )&&( rd_cnts <= ( all_dat_num_1 + 1 )))
        begin
        dout_clk_p<=1'b1;        
        end
        
        else if((select_0_1==1'b0 )&&( rd_cnts <= ( all_dat_num_0 + 1 )))
        begin
        dout_clk_p<=1'b1;      
        end
        
        else
        begin
        dout_clk_p<=1'b0;  
        end
    end
            
    else
    begin
    dout_clk_p<=dout_clk_p;
    end     
end

//
wire [7:0] doutb_0;
wire [7:0] doutb_1;
reg [15:0] dout;
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    dout<=16'd0;
    end
    
    else if(rd_cnts==16'd1)   
    begin
        if(select_0_1==1'b1)
        begin
        dout<=all_dat_num_1 ;        
        end
        
        else 
        begin
        dout<=all_dat_num_0 ;         
        end
    end
            
    else
    begin
        if(select_0_1==1'b1)
        begin
        dout<={dout[15:8],doutb_1};        
        end
        
        else 
        begin
        dout<={dout[15:8],doutb_0};                
        end    
    end     
end

wire [7 : 0] atblk_douta,atblk_doutb;
blk_mem_8_2048 BLKS_A_0 (
  .clka(clk                       ),// input wire clka
  .ena(1'b1                       ),// input wire ena
  .wea(wea_0                      ),// input wire [0 : 0] wea
  .addra(addra_0                  ),// input wire [10 : 0] addra
  .dina(delay_dina_2              ),// input wire [7 : 0] dina
  .douta(atblk_douta              ),// output wire [7 : 0] douta 不用
  
  .clkb(clk                       ),// input wire clkb
  .web(1'b0                       ),// input wire [0 : 0] web
  .addrb(addrb_0                  ),// input wire [10 : 0] addrb
  .dinb(8'd0                      ),// input wire [7 : 0] dinb   不用
  .doutb(doutb_0                  )  // output wire [7 : 0] doutb
);

//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
blk_mem_8_2048 BLKS_A_1 (
  .clka(clk                       ),// input wire clka
  .ena(1'b1                       ),// input wire ena
  .wea(wea_1                      ),// input wire [0 : 0] wea
  .addra(addra_1                  ),// input wire [10 : 0] addra
  .dina(delay_dina_2              ),// input wire [7 : 0] dina
  .douta(atblk_doutb              ),// output wire [7 : 0] douta 不用
  
  .clkb(clk                       ),// input wire clkb
  .web(1'b0                       ),// input wire [0 : 0] web
  .addrb(addrb_1                  ),// input wire [10 : 0] addrb
  .dinb(8'd0                      ),// input wire [7 : 0] dinb   不用
  .doutb(doutb_1                  )  // output wire [7 : 0] doutb
);

endmodule


原文地址:https://blog.csdn.net/qq_36666115/article/details/140386972

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!