【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
相关推荐
周湘zx26 分钟前
项目三:信号源的FPGA实现
fpga开发
9527华安2 小时前
FPGA多路MIPI转FPD-Link视频缩放拼接显示,基于IMX327+FPD953架构,提供2套工程源码和技术支持
fpga开发·架构·音视频
上理考研周导师2 小时前
【FPGA】ISE13.4操作手册,新建工程示例
fpga开发
技术小白爱FPGA5 小时前
Xilinx 平台 drp 动态调节 mmcm
fpga开发
北京太速科技股份有限公司7 小时前
太速科技-889-基于RFSOC XCZU49DR的 16T16R的软件无线电硬件
fpga开发
stm 学习ing8 小时前
HDLBits训练5
c语言·fpga开发·fpga·eda·hdlbits·pld·hdl语言
超能力MAX8 小时前
IIC驱动EEPROM
单片机·嵌入式硬件·fpga开发
吉大一菜鸡21 小时前
FPGA学习(基于小梅哥Xilinx FPGA)学习笔记
笔记·学习·fpga开发
9527华安1 天前
FPGA实现MIPI转FPD-Link车载同轴视频传输方案,基于IMX327+FPD953架构,提供工程源码和技术支持
fpga开发·架构·mipi·imx327·fpd-link·fpd953