【Verilog】将分包的数据包进行 合并

合起来 dat_recv_blocks

c 复制代码
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// Create Date:  
// 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比特
    real_clk_p        ,//接收到有效数据时钟,脉冲型
    dout_clk_p        , //链路数据时钟,脉冲型
    
    LENGTH_REAL    ,
    LENGTH_THIMBLE ,
    LENGTH_DIV4    ,
    thimble_valid  
);
//
input clk         ;//系统时钟,110M
input rst         ;//系统复位,高有效
input [7:0] din   ;//接收到的数据,第一个数据为总帧长[16],其余数据均为8比特数据
input din_clk_p   ;//接收到的数据时钟,脉冲型

output [15:0] dout;//链路数据,16比特
output real_clk_p ;//接收到有效数据时钟,脉冲型
output dout_clk_p ;//链路数据时钟,脉冲型

//  给传输上位机网口模块的
output [15:0] LENGTH_REAL    ; 
output [23:0] LENGTH_THIMBLE ; 
output [15:0] LENGTH_DIV4    ; 
output thimble_valid         ;
//
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 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'd7))//区间正确
        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'd7))//区间正确
        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'd220)&&(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'd230)
    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'd220)&&(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         ; // 写入 ram 的 enable 信号
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'd220)&&(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'd228)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
    addra_0<=16'd0;
    end
    
    else if((select_0_1==1'b0)&&(local_cnts<=16'd221)&&(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'd228)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
    addra_1<=16'd0;
    end
    
    else if((select_0_1==1'b1)&&(local_cnts<=16'd221)&&(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'd224)&&(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'd224)&&(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 [15:0] LENGTH_REAL    ;//数据的总长度
reg [23:0] LENGTH_THIMBLE ;//顶针的数据长度
reg [15:0] LENGTH_DIV4    ;//网络的最低传输长度
reg thimble_valid         ;//是否需要顶针

always @ (posedge clk or posedge rst) //  LENGTH_REAL   数据的总长度
begin
    if(rst)
    begin
    LENGTH_REAL<=16'd2047;
    end
    
    else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
    LENGTH_REAL<=addra_0;
    end

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

always @ (posedge clk or posedge rst) // thimble_valid  是否需要顶针
begin
    if(rst)
    begin
    thimble_valid <= 1'd0; // 默认不顶针
    end
    
    else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
        if(addra_0[1:0] == 2'd0)
        begin
        thimble_valid <= 1'b0;
        end
        
        else
        begin
        thimble_valid <= 1'b1;
        end
    end

    else if((select_0_1==1'b1)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
        if(addra_1[1:0] == 2'd0)
        begin
        thimble_valid <= 1'b0;
        end
        
        else
        begin
        thimble_valid <= 1'b1;
        end
    end
            
    else
    begin
    thimble_valid <= thimble_valid;
    end     
end

always @ (posedge clk or posedge rst) // LENGTH_THIMBLE 顶针的数据长度
begin
    if(rst)
    begin
    LENGTH_THIMBLE <= 24'd0; 
    end
    
    else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
    case(addra_0[1:0])
    2'b00:begin LENGTH_THIMBLE <= 24'd0; end
    2'b01:begin LENGTH_THIMBLE <= 24'd3; end
    2'b10:begin LENGTH_THIMBLE <= 24'd2; end
    2'b11:begin LENGTH_THIMBLE <= 24'd1; end
    default:begin LENGTH_THIMBLE<=LENGTH_THIMBLE;  end
    endcase
    end

    else if((select_0_1==1'b1)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin // addra_1[1:0]
    case(addra_1[1:0])
    2'b00:begin LENGTH_THIMBLE <= 24'd0; end
    2'b01:begin LENGTH_THIMBLE <= 24'd3; end
    2'b10:begin LENGTH_THIMBLE <= 24'd2; end
    2'b11:begin LENGTH_THIMBLE <= 24'd1; end
    default:begin LENGTH_THIMBLE<=LENGTH_THIMBLE;  end
    endcase
    end
            
    else
    begin
    LENGTH_THIMBLE <= LENGTH_THIMBLE;
    end     
end

always @ (posedge clk or posedge rst) // LENGTH_DIV4 网络的最低传输长度
begin
    if(rst)
    begin
    LENGTH_DIV4 <= 16'd0; // 默认不顶针
    end
    
    else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
        if(addra_0[1:0] == 2'd0) // 不顶针
        begin
        LENGTH_DIV4 <= {addra_0[15],addra_0[15],addra_0[15:2]};
        end
        
        else
        begin
        LENGTH_DIV4 <= {addra_0[15],addra_0[15],addra_0[15:2]} + 1'b1;
        end
    end

    else if((select_0_1==1'b1)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
        if(addra_1[1:0] == 2'd0)
        begin
        LENGTH_DIV4 <= {addra_1[15],addra_1[15],addra_1[15:2]};
        end
        
        else
        begin
        LENGTH_DIV4 <= {addra_1[15],addra_1[15],addra_1[15:2]} + 1'b1;
        end
    end
            
    else
    begin
    LENGTH_DIV4 <= LENGTH_DIV4;
    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'd228)&&(pack_end==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 real_clk_p; // 原文有bug
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    real_clk_p<=1'b0;
    end
        
    else if(((select_0_1==1'b1)&&(rd_cnts<=16'd1540)&&(rd_cnts<=(all_dat_num_1+1))&&(rd_cnts>=16'd2))||((select_0_1==1'b0)&&(rd_cnts<=16'd1540)&&(rd_cnts<=(all_dat_num_0+1))&&(rd_cnts>=16'd2)))
    begin
    real_clk_p<=1'b1;
    end
        
    else
    begin
    real_clk_p<=1'b0;
    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'd1)&&(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
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
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(                         ),// 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(                          ),// 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(                         ),// 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(                          ),// input wire [7 : 0] dinb   不用
  .doutb(doutb_1                  )  // output wire [7 : 0] doutb
);
//

//ila_data_recv ila_data_recv (
//	.clk(clk), // input wire clk


//	.probe0(din), // input wire [7:0]  probe0  
//	.probe1(din_clk_p), // input wire [0:0]  probe1 
//	.probe2(delay_din_clk_p), // input wire [0:0]  probe2 
//	.probe3(select_0_1), // input wire [0:0]  probe3 
//	.probe4(pack_check_pulse), // input wire [0:0]  probe4 
//	.probe5(pack_check), // input wire [0:0]  probe5 
//	.probe6(pack_end), // input wire [0:0]  probe6 
//	.probe7(length_check_pulse), // input wire [0:0]  probe7 
//	.probe8(length_check), // input wire [0:0]  probe8 
//	.probe9(local_length), // input wire [7:0]  probe9 
//	.probe10(wr_pulse), // input wire [0:0]  probe10 
//	.probe11(local_cnts), // input wire [15:0]  probe11 
//	.probe12(wea_0), // input wire [0:0]  probe12 
//	.probe13(wea_1), // input wire [0:0]  probe13 
//	.probe14(addra_0), // input wire [15:0]  probe14 
//	.probe15(addra_1), // input wire [15:0]  probe15 
//	.probe16(delay_dina_0), // input wire [7:0]  probe16 
//	.probe17(delay_dina_1), // input wire [7:0]  probe17 
//	.probe18(delay_dina_2), // input wire [7:0]  probe18 
//	.probe19(all_dat_num_0), // input wire [15:0]  probe19 
//	.probe20(all_dat_num_1), // input wire [15:0]  probe20 
//	.probe21(rd_cnts), // input wire [15:0]  probe21 
//	.probe22(addrb_0), // input wire [15:0]  probe22 
//	.probe23(addrb_1), // input wire [15:0]  probe23 
//	.probe24(real_clk_p), // input wire [0:0]  probe24 
//	.probe25(dout_clk_p), // input wire [0:0]  probe25 
//	.probe26(doutb_0), // input wire [7:0]  probe26 
//	.probe27(doutb_1), // input wire [7:0]  probe27 
//	.probe28(dout), // input wire [15:0]  probe28 
//	.probe29(LENGTH_REAL), // input wire [15:0]  probe29 
//	.probe30(LENGTH_THIMBLE), // input wire [23:0]  probe30 
//	.probe31(LENGTH_DIV4), // input wire [15:0]  probe31 
//	.probe32(thimble_valid) // input wire [0:0]  probe32
//);

endmodule

升级版本: 丢失一小包 整包全部丢弃

c 复制代码
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/08/09 19:24:42
// Design Name: 
// Module Name: dat_recv_block_complete
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


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

output [15:0] dout;//链路数据,16比特
output real_clk_p ;//接收到有效数据时钟,脉冲型
output dout_clk_p ;//链路数据时钟,脉冲型

//  给传输上位机网口模块的
output [15:0] LENGTH_REAL    ;//发送625字节
output [23:0] LENGTH_THIMBLE ;//发送625字节
output [15:0] LENGTH_DIV4    ;//发送625字节
output thimble_valid         ;
//
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'd220;  end
    4'd3: begin min_length<=16'd440;  end
    4'd4: begin min_length<=16'd660;  end
    4'd5: begin min_length<=16'd880;  end
    4'd6: begin min_length<=16'd1100; end
    4'd7: begin min_length<=16'd1320; 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'd7))//区间正确
        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'd7))//区间正确
        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'd220)&&(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'd230)
    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'd220)&&(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         ; // 写入 ram 的 enable 信号
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'd220)&&(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'd228)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
    addra_0<=16'd0;
    end
    
    else if((select_0_1==1'b0)&&(local_cnts<=16'd221)&&(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'd228)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
    addra_1<=16'd0;
    end
    
    else if((select_0_1==1'b1)&&(local_cnts<=16'd221)&&(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'd224)&&(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'd224)&&(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'd224)&&(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'd224)&&(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] LENGTH_REAL    ;//数据的总长度
reg [23:0] LENGTH_THIMBLE ;//顶针的数据长度
reg [15:0] LENGTH_DIV4    ;//网络的最低传输长度
reg thimble_valid         ;//是否需要顶针

always @ (posedge clk or posedge rst) //  LENGTH_REAL   数据的总长度
begin
    if(rst)
    begin
    LENGTH_REAL<=16'd2047;
    end
    
    else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
    LENGTH_REAL<=addra_0;
    end

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

always @ (posedge clk or posedge rst) // thimble_valid  是否需要顶针
begin
    if(rst)
    begin
    thimble_valid <= 1'd0; // 默认不顶针
    end
    
    else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
        if(addra_0[1:0] == 2'd0)
        begin
        thimble_valid <= 1'b0;
        end
        
        else
        begin
        thimble_valid <= 1'b1;
        end
    end

    else if((select_0_1==1'b1)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
        if(addra_1[1:0] == 2'd0)
        begin
        thimble_valid <= 1'b0;
        end
        
        else
        begin
        thimble_valid <= 1'b1;
        end
    end
            
    else
    begin
    thimble_valid <= thimble_valid;
    end     
end

always @ (posedge clk or posedge rst) // LENGTH_THIMBLE 顶针的数据长度
begin
    if(rst)
    begin
    LENGTH_THIMBLE <= 24'd0; 
    end
    
    else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
    case(addra_0[1:0])
    2'b00:begin LENGTH_THIMBLE <= 24'd0; end
    2'b01:begin LENGTH_THIMBLE <= 24'd3; end
    2'b10:begin LENGTH_THIMBLE <= 24'd2; end
    2'b11:begin LENGTH_THIMBLE <= 24'd1; end
    default:begin LENGTH_THIMBLE<=LENGTH_THIMBLE;  end
    endcase
    end

    else if((select_0_1==1'b1)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin // addra_1[1:0]
    case(addra_1[1:0])
    2'b00:begin LENGTH_THIMBLE <= 24'd0; end
    2'b01:begin LENGTH_THIMBLE <= 24'd3; end
    2'b10:begin LENGTH_THIMBLE <= 24'd2; end
    2'b11:begin LENGTH_THIMBLE <= 24'd1; end
    default:begin LENGTH_THIMBLE<=LENGTH_THIMBLE;  end
    endcase
    end
            
    else
    begin
    LENGTH_THIMBLE <= LENGTH_THIMBLE;
    end     
end

always @ (posedge clk or posedge rst) // LENGTH_DIV4 网络的最低传输长度
begin
    if(rst)
    begin
    LENGTH_DIV4 <= 16'd0; // 默认不顶针
    end
    
    else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
        if(addra_0[1:0] == 2'd0) // 不顶针
        begin
        LENGTH_DIV4 <= {addra_0[15],addra_0[15],addra_0[15:2]};
        end
        
        else
        begin
        LENGTH_DIV4 <= {addra_0[15],addra_0[15],addra_0[15:2]} + 1'b1;
        end
    end

    else if((select_0_1==1'b1)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
    begin
        if(addra_1[1:0] == 2'd0)
        begin
        LENGTH_DIV4 <= {addra_1[15],addra_1[15],addra_1[15:2]};
        end
        
        else
        begin
        LENGTH_DIV4 <= {addra_1[15],addra_1[15],addra_1[15:2]} + 1'b1;
        end
    end
            
    else
    begin
    LENGTH_DIV4 <= LENGTH_DIV4;
    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'd228)&&(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 real_clk_p; // 原文有bug
always @ (posedge clk or posedge rst)
begin
    if(rst)
    begin
    real_clk_p<=1'b0;
    end
        
    else if(((select_0_1==1'b1)&&(rd_cnts<=16'd1540)&&(rd_cnts<=(all_dat_num_1+1))&&(rd_cnts>=16'd2))||((select_0_1==1'b0)&&(rd_cnts<=16'd1540)&&(rd_cnts<=(all_dat_num_0+1))&&(rd_cnts>=16'd2)))
    begin
    real_clk_p<=1'b1;
    end
        
    else
    begin
    real_clk_p<=1'b0;
    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'd1)&&(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
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
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(                         ),// 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(                          ),// 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(                         ),// 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(                          ),// input wire [7 : 0] dinb   不用
  .doutb(doutb_1                  )  // output wire [7 : 0] doutb
);
//


ila_data_recv_com ila_data_recv_com (
	.clk(clk), // input wire clk


	.probe0(din), // input wire [7:0]  probe0  
	.probe1(din_clk_p), // input wire [0:0]  probe1 
	.probe2(delay_din_clk_p), // input wire [0:0]  probe2 
	.probe3(select_0_1), // input wire [0:0]  probe3 
	.probe4(pack_check_pulse), // input wire [0:0]  probe4 
	.probe5(pack_check), // input wire [0:0]  probe5 
	.probe6(pack_end), // input wire [0:0]  probe6 
	.probe7(length_check_pulse), // input wire [0:0]  probe7 
	.probe8(length_check), // input wire [0:0]  probe8 
	.probe9(local_length), // input wire [7:0]  probe9 
	.probe10(wr_pulse), // input wire [0:0]  probe10 
	.probe11(local_cnts), // input wire [15:0]  probe11 
	.probe12(wea_0), // input wire [0:0]  probe12 
	.probe13(wea_1), // input wire [0:0]  probe13 
	.probe14(addra_0), // input wire [15:0]  probe14 
	.probe15(addra_1), // input wire [15:0]  probe15 
	.probe16(delay_dina_0), // input wire [7:0]  probe16 
	.probe17(delay_dina_1), // input wire [7:0]  probe17 
	.probe18(delay_dina_2), // input wire [7:0]  probe18 
	.probe19(all_dat_num_0), // input wire [15:0]  probe19 
	.probe20(all_dat_num_1), // input wire [15:0]  probe20 
	.probe21(rd_cnts), // input wire [15:0]  probe21 
	.probe22(addrb_0), // input wire [15:0]  probe22 
	.probe23(addrb_1), // input wire [15:0]  probe23 
	.probe24(real_clk_p), // input wire [0:0]  probe24 
	.probe25(dout_clk_p), // input wire [0:0]  probe25 
	.probe26(doutb_0), // input wire [7:0]  probe26 
	.probe27(doutb_1), // input wire [7:0]  probe27 
	.probe28(dout), // input wire [15:0]  probe28 
	.probe29(LENGTH_REAL), // input wire [15:0]  probe29 
	.probe30(LENGTH_THIMBLE), // input wire [23:0]  probe30 
	.probe31(LENGTH_DIV4), // input wire [15:0]  probe31 
	.probe32(thimble_valid), // input wire [0:0]  probe32 
	.probe33(min_length), // input wire [15:0]  probe33 
	.probe34(output_flag) // input wire [0:0]  probe34
);

endmodule
相关推荐
DS小龙哥8 小时前
基于Zynq FPGA的雷龙SD NAND存储芯片性能测试
fpga开发·sd nand·雷龙·spi nand·spi nand flash·工业级tf卡·嵌入式tf卡
上理考研周导师17 小时前
第二章 虚拟仪器及其构成原理
fpga开发
FPGA技术实战19 小时前
《探索Zynq MPSoC》学习笔记(二)
fpga开发·mpsoc
bigbig猩猩1 天前
FPGA(现场可编程门阵列)的时序分析
fpga开发
Terasic友晶科技1 天前
第2篇 使用Intel FPGA Monitor Program创建基于ARM处理器的汇编或C语言工程<二>
fpga开发·汇编语言和c语言
码农阿豪1 天前
基于Zynq FPGA对雷龙SD NAND的测试
fpga开发·sd nand·spi nand·spi nand flash·工业级tf卡·嵌入式tf卡
江山如画,佳人北望1 天前
EDA技术简介
fpga开发
淘晶驰AK1 天前
电子设计竞赛准备经历分享
嵌入式硬件·fpga开发
最好有梦想~1 天前
FPGA时序分析和约束学习笔记(4、IO传输模型)
笔记·学习·fpga开发